diff --git a/.claude/rules/api-and-config.md b/.claude/rules/api-and-config.md index bf64a8c9e..83d3473c8 100644 --- a/.claude/rules/api-and-config.md +++ b/.claude/rules/api-and-config.md @@ -2,8 +2,6 @@ - Respect precedence: `options.yml` overrides CLI/env values, which override defaults. - Adding a new option: update `internal/config/options.go` (yaml/flag tags), register in `internal/config/flags.go`, expose a getter, surface it in `*config.Report()`, and write generated values back to `options.yml`. Use `CliTestContext` in `internal/config/test.go` to exercise new flags. -- Adding a `customize.FeatureSettings` flag: a new field defaults to `true` via reflection (`features_default.go`) and is operator-disableable through `PHOTOPRISM_DISABLE_FEATURES` — no new CLI option needed. It cascades: update the full-struct literals in `internal/config/customize/{acl,scope}_test.go` and `internal/config/client_config_test.go` (the longest field name re-aligns every literal via gofmt), and `testdata/settings.yml` self-updates via `TestSettings_Save`. If the flag is only meaningful for accounts/roles, gate it per-session in `customize.Settings.ApplyACL` / `ApplyScope` (e.g. `Account`/`AppPasswords` require `ResourcePassword`/`ActionUpdate`); that shapes the Web UI client config only — enforce server-side behavior on the global flag via a `Config.DisableX()` helper. -- Identify an app-password credential by its session, not its token: `(*entity.Session).IsApplication()` (auth provider `application`) covers every grant that mints one (`password`/`session`/`cli`). The token format and grant type vary, so don't gate on `rnd.IsAppPassword` or `GrantType`. - For `options.yml` writes, prefer config-owned persistence helpers: `Config.SaveOptionsPatch(...)` for generic merges, `Config.SaveClusterOptionsUpdate(...)` for cluster-managed metadata. - Use `pkg/fs.ConfigFilePath` for config filenames so existing `.yml` files stay valid and new installs can adopt `.yaml` transparently. - Use the public accessors on `*config.Config` (e.g. `JWKSUrl()`, `SetJWKSUrl()`) instead of mutating `Config.Options()` directly; reserve raw option tweaks for test fixtures. @@ -22,7 +20,6 @@ ## API Shape Checklist When renaming or adding fields: -- Field casing: **TitleCase** (`UUID`, `Name`, `SiteUrl`) for fields backed by a DB entity (mirror the entity/model), **camelCase** (`storageNamespace`, `redirectUri`) for generated/artificial payloads (client config, session, action/RPC bodies). A filtered/computed entity projection stays TitleCase; an action payload stays camelCase but MAY TitleCase its single entity-identity field (e.g. `UUID`). See `specs/common/field-casing.md`. - Update DTOs in `internal/service/cluster/response.go` and any mappers. - Update handlers and regenerate Swagger: `make fmt-go swag-fmt swag`. - Update tests (search/replace old field names) and examples in `specs/`. @@ -38,5 +35,5 @@ When renaming or adding fields: - Map roles via the shared tables: users through `acl.ParseRole(s)` / `acl.UserRoles[...]`, clients through `acl.ClientRoles[...]`. - Treat `RoleAliasNone` ("none") and an empty string as `RoleNone`; default unknown client roles to `RoleClient`. -- Build CLI role help from the registered role map (never hand-maintained literals) so each edition lists exactly the roles it accepts: `commands.UserRoleUsageFor()` / `Roles.CliUsageString()`, passing CE `acl.UserRoles` or an edition's own static `auth.UserRoles` (reference the edition map directly, not the runtime-reassigned `acl.UserRoles`, to avoid the init-order trap; Portal's map includes `cluster_admin`). For federatable / cluster-instance contexts (LDAP, OIDC group→role, cluster grants) use `acl.ClusterInstanceRolesCliUsageString()` — it excludes `cluster_admin`/`visitor`. `pkg/txt.JoinOr` renders the "a, b, or c" style. +- Build CLI role help from `Roles.CliUsageString()` (e.g. `acl.ClientRoles.CliUsageString()`) — never hand-maintain role lists. - For JWT/client scope checks, use the shared helpers (`acl.ScopePermits` / `acl.ScopeAttrPermits`). diff --git a/.claude/rules/commit-and-docs-style.md b/.claude/rules/commit-and-docs-style.md index 284073b74..5d17e8db1 100644 --- a/.claude/rules/commit-and-docs-style.md +++ b/.claude/rules/commit-and-docs-style.md @@ -27,10 +27,6 @@ Descriptions MUST conclude with a checklist of **Acceptance Criteria**: - `MUST` — required for the issue to be considered complete - `SHOULD` — strongly recommended but not strictly required - `MAY` — optional enhancement -- Keep the checklist current: once the work for a criterion is implemented **and verified**, mark it done (`- [x]`). -- Leave items that are unverified, not yet implemented, or skipped optional (`MAY`) enhancements unchecked. -- An issue is complete only when every `MUST` is checked; never tick a box on the strength of a plan alone or an unrun test. -- When referencing an issue from a commit that fulfills some of its criteria, update the matching boxes first. > Agents MUST create, edit, close, reopen, relabel, or otherwise modify GitHub issues only when explicitly requested by the user. diff --git a/.claude/rules/frontend-rules.md b/.claude/rules/frontend-rules.md index 982f2e9f7..ced3e024e 100644 --- a/.claude/rules/frontend-rules.md +++ b/.claude/rules/frontend-rules.md @@ -39,11 +39,11 @@ ## Frontend Test Gotchas -- Hidden-route UI checks under `/library/hidden` or `/portal/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. +- Hidden-route UI checks under `/library/hidden` or `/portal/admin/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. ## Playwright MCP Usage -- Endpoint `http://localhost:2342/`; logins at `/library/login` (CE/Plus/Pro) and `/portal/login` (Portal). Use local compose admin credentials; if login fails, inspect the active compose env. +- Endpoint `http://localhost:2342/`; logins at `/library/login` (CE/Plus/Pro) and `/portal/admin/login` (Portal). Use local compose admin credentials; if login fails, inspect the active compose env. - Viewports: desktop `1280x900`; mobile uses the mobile Playwright server at `375x667`. Close the browser tab after scripted interactions. - Prefer waits over sleeps; click only visible/enabled elements; use role/label/text selectors (not XPath). - Screenshots: small and reproducible — JPEG, visible viewport, deterministic `.local/screenshots//__.jpg` names, no large inline screenshots. @@ -60,12 +60,8 @@ ## Frontend Translations - Never hardcode locale strings in templates or scripts — every user-visible string MUST go through `$gettext` / `T` so it appears in `frontend/src/locales/translations.pot`. -- **Exception — standardized technical identifiers stay untranslated.** Render protocol/acronym/identifier field labels and option values as literal strings, not via `$gettext`: e.g. `Client ID`, `Client Credentials`, `OIDC`, `UUID`, `Node UUID`. Translating them adds catalog noise and risks ambiguous renderings (e.g. "Client" → German "Kunde"). Common English field names like `Site URL` or `Advertise URL` stay translated. -- **Share role/provider labels, not the selectable lists.** Display names live once in `frontend/src/options/auth.js` (`Roles()` / `Providers()` maps, with `RoleOptions(keys, labelKey)` / `ProviderOptions(keys, labelKey)` builders). Private editions (`plus`/`pro`/`portal`) import these and pass their own key list — the selectable sets legitimately differ per edition (cluster_admin, LDAP/AD, reduced Plus set) but the labels must not be re-listed. -- Extraction source of truth: root `make gettext-extract` (via `scripts/gettext-extract.sh`), which scans `frontend/src` plus available overlays in `plus/frontend`, `pro/frontend`, `portal/frontend`. Feature PRs do **not** commit the resulting `.pot`/`.po` churn — Weblate re-extracts on its refresh cycle (see `specs/frontend/translations.md`); a dedicated "Regenerate translation catalogs" commit is the exception. +- Extraction source of truth: root `make gettext-extract` (via `scripts/gettext-extract.sh`), which scans `frontend/src` plus available overlays in `plus/frontend`, `pro/frontend`, `portal/frontend`. - Avoid punctuation-only gettext keys (e.g. `$gettext("—")`) — they clutter `frontend/src/locales/translations.pot`. -- Catalog integrity gate: run `make gettext-lint` (`scripts/gettext-lint.mjs`) after any `.po`/`.pot` edit. It flags placeholder-set mismatches between `msgid` and `msgstr` (frontend `%{name}`, backend printf verbs), edge-whitespace drift, and `msgfmt -c` c-format fatals — defects that silently break variable substitution at runtime. Leading/trailing/internal whitespace inside a `msgid` is itself runtime-inert (`vue3-gettext` trims + collapses keys on load and lookup), so trailing-space findings are cleanliness, not correctness. -- Trimming a source string's trailing space must stay consistent across template + `.po` + `.pot`: trim the literal, then `make gettext-extract`. Caveat: `msgmerge --no-fuzzy-matching` treats the trimmed `msgid` as new, blanks its `msgstr`, and moves the old translation to an obsolete `#~` block — so carry that translation onto the active trimmed entry (collapse any folded multi-line `#~ msgstr`) before `make gettext-compile`, or every locale renders untranslated. This only fills `msgstr`, so Weblate merges it cleanly. ## Web Templates & Shared Assets diff --git a/.claude/rules/go-testing.md b/.claude/rules/go-testing.md index 736ac3571..1705dbd15 100644 --- a/.claude/rules/go-testing.md +++ b/.claude/rules/go-testing.md @@ -5,7 +5,7 @@ ## Go Testing Patterns -- Tests live next to sources (`_test.go`); group cases with `t.Run(...)` using **PascalCase** names (`Success`, `InvalidRequest`). Consecutive subtests inside the same `Test*` function are written without blank lines between them so the cases read as a compact table; reserve blank lines for separating distinct setup blocks. +- Tests live next to sources (`_test.go`); group cases with `t.Run(...)` using **PascalCase** names (`Success`, `InvalidRequest`). - Do not run multiple test commands in parallel — suites share fixtures, temp assets, and DB state. - Keep Go scratch work inside `internal/...` (Go refuses `internal/` imports from `/tmp`). - Prefer focused runs: `go test ./internal/ -run -count=1`. Avoid `./...` unless needed; heavy packages (`internal/entity`, `internal/photoprism`) take 30–120s on first run. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9c259a0a5..19c0508ec 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -13,7 +13,7 @@ PLEASE PROCEED ONLY IF YOU ARE SURE THAT THIS IS NOT A TECHNICAL SUPPORT INCIDEN 1. Thoroughly review our [Getting Started](https://docs.photoprism.app/getting-started/) and [User Guides](https://docs.photoprism.app/user-guide/). 2. Work through the [Troubleshooting Checklists](https://docs.photoprism.app/getting-started/troubleshooting/) we provide. 3. Do not report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs. -4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support/) to learn more about support options. +4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support) to learn more about support options. THANK YOU! 💎 @@ -23,7 +23,7 @@ THANK YOU! 💎 Links to the related documentation on [docs.photoprism.app](https://docs.photoprism.app/): - ... -*Please never report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs, and do not submit bug reports for the purpose of getting [technical support](https://www.photoprism.app/kb/getting-support/) or because you have not received a response in our [public community forums](https://github.com/photoprism/photoprism/discussions). Thank you very much!* +*Please never report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs, and do not submit bug reports for the purpose of getting [technical support](https://www.photoprism.app/kb/getting-support) or because you have not received a response in our [public community forums](https://github.com/photoprism/photoprism/discussions). Thank you very much!* ### 1. How can we reproduce it? @@ -46,7 +46,7 @@ Always try to determine the cause of your problem using the checklists at for details. +Please include sample files or screenshots that help to reproduce your problem. You can also email files or share a download link, see for details. Visit to learn how to diagnose frontend issues. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 0f3349f00..01ac9afce 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -11,7 +11,7 @@ body: 1. Thoroughly review our [Getting Started](https://docs.photoprism.app/getting-started/) and [User Guides](https://docs.photoprism.app/user-guide/). 2. Work through the [Troubleshooting Checklists](https://docs.photoprism.app/getting-started/troubleshooting/) we provide. 3. Do not report [known issues](https://docs.photoprism.app/known-issues/) or [missing features](https://github.com/photoprism/photoprism/issues) as bugs. - 4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support/) to learn more about support options. + 4. Use [GitHub Discussions](https://github.com/photoprism/photoprism/discussions) for community help, and visit our [Support Guide](https://www.photoprism.app/kb/getting-support) to learn more about support options. - type: textarea id: documented-behavior attributes: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 090c11be8..5cea95fd2 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -4,5 +4,5 @@ contact_links: url: https://github.com/photoprism/photoprism/discussions about: Use Discussions for general questions, community support, and troubleshooting help. - name: Read Our Support Guide - url: https://www.photoprism.app/kb/getting-support/ + url: https://www.photoprism.app/kb/getting-support about: Learn about official support options and how to get assistance with PhotoPrism. diff --git a/AGENTS.md b/AGENTS.md index d919667d8..74fe0eef2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -54,10 +54,6 @@ Optional nested repositories such as `plus/`, `pro/`, `portal/`, and `specs/` ma - Use level-3 Markdown headings for sections within issue descriptions, for example `### Acceptance Criteria`. - Follow with behavior, rationale, technical considerations, and constraints. - End with `- [ ]` checklist items for the acceptance criteria, each using `MUST`, `SHOULD`, or `MAY`. - - Keep the checklist current: once the work for a criterion is implemented **and verified**, mark it done (`- [x]`). - - Leave items that are unverified, not yet implemented, or skipped optional (`MAY`) enhancements unchecked. - - An issue is complete only when every `MUST` is checked; never tick a box on the strength of a plan alone or an unrun test. - - When referencing an issue from a commit that fulfills some of its criteria, update the matching boxes first. - Agents MUST create, edit, close, reopen, relabel, or otherwise modify GitHub issues only when explicitly requested by the user. ### Specifications & Documentation @@ -159,7 +155,7 @@ Formatting and test entry points: - Full suite: `make test`, `make lint` - Go-specific lint, format, and package-test rules live in [`internal/AGENTS.md`](internal/AGENTS.md). - Frontend lint, Vitest, acceptance, and Playwright rules live in [`frontend/AGENTS.md`](frontend/AGENTS.md). -- Go tests live next to their sources; use PascalCase `t.Run(...)` names for related subtests. Keep consecutive subtests inside the same `Test*` function back-to-back without blank lines so the cases read as a compact table; reserve blank lines for separating distinct setup blocks. +- Go tests live next to their sources; use PascalCase `t.Run(...)` names for related subtests. - Do not run multiple test commands in parallel; suites share fixtures, assets, and database state. - Prefer focused test runs such as `go test ./path/to/pkg -run Name -count=1` while iterating. - Use `mariadb -D photoprism` inside the dev shell when you need to inspect MariaDB state directly. diff --git a/CODEMAP.md b/CODEMAP.md index 133312f9e..1d5e5559c 100644 --- a/CODEMAP.md +++ b/CODEMAP.md @@ -70,7 +70,7 @@ HTTP API - `make swag-json` runs a stabilization step (`swaggerfix`) removing duplicated enums for `time.Duration`; API uses integer nanoseconds for durations. - `/api/v1/metrics` (see `internal/api/metrics.go`) exposes Prometheus metrics, including cached filesystem/account usage derived from `config.Usage()`, registered user/guest totals, and portal cluster node counts when `NodeRole=portal`; the handler returns the standard Prometheus exposition content type (`text/plain; version=0.0.4`). - Common groups in `routes.go`: sessions, OAuth/OIDC, config, users, services, thumbnails, video, downloads/zip, index/import, photos/files/labels/subjects/faces, batch ops, cluster, technical (metrics, status, echo). -- Hidden search behavior (used by the hidden route under the configured frontend URI, default `/library/hidden` for CE/Plus/Pro and `/portal/hidden` for Portal) is implemented in `internal/entity/search/photos.go`: +- Hidden search behavior (used by the hidden route under the configured frontend URI, default `/library/hidden` for CE/Plus/Pro and `/portal/admin/hidden` for Portal) is implemented in `internal/entity/search/photos.go`: - `frm.Hidden` enforces `photos.photo_quality = -1` and `photos.deleted_at IS NULL`. - Non-hidden searches exclude errored files by default (`files.file_error = ''`) unless `frm.Error` is explicitly set. - Search DTOs in `internal/entity/search/photos_results.go` expose `FileError` (`files.file_error`) so clients can render hidden reasons without loading full file details first. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 5d3e6cef7..c50ea0812 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,8 +1,8 @@ # PhotoPrism® Code of Conduct -**By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms/), including our [Privacy Policy](https://www.photoprism.app/privacy/) and the following Code of Conduct. It explains the "dos and don’ts" when interacting with our team and other community members.** +**By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms), including our [Privacy Policy](https://www.photoprism.app/privacy) and the following Code of Conduct. It explains the "dos and don’ts" when interacting with our team and other community members.** -*This Code of Conduct was last updated on May 30, 2026. A German translation is available at [photoprism.app/de/code-of-conduct](https://www.photoprism.app/de/code-of-conduct/).* +*This Code of Conduct was last updated on May 6, 2024. A German translation is available at [photoprism.app/de/code-of-conduct](https://www.photoprism.app/de/code-of-conduct).* ## Rules @@ -30,12 +30,16 @@ We have found that many of the issues that new users get upset about when they r ## Reporting -We encourage all community members to resolve problems on their own whenever possible. Serious and persistent violations, such as disrespectful, abusive, harassing, or otherwise unacceptable behavior, [may be reported](https://www.photoprism.app/contact/) to us. +We encourage all community members to resolve problems on their own whenever possible. Serious and persistent violations, such as disrespectful, abusive, harassing, or otherwise unacceptable behavior, [may be reported](https://www.photoprism.app/contact) to us. ## Enforcement -Our community standards will be enforced as necessary to protect everyone's well-being and ensure our discussion forums, chat rooms, and other infrastructure, such as GitHub, can be used as intended. +Our community standards will be enforced as necessary to protect everyone's well-being and to ensure that our discussion forums, chat rooms, and other infrastructure can be used as intended. -In cases where violations may be unintentional and improvement seems possible, we aim to issue warnings before taking further action. +Initial warnings may be issued in the form of a [snarky comment](https://www.urbandictionary.com/define.php?term=snarky), especially if you seem reckless or [surprisingly harsh](https://github.com/photoprism/photoprism/issues/281#issuecomment-1207233135). In serious cases, we will provide a link to this Code of Conduct to avoid misunderstandings. We also reserve the right to delete rants, personal attacks, spam, and unsolicited advertising from our community forums. -In serious cases, we may use technical measures to restrict your access to our infrastructure, including GitHub, forums, and chats, either temporarily or permanently. We also reserve the right to delete rants, personal attacks, spam, and unsolicited advertisements. If you believe we made a mistake, you may [email us](https://www.photoprism.app/contact/) to request an appeal. \ No newline at end of file +Getting a simple **\*plonk\***[^1] in response finally signals that we have lost hope and you're being ignored according to **Rule #3**. This old tradition from Usenet days is as time-saving as it is clear. It is not meant in a disrespectful way. + +In addition, we may use technical measures to temporarily or permanently restrict your access to our infrastructure, including forums and chats. + +[^1]: \*plonk\* including variants such as "Plonk." stands for the metaphorical sound of a user hitting the bottom of the kill file. It was first used in [Usenet forums](https://en.everybodywiki.com/Plonk_(Usenet)), a worldwide distributed discussion system and precursor to the Web. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1fba42708..b4d175e3c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,9 +4,9 @@ We welcome contributions of any kind, including blog posts, tutorials, testing, ## Join the Community ## -Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct/) explains the "dos and don’ts" when interacting with other community members. +Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct) explains the "dos and don’ts" when interacting with other community members. -As a [contributor](https://docs.photoprism.app/developer-guide/), you are also welcome to [contact us directly](https://www.photoprism.app/contact/) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. +As a [contributor](https://docs.photoprism.app/developer-guide/), you are also welcome to [contact us directly](https://www.photoprism.app/contact) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. ## Not a Developer? No Problem ## @@ -36,7 +36,7 @@ We kindly ask you not to report bugs via GitHub Issues **unless you are certain - When reporting a problem, always include the software versions you are using and other information about your environment such as [browser, browser plugins](https://docs.photoprism.app/getting-started/troubleshooting/browsers/), operating system, [storage type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#storage), [memory size](https://docs.photoprism.app/getting-started/troubleshooting/performance/#memory), and [processor](https://docs.photoprism.app/getting-started/troubleshooting/performance/#server-cpu) - Note that all issue **subscribers receive an email notification** from GitHub whenever a new comment is added, so these should only be used for sharing important information and not for discussions, questions or expressing personal opinions -- [Contact us](https://www.photoprism.app/contact/) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works +- [Contact us](https://www.photoprism.app/contact) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works - This gives our team the opportunity to [improve the docs](https://docs.photoprism.app/getting-started/troubleshooting/) and provide best-in-class support to you, instead of handling unclear/duplicate bug reports or triggering a flood of notifications by responding to comments ## Submitting Pull Requests ## @@ -51,7 +51,7 @@ Pull requests solving ["help wanted"](https://github.com/photoprism/photoprism/l ## Contributor License Agreement (CLA) ## -After you submit your first pull request, you will be asked to accept our Contributor License Agreement (CLA). Visit [photoprism.app/cla](https://www.photoprism.app/cla/) and [photoprism.app/oss/faq](https://www.photoprism.app/oss/faq/#cla) to learn more. +After you submit your first pull request, you will be asked to accept our Contributor License Agreement (CLA). Visit [photoprism.app/cla](https://www.photoprism.app/cla) and [photoprism.app/oss/faq](https://www.photoprism.app/oss/faq#cla) to learn more. ## Thank You to All Current and Past Sponsors 💎 ## @@ -76,4 +76,4 @@ Because many of these apps and tools were originally developed for internal use ---- -*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark/). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms/), [Privacy Policy](https://www.photoprism.app/privacy/), and [Code of Conduct](https://www.photoprism.app/code-of-conduct/). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* +*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms), [Privacy Policy](https://www.photoprism.app/privacy), and [Code of Conduct](https://www.photoprism.app/code-of-conduct). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* diff --git a/Dockerfile b/Dockerfile index 2a5bbfc1d..ec6479d6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Ubuntu 26.04 LTS (Resolute Raccoon) -FROM photoprism/develop:260709-resolute +FROM photoprism/develop:260520-resolute # Harden npm usage by default (applies to npm ci / install in dev container) ENV NPM_CONFIG_IGNORE_SCRIPTS=true @@ -26,8 +26,6 @@ WORKDIR "${WORKING_DIR}" # Copy source to image. COPY . . - -# Update scripts in image. COPY --chown=root:root ./scripts/dist/ /scripts/ # Re-install the dev "mariadb" client config so a custom MARIADB_PORT in .env diff --git a/FUNDING.yml b/FUNDING.yml index 59ac9122e..6aef57e9c 100644 --- a/FUNDING.yml +++ b/FUNDING.yml @@ -1,3 +1,3 @@ -custom: "https://www.photoprism.app/editions/#compare" +custom: "https://www.photoprism.app/editions#compare" github: photoprism patreon: photoprism \ No newline at end of file diff --git a/LICENSE b/LICENSE index aec49a5f5..ca13a5762 100644 --- a/LICENSE +++ b/LICENSE @@ -625,7 +625,7 @@ corporate design, product and service names, and any other brand features and elements, whether registered or unregistered („Brand Assets“) — are proprietary assets owned exclusively by PhotoPrism UG („PhotoPrism“). We reserve the right to object to any use or misuse in any jurisdiction -worldwide. Visit to learn more. +worldwide. Visit to learn more. (b) Contributors, licensees, business partners, and other third parties may never claim ownership of PhotoPrism's Brand Assets or brands confusingly diff --git a/Makefile b/Makefile index ea696d52b..e4e460660 100644 --- a/Makefile +++ b/Makefile @@ -89,22 +89,21 @@ test-commands: run-test-commands test-photoprism: run-test-photoprism test-short: run-test-short test-mariadb: reset-acceptance run-test-mariadb -acceptance-run-chromium: storage/acceptance acceptance-sqlite-restart-1 wait-1 acceptance-api acceptance-sqlite-stop-1 acceptance-auth-sqlite-restart wait-2 acceptance-auth acceptance-auth-sqlite-stop acceptance-sqlite-restart-3 wait-3 acceptance acceptance-sqlite-stop-3 -acceptance-run-chromium-short: storage/acceptance acceptance-auth-sqlite-restart wait-1 acceptance-auth-short acceptance-auth-sqlite-stop acceptance-sqlite-restart-2 wait-2 acceptance-short acceptance-sqlite-stop-2 -acceptance-auth-run-chromium: storage/acceptance acceptance-auth-sqlite-restart wait-1 acceptance-auth acceptance-auth-sqlite-stop -acceptance-public-run-chromium: storage/acceptance acceptance-sqlite-restart-1 wait-1 acceptance acceptance-sqlite-stop-1 -acceptance-api-run-chromium: storage/acceptance acceptance-sqlite-restart-1 wait-1 acceptance-api acceptance-sqlite-stop-1 +acceptance-run-chromium: storage/acceptance acceptance-auth-sqlite-restart wait acceptance-auth acceptance-auth-sqlite-stop acceptance-sqlite-restart wait-2 acceptance acceptance-sqlite-stop +acceptance-run-chromium-short: storage/acceptance acceptance-auth-sqlite-restart wait acceptance-auth-short acceptance-auth-sqlite-stop acceptance-sqlite-restart wait-2 acceptance-short acceptance-sqlite-stop +acceptance-auth-run-chromium: storage/acceptance acceptance-auth-sqlite-restart wait acceptance-auth acceptance-auth-sqlite-stop +acceptance-public-run-chromium: storage/acceptance acceptance-sqlite-restart wait acceptance acceptance-sqlite-stop help: list list: @awk '/^[[:alnum:]]+[^[:space:]]+:/ {printf "%s",substr($$1,1,length($$1)-1); if (match($$0,/#/)) {desc=substr($$0,RSTART+1); sub(/^[[:space:]]+/,"",desc); printf " - %s\n",desc} else printf "\n" }' "$(firstword $(MAKEFILE_LIST))" -wait-%: +wait: + sleep 20 +wait-2: sleep 20 show-rev: @git rev-parse HEAD show-build: @echo "$(BUILD_TAG)" -tag-release: - scripts/tag-release.sh $(EDITION) $(TAG_ARGS) test-all: test acceptance-run-chromium fmt: fmt-js fmt-go fmt-swag format: format-tables fmt-go fmt-swag @@ -181,8 +180,6 @@ gettext-compile: $(MAKE) -C frontend gettext-compile gettext-clear-fuzzy: ./scripts/gettext-clear-fuzzy.sh -gettext-lint: - node scripts/gettext-lint.mjs clean: rm -f *.log .test* [ ! -f "$(BINARY_NAME)" ] || rm -f $(BINARY_NAME) @@ -227,7 +224,7 @@ install-onnx: sudo scripts/dist/install-onnx.sh install-darktable: sudo scripts/dist/install-darktable.sh -acceptance-sqlite-restart-%: acceptance-sqlite-stop-% +acceptance-sqlite-restart: acceptance-sqlite-stop cp -f storage/acceptance/backup.db storage/acceptance/index.db cp -f storage/acceptance/config-sqlite/settingsBackup.yml storage/acceptance/config-sqlite/settings.yml rm -rf storage/acceptance/sidecar/2020 @@ -238,7 +235,7 @@ acceptance-sqlite-restart-%: acceptance-sqlite-stop-% rm -rf storage/acceptance/originals/2013 rm -rf storage/acceptance/originals/2017 ./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" start -d -acceptance-sqlite-stop-%: +acceptance-sqlite-stop: ./photoprism --auth-mode="public" -c "./storage/acceptance/config-sqlite" stop acceptance-auth-sqlite-restart: acceptance-auth-sqlite-stop cp -f storage/acceptance/backup.db storage/acceptance/index.db @@ -283,7 +280,8 @@ dep-list-all: go list -u -m -json all | go-mod-outdated vuln: audit audit: audit-frontend audit-backend -audit-frontend: npm-audit +audit-frontend: + npm audit --ignore-scripts --no-fund --no-audit --no-update-notifier audit-backend: dep-vuln dep-audit: dep-vuln dep-vuln: @@ -301,22 +299,12 @@ npm-version: dep-npm: @echo "Installing NPM package manager..." @if command -v sudo >/dev/null 2>&1; then \ - sudo npm install -g --location=global --ignore-scripts --no-audit --no-fund --no-update-notifier "npm@latest"; \ + sudo npm install -g --location=global --ignore-scripts --no-fund --no-audit --no-update-notifier "npm@latest"; \ else \ - npm install -g --location=global --ignore-scripts --no-audit --no-fund --no-update-notifier "npm@latest"; \ + npm install -g --location=global --ignore-scripts --no-fund --no-audit --no-update-notifier "npm@latest"; \ fi -dep-js: npm-ci -npm-ci: - $(info Clean install of NPM dependencies...) - npm ci --ignore-scripts --no-audit --no-fund --no-update-notifier -npm-install: - $(info Installing NPM dependencies...) - npm install --save --ignore-scripts --no-audit --no-fund --no-update-notifier -npm-update: - $(info Updating NPM dependencies in package.json and package-lock.json...) - npm update --save --package-lock --ignore-scripts --no-audit --no-fund --no-update-notifier -npm-audit: - npm audit --ignore-scripts --no-fund --no-update-notifier +dep-js: + npm ci --ignore-scripts --no-update-notifier --no-audit tools: gh claude codex codex: dep-codex codex-version codex-skills codex-version: @@ -325,9 +313,9 @@ dep-codex: @echo "Installing Codex CLI..." @[ -n "$(CODEX_HOME)" ] && [ "$(CODEX_HOME)" != "/" ] && install -d -m 700 -- "$(CODEX_HOME)" || true @if command -v sudo >/dev/null 2>&1; then \ - sudo npm install -g --location=global --ignore-scripts --no-audit --no-fund --no-update-notifier "@openai/codex@latest"; \ + sudo npm install -g --location=global --ignore-scripts --no-fund --no-audit --no-update-notifier "@openai/codex@latest"; \ else \ - npm install -g --location=global --ignore-scripts --no-audit --no-fund --no-update-notifier "@openai/codex@latest"; \ + npm install -g --location=global --ignore-scripts --no-fund --no-audit --no-update-notifier "@openai/codex@latest"; \ fi skills: agents-skills claude-skills agents-skills: codex-skills @@ -439,43 +427,32 @@ build-static: scripts/build.sh static $(BINARY_NAME) build-libheif: build-libheif-amd64 build-libheif-arm64 build-libheif-armv7 build-libheif-amd64: - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:trixie ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.21.2 build-libheif-arm64: - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.23.1 - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:trixie ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:questing ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh v1.21.2 + docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:bookworm ./scripts/dist/build-libheif.sh v1.21.2 build-libheif-armv7: - docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh v1.23.1 + docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh v1.21.2 build-libheif-latest: build-libheif-amd64-latest build-libheif-arm64-latest build-libheif-armv7-latest build-libheif-amd64-latest: - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:questing ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:noble ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh build-libheif-arm64-latest: - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:resolute ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:questing ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:plucky ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:noble ./scripts/dist/build-libheif.sh docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:jammy ./scripts/dist/build-libheif.sh build-libheif-armv7-latest: docker run --rm -u $(UID) --platform=arm --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm -e SYSTEM_ARCH=arm photoprism/develop:armv7 ./scripts/dist/build-libheif.sh -build-libheif-deb: build-libheif-deb-amd64 build-libheif-deb-arm64 -build-libheif-deb-amd64: - docker run --rm -u $(UID) --platform=amd64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=amd64 -e SYSTEM_ARCH=amd64 photoprism/develop:resolute ./scripts/dist/build-libheif-deb.sh v1.23.1 -build-libheif-deb-arm64: - docker run --rm -u $(UID) --platform=arm64 --pull=always -v ".:/go/src/github.com/photoprism/photoprism" -e BUILD_ARCH=arm64 -e SYSTEM_ARCH=arm64 photoprism/develop:resolute ./scripts/dist/build-libheif-deb.sh v1.23.1 build-tensorflow: docker-tensorflow-amd64 docker-tensorflow: docker-tensorflow-amd64 docker-tensorflow-amd64: @@ -501,23 +478,20 @@ test-js: (cd frontend && npm run test) acceptance: $(info Running public-mode tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public --config-file ./.testcaferc.cjs "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public --config-file ./testcaferc.json --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public --config-file ./testcaferc.json "tests/acceptance") acceptance-short: $(info Running JS acceptance tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public,type=short --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public,type=short --config-file ./.testcaferc.cjs "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"auth[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=public,type=short --config-file ./testcaferc.json --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=public,type=short --config-file ./testcaferc.json "tests/acceptance") acceptance-auth: $(info Running JS acceptance-auth tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth --config-file ./.testcaferc.cjs "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth --config-file ./testcaferc.json --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth --config-file ./testcaferc.json "tests/acceptance") acceptance-auth-short: $(info Running JS acceptance-auth tests in Chrome...) - (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth,type=short --config-file ./.testcaferc.cjs --test "testname" "tests/acceptance"') - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth,type=short --config-file ./.testcaferc.cjs "tests/acceptance") -acceptance-api: - $(info Running JS acceptance-api tests in Chrome...) - (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-meta mode=api --config-file ./.testcaferc.cjs "tests/acceptance") + (cd frontend && find ./tests/acceptance -type f -name "*.js" | xargs -i perl -0777 -ne 'while(/(?:mode: \"public[^,]*\,)|(Multi-Window\:[A-Za-z 0-9\-_]*)/g){print "$$1\n" if ($$1);}' {} | xargs -I testname bash -c 'npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --experimental-multiple-windows --test-meta mode=auth,type=short --config-file ./testcaferc.json --test "testname" "tests/acceptance"') + (cd frontend && npm run testcafe -- "chrome --headless=new --use-gl=angle --use-angle=swiftshader --disable-features=LocalNetworkAccessChecks" --test-grep "^(Common|Core)\:*" --test-meta mode=auth,type=short --config-file ./testcaferc.json "tests/acceptance") vitest-watch: $(info Running Vitest unit tests in watch mode...) (cd frontend && npm run test-watch) @@ -611,7 +585,7 @@ docker-pull: $(DOCKER_COMPOSE) -f compose.latest.yaml pull --ignore-pull-failures build-docker: docker-build docker-build: - $(DOCKER_COMPOSE) --profile=postgres --profile=keycloak pull --ignore-pull-failures + $(DOCKER_COMPOSE) --profile=all pull --ignore-pull-failures $(DOCKER_COMPOSE) down --remove-orphans $(DOCKER_COMPOSE) build --pull nvidia: nvidia-up @@ -1082,6 +1056,9 @@ docker-local-develop-resolute: docker-ddns: docker pull golang:alpine scripts/docker/buildx-multi.sh ddns linux/amd64,linux/arm64 $(BUILD_DATE) +docker-goproxy: + docker pull golang:alpine + scripts/docker/buildx-multi.sh goproxy linux/amd64,linux/arm64 $(BUILD_DATE) demo: docker-demo docker-demo: docker-demo-latest docker-demo-all: docker-demo-latest docker-demo-debian diff --git a/NOTICE b/NOTICE index 1c2ce81f0..1125a4a45 100644 --- a/NOTICE +++ b/NOTICE @@ -9,7 +9,7 @@ The following 3rd-party software packages may be used by or distributed with PhotoPrism. Any information relevant to third-party vendors listed below are collected using common, reasonable means. -Date generated: 2026-07-09 +Date generated: 2026-05-20 ================================================================================ @@ -267,8 +267,8 @@ limitations under the License. -------------------------------------------------------------------------------- Package: github.com/abema/go-mp4 -Version: v1.7.1 -License: MIT (https://github.com/abema/go-mp4/blob/v1.7.1/LICENSE) +Version: v1.6.0 +License: MIT (https://github.com/abema/go-mp4/blob/v1.6.0/LICENSE) MIT License @@ -294,52 +294,6 @@ SOFTWARE. -------------------------------------------------------------------------------- -Package: github.com/antchfx/xmlquery -Version: v1.5.1 -License: MIT (https://github.com/antchfx/xmlquery/blob/v1.5.1/LICENSE) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. --------------------------------------------------------------------------------- - -Package: github.com/antchfx/xpath -Version: v1.3.6 -License: MIT (https://github.com/antchfx/xpath/blob/v1.3.6/LICENSE) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. --------------------------------------------------------------------------------- - Package: github.com/beorn7/perks/quantile Version: v1.0.1 License: MIT (https://github.com/beorn7/perks/blob/v1.0.1/LICENSE) @@ -2433,8 +2387,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -------------------------------------------------------------------------------- Package: github.com/golang/geo -Version: v0.0.0-20260706204034-7a8d33c78269 -License: Apache-2.0 (https://github.com/golang/geo/blob/7a8d33c78269/LICENSE) +Version: v0.0.0-20260512202753-e3c51de6d1b6 +License: Apache-2.0 (https://github.com/golang/geo/blob/e3c51de6d1b6/LICENSE) Apache License @@ -2641,204 +2595,6 @@ License: Apache-2.0 (https://github.com/golang/geo/blob/7a8d33c78269/LICENSE) -------------------------------------------------------------------------------- -Package: github.com/golang/groupcache/lru -Version: v0.0.0-20210331224755-41bb18bfe9da -License: Apache-2.0 (https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE) - -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --------------------------------------------------------------------------------- - Package: github.com/google/jsonschema-go/jsonschema Version: v0.4.3 License: MIT (https://github.com/google/jsonschema-go/blob/v0.4.3/LICENSE) @@ -4060,8 +3816,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: github.com/klauspost/compress -Version: v1.19.0 -License: Apache-2.0 (https://github.com/klauspost/compress/blob/v1.19.0/LICENSE) +Version: v1.18.6 +License: Apache-2.0 (https://github.com/klauspost/compress/blob/v1.18.6/LICENSE) Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2019 Klaus Post. All rights reserved. @@ -4371,8 +4127,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -------------------------------------------------------------------------------- Package: github.com/klauspost/compress/internal/snapref -Version: v1.19.0 -License: BSD-3-Clause (https://github.com/klauspost/compress/blob/v1.19.0/internal/snapref/LICENSE) +Version: v1.18.6 +License: BSD-3-Clause (https://github.com/klauspost/compress/blob/v1.18.6/internal/snapref/LICENSE) Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. @@ -4405,8 +4161,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: github.com/klauspost/compress/zstd/internal/xxhash -Version: v1.19.0 -License: MIT (https://github.com/klauspost/compress/blob/v1.19.0/zstd/internal/xxhash/LICENSE.txt) +Version: v1.18.6 +License: MIT (https://github.com/klauspost/compress/blob/v1.18.6/zstd/internal/xxhash/LICENSE.txt) Copyright (c) 2016 Caleb Spare @@ -4434,8 +4190,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Package: github.com/klauspost/cpuid/v2 -Version: v2.4.0 -License: MIT (https://github.com/klauspost/cpuid/blob/v2.4.0/LICENSE) +Version: v2.3.0 +License: MIT (https://github.com/klauspost/cpuid/blob/v2.3.0/LICENSE) The MIT License (MIT) @@ -4967,8 +4723,8 @@ SOFTWARE. -------------------------------------------------------------------------------- Package: github.com/modelcontextprotocol/go-sdk -Version: v1.6.1 -License: Apache-2.0 (https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.1/LICENSE) +Version: v1.6.0 +License: Apache-2.0 (https://github.com/modelcontextprotocol/go-sdk/blob/v1.6.0/LICENSE) The MCP project is undergoing a licensing transition from the MIT License to the Apache License, Version 2.0 ("Apache-2.0"). All new code and specification contributions to the project are licensed under Apache-2.0. Documentation contributions (excluding specifications) are licensed under CC-BY-4.0. @@ -6138,8 +5894,8 @@ License: Apache-2.0 (https://github.com/prometheus/client_model/blob/v0.6.2/LICE -------------------------------------------------------------------------------- Package: github.com/prometheus/common -Version: v0.69.0 -License: Apache-2.0 (https://github.com/prometheus/common/blob/v0.69.0/LICENSE) +Version: v0.67.5 +License: Apache-2.0 (https://github.com/prometheus/common/blob/v0.67.5/LICENSE) Apache License Version 2.0, January 2004 @@ -7217,8 +6973,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Package: github.com/yalue/onnxruntime_go -Version: v1.31.0 -License: MIT (https://github.com/yalue/onnxruntime_go/blob/v1.31.0/LICENSE) +Version: v1.30.1 +License: MIT (https://github.com/yalue/onnxruntime_go/blob/v1.30.1/LICENSE) Copyright (c) 2023 Nathan Otterness @@ -8851,6 +8607,214 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- +Package: go.yaml.in/yaml/v2 +Version: v2.4.4 +License: Apache-2.0 (https://github.com/yaml/go-yaml/blob/v2.4.4/LICENSE) + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------- + Package: go4.org/media/heif Version: v0.0.0-20260112195520-a5071408f32f License: Apache-2.0 (https://github.com/go4org/go4/blob/a5071408f32f/LICENSE) @@ -9061,8 +9025,8 @@ License: Apache-2.0 (https://github.com/go4org/go4/blob/a5071408f32f/LICENSE) -------------------------------------------------------------------------------- Package: golang.org/x/crypto -Version: v0.54.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.54.0:LICENSE) +Version: v0.51.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.51.0:LICENSE) Copyright 2009 The Go Authors. @@ -9095,8 +9059,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/image -Version: v0.44.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.44.0:LICENSE) +Version: v0.40.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.40.0:LICENSE) Copyright 2009 The Go Authors. @@ -9129,8 +9093,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/mod/semver -Version: v0.38.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/mod/+/v0.38.0:LICENSE) +Version: v0.36.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/mod/+/v0.36.0:LICENSE) Copyright 2009 The Go Authors. @@ -9163,8 +9127,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/net -Version: v0.57.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.57.0:LICENSE) +Version: v0.54.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.54.0:LICENSE) Copyright 2009 The Go Authors. @@ -9231,8 +9195,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/sync/errgroup -Version: v0.22.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.22.0:LICENSE) +Version: v0.20.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.20.0:LICENSE) Copyright 2009 The Go Authors. @@ -9265,8 +9229,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/sys -Version: v0.47.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.47.0:LICENSE) +Version: v0.44.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.44.0:LICENSE) Copyright 2009 The Go Authors. @@ -9299,8 +9263,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Package: golang.org/x/text -Version: v0.40.0 -License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.40.0:LICENSE) +Version: v0.37.0 +License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.37.0:LICENSE) Copyright 2009 The Go Authors. @@ -9646,95 +9610,94 @@ License: Apache-2.0 (https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE) -------------------------------------------------------------------------------- Package License Copyright -------------------------------------------------------------------------------- -@babel/cli MIT The Babel Team (https://babel.dev/team) -@babel/core MIT The Babel Team (https://babel.dev/team) -@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) -@babel/preset-env MIT The Babel Team (https://babel.dev/team) -@babel/register MIT The Babel Team (https://babel.dev/team) -@babel/runtime MIT The Babel Team (https://babel.dev/team) -@eslint/eslintrc MIT Nicholas C. Zakas -@eslint/js MIT n/a -@mdi/font Apache-2.0 Austin Andrews -@photo-sphere-viewer/core MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr -@photo-sphere-viewer/equirectangular-video-adapter MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr -@photo-sphere-viewer/video-plugin MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr -@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) -@vitejs/plugin-vue MIT Evan You -@vitest/coverage-v8 MIT Anthony Fu -@vue/compiler-sfc MIT Evan You -@vue/language-server MIT n/a -@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com -@vvo/tzdb MIT Vincent Voyer -axios MIT Matt Zabriskie -axios-mock-adapter MIT Colin Timmermans -babel-loader MIT Luis Couto -babel-plugin-polyfill-corejs3 MIT n/a -browserslist MIT Andrey Sitnik -core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru -cross-env MIT Kent C. Dodds (https://kentcdodds.com) -css-loader MIT Tobias Koppers @sokra -cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info -eslint MIT Nicholas C. Zakas -eslint-config-prettier MIT Simon Lydell -eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -eslint-plugin-html ISC n/a -eslint-plugin-import MIT Ben Mosher -eslint-plugin-node MIT Toru Nagashima -eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) -eslint-plugin-vuetify MIT Kael Watts-Deuchar -eslint-webpack-plugin MIT Ricardo Gobbo de Souza -eventsource-polyfill MIT amvtek -file-loader MIT Tobias Koppers @sokra -file-saver MIT Eli Grey -globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -hls.js Apache-2.0 n/a -i MIT Pavan Kumar Sunkara (pksunkara.github.com) -jsdom MIT n/a -luxon MIT Isaac Cambron -maplibre-gl BSD-3-Clause n/a -memoize-one MIT Alex Reardon -mini-css-extract-plugin MIT Tobias Koppers @sokra -minimist MIT James Halliday mail@substack.net http://substack.net -node-storage-shim ISC Michael Nahkies -passive-events-support MIT Ignas Damunskis -photoswipe MIT Dmytro Semenov (https://dimsemenov.com) -playwright Apache-2.0 Microsoft Corporation -postcss MIT Andrey Sitnik -postcss-import MIT Maxime Thirouin -postcss-loader MIT Andrey Sitnik -postcss-preset-env MIT-0 n/a -postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com -prettier MIT James Long -pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk -regenerator-runtime MIT Ben Newman -resolve-url-loader MIT bholloway -sanitize-html MIT Apostrophe Technologies, Inc. -sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 -sass-loader MIT J. Tangelder -sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com -style-loader MIT Tobias Koppers @sokra -svg-url-loader MIT Hovhannes Babayan -tar BlueOak-1.0.0 Isaac Z. Schlueter -url-loader MIT Tobias Koppers @sokra -util MIT Joyent http://www.joyent.com -vite MIT Evan You -vitest MIT Anthony Fu -vue MIT Evan You -vue-3-sanitize MIT Vannsl, Vanessa Otto -vue-loader MIT Evan You -vue-loader-plugin ISC Ivan liu -vue-luxon MIT Cas Bloem -vue-router MIT Eduardo San Martin Morote posva13@gmail.com -vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com -vue-style-loader MIT Evan You -vue3-gettext MIT Leo Zurbriggen -vuetify MIT John Leider john@vuetifyjs.com -webpack MIT Tobias Koppers @sokra -webpack-bundle-analyzer MIT Yury Grunin -webpack-cli MIT n/a -webpack-hot-middleware MIT Glen Mailer -webpack-manifest-plugin MIT Dane Thurber -webpack-md5-hash MIT Kirill Ermolov -webpack-merge MIT Juho Vepsalainen -webpack-plugin-vuetify MIT Kael Watts-Deuchar -workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team +@babel/cli MIT The Babel Team (https://babel.dev/team) +@babel/core MIT The Babel Team (https://babel.dev/team) +@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) +@babel/preset-env MIT The Babel Team (https://babel.dev/team) +@babel/register MIT The Babel Team (https://babel.dev/team) +@babel/runtime MIT The Babel Team (https://babel.dev/team) +@eslint/eslintrc MIT Nicholas C. Zakas +@eslint/js MIT n/a +@mdi/font Apache-2.0 Austin Andrews +@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) +@vitejs/plugin-vue MIT Evan You +@vitest/browser MIT n/a +@vitest/coverage-v8 MIT Anthony Fu +@vitest/ui MIT n/a +@vue/compiler-sfc MIT Evan You +@vue/language-server MIT n/a +@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com +@vvo/tzdb MIT Vincent Voyer +axios MIT Matt Zabriskie +axios-mock-adapter MIT Colin Timmermans +babel-loader MIT Luis Couto +babel-plugin-istanbul BSD-3-Clause Thai Pangsakulyanont @dtinth +babel-plugin-polyfill-corejs3 MIT n/a +browserslist MIT Andrey Sitnik +core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru +cross-env MIT Kent C. Dodds (https://kentcdodds.com) +css-loader MIT Tobias Koppers @sokra +cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info +eslint MIT Nicholas C. Zakas +eslint-config-prettier MIT Simon Lydell +eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +eslint-plugin-html ISC n/a +eslint-plugin-import MIT Ben Mosher +eslint-plugin-node MIT Toru Nagashima +eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) +eslint-plugin-vuetify MIT Kael Watts-Deuchar +eslint-webpack-plugin MIT Ricardo Gobbo de Souza +eventsource-polyfill MIT amvtek +file-loader MIT Tobias Koppers @sokra +file-saver MIT Eli Grey +globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +hls.js Apache-2.0 n/a +i MIT Pavan Kumar Sunkara (pksunkara.github.com) +jsdom MIT n/a +luxon MIT Isaac Cambron +maplibre-gl BSD-3-Clause n/a +memoize-one MIT Alex Reardon +mini-css-extract-plugin MIT Tobias Koppers @sokra +minimist MIT James Halliday mail@substack.net http://substack.net +node-storage-shim ISC Michael Nahkies +passive-events-support MIT Ignas Damunskis +photoswipe MIT Dmytro Semenov (https://dimsemenov.com) +playwright Apache-2.0 Microsoft Corporation +postcss MIT Andrey Sitnik +postcss-import MIT Maxime Thirouin +postcss-loader MIT Andrey Sitnik +postcss-preset-env MIT-0 n/a +postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com +prettier MIT James Long +pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk +regenerator-runtime MIT Ben Newman +resolve-url-loader MIT bholloway +sanitize-html MIT Apostrophe Technologies, Inc. +sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 +sass-loader MIT J. Tangelder +sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com +style-loader MIT Tobias Koppers @sokra +svg-url-loader MIT Hovhannes Babayan +tar BlueOak-1.0.0 Isaac Z. Schlueter +url-loader MIT Tobias Koppers @sokra +util MIT Joyent http://www.joyent.com +vitest MIT Anthony Fu +vue MIT Evan You +vue-3-sanitize MIT Vannsl, Vanessa Otto +vue-loader MIT Evan You +vue-loader-plugin ISC Ivan liu +vue-luxon MIT Cas Bloem +vue-router MIT Eduardo San Martin Morote posva13@gmail.com +vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com +vue-style-loader MIT Evan You +vue3-gettext MIT Leo Zurbriggen +vuetify MIT John Leider john@vuetifyjs.com +webpack MIT Tobias Koppers @sokra +webpack-bundle-analyzer MIT Yury Grunin +webpack-cli MIT n/a +webpack-hot-middleware MIT Glen Mailer +webpack-manifest-plugin MIT Dane Thurber +webpack-md5-hash MIT Kirill Ermolov +webpack-merge MIT Juho Vepsalainen +webpack-plugin-vuetify MIT Kael Watts-Deuchar +workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team diff --git a/README.md b/README.md index 8f39569d3..354f11d7d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ PhotoPrism: Browse Your Life in Pictures [![Bluesky Social](https://dl.photoprism.app/img/badges/badge-bluesky.svg)](https://bsky.app/profile/photoprism.app) [![Mastodon](https://dl.photoprism.app/img/badges/badge-floss-social.svg)](https://floss.social/@photoprism) -PhotoPrism® is an AI-powered, privacy-first app for browsing, organizing, and sharing photos and videos. It helps tag, search, and rediscover media without getting in your way, whether self-hosted or in the cloud. +PhotoPrism® is an AI-Powered Photos App for the [Decentralized Web](https://en.wikipedia.org/wiki/Decentralized_web). +It makes use of the latest technologies to tag and find pictures automatically without getting in your way. +You can run it at home, on a private server, or in the cloud. ![](https://dl.photoprism.app/img/ui/2025/desktop-search.jpg) @@ -20,7 +22,7 @@ To get a first impression, you are welcome to play with our [public demo](https: -* Browse [all your pictures](https://docs.photoprism.app/user-guide/organize/browse/) without worrying about [RAW images](https://www.photoprism.app/kb/file-formats/) or [video formats](https://docs.photoprism.app/user-guide/organize/video/) +* Browse [all your pictures](https://docs.photoprism.app/user-guide/organize/browse/) without worrying about [RAW images](https://www.photoprism.app/kb/file-formats) or [video formats](https://docs.photoprism.app/user-guide/organize/video/) * Whether you're using a phone, tablet, or desktop computer, our [intuitive PWA](https://try.photoprism.app/) provides a native app-like experience and can be [easily installed](https://docs.photoprism.app/user-guide/pwa/) on your home screen * Quickly find specific photos and videos with [powerful search filters](https://docs.photoprism.app/user-guide/search/filters/) that can be combined and are available for [many different properties](https://docs.photoprism.app/user-guide/search/filters/#filter-reference), including [labels](https://try.photoprism.app/library/labels), [location](https://try.photoprism.app/library/places?q=s2:47a85a63f764), [resolution](https://try.photoprism.app/library/browse?view=cards&q=mp:4), [color](https://try.photoprism.app/library/browse?view=cards&q=color:red), [chroma](https://try.photoprism.app/library/browse?view=cards&q=mono%3Atrue), and [quality](https://try.photoprism.app/library/review) * [Automatically labels your pictures](https://try.photoprism.app/library/labels) based on content and location, and recognizes the faces of [your family and friends](https://try.photoprism.app/library/people/new) @@ -30,7 +32,7 @@ To get a first impression, you are welcome to play with our [public demo](https: * [Use compatible apps](https://docs.photoprism.app/user-guide/native-apps/) like [PhotoSync](https://link.photoprism.app/photosync) to back up iOS and Android phones in the background * WebDAV clients such as [Microsoft's Windows Explorer](https://docs.photoprism.app/user-guide/sync/webdav/#__tabbed_1_2) and [Apple's Finder](https://docs.photoprism.app/user-guide/sync/webdav/#connect-to-a-webdav-server) can [connect directly to PhotoPrism](https://docs.photoprism.app/user-guide/sync/webdav/), allowing you to open, edit, and delete files from your computer as if they were local -Being completely [**self-funded and independent**](https://link.photoprism.app/membership), we can promise you that we will [never sell your data](https://www.photoprism.app/privacy/) and that we will [always be transparent](https://www.photoprism.app/terms/) about our software and services. Your data will never be shared with Google, Amazon, Microsoft or Apple unless you intentionally upload files to one of their services. 🔒 +Being completely [**self-funded and independent**](https://link.photoprism.app/membership), we can promise you that we will [never sell your data](https://www.photoprism.app/privacy) and that we will [always be transparent](https://www.photoprism.app/terms) about our software and services. Your data will never be shared with Google, Amazon, Microsoft or Apple unless you intentionally upload files to one of their services. 🔒 ## Getting Started ## @@ -43,18 +45,18 @@ See our [Getting Started FAQ](https://docs.photoprism.app/getting-started/faq/#h ## Support Our Mission 💎 ## -**PhotoPrism is 100% self-funded and independent.** Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq/#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! +**PhotoPrism is 100% self-funded and independent.** Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! -Our members [enjoy additional features](https://www.photoprism.app/kb/personal/), including access to [interactive world maps](https://try.photoprism.app/library/places), and can join our private chat room to [connect with our team](https://www.photoprism.app/about/team/). We currently have the following membership options: +Our members [enjoy additional features](https://www.photoprism.app/kb/personal), including access to [interactive world maps](https://try.photoprism.app/library/places), and can join our private chat room to [connect with our team](https://www.photoprism.app/about/team). We currently have the following membership options: -- You can [sign up directly on our website](https://link.photoprism.app/membership) and pay with credit card or SEPA through Stripe, so you don't need to [link an external account](https://www.photoprism.app/kb/activation/) and can easily upgrade or downgrade at any time +- You can [sign up directly on our website](https://link.photoprism.app/membership) and pay with credit card or SEPA through Stripe, so you don't need to [link an external account](https://www.photoprism.app/kb/activation) and can easily upgrade or downgrade at any time - Alternatively, [Patreon](https://link.photoprism.app/patreon) also supports PayPal, additional currencies, and lets you choose between monthly and annual billing for all tiers -If you currently support us through [GitHub Sponsors](https://link.photoprism.app/sponsor), you can also [register on our website](https://my.photoprism.app/register) and use the *Activate GitHub Sponsors Membership* button to link your account. For details on this and how to [link your Patreon account](https://www.patreon.com/pledges), see our [Activation Guide](https://www.photoprism.app/kb/activation/). +If you currently support us through [GitHub Sponsors](https://link.photoprism.app/sponsor), you can also [register on our website](https://my.photoprism.app/register) and use the *Activate GitHub Sponsors Membership* button to link your account. For details on this and how to [link your Patreon account](https://www.patreon.com/pledges), see our [Activation Guide](https://www.photoprism.app/kb/activation). -You are [welcome to contact us](https://www.photoprism.app/contact/) for change requests, membership questions, and business partnerships. +You are [welcome to contact us](https://www.photoprism.app/contact) for change requests, membership questions, and business partnerships. -[View Membership FAQ ›](https://www.photoprism.app/membership/faq/) [Sign Up ›](https://link.photoprism.app/membership) +[View Membership FAQ ›](https://www.photoprism.app/kb/membership) [Sign Up ›](https://link.photoprism.app/membership) ### Why Your Support Matters ### @@ -81,7 +83,7 @@ Our [Project Roadmap](https://link.photoprism.app/roadmap) shows what tasks are Be aware that we have a zero-bug policy and do our best to help users when they need support or have other questions. This comes at a price though, as we can't give exact release dates for new features. Our team receives many more requests than can be implemented, so we want to emphasize that we are in no way obligated to implement the features, enhancements, or other changes you request. We do, however, appreciate your feedback and carefully consider all requests. -**Because sustained funding is key to quickly releasing new features, we encourage you to support our mission by [signing up for a personal membership](https://link.photoprism.app/membership) or [purchasing a commercial license](https://www.photoprism.app/teams/#compare).** +**Because sustained funding is key to quickly releasing new features, we encourage you to support our mission by [signing up for a personal membership](https://link.photoprism.app/membership) or [purchasing a commercial license](https://www.photoprism.app/teams#compare).** [Become a Member ›](https://link.photoprism.app/membership) @@ -89,18 +91,18 @@ Be aware that we have a zero-bug policy and do our best to help users when they We kindly ask you not to report bugs via GitHub Issues **unless you are certain to have found a fully reproducible and previously unreported issue** that must be fixed directly in the app. Thank you for your careful consideration! -- When browsing issues, please note that **our team and all issue subscribers receive an email notification** from GitHub whenever a new comment is added, so these should only be used for sharing important information and not for [discussions, questions](https://github.com/photoprism/photoprism/discussions), or [expressing personal opinions](https://www.photoprism.app/code-of-conduct/) -- In order for us to investigate [new bug reports](https://www.photoprism.app/kb/reporting-bugs/), they must include **a complete list of steps to reproduce the problem**, the software versions used and information about the environment in which the problem occurred, such as [browser type, browser version, browser plug-ins](https://docs.photoprism.app/getting-started/troubleshooting/browsers/), operating system, [storage type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#storage), [processor type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#server-cpu), and [memory size](https://docs.photoprism.app/getting-started/troubleshooting/performance/#memory) -- [Contact us](https://www.photoprism.app/contact/) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works +- When browsing issues, please note that **our team and all issue subscribers receive an email notification** from GitHub whenever a new comment is added, so these should only be used for sharing important information and not for [discussions, questions](https://github.com/photoprism/photoprism/discussions), or [expressing personal opinions](https://www.photoprism.app/code-of-conduct) +- In order for us to investigate [new bug reports](https://www.photoprism.app/kb/reporting-bugs), they must include **a complete list of steps to reproduce the problem**, the software versions used and information about the environment in which the problem occurred, such as [browser type, browser version, browser plug-ins](https://docs.photoprism.app/getting-started/troubleshooting/browsers/), operating system, [storage type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#storage), [processor type](https://docs.photoprism.app/getting-started/troubleshooting/performance/#server-cpu), and [memory size](https://docs.photoprism.app/getting-started/troubleshooting/performance/#memory) +- [Contact us](https://www.photoprism.app/contact) or [a community member](https://link.photoprism.app/discussions) if you need help, it could be a local configuration problem, or a misunderstanding in how the software works - This gives us the opportunity to [improve our documentation](https://docs.photoprism.app/getting-started/troubleshooting/) and provide best-in-class support instead of dealing with unclear/duplicate bug reports or triggering a flood of notifications by replying to comments ## Connect with the Community ## -Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct/) explains the "dos and don’ts" when interacting with other community members. +Follow us on [Mastodon](https://floss.social/@photoprism), [Bluesky](https://bsky.app/profile/photoprism.app), or join the [Community Chat](https://link.photoprism.app/chat) to get regular updates, connect with other users, and discuss your ideas. Our [Code of Conduct](https://www.photoprism.app/code-of-conduct) explains the "dos and don’ts" when interacting with other community members. -As a [contributor](CONTRIBUTING.md), you are also welcome to [contact us directly](https://www.photoprism.app/contact/) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. +As a [contributor](CONTRIBUTING.md), you are also welcome to [contact us directly](https://www.photoprism.app/contact) if you have something on your mind that you don't want to discuss publicly. Please note, however, that due to the high volume of emails we receive, our team may be unable to get back to you immediately. We do our best to respond within five business days or less. ## Every Contribution Makes a Difference ## @@ -108,4 +110,4 @@ We welcome [contributions](CONTRIBUTING.md) of any kind, including blog posts, t ---- -*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark/). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms/), [Privacy Policy](https://www.photoprism.app/privacy/), and [Code of Conduct](https://www.photoprism.app/code-of-conduct/). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* +*PhotoPrism® is a [registered trademark](https://www.photoprism.app/trademark). By using the software and services we provide, you agree to our [Terms of Service](https://www.photoprism.app/terms), [Privacy Policy](https://www.photoprism.app/privacy), and [Code of Conduct](https://www.photoprism.app/code-of-conduct). Docs are [available](https://link.photoprism.app/github-docs) under the [CC BY-NC-SA 4.0 License](https://creativecommons.org/licenses/by-nc-sa/4.0/); [additional terms](https://github.com/photoprism/photoprism/blob/develop/assets/README.md) may apply.* diff --git a/SPONSORS.md b/SPONSORS.md index 3ecb03344..9b0be5d56 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -1,10 +1,10 @@ # Thank You to All Current and Past Sponsors 💎 # -Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq/#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! 💜 +Your [continued support](https://link.photoprism.app/membership) helps us [provide more features to the public](https://www.photoprism.app/oss/faq#what-functionality-is-generally-available), release [regular updates](https://docs.photoprism.app/release-notes/), and remain independent! 💜 -You are [welcome to contact us](https://www.photoprism.app/contact/) for change requests, membership questions, and business partnerships. +You are [welcome to contact us](https://www.photoprism.app/contact) for change requests, membership questions, and business partnerships. -[View Membership FAQ ›](https://www.photoprism.app/membership/faq/) [Contact Us ›](https://www.photoprism.app/contact/) +[View Membership FAQ ›](https://www.photoprism.app/kb/membership) [Contact Us ›](https://www.photoprism.app/contact) ## Platinum Sponsors ## diff --git a/assets/locales/README.md b/assets/locales/README.md index b15651e5a..f360d1f90 100644 --- a/assets/locales/README.md +++ b/assets/locales/README.md @@ -15,9 +15,6 @@ It's source code can be obtained on [GitHub](https://github.com/vslavik/poedit). Only asynchronous notifications and certain API responses need translation to provide a consistent user experience. -Asynchronous notifications and user-facing API error responses are additionally rendered by the web -frontend in each user's current UI language (using the message identifier); the `default.po` translation -here serves as a fallback and for non-browser consumers such as the CLI. Technical log messages should be in English to avoid ambiguities and (even slightly) wrong translations. `default.po` files in subdirectories contain localized messages for each @@ -32,7 +29,7 @@ the language. Now you can start translating. When done, create a new directory (using the locale as name) and save your translation there as `default.po`. The POT file `/assets/locales/messages.pot` will be automatically updated when -running `go generate` in `/pkg/i18n` or `make generate` in the main project directory. +running `go generate` in `/internal/i18n` or `make generate` in the main project directory. Note that this will only work when you have gettext installed on your system. We recommend using our latest development image as described in the Developer Guide. diff --git a/assets/locales/af/default.po b/assets/locales/af/default.po index fda442d49..83bb81025 100644 --- a/assets/locales/af/default.po +++ b/assets/locales/af/default.po @@ -2,427 +2,412 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: af\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Iets het verkeerd geloop, probeer weer" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Kan dit nie doen nie" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Veranderinge kon nie gestoor word nie" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Kan nie verwyder word nie" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s bestaan reeds" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nie gevind" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Lêer nie gevind nie" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Lêer te groot" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Ongesteun" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Ongesteunde tipe" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Ongesteunde formaat" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Oorspronklike omslag is leeg" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Seleksie nie gevind nie" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entiteit nie gevind nie" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Rekening nie gevind nie" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Verbruiker nie gevind nie" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Merker nie gevind nie" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera nie gevind nie" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lens nie gevind nie" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nie gevind nie" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Onderwerp nie gevind nie" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Persoon nie gevind nie" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Gesig nie gevind nie" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Nie beskikbaar in publieke modus nie" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Nie beskikbaar in leesalleen modus nie" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Teken asseblief in op jou rekening" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Toegang geweier" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Betaling vereis" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Oplegging mag aanstoot gee" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Oplegging misluk" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Geen items gekies nie" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Kon nie lêer skep nie. Gaan asseblief toestemmings na" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Kon nie vouer skep nie. Gaan asseblief toestemmings na" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Kon nie konnekteer nie, probeer asseblief weer" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Tik verifikasiekode" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Ongeldige verifikasiekode, probeer asseblief weer" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Ongeldige wagwoord, probeer asseblief weer" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Eienskap gedeaktiveer" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Geen merker geselekteer" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Geen albums geselekteer nie" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Geen lêers beskikbaar vir aflaai nie" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Kon nie zip-lêer skep nie" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Ongeldige magtiging" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Ongeldige skakel" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Ongeldige naam" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Besig, probeer asseblief later weer" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Die opwek tydperk is %s, maar moet 1 uur of minder wees" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Jou rekening kon nie gekoppel word nie" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Te veel versoeke" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Onvoldoende berging" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kwota oorskry" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrasie gedeaktiveer" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Geverifieerde e-pos vereis" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Veranderinge suksesvol gestoor" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album geskep" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album gestoor" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s uitgevee" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albuminhoud gekloon" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Lêer verwyder uit stapel" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Lêer uitgevee" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Seleksie bygevoeg na %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Een inskrywing bygevoeg na %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d inskrywings by %s gevoeg" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Een inskrywing verwyder uit %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d inskrywings verwyder uit %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Rekening geskep" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Rekening gestoor" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Rekening uitgevee" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Stellings gestoor" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Wagwoord verander" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Invoer voltooi in %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Invoer gekanselleer" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "inhoudsopgawe voltooi in %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indekseer van oorspronklikes …" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indekseer lêers in %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksering gekanselleer" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d lêers en %d foto's verwyder" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Skuif lêers van %s af" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopieer lêers van %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Merkers uitgevee" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Merkers gestoor" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Onderwerp gestoor" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Onderwerp uitgevee" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Persoon gestoor" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Persoon uitgevee" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Lêer opgelaai" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d lêers opgelaai in %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Verwerk oplegging..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Oplegging geprosesseer" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Seleksie goedgekeur" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Seleksie geargiveer" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Seleksie herstel" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Seleksie gemerk as privaat" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albums uitgevee" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip geskep in %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Permanent uitgevee" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s geherstel" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Suksesvol geverifieer" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Suksesvol geaktiveer" diff --git a/assets/locales/ar/default.po b/assets/locales/ar/default.po index a940e0c4b..2af0ed4eb 100644 --- a/assets/locales/ar/default.po +++ b/assets/locales/ar/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: ar\n" "MIME-Version: 1.0\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "حدث خطأ ما، حاول مرة أخرى" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "غير قادر على فعل ذلك" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "لا يمكن حفظ التغييرات" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "لا يمكن حذفه" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s موجود بالفعل" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "لم يتم العثور" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "لم يتم العثور على الملف" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "الملف كبير جدًا" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "غير مدعوم" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "نوع غير معتمد" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "صيغة غير مدعومة" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "مجلد النسخ الأصلية فارغ" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "الاختيار غير موجود" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "الكيان غير موجود" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "الحساب غير موجود" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "المستخدم غير موجود" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "التصنيف غير موجود" -#: messages.go:129 -msgid "Camera not found" -msgstr "لم يتم العثور على الكاميرا" - -#: messages.go:130 -msgid "Lens not found" -msgstr "لم يتم العثور على العدسة" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "الألبوم غير موجود" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "الموضوع غير موجود" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "لم يتم العثور على الشخص" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "الوجه غير موجود" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "غير متاح في الوضع العام" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "غير متوفر في وضع القراءة فقط" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "يرجى تسجيل الدخول إلى حسابك" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "طلب الاذن مرفوض" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "الدفع مطلوب" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "المحتوى المرفوع قد يكون مسيئا" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "فشل التحميل" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "لم يتم اختيار المحتوى" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "فشل إنشاء الملف ، يرجى التحقق من الصلاحيات" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "لم يتم إنشاء المجلد ، يرجى التحقق من الصلاحيات" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "تعذر الاتصال ، يرجى المحاولة مرة أخرى" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "أدخل رمز التحقق" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "رمز التحقق غير صالح، يرجى المحاولة مرة أخرى" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "كلمة السر غير مطابقة، يرجى المحاولة مرة أخرى" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "الخاصية غير مفعلة" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "لم يتم تحديد المعرفات" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "لم يتم تحديد ألبومات" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "لا توجد ملفات متاحة للتنزيل" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "فشل في إنشاء ملف مضغوط" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "بيانات الاعتماد غير صالحة" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "رابط غير صالح" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "اسم غير صحيح" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "مشغول، يرجى المحاولة مرة أخرى في وقت لاحق" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "فترة التنبيه هي %s ، لكن يجب أن تكون ساعة واحدة أو أقل" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "لا يمكن ربط حسابك" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "طلبات كثيرة جدا" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "مساحة تخزين غير كافية" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "تم تجاوز المساحة المخصصة" -#: messages.go:163 -msgid "Registration disabled" -msgstr "تم تعطيل التسجيل" - -#: messages.go:164 -msgid "Verified email required" -msgstr "البريد الإلكتروني الموثق مطلوب" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "تم حفظ التغييرات بنجاح" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "تم إنشاء الألبوم" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "تم حفظ الألبوم" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "تم حذف الألبوم %s" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "تم نسخ محتويات الألبوم" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "تمت إزالة الملف من المكدس" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "تم حذف الملف" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "تمت إضافة التحديد إلى %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "تمت إضافة إدخال واحد إلى %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "تمت إضافة %d مدخلات إلى %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "تمت إزالة إدخال واحد من %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "تمت إزالة %d مدخلات من %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "تم إنشاء الحساب" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "تم حفظ الحساب" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "تم حذف الحساب" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "تم حفظ الإعدادات" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "تم تغيير كلمة السر" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "اكتمل الاستيراد في %d ثانية" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "تم إلغاء الاستيراد" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "اكتملت الفهرسة في %d ثانية" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "تتم فهرسة الصور الأصلية ..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "فهرسة الملفات في %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "تم إلغاء الفهرسة" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "تمت إزالة %d ملفات و %d صورة" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "نقل الملفات من %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "نسخ ملفات من %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "تم حذف التصنيفات" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "تم حفظ التصنيف" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "تم حفظ الموضوع" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "تم حذف الموضوع" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "حفظ الشخص" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "تم حذف الشخص" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "تم تحميل الملف" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "تم تحميل %d ملف في %d ثانية" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "جارٍ معالجة التحميل ..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "تمت معالجة التحميل" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "تمت الموافقة على الاختيار" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "تمت أرشفة الاختيار" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "تم استعادة المحتوى المحدد" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "تم تحديد الاختيار على أنه خاص" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "تم حذف الألبومات" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "تم إنشاء الملف المضغوط خلال %d ثوانٍ" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "تم الحذف بشكل نهائي" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "تمت استعادة %s" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "تم التحقق بنجاح" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "تم التفعيل بنجاح" diff --git a/assets/locales/be/default.po b/assets/locales/be/default.po index 1bad6b397..4d4819a81 100644 --- a/assets/locales/be/default.po +++ b/assets/locales/be/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: be\n" "MIME-Version: 1.0\n" @@ -12,418 +13,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Нешта пайшло не так, паўтарыце спробу" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Немагчыма зрабіць гэта" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Не ўдалося захаваць змены" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Немагчыма выдаліць" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s ужо існуе" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Не знойдзена" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Файл не знойдзены" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Файл занадта вялікі" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Не падтрымліваецца" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Тып не падтрымліваецца" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Фармат не падтрымліваецца" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Тэчка арыгіналаў пустая" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Выбар не знойдзены" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Аб'ект не знойдзены" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Уліковы запіс не знойдзены" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Карыстальнік не знойдзены" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Тэг не знойдзены" -#: messages.go:129 -msgid "Camera not found" -msgstr "Камера не знойдзена" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Аб'ектыў не знойдзены" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Альбом не знойдзены" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Тэма не знойдзена" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Чалавек не знойдзены" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Твар не знойдзены" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Недаступна ў публічным рэжыме" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Недаступна ў рэжыме толькі для чытання" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Калі ласка, увайдзіце ў свой уліковы запіс" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "У доступе адмоўлена" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Патрабуецца аплата" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Запампоўка можа быць абразлівай" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Памылка загрузкі" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Элементы не выбраны" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Не ўдалося стварыць файл, праверце дазволы" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Не атрымалася стварыць папку, праверце дазволы" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Немагчыма падключыцца, паспрабуйце яшчэ раз" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Увядзіце праверачны код" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Няправільны код спраўджання, паўтарыце спробу" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Няправільны пароль, паспрабуйце яшчэ раз" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Функцыя адключана" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Меткі не выбраны" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Альбомы не выбраны" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Няма даступных файлаў для спампоўкі" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Не ўдалося стварыць zip-файл" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Няправільныя ўліковыя даныя" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Няправільная спасылка" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Няправільнае імя" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Заняты, паўтарыце спробу пазней" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Інтэрвал абуджэння складае %s, але павінен быць не больш за 1 гадзіну" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Ваш уліковы запіс не можа быць падключаны" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Занадта шмат запытаў" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Недастаткова месца для захоўвання" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Квота перавышана" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Рэгістрацыя адключана" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Патрабуецца правераны адрас электроннай пошты" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Змены паспяхова захаваны" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Альбом створаны" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Альбом захаваны" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Альбом %s выдалены" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Змест альбома кланаваны" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Файл выдалены са стэка" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Файл выдалены" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Выбар дададзены ў %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Адзін запіс дададзены ў %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d запісы дададзены ў %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Адзін запіс выдалены з %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "Запісы %d выдалены з %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Уліковы запіс створаны" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Уліковы запіс захаваны" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Уліковы запіс выдалены" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Налады захаваны" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Пароль зменены" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Імпарт завершаны праз %d с" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Імпарт адменены" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Індэксацыя завершана ў %d с" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Індэксаванне арыгіналаў..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Індэксацыя файлаў у %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Індэксацыя адменена" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Выдалена %d файлаў і %d фота" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Перамяшчэнне файлаў з %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Капіраванне файлаў з %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Меткі выдалены" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Цэтлік захаваны" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Тэма захавана" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Тэма выдалена" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Чалавек выратаваны" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Асоба выдалена" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Файл запампаваны" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлы, загружаныя ў %d с" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Апрацоўка запампоўкі..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Загрузка апрацавана" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Выбар ухвалены" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Выбранае заархівавана" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Выбар адноўлены" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Выбар пазначаны як прыватны" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Альбомы выдалены" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip створаны ў %d с" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Выдалены назаўсёды" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s быў адноўлены" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Паспяхова праверана" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Паспяхова актывавана" diff --git a/assets/locales/bg/default.po b/assets/locales/bg/default.po index 1feaaf157..366a5ceb1 100644 --- a/assets/locales/bg/default.po +++ b/assets/locales/bg/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: none\n" "Language: bg\n" @@ -11,418 +11,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Нещо се е объркало, опитайте отново" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Не можете да го направите" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Промените не могат да бъдат запазени" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Не може да бъде изтрит" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s вече съществува" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Не е намерен" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Файлът не е намерен" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Твърде голям файл" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Не се поддържа" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Неподдържан тип" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Неподдържан формат" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Папката с оригинали е празна" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Изборът не е намерен" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Субектът не е намерен" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Акаунтът не е намерен" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Потребителят не е намерен" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Етикетът не е намерен" -#: messages.go:129 -msgid "Camera not found" -msgstr "Камерата не е открита" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Обективът не е открит" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Албумът не е намерен" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Темата не е намерена" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Лицето не е намерено" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Лицето не е намерено" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Не е наличен в публичен режим" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Не е наличен в режим само за четене" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Моля, влезте в профила си" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Достъп отказан" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Изисква се плащане" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Качването може да е обидно" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Файловете не успяха да се качат" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Няма избрани елементи" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Неуспешно създаване на файл, моля, проверете разрешенията" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Неуспешно създаване на папка, моля, проверете разрешенията" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Не може да се свърже, опитайте отново" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Въведете код за верификация" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Невалиден код за потвърждение, моля опитайте отново" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Невалидна парола, моля, опитайте отново" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Функцията е деактивирана" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Няма избрани етикети" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Няма избрани албуми" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Няма налични файлове за изтегляне" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Неуспешно създаване на zip файл" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Невалидни креденции" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Невалидна връзка" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Невалидно име" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Заето, моля, опитайте отново по-късно" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Интервалът на събуждане е %s, но трябва да е 1 час или по-малко" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Вашият акаунт не може да бъде свързан" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Твърде много заявки" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Недостатъчно място за съхранение" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Превишаване на квотата" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Регистрацията е деактивирана" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Необходим е потвърден имейл адрес" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Промените са успешно записани" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Създаден албум" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Запазен албум" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Албум %s изтрит" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Съдържанието на албума беше клонирано" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Премахване на файла от стека" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Изтрит файл" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Добавяне на селекция към %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Добавяне на един запис към %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d добавени записи към %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Отстранен е един запис от %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d премахнати записи от %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Създаден акаунт" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Акаунтът запазен" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Изтрит акаунт" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Запазени настройки" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Паролата е променена" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Импортът е завършен за %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Вносът е отменен" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Индексирането е завършено за %d сек" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Индексиране на оригинали..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Индексиране на файлове в %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Отменено индексиране" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Премахнати са %d файлове и %d снимки" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Преместване на файлове от %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Копиране на файлове от %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Изтрити етикети" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Запазен етикет" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Тема: запазени" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Изтрит предмет" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Запазено лице" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Изтрито лице" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Качен файл" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлове, качени за %d сек" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Обработка на качването..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Качването е обработено" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Одобрена селекция" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Архивирана селекция" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Възстановена селекция" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Селекция, отбелязана като частна" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Изтрити албуми" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip създаден за %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Постоянно изтрити" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s е възстановена" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Успешно потвърдено" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Успешно активиран" diff --git a/assets/locales/ca/default.po b/assets/locales/ca/default.po index 16bec0e66..34a15fa66 100644 --- a/assets/locales/ca/default.po +++ b/assets/locales/ca/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "S'ha produït un error, torna-ho a provar" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Incapaç de fer-ho" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "No s'han pogut desar els canvis" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "No s'ha pogut suprimir" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s El nom ja existeix" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "No trobat" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "No s'ha trobat el fitxer" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Fitxer massa gran" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Sense suport" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Tipus no compatible" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Format no compatible" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "La carpeta d'originals està buida" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "No s'ha trobat la selecció" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "No s'ha trobat l'entitat" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Compte no trobat" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Usuari no trobat" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "No s'ha trobat l'etiqueta" -#: messages.go:129 -msgid "Camera not found" -msgstr "No s'ha trobat la càmera" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lent no trobada" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "No s'ha trobat l'àlbum" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "No s'ha trobat el tema" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Persona no trobada" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "No s'ha trobat la cara" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "No disponible en mode públic" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "No disponible en mode només de lectura" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Si us plau, inicieu sessió al vostre compte" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Permís denegat" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Pagament requerit" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "La càrrega pot ser ofensiva" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "La càrrega ha fallat" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "No s'ha seleccionat cap element" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "No s'ha pogut crear el fitxer, comproveu els permisos" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "No s'ha pogut crear la carpeta, comproveu els permisos" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "No s'ha pogut connectar, torna-ho a provar" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Introduïu el codi de verificació" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Codi de verificació no vàlid, torneu-ho a provar" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "La contrasenya no és vàlida, torneu-ho a provar" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funció desactivada" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "No s'ha seleccionat cap etiqueta" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "No s'ha seleccionat cap àlbum" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "No hi ha fitxers disponibles per a la baixada" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "No s'ha pogut crear el fitxer zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Credencials incorrectes" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Enllaç no vàlid" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nom no vàlid" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Ocupat, torna-ho a provar més tard" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "L'interval d'activació és %s, però ha de ser d'1 h o menys" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "No s'ha pogut connectar el vostre compte" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Massa peticions" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Emmagatzematge insuficient" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "S'ha superat la quota" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registre desactivat" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Cal un correu electrònic verificat" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Els canvis s'han desat correctament" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Àlbum creat" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Àlbum desat" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "S'ha suprimit l'àlbum %s" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Contingut de l'àlbum clonat" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "S'ha eliminat el fitxer de la pila" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "S'ha suprimit el fitxer" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "S'ha afegit una selecció a %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "S'ha afegit una entrada a %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d entrades afegides a %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "S'ha eliminat una entrada de %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "S'han eliminat %d entrades de %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Compte creat" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Compte desat" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Compte suprimit" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Configuració desada" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "S’ha canviat la contrasenya" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importació completada en %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importació cancel·lada" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexació completada en %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "S'estan indexant els originals..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexant fitxers a %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "S'ha cancel·lat la indexació" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "S'han eliminat %d fitxers i %d fotos" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "S'estan movent fitxers de %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "S'estan copiant fitxers de %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "S'han suprimit les etiquetes" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "S'ha desat l'etiqueta" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Assumpte desat" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "S'ha suprimit el tema" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Persona salvada" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "S'ha suprimit la persona" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Fitxer penjat" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fitxers penjats en %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "S'està processant la càrrega..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "S'ha processat la càrrega" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Selecció aprovada" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Selecció arxivada" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "S'ha restaurat la selecció" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "La selecció s'ha marcat com a privada" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Àlbums suprimits" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip creat en %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Esborrat permanentment" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s s'ha restaurat" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verificat correctament" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "S'ha activat correctament" diff --git a/assets/locales/cs/default.po b/assets/locales/cs/default.po index 474f4718d..0fc1800ba 100644 --- a/assets/locales/cs/default.po +++ b/assets/locales/cs/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: Czech \n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Něco se pokazilo, zkuste to znovu" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Nelze to udělat" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Změny nemohly být uloženy" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Nemohlo být vymazáno" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s již existuje" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nenalezeno" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Soubor nenalezen" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Příliš velký soubor" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Nepodporováno" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Nepodporovaný typ" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nepodporovaný formát" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Složka Originály je prázdná" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Výběr nenalezen" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Subjekt nebyl nalezen" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Účet nenalezen" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Uživatel nenalezen" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Štítek nenalezen" -#: messages.go:129 -msgid "Camera not found" -msgstr "Fotoaparát nebyl nalezen" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektiv nebyl nalezen" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nenalezeno" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Předmět nebyl nalezen" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Osoba nebyla nalezena" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Obličej nebyl nalezen" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Není k dispozici ve veřejném módu" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Není k dispozici v režimu pouze pro čtení" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Přihlaste se ke svému účtu" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Přístup zamítnut" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Požadovaná platba" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Nahrané soubory by mohly být urážlivé" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Nahrávání selhalo" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nebyly vybrány žádné položky" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Vytváření souboru selhalo, zkontrolujte prosím oprávnění" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Vytváření složky selhalo, zkontrolujte prosím oprávnění" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Nemohlo být připojeno, zkuste to prosím znovu" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Vložte ověřovací kód" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Neplatný ověřovací kód, zkuste to prosím znovu" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Neplatné heslo, zkuste to prosím znovu" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funkce deaktivovaná" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nebyly vybrány žádné štítky" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nebyla vybrána žádná alba" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Žádné soubory ke stažení k dispozici" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Nebylo možné vytvořit soubor ZIP" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Neplatné údaje" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Neplatný odkaz" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Neplatný jméno" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Zaneprázdněn, zkuste to prosím později" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval buzení je %s, ale musí být 1h nebo kratší" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Váš účet se nepodařilo připojit" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Příliš mnoho požadavků" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Nedostatečné skladování" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Překročení kvóty" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrace je deaktivována" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Je nutné zadat ověřenou e-mailovou adresu" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Změny byly úspěšně uloženy" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album vytvořeno" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album uloženo" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s vymazáno" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Obsah alba naklonován" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Soubor odstraněn ze stohu" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Soubor vymazán" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Výběr přidán do %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Jeden záznam přidán do %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d záznamů přidáno do %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Jeden záznam odstraněn z %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d záznamů odstraněno z %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Účet vytvořen" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Účet uložen" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Účet vymazán" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Nastavení uloženo" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Heslo změněno" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import dokončen za %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import zrušen" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexování dokončeno za %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexování originálů..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexování souborů v %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexování zrušeno" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Odstraněno %d souborů a %d fotografií" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Přesouvání souborů z %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopírování souborů z %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Štítky vymazány" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Štítek uložen" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Předmět uložen" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Předmět smazán" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Uložená osoba" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Vymazaná osoba" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Soubor odeslán" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d souborů nahráno za %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Zpracování nahrávání..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Nahrávání bylo zpracováno" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Výběr potvrzen" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Výběr archivován" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Výběr obnoven" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Výběr označen jako Soukromý" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Alba vymazána" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "ZIP vytvořen za %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Trvale smazáno" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s bylo obnoveno" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Úspěšně ověřeno" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Úspěšně aktivováno" diff --git a/assets/locales/da/default.po b/assets/locales/da/default.po index d89dda9b9..6b48e0861 100644 --- a/assets/locales/da/default.po +++ b/assets/locales/da/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: Danish \n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Der gik noget galt, prøv igen" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Det kan ikke lade sig gøre" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Ændringer kunne ikke gemmes" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Kunne ikke slettes" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s findes allerede" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Ikke fundet" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fil ikke fundet" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Filen er for stor" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Ikke understøttet" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Ikke-understøttet type" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Ikke understøttet format" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Mappen Originaler er tom" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Valg ikke fundet" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Enhed ikke fundet" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Konto ikke fundet" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Bruger ikke fundet" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etiket ikke fundet" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kameraet blev ikke fundet" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektiv ikke fundet" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album ikke fundet" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Emne ikke fundet" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Person ikke fundet" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Ansigt ikke fundet" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Ikke tilgængelig i offentlig tilstand" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Ikke tilgængelig i skrivebeskyttet tilstand" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Log ind på din konto" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Tilladelse nægtet" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Betaling påkrævet" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Upload kan være stødende" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Upload mislykkedes" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Ingen emner valgt" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Oprettelse af fil mislykkedes, tjek venligst tilladelser" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Oprettelse af mappe mislykkedes, tjek venligst tilladelser" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Kunne ikke oprette forbindelse, prøv venligst igen" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Indtast verifikations kode" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Ugyldig bekræftelseskode. Prøv venligst igen" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Ugyldig adgangskode, prøv venligst igen" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funktion deaktiveret" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Ingen etiketter valgt" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Ingen album valgt" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Ingen filer til rådighed til download" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Det lykkedes ikke at oprette zip-fil" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Ugyldige legitimationsoplysninger" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Ugyldigt link" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Ugyldigt navn" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Optaget, prøv venligst igen senere" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Vækningsintervallet er %s, men skal være 1 time eller mindre" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Der kunne ikke oprettes forbindelse til din konto" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "For mange anmodninger" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Utilstrækkelig opbevaring" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kvote overskredet" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrering er deaktiveret" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Der kræves en bekræftet e-mailadresse" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Ændringer gemt med succes" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album oprettet" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album gemt" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s slettet" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albumindhold klonet" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fil fjernet fra stakken" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fil slettet" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Valg tilføjet til %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "En post tilføjet til %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d poster tilføjet til %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "En post fjernet fra %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d poster fjernet fra %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Konto oprettet" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Gemte konto" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Konto slettet" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Indstillinger gemt" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Adgangskode ændret" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import afsluttet efter %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import annulleret" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksering afsluttet efter %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indeksering af originaler..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indeksering af filer i %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksering annulleret" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Fjernede %d filer og %d fotos" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Flytter filer fra %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopierer filer fra %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etiketter slettet" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etikette gemt" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Emne gemt" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Emne slettet" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Person gemt" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Person slettet" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Fil uploadet" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d filer uploadet på %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Behandling af upload..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Upload er blevet behandlet" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Udvælgelse godkendt" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Udvælgelse arkiveret" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Udvalgte gendannet" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Udvalgte er markeret som privat" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albums slettet" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip filen blev lavet på %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Permanent slettet" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s er blevet genoprettet" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verifikation lykkedes" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Aktivering lykkedes" diff --git a/assets/locales/de/default.po b/assets/locales/de/default.po index 6d1001d46..6a06c236d 100644 --- a/assets/locales/de/default.po +++ b/assets/locales/de/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: German \n" @@ -12,419 +12,403 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" "X-Poedit-Basepath: .\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Etwas ist schief gelaufen, versuche es noch einmal" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Dies ist nicht möglich" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Fehler beim Speichern der Daten" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Konnte nicht gelöscht werden" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s existiert bereits" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nicht gefunden" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Datei konnte nicht gefunden werden" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Datei zu groß" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Wird nicht unterstützt" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Typ wird nicht unterstützt" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nicht unterstütztes Format" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Originals-Verzeichnis ist leer" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Auswahl nicht gefunden" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Keine Daten gefunden" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Unbekannter Account" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Nutzer nicht gefunden" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Kategorie nicht gefunden" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera nicht gefunden" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektiv nicht gefunden" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nicht gefunden" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Unbekanntes Motiv" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Unbekannte Person" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Unbekanntes Gesicht" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Im öffentlichen Modus nicht verfügbar" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Im Nur-Lese-Modus nicht verfügbar" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Bitte melde dich an" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Erlaubnis verweigert" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Zahlung erforderlich" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Inhalt könnte anstößig sein und wurde abgelehnt" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Upload fehlgeschlagen" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nichts ausgewählt" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Datei konnte nicht erstellt werden" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Ordner konnte nicht erstellt werden" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Verbindung fehlgeschlagen" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Verifizierungscode eingeben" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Ungültiger Verifizierungscode, bitte erneut versuchen" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Ungültiges Passwort" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funktion deaktiviert" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Keine Kategorien ausgewählt" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Keine Alben ausgewählt" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Keine Dateien zum Download verfügbar" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Zip-Datei konnte nicht erstellt werden" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Ungültige Zugangsdaten" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Ungültiger Link" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Ungültiger Name" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Beschäftigt, bitte später erneut versuchen" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Worker-Intervall ist %s, muss aber 1h oder weniger betragen" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Das Konto konnte nicht verbunden werden" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Zu viele Anfragen" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Zu wenig Speicherplatz" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Maximale Anzahl erreicht" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrierung deaktiviert" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Eine verifizierte E-Mail-Adresse ist erforderlich" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Änderungen erfolgreich gespeichert" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album erstellt" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album gespeichert" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s gelöscht" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Album-Einträge kopiert" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Datei aus Stapel entfernt" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Datei gelöscht" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Auswahl zu %s hinzugefügt" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Ein Eintrag zu %s hinzugefügt" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d Einträge zu %s hinzugefügt" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Ein Eintrag aus %s entfernt" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d Einträge aus %s entfernt" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Konto hinzugefügt" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Konto gespeichert" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Konto gelöscht" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Einstellungen gespeichert" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Passwort geändert" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import in %d s abgeschlossen" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import abgebrochen" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexierung in %d s abgeschlossen" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexiere Dateien…" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexiere Dateien in %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexierung abgebrochen" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d Dateien und %d Bilder wurden entfernt" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Verschiebe Dateien von %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopiere Dateien von %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Kategorien gelöscht" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Kategorie gespeichert" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Motiv gespeichert" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Motiv gelöscht" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Person gespeichert" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Person gelöscht" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Datei hochgeladen" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d Dateien hochgeladen in %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Verarbeitung des Uploads..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Der Upload wurde verarbeitet" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Auswahl übernommen" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Auswahl archiviert" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Auswahl wiederhergestellt" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Auswahl als privat markiert" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Alben gelöscht" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip-Datei erstellt in %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Endgültig gelöscht" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s wurde wiederhergestellt" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Erfolgreich verifiziert" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Erfolgreich aktiviert" diff --git a/assets/locales/el/default.po b/assets/locales/el/default.po index a4abcbc15..97356b0f2 100644 --- a/assets/locales/el/default.po +++ b/assets/locales/el/default.po @@ -2,427 +2,411 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-11-19 10:23+0000\n" +"Last-Translator: dtsolakis \n" "Language-Team: none\n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Κάτι πήγε στραβά, δοκιμάστε ξανά" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Αυτό δεν είναι εφικτό" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Οι αλλαγές δεν ήταν δυνατό να αποθηκευτούν" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Δεν ήταν εφικτή η διαγραφή" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s υπάρχει ήδη" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Δεν βρέθηκε" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Το αρχείο δεν βρέθηκε" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Πολύ μεγάλο αρχείο" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Δεν υποστηρίζεται" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Μη υποστηριζόμενος τύπος" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Μη υποστηριζόμενος μορφότυπος" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Ο φάκελος πρωτότυπων είναι άδειος" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Η επιλογή δεν βρέθηκε" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Η οντότητα δεν βρέθηκε" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Ο λογαριασμός δεν βρέθηκε" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Ο χρήστης δεν βρέθηκε" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Η ετικέτα δεν βρέθηκε" -#: messages.go:129 -msgid "Camera not found" -msgstr "Δεν εντοπίστηκε η κάμερα" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Δεν βρέθηκε ο φακός" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Το άλμπουμ δεν βρέθηκε" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Το θέμα δεν βρέθηκε" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Το άτομο δεν βρέθηκε" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Το πρόσωπο δεν βρέθηκε" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Μη διαθέσιμο κατά τη δημόσια λειτουργία" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Μη διαθέσιμο στην κατάσταση \"μόνο ανάγνωση\"" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Συνδεθείτε στο λογαριασμό σας" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Δέν δόθηκε άδεια" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Απαιτείται πληρωμή" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Το ανέβασμα μπορεί να είναι προσβλητικό" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Αποτυχία ανεβάσματος" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Δεν έχουν επιλεγεί στοιχεία" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Απέτυχε η δημιουργία αρχείου, ελέγξτε τα δικαιώματα" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Απέτυχε η δημιουργία φακέλου, ελέγξτε τα δικαιώματα" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Δεν ήταν δυνατή η σύνδεση, δοκιμάστε ξανά" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Εισάγετε τον κωδικό επαλήθευσης" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Μη έγκυρος κωδικός επαλήθευσης, δοκιμάστε ξανά" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Μη έγκυρος κωδικός πρόσβασης, δοκιμάστε ξανά" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Απενεργοποιημένη λειτουργία" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Δεν έχουν επιλεγεί ετικέτες" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Δεν έχουν επιλεγεί άλμπουμ" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Δεν υπάρχουν διαθέσιμα αρχεία για λήψη" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Απέτυχε η δημιουργία αρχείου zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Μη έγκυρα διαπιστευτήρια" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Μη έγκυρος σύνδεσμος" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Μη έγκυρο όνομα" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Το σύστημα είναι απασχολημένο, προσπαθήστε ξανά αργότερα" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Το διάστημα αφύπνισης είναι %s, αλλά πρέπει να είναι 1 ώρα ή λιγότερο" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Ο λογαριασμός σας δεν ήταν δυνατό να συνδεθεί" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Πάρα πολλά αιτήματα" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Ανεπαρκής χώρος" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Υπέρβαση ορίου" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Η εγγραφή έχει απενεργοποιηθεί" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Απαιτείται επαληθευμένη διεύθυνση ηλεκτρονικού ταχυδρομείου" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Οι αλλαγές αποθηκεύτηκαν επιτυχώς" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Το άλμπουμ δημιουργήθηκε" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Το άλμπουμ αποθηκεύθηκε" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Το άλμπουμ %s διαγράφηκε" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Τα περιεχόμενα του άλμπουμ αντιγράφηκαν" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Αφαίρεση αρχείου από τη στοίβα" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Το αρχείο διαγράφηκε" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Η επιλογή προστέθηκε στο %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Μία εγγραφή προστέθηκε στο %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d καταχωρήσεις προστέθηκαν στο %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Μία καταχώρηση αφαιρέθηκε από %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d καταχωρήσεις αφαιρέθηκαν από %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Ο λογαριασμός δημιουργήθηκε" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Ο λογαριασμός αποθηκεύτηκε" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Ο λογαριασμός διαγράφηκε" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Οι ρυθμίσεις αποθηκεύτηκαν" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Ο κωδικός πρόσβασης άλλαξε" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Η εισαγωγή ολοκληρώθηκε σε %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Η εισαγωγή ακυρώθηκε" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Η ευρετηρίαση ολοκληρώθηκε σε %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Δημιουργία ευρετηρίου για τα πρωτότυπα..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Δημιουργία ευρετηρίου αρχείων σε %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Η δημιουργία ευρετηρίου ακυρώθηκε" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Αφαίρεση %d αρχείων και %d φωτογραφιών" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Μετακίνηση αρχείων από %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Αντιγραφή αρχείων από %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Οι ετικέτες διαγράφηκαν" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Η ετικέτα αποθηκεύτηκε" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Το θέμα αποθηκεύθηκε" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Το θέμα διαγράφηκε" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Το άτομο αποθηκεύτηκε" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Το άτομο διαγράφηκε" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Το αρχείο διαγράφηκε" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d αρχεία ανεβάστηκαν σε %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Επεξεργασία ανεβάσματος..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Το ανέβασμα έχει ολοκληρωθεί" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Η επιλογή εγκρίθηκε" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Η επιλογή αρχειοθετήθηκε" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Η επιλογή αποκαταστάθηκε" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Η επιλογή μαρκαρίστηκε ως ιδιωτική" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Διαγραμμένα άλμπουμ" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Το αρχείο zip δημιουργήθηκε σε %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Διαγράφηκε μόνιμα" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s έχει αποκατασταθεί" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Επιτυχής επαλήθευση" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Επιτυχής ενεργοποίηση" diff --git a/assets/locales/en/default.po b/assets/locales/en/default.po index c4d5983de..781824619 100644 --- a/assets/locales/en/default.po +++ b/assets/locales/en/default.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" "PO-Revision-Date: 2022-10-31 16:44+0100\n" "Last-Translator: Michael Mayer \n" "Language-Team: \n" @@ -13,415 +13,399 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "" -#: messages.go:129 -msgid "Camera not found" -msgstr "" - -#: messages.go:130 -msgid "Lens not found" -msgstr "" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "" -#: messages.go:163 -msgid "Registration disabled" -msgstr "" - -#: messages.go:164 -msgid "Verified email required" -msgstr "" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "" -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "" diff --git a/assets/locales/es/default.po b/assets/locales/es/default.po index 9b329bd5a..b2efd0c1a 100644 --- a/assets/locales/es/default.po +++ b/assets/locales/es/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: Spanish \n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Algo ha ido mal, inténtalo de nuevo" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Incapaz de hacerlo" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "No se pudieron guardar los cambios" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "No se pudo borrar" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s ya existe" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "No encontrado" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "No se encuentra el archivo" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Archivo demasiado grande" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "No compatible" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Tipo no admitido" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Formato no admitido" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "La carpeta de originales está vacía" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Selección no encontrada" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entidad no encontrada" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Cuenta no encontrada" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Usuario no encontrado" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etiqueta no encontrada" -#: messages.go:129 -msgid "Camera not found" -msgstr "No se encuentra la cámara" - -#: messages.go:130 -msgid "Lens not found" -msgstr "No se ha encontrado la lente" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Álbum no encontrado" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Asunto no encontrado" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Persona no encontrada" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Cara no encontrada" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "No disponible en modo público" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "No está disponible en modo de sólo lectura" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Por favor inicie sesión" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Permiso denegado" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Pago requerido" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "El archivo subido puede ser ofensivo" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Carga fallida" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Ningún elemento seleccionado" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Fallo al crear el archivo, por favor, compruebe los permisos" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Fallo al crear la carpeta, por favor, compruebe los permisos" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "No se pudo conectar, por favor vuelva a intentarlo" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Ingrese el código de verificación" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Código de verificación no válido, inténtalo de nuevo" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Contraseña inválida, por favor vuelva a intentarlo" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Característica desactivada" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Ninguna etiqueta seleccionada" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Ningún álbum seleccionado" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Ningún archivo disponible para descargar" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Fallo al crear el archivo zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Credenciales no válidas" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Enlace inválido" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nombre inválido" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Ocupado, por favor vuelva a intentarlo más tarde" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "El intervalo de activación es %s, pero debe ser 1h o menos" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Su cuenta no pudo ser conectada" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Demasiadas peticiones" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Almacenamiento insuficiente" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Cuota superada" -#: messages.go:163 -msgid "Registration disabled" -msgstr "El registro está desactivado" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Se requiere una dirección de correo electrónico verificada" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Cambios guardados con éxito" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Álbum creado" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Álbum guardado" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Álbum %s borrado" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Contenidos del álbum clonados" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Archivo eliminado de la pila" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Archivo eliminado" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Selección añadida a %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Una entrada añadida a %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d entradas añadidas a %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Una entrada eliminada de %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d entradas eliminadas de %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Cuenta creada" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Cuenta guardada" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Cuenta borrada" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Ajustes guardados" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Contraseña cambiada" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importación completada en %d" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importación cancelada" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexación completada en %d" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexando originales..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexando archivos en %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexación cancelada" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Eliminados %d archivos y %d fotos" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Moviendo achivos desde %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Copiando archivos desde %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etiquetas borradas" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etiqueta guardada" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Asunto guardado" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Sujeto eliminado" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Persona salvada" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Persona eliminada" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Archivo cargado" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d archivos subidos en %d" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Procesando la carga..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "La carga ha sido procesada" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Selección aprobada" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Selección archivada" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Selección restaurada" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Selección marcada como privada" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Álbumes borrados" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip creado en %d" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Eliminado permanentemente" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s ha sido restaurado" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verificado con éxito" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Activado exitosamente" diff --git a/assets/locales/et/default.po b/assets/locales/et/default.po index 8f298ff7d..ee7e0d32e 100644 --- a/assets/locales/et/default.po +++ b/assets/locales/et/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: none\n" "Language: et\n" @@ -11,418 +11,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Midagi läks valesti, proovige uuesti" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Seda ei ole võimalik teha" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Muudatuste salvestamine ebaõnnestus" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Kustutamine ebaõnnestus" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s on juba olemas" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Ei leitud" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Faili ei leitud" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Fail on liiga suur" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Toetamata" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Toetamata tüüp" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Mittetoetatud formaat" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Originaalide kaust on tühi" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Valikut ei leitud" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Olemit ei leitud" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Kontot ei leitud" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Kasutajat ei leitud" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Silti ei leitud" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kaamerat ei leitud" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektiivi ei leitud" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Albumit ei leitud" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Teemat ei leitud" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Isikut ei leitud" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Nägu ei leitud" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Pole avalikus režiimis saadaval" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Pole kirjutuskaitstud režiimis saadaval" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Palun logi oma kontole sisse" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Õigused puuduvad" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Nõutav makse" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Fail võib olla solvav" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Üleslaadimine ebaõnnestus" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Midagi pole valitud" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Faili loomine ebaõnnestus, kontrolli õiguseid" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Kausta loomine ebaõnnestus, kontrolli õiguseid" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Ühendumine ebaõnnestus, palun proovi uuesti" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Sisesta kontrollkood" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Vale kinnituskood, proovige uuesti" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Vale parool, palun proovi uuesti" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funktsioon välja lülitatud" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Ühtegi silti pole valitud" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Ühtegi albumit pole valitud" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Ühtegi faili ei ole allalaadimiseks saadaval" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "ZIP-faili loomine ebaõnnestus" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Kehtetud ligipääsuandmed" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Vigane link" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Vigane nimi" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Hõivatud, palun proovi hiljem uuesti" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Ärkamisintervall on %s, kuid peab olema 1 tund või vähem" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Konto ühendamine ebaõnnestus" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Liiga palju taotlusi" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Ebapiisav ladustamine" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kvoot ületatud" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registreerimine on keelatud" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Nõutav on kinnitatud e-posti aadress" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Muudatused edukalt salvestatud" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album lisatud" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album salvestatud" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s kustutatud" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albumi sisu kloonitud" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fail virnast eemaldatud" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fail kustutatud" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Valik lisatud albumisse %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Üks kirje lisatud albumisse %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d kirjet lisatud albumisse %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Üks kirje eemaldatud albumist %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d kirjet eemaldatud albumist %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Konto loodud" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Konto salvestatud" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Konto kustutatud" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Seaded salvestatud" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Parool muudetud" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import tehtud %d sekundiga" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import tühistatud" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indekseerimine lõpetatud %d sekundiga" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Originaalide indekseerimine..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Failide indekseerimine: %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indekseerimine tühistatud" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Eemaldatud %d faili ja %d fotot" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Failide liigutamine asukohast %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Failide kopeerimine asukohast %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Sildid kustutatud" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Silt salvestatud" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Teema salvestatud" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Teema kustutatud" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Isik salvestatud" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Isik kustutatud" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "File üles laaditud" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d faili üles laaditud %d sekundiga" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Üleslaaditud faili töötlemine..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Üleslaaditud fail on töödeldud" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Valik heaks kiidetud" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Valik arhiveeritud" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Valik taastatud" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Valik privaatseks märgitud" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumid kustutatud" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "ZIP-fail loodud %d sekundiga" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Lõplikult kustutatud" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s on taastatud" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Edukalt kinnitatud" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Edukalt aktiveeritud" diff --git a/assets/locales/eu/default.po b/assets/locales/eu/default.po index c9e2a8bb0..c9b4aadd7 100644 --- a/assets/locales/eu/default.po +++ b/assets/locales/eu/default.po @@ -2,427 +2,412 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Arazoren bat izan da. Saiatu berriro" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Hori egin ezinik" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Ezin izan dira aldaketak gorde" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Ezin izan da ezabatu" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s dagoeneko existitzen da" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Ez da aurkitu" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fitxategia ez da aurkitu" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Fitxategi handiegia" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Onartu gabe" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Onartu gabeko mota" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Onartu gabeko formatua" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Jatorrizkoen karpeta hutsik dago" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Ez da hautapena aurkitu" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Ez da aurkitu entitatea" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Ez da kontua aurkitu" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Ez da erabiltzailea aurkitu" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Ez da etiketa aurkitu" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera ez da aurkitu" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lentila ez da aurkitu" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Ez da aurkitu albuma" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Ez da aurkitu gaia" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Pertsona ez da aurkitu" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Aurpegia ez da aurkitu" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Ez dago eskuragarri modu publikoan" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Ez dago erabilgarri irakurtzeko soilik moduan" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Mesedez, hasi saioa zure kontuan" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Baimena ukatu egin da" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Ordainketa beharrezkoa da" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Kargatzea iraingarria izan daiteke" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Ezin izan da kargatu" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Ez da elementurik hautatu" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Ezin izan da fitxategia sortzean. Egiaztatu baimenak" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Ezin izan da karpeta sortzean. Egiaztatu baimenak" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Ezin izan da konektatu. Saiatu berriro" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Sartu egiaztapen-kodea" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Egiaztapen-kode baliogabea. Saiatu berriro" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Pasahitz baliogabea, saiatu berriro" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Eginbidea desgaituta dago" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Ez da etiketarik hautatu" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Ez dago albumik hautatu" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Ez dago fitxategirik deskargatzeko erabilgarri" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Ezin izan da zip fitxategia sortu" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Kredentzialak baliogabeak" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Esteka baliogabea" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Izen baliogabea" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Lanpetuta, saiatu berriro geroago" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Esnatzeko tartea %s da, baina ordu 1 edo gutxiagokoa izan behar du" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Ezin izan da zure kontua konektatu" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Eskaera gehiegi" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Biltegiratze nahikoa ez" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kuota gainditu da" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Erregistroa desgaituta dago" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Egiaztatutako posta elektronikoa beharrezkoa da" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Aldaketak ongi gorde dira" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Sortu da albuma" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Albuma gorde da" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "%s albuma ezabatu da" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albumen edukia klonatu da" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fitxategia pilatik kendu da" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fitxategia ezabatu da" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Aukeraketa gehitu da %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Sarrera bat gehitu da %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d sarrerak gehitu dira %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Sarrera bat kendu da %s-tik" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d sarrerak kendu dira %s-tik" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Kontua sortu da" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Kontua gorde da" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Kontua ezabatu da" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Ezarpenak gorde dira" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Pasahitza aldatu da" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Inportazioa %d s-an amaitu da" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Inportazioa bertan behera utzi da" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexatzea %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Jatorrizkoak indexatzen..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Fitxategiak indexatzen %s-n" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexazioa bertan behera utzi da" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d fitxategiak eta %d argazkiak kendu dira" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Fitxategiak mugitzen %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "%s fitxategiak kopiatzen" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etiketak ezabatu dira" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etiketa gorde da" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Gaia gorde da" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Gaia ezabatu da" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Pertsona gordeta" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Pertsona ezabatu da" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Kargatu da fitxategia" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fitxategiak %d s-etan kargatu dira" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Kargaketa prozesatzen..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Kargatzea prozesatu da" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Hautaketa onartu da" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Hautaketa artxibatuta dago" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Hautaketa leheneratu da" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Hautapena pribatu gisa markatu da" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumak ezabatu dira" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip sortu zen %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Betiko ezabatu da" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s leheneratu da" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Behar bezala egiaztatu da" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Behar bezala aktibatu da" diff --git a/assets/locales/fa/default.po b/assets/locales/fa/default.po index a8244c596..20f8e299a 100644 --- a/assets/locales/fa/default.po +++ b/assets/locales/fa/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n==0 || n==1);\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "یه چیزی اشتباه شد دوباره تلاش کن" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "قادر به انجام آن نیست" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "تغییرات را نمی توان ذخیره کرد" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "نمی توان حذف کرد" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s از قبل وجود دارد" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "پیدا نشد" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "فایل پیدا نشد" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "فایل خیلی بزرگ است" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "پشتیبانی نمی شود" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "نوع پشتیبانی نشده" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "قالب پشتیبانی نشده" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "پوشه اصلی خالی است" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "انتخاب پیدا نشد" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "موجودیت پیدا نشد" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "حساب کاربری پیدا نشد" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "کاربر پیدا نشد" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "برچسب پیدا نشد" -#: messages.go:129 -msgid "Camera not found" -msgstr "دوربین پیدا نشد" - -#: messages.go:130 -msgid "Lens not found" -msgstr "لنز یافت نشد" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "آلبوم پیدا نشد" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "موضوع پیدا نشد" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "فرد پیدا نشد" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "صورت پیدا نشد" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "در حالت عمومی در دسترس نیست" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "در حالت فقط خواندنی در دسترس نیست" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "لطفا وارد شوید و دوباره امتحان کنید" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "فرد حذف شد" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "پرداخت لازم است" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "آپلود ممکن است توهین آمیز باشد" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "آپلود انجام نشد" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "هیچ موردی انتخاب نشده است" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "فایل ایجاد نشد، لطفا مجوزها را بررسی کنید" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "پوشه ایجاد نشد، لطفا مجوزها را بررسی کنید" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "اتصال برقرار نشد، لطفاً دوباره امتحان کنید" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "کد تایید را وارد کنید" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "کد تأیید نامعتبر است، لطفاً دوباره امتحان کنید" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "رمز عبور نامعتبر است، لطفا دوباره امتحان کنید" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "ویژگی غیرفعال است" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "هیچ برچسبی انتخاب نشده است" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "هیچ آلبومی انتخاب نشده است" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "هیچ فایلی برای دانلود موجود نیست" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "فایل فشرده ایجاد نشد" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "گواهی نامه نامعتبر" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "لینک نامعتبر" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "نام نامعتبر" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "مشغول است، لطفاً بعداً دوباره امتحان کنید" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "فاصله بیداری %s است، اما باید 1 ساعت یا کمتر باشد" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "حساب شما متصل نشد" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "درخواست های خیلی زیاد" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "ذخیره سازی ناکافی" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "از سهمیه فراتر رفت" -#: messages.go:163 -msgid "Registration disabled" -msgstr "ثبت نام غیرفعال شد" - -#: messages.go:164 -msgid "Verified email required" -msgstr "ایمیل تایید شده الزامی است" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "تغییرات با موفقیت ذخیره شد" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "آلبوم ایجاد شد" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "آلبوم ذخیره شد" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "آلبوم %s حذف شد" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "محتویات آلبوم کلون شد" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "فایل از پشته حذف شد" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "فایل حذف شد" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "مورد انتخابی به %s اضافه شد" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "یک مورد به %s اضافه شد" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d مورد به %s اضافه شد" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "یک مورد از %s حذف شد" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d مورد از %s حذف شد" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "حساب کاربری ایجاد شد" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "حساب کاربری ذخیره شد" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "حساب کاربری حذف شد" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "تنظیمات ذخیره شد" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "رمزعبور تغییر کرد" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "وارد کردن در %d ثانیه تکمیل شد" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "وارد کردن لغو شد" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "نمایه سازی در %d ثانیه تکمیل شد" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "نمایه سازی نسخه های اصلی ..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "نمایه سازی فایل ها در %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "نمایه سازی لغو شد" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d فایل و %d عکس حذف شد" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "انتقال فایل ها از %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "کپی کردن فایل ها از %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "برچسب ها حذف شدند" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "برچسب ذخیره شد" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "موضوع ذخیره شد" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "موضوع حذف شد" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "فرد ذخیره شد" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "فرد حذف شد" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "فایل حذف شد" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d فایل در %d ثانیه آپلود شد" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "در حال پردازش آپلود..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" -msgstr "بارگذاری پردازش شده است" +msgstr "%s بازیابی شده است" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "مورد انتخابی تایید شد" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "مورد انتخابی بایگانی شد" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "مورد انتخابی بازیابی شد" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "مورد انتخابی به‌عنوان خصوصی علامت‌گذاری شد" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "آلبوم حذف شد" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "فایل فشرده در %d ثانیه ایجاد شد" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "برای همیشه حذف شد" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s بازیابی شده است" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "با موفقیت تأیید شد" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "با موفقیت فعال شد" diff --git a/assets/locales/fi/default.po b/assets/locales/fi/default.po index e682727ac..e3f4ee7e4 100644 --- a/assets/locales/fi/default.po +++ b/assets/locales/fi/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: none\n" "Language: fi\n" @@ -11,418 +11,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Jokin meni pieleen, yritä uudelleen" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Se ei onnistu" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Muutoksia ei voitu tallentaa" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Ei voitu poistaa" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s on jo olemassa" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Ei löytynyt" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Tiedostoa ei löydy" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Tiedosto liian suuri" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Ei tuettu" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Tyyppiä ei tueta" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Ei tuettu muoto" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Originaalit-kansio on tyhjä" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Valintaa ei löydy" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entiteettiä ei löydy" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Tiliä ei löydy" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Käyttäjää ei löydy" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Tarraa ei löydy" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kameraa ei löydy" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektiivia ei löydy" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Albumia ei löydy" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Aihetta ei löydy" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Henkilöä ei löydy" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Kasvoja ei löydy" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Ei käytettävissä julkisessa tilassa" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Ei käytettävissä vain luku-tilassa" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Kirjaudu sisään tilillesi" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Lupa evätty" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Vaadittu maksu" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Upload saattaa olla loukkaava" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Lataus epäonnistui" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Kohdetta ei ole valittu" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Tiedoston luominen epäonnistui, tarkista käyttöoikeudet" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Kansion luominen epäonnistui, tarkista käyttöoikeudet" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Yhteyttä ei saatu muodostettua, yritä uudelleen" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "syötä vahvistus koodi" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Virheellinen vahvistuskoodi, yritä uudelleen" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Väärä salasana, yritä uudelleen" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Ominaisuus poistettu käytöstä" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Ei valittuja tarroja" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Ei valittuja albumeita" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Tiedostoja ei ole ladattavissa" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Zip-tiedoston luominen epäonnistui" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Virheelliset valtakirjat" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Virheellinen linkki" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Virheellinen nimi" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Varattu, yritä myöhemmin uudelleen" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Heräämisväli on %s, mutta sen on oltava enintään 1h" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Tiliäsi ei voitu yhdistää" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Liian monta pyyntöä" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Riittämätön varastointi" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kiintiö ylitetty" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Rekisteröityminen on poistettu käytöstä" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Vaaditaan vahvistettu sähköpostiosoite" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Muutokset tallennettu onnistuneesti" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Albumi luotu" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Albumi tallennettu" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Albumi %s poistettu" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albumin sisältö kloonattu" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Tiedosto poistettu pinosta" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Tiedosto poistettu" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Valinta lisätty %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Yksi merkintä lisätty kohtaan %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d merkintöjä lisätty %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Yksi merkintä poistettu kohdasta %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d merkinnät poistettu %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Tili luotu" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Tallennettu tili" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Tili poistettu" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Asetukset tallennettu" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Salasana vaihdettu" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Tuonti valmis %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Tuonti peruutettu" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksointi valmis %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Alkuperäiskappaleiden indeksointi..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Tiedostojen indeksointi osoitteessa %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksointi peruutettu" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Poistettiin %d tiedostoa ja %d valokuvaa" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Tiedostojen siirtäminen %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Tiedostojen kopiointi %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Tunnisteet poistettu" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Tarra tallennettu" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Aihe tallennettu" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Aihe poistettu" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Tallennettu henkilö" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Henkilö poistettu" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Ladattu tiedosto" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d tiedostoa ladattu %d s aikana" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Käsittelen latausta..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Lataus on käsitelty" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Valinta hyväksytty" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Valinta arkistoitu" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Valinta palautettu" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Valinta merkitty yksityiseksi" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumit poistettu" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip luotu %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Poistettu pysyvästi" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s on palautettu" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Vahvistettu onnistuneesti" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Aktivointi onnistui" diff --git a/assets/locales/fr/default.po b/assets/locales/fr/default.po index 3476325ad..12cea6c83 100644 --- a/assets/locales/fr/default.po +++ b/assets/locales/fr/default.po @@ -2,9 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-28 15:07+0000\n" -"Last-Translator: jean-louis67 \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: French \n" "Language: fr\n" @@ -12,422 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Quelque chose s'est mal passé, réessayez" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" -msgstr "Impossible d'effectuer cela" +msgstr "Impossible de faire cela" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Les modifications n'ont pas pu être sauvegardées" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "N'a pas pu être supprimé" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s existe déjà" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Non trouvé" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fichier non trouvé" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Fichier trop volumineux" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Non pris en charge" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Type non pris en charge" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Format non supporté" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Le dossier des originaux est vide" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Sélection non trouvée" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entité non trouvée" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Compte non trouvé" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Utilisateur non trouvé" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Étiquette non trouvée" -#: messages.go:129 -msgid "Camera not found" -msgstr "Caméra non trouvée" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objectif non trouvé" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" -msgstr "Album non trouvé" +msgstr "Album introuvable" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Sujet non trouvé" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Personne non trouvée" -#: messages.go:134 -#, fuzzy +#: messages.go:124 msgid "Face not found" msgstr "Visage non trouvé" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Non disponible en mode public" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Non disponible en mode lecture seule" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" -msgstr "Veuillez vous connecter à votre compte" +msgstr "Veuillez vous connecter avec votre compte" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" -msgstr "Autorisation refusée" +msgstr "Permission refusée" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Paiement requis" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" -msgstr "Le contenu chargé pourrait être de nature offensante" +msgstr "Le contenu chargé peut être choquant" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Échec du chargement" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Aucun élément sélectionné" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "La création du fichier a échoué, veuillez vérifier les permissions" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Échec de la création du dossier, veuillez vérifier les permissions" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Échec lors de la connexion, veuillez réessayer" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Entrer le code de vérification" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" -msgstr "Code de vérification incorrect, veuillez réessayer" +msgstr "Code de vérification invalide, veuillez réessayer" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" -msgstr "Mot de passe incorrect, veuillez réessayer" +msgstr "Mot de passe invalide, veuillez réessayer" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Fonctionnalité désactivée" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Aucune étiquette sélectionnée" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Aucun album sélectionné" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" -msgstr "Aucun fichier à télécharger" +msgstr "Aucun fichier disponible au téléchargement" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Échec de la création du fichier zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" -msgstr "Les informations d'identification ne sont pas valables" +msgstr "Les informations d'identification sont invalides" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" -msgstr "Lien incorrect" +msgstr "Lien invalide" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" -msgstr "Nom incorrect" +msgstr "Nom invalide" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Occupé, veuillez réessayer plus tard" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" -msgstr "" -"L'intervalle entre les tâches est de %s, mais il doit être inférieur ou égal " -"à 1 h" +msgstr "L'intervalle de réveil est %s, mais doit être inférieur ou égal à 1h" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Votre compte n'a pas pu être connecté" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Trop de demandes" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Espace de stockage insuffisant" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Quota dépassé" -#: messages.go:163 -#, fuzzy -msgid "Registration disabled" -msgstr "Inscription désactivée" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Adresse de courriel vérifiée requise" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Les modifications ont bien été enregistrées" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album créé" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album sauvegardé" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s supprimé" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Le contenu de l'album a été copié" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" -msgstr "Le fichier a été retiré de la pile" +msgstr "Le fichier a été retiré du groupe" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fichier supprimé" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Sélection ajoutée à %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Une entrée a été ajoutée à %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d entrées ont été ajoutées à %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" -msgstr "Une entrée a été supprimée dans %s" +msgstr "Une entrée a été supprimée de %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d entrées ont été supprimées de %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Compte créé" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Compte sauvegardé" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Compte supprimé" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Paramètres sauvegardés" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Mot de passe modifié" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importation terminée en %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importation annulée" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexation terminée en %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexage des originaux…" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" -msgstr "Indexation des fichiers en %s" +msgstr "Indexation des fichiers de %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexation annulée" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Suppression de %d fichiers et %d photos" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Déplacement de fichiers depuis %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Copie de fichiers depuis %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Étiquettes supprimées" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" -msgstr "Étiquette sauvegardée" +msgstr "Étiquettes sauvegardées" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Sujet sauvegardé" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Sujet supprimé" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Personne sauvegardée" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Personne supprimée" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" -msgstr "Fichier chargé" +msgstr "Fichier téléchargé" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fichiers chargés en %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." -msgstr "Chargement en cours…" +msgstr "Traitement du téléchargement..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" -msgstr "Le chargement a été effectué" +msgstr "Le téléchargement a été traité" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Sélection approuvée" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Sélection archivée" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Sélection restaurée" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Sélection marquée comme privée" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albums supprimés" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Archive zip créée en %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Supprimé définitivement" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s a été restauré" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Vérifié avec succès" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Activation réussie" diff --git a/assets/locales/ga/default.po b/assets/locales/ga/default.po index 89438350d..d0f6de88d 100644 --- a/assets/locales/ga/default.po +++ b/assets/locales/ga/default.po @@ -7,9 +7,10 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" "Language: ga\n" "MIME-Version: 1.0\n" @@ -17,418 +18,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : (n>2 && n<7) ? 2 :" "(n>6 && n<11) ? 3 : 4;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Chuaigh rud éigin mícheart, bain triail eile as" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Ní féidir é sin a dhéanamh" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Níorbh fhéidir na hathruithe a shábháil" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Níorbh fhéidir a scriosadh" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s ann cheana" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Ní bhfuarthas" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Comhad gan aimsiú" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Comhad ró-mhór" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Gan tacaíocht" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Cineál nach dtacaítear leis" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Formáid nach dtacaítear léi" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Tá fillteán bunghnéithe folamh" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Níor aimsíodh an rogha" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Aonán gan aimsiú" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Cuntas gan aimsiú" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Úsáideoir gan aimsiú" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Níor aimsíodh an lipéad" -#: messages.go:129 -msgid "Camera not found" -msgstr "Níor aimsíodh an ceamara" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Níor aimsíodh an lionsa" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Albam gan aimsiú" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Ní bhfuarthas an t-ábhar" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Ní bhfuarthas an duine" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Aghaidh gan aimsiú" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Níl sé ar fáil i mód poiblí" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Níl sé ar fáil i mód inléite amháin" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Logáil isteach i do chuntas le do thoil" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Cead diúltaithe" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Íocaíocht ag teastáil" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "D'fhéadfadh uaslódáil a bheith maslach" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Theip ar an uaslódáil" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Níl aon mhír roghnaithe" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Theip ar chruthú an chomhaid, seiceáil na ceadanna" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Theip ar chruthú fillteán, seiceáil na ceadanna" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Níorbh fhéidir ceangal a dhéanamh, bain triail eile as" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Cuir isteach cód fíorúcháin" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Cód fíoraithe neamhbhailí, bain triail eile as" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Pasfhocal neamhbhailí, bain triail eile as" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Gné díchumasaithe" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Níor roghnaíodh aon lipéid" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Níor roghnaíodh aon albam" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Níl aon chomhaid ar fáil le híoslódáil" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Theip ar chruthú an chomhaid zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Dintiúir neamhbhailí" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Nasc neamhbhailí" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Ainm neamhbhailí" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Gnóthach, bain triail eile as ar ball" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Is é %s an t-eatramh múscail, ach caithfidh sé a bheith 1h nó níos lú" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Níorbh fhéidir do chuntas a nascadh" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "An iomarca iarratas" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Stóráil neamhleor" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Sáraíodh an cuóta" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Clárú díchumasaithe" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Ríomhphost fíoraithe ag teastáil" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Sábháladh na hathruithe" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Albam cruthaithe" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Sábháilte albam" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Albam %s scriosta" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Clónáilte ábhar albam" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Baineadh an comhad den chruach" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Scriosadh an comhad" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Cuireadh an rogha le %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Cuireadh iontráil amháin le %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d iontráil curtha le %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Baineadh iontráil amháin de %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d iontráil bainte de %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Cuntas cruthaithe" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Cuntas sábháilte" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Scriosadh an cuntas" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Socruithe sábháilte" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Athraíodh an pasfhocal" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Iompórtáil críochnaithe i %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Cealaíodh an iompórtáil" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Innéacsú curtha i gcrích in %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Buntéacs á innéacsú..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Comhaid á innéacsú in %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Innéacsú cealaithe" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Baineadh %d comhaid agus %d grianghraif" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Comhaid á mbogadh ó %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Comhaid á gcóipeáil ó %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Scriosadh na lipéid" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Lipéad sábháilte" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Ábhar sábháilte" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Scriosadh an t-ábhar" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Sábháladh an duine" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Scriosadh an duine" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Comhad uaslódáilte" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d comhaid uaslódáilte i %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Uaslódáil á phróiseáil..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Próiseáladh an t-uaslódáil" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Faomhadh an roghnúcháin" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Roghnaithe sa chartlann" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Athchóiríodh an roghnúchán" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Roghnú marcáilte mar phríobháideach" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albaim scriosta" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip cruthaithe i %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Scriosta go buan" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s athchóirithe" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "D'éirigh leis a fhíorú" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Cuireadh i ngníomh go rathúil" diff --git a/assets/locales/he/default.po b/assets/locales/he/default.po index 79846fb27..1603d53d7 100644 --- a/assets/locales/he/default.po +++ b/assets/locales/he/default.po @@ -2,9 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: DeepL \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Hebrew \n" "Language: he\n" @@ -13,418 +14,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" -msgstr "משהו השתבש נא לנסות שוב" +msgstr "קרתה תקלה נסה שוב" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" -msgstr "לא ניתן לבצע זאת" +msgstr "לא מסוגל לעשות את זה" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "לא ניתן לשמור שינויים" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "לא ניתן למחיקה" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s כבר קיים" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "לא נמצא" -#: messages.go:118 +#: messages.go:110 msgid "File not found" -msgstr "קובץ לא נמצא" +msgstr "הקובץ לא נמצא" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "קובץ גדול מדי" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" -msgstr "לא נתמך" +msgstr "אינו נתמך" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "סוג לא נתמך" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" -msgstr "תסדיר לא נתמך" +msgstr "פורמט לא נתמך" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" -msgstr "תיקיית מקור ריקה" +msgstr "תיקיית המקור ריקה" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "הבחירה לא נמצאה" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "הישות לא נמצאה" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "החשבון לא נמצא" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "המשתמש לא נמצא" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "התווית לא נמצאה" -#: messages.go:129 -msgid "Camera not found" -msgstr "לא נמצאה מצלמה" - -#: messages.go:130 -msgid "Lens not found" -msgstr "לא נמצא עדשה" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "האלבום לא נמצא" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "הנושא לא נמצא" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "אדם לא נמצא" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "הפנים לא נמצאו" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "לא זמין במצב ציבורי" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "לא זמין במצב קריאה בלבד" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "אנא היכנס לחשבון שלך" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "גישה נדחתה" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "נדרש תשלום" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "ההעלאה עשויה להיות פוגענית" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" -msgstr "העלאה כשלה" +msgstr "העלאה נכשלה" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "לא נבחרו פריטים" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "יצירת הקובץ נכשלה, אנא בדוק את ההרשאות" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "יצירת התיקיה נכשלה, אנא בדוק את ההרשאות" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "לא ניתן היה להתחבר, נסה שוב" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "הכנס קוד אימות" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "קוד אימות לא חוקי, אנא נסה שוב" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "סיסמה לא תקינה, נסה שוב" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "התכונה מושבתת" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "לא נבחרו תוויות" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "לא נבחרו אלבומים" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "אין קבצים זמינים להורדה" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "יצירת קובץ ה-zip נכשלה" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "אישורים לא תקינים" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "קישור לא תקין" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "מספר לא תקף" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "עסוק, אנא נסה שוב מאוחר יותר" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "מרווח ההשכמה הוא %s, אך חייב להיות שעה אחת או פחות" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "לא ניתן היה לחבר את החשבון שלך" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "יותר מדי בקשות" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "אחסון לא מספיק" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "חריגה מהמכסה" -#: messages.go:163 -msgid "Registration disabled" -msgstr "ההרשמה אינה פעילה" - -#: messages.go:164 -msgid "Verified email required" -msgstr "נדרש כתובת דוא\"ל מאומתת" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "השינויים נשמרו בהצלחה" -#: messages.go:168 +#: messages.go:156 msgid "Album created" -msgstr "אלבום נוצר" +msgstr "האלבום נוצר" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "האלבום נשמר" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "האלבום %s נמחק" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "תוכן האלבום שוכפל" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "הקובץ הוסר מהאיחוד" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "הקובץ נמחק" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "הבחירה נוספה ל-%s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "רשומה אחת נוספה ל-%s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d רשומות נוספו ל-%s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "רשומה אחת הוסרה מ-%s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d רשומות הוסרו מ-%s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" -msgstr "חשבון נוצר" +msgstr "החשבון נוצר" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "החשבון נשמר" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" -msgstr "חשבון נמחק" +msgstr "החשבון נמחק" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "ההגדרות נשמרו" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "סיסמא שונתה" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "הייבוא הושלם ב-%d שניות" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "הייבוא בוטל" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "האינדוקס הושלם ב-%d שניות" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "מאנדקס קבצי מקור..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "מאנדקס קבצים תוך %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "יצירת האינדקס בוטלה" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "הוסרו %d קבצים ו-%d תמונות" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "מעביר קבצים מ-%s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "מעתיק קבצים מ-%s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "תוויות נמחקו" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "התווית נשמרה" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "הנושא נשמר" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "הנושא נמחק" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "אדם נשמר" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "אדם נמחק" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "הקובץ הועלה" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d קבצים הועלו תוך %d שניות" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "מעבד העלאה..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "ההעלאה עובדה" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "הבחירה אושרה" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "הבחירה הועברה לארכיון" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "הבחירה שוחזרה" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "הבחירה סומנה כפרטית" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "אלבומים נמחקו" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" -msgstr "קובץ Zip נוצר תוך %d שניות" +msgstr "ה-ZIP נוצר תוך %d שניות" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "נמחק לצמיתות" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s שוחזר" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "אומת בהצלחה" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "הופעל בהצלחה" diff --git a/assets/locales/hi/default.po b/assets/locales/hi/default.po index cd32b24e6..0d14ff1bf 100644 --- a/assets/locales/hi/default.po +++ b/assets/locales/hi/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Hindi \n" "Language-Team: none\n" @@ -13,418 +13,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Nešto nije u redu, pokušajte ponovno" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Nesposoban to učiniti" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Promjene se nisu mogle spremiti" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Nije moguće izbrisati" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s već postoji" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nije pronađeno" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Datoteka nije pronađena" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Datoteka je prevelika" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Nepodržano" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Nepodržana vrsta" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nepodržani format" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Originalna mapa je prazna" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Odabir nije pronađen" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entitet nije pronađen" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "račun nije pronađen" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Korisnik nije pronađen" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Oznaka nije pronađena" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera nije pronađena" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Leća nije pronađena" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nije pronađen" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Predmet nije pronađen" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Osoba nije pronađena" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Lice nije pronađeno" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Nije dostupno u javnom načinu" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "nije dostupno u načinu samo za čitanje" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Molimo prijavite se i pokušajte ponovno" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Osoba je izbrisana" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Potrebno je plaćanje" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Prijenos bi mogao biti uvredljiv" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Prijenos nije uspio" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nema odabranih stavki" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Izrada datoteke nije uspjela, provjerite dopuštenja" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Izrada mape nije uspjela, provjerite dopuštenja" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Povezivanje nije uspjelo, pokušajte ponovno" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Unesite kontrolni kod" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Nevažeći kontrolni kod, pokušajte ponovno" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Nevažeća lozinka, pokušajte ponovo" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Značajka je onemogućena" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nije odabrana nijedna oznaka" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nije odabran nijedan album" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Nema dostupnih datoteka za preuzimanje" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Izrada zip datoteke nije uspjela" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Nevažeće vjerodajnice" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Nevažeća veza" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nevažeći naziv" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Zauzeto, pokušajte ponovo kasnije" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval buđenja je %s, ali mora biti 1 sat ili manje" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Vaš račun nije bilo moguće povezati" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Previše zahtjeva" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Nedovoljno prostora za pohranu" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kvota premašena" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registracija onemogućena" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Potrebna je potvrđena e-pošta" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Promjene su uspješno spremljene" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album stvoren" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album je spremljen" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s je izbrisan" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Sadržaj albuma je kloniran" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Datoteka je uklonjena iz hrpe" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Datoteka je izbrisana" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Odabir je dodan u %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Jedan unos dodan u %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d unosi dodani u %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Jedan unos uklonjen iz %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d unosi uklonjeni iz %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Račun kreiran" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Račun spremljen" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Račun je izbrisan" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Postavke spremljene" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Lozinka je promijenjena" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Uvoz dovršen za %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Uvoz je otkazan" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksiranje dovršeno za %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indeksiranje originala..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indeksiranje datoteka u %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksiranje je otkazano" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Uklonjene %d datoteke i %d fotografije" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Premještanje datoteka iz %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopiranje datoteka s %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Oznake su izbrisane" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Oznaka je spremljena" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Predmet je spremljen" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Predmet je izbrisan" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Osoba je spremljena" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Osoba je izbrisana" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Datoteka je izbrisana" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d datoteke prenesene u %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Obrada prijenosa..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Prijenos bi mogao biti uvredljiv" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Odabir odobren" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Odabir je arhiviran" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Odabir je vraćen" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Odabir je označen kao privatan" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumi su izbrisani" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip stvoren u %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Trajno izbrisano" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" -msgstr "%s je vraćen" +msgstr "Odabir je vraćen" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Uspješno potvrđeno" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Uspješno aktiviran" diff --git a/assets/locales/hu/default.po b/assets/locales/hu/default.po index 776f39004..3e64ef7e4 100644 --- a/assets/locales/hu/default.po +++ b/assets/locales/hu/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Hungarian \n" "Language: hu\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Valami rosszul ment, próbálja újra" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Erre képtelen" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Módosításokat nem sikerült menteni" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Nem sikerült törölni" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s már létezik" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nem található" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fájl nem található" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Túl nagy fájl" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Nem támogatott" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Nem támogatott típus" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nem támogatott formátum" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Az Originals mappa üres" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Kiválasztás nem található" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entitás nem található" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Fiók nem található" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Felhasználó nem található" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Címke nem található" -#: messages.go:129 -msgid "Camera not found" -msgstr "A kamera nem található" - -#: messages.go:130 -msgid "Lens not found" -msgstr "A lencse nem található" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nem található" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Tárgy nem található" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Személy nem található" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Arc nem található" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Nyilvános módban nem elérhető" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Nem elérhető olvasói módban" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Kérjük, jelentkezzen be fiókjába" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Engedély megtagadva" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Fizetés szükséges" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "A feltöltött fájl sértő lehet" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Feltöltés sikertelen" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nincsenek kiválasztva elemek" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Sikertelen fájl létrehozás. Kérjük, ellenőrizze a jogosultságokat" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Sikertelen mappa létrehozás. Kérjük, ellenőrizze a jogosultságokat" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Nem sikerült csatlakozni, próbálja újra" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Adja meg a megerősítő kódot" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Érvénytelen ellenőrző kód. Kérjük, próbálja újra" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Érvénytelen jelszó, próbálkozzon újra" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funkció letiltva" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nincsenek kiválasztva címkék" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nincsenek kiválasztott albumok" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Nincsenek letölthető fájlok" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Nem sikerült létrehozni a zip fájlt" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Érvénytelen belépési adatok" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Érvénytelen hivatkozás" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Érvénytelen név" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Túl magas terhelés, próbálkozzon újra később" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Az ébresztési intervallum a %s, de legfeljebb 1 óra lehet." -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "A fiókját nem lehetett csatlakoztatni" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Túl sok kérés" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Elégtelen tárolás" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "A kvóta túllépése" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Regisztráció letiltva" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Ellenőrzött e-mail cím szükséges" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Módosítások sikeresen mentve" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album létrehozva" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album mentve" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "%s album törölve" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Album tartalma klónozva" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fájl eltávolítva a halomból" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fájl törölve" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Választék hozzáadva a következőhöz: %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Egy bejegyzés hozzáadva a következőhöz: %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d bejegyzés hozzáadva a következőhöz: %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Egy bejegyzés eltávolítva innen: %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d bejegyzés eltávolítva innen: %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Fiók létrehozva" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Fiók mentve" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Fiók törölve" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Beállítások elmentve" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Jelszó megváltoztatva" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importálás %d másodperc alatt befejeződött" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importálás megszakítva" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexelés %d másodperc alatt befejeződött" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Eredeti dokumentumok indexelése..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Fájlok indexelése itt: %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexelés megszakítva" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d fájl és %d fénykép eltávolítva" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Fájlok áthelyezése innen: %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Fájlok másolása innen: %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Címkék törölve" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Címkék mentve" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Tárgy mentve" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Tárgy törölve" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Személy mentve" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Személy törölve" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Fájl feltöltve" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fájl feltöltve %d másodperc alatt" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Feltöltött fájlok feldolgozása..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Feltöltött fájlok feldolgozva" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "A kijelölés jóváhagyva" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "A kijelölés archiválva" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "A kijelölés visszaállítva" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "A kijelölés privátként megjelölve" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumok törölve" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "A tömörített fájl létrejött %d másodperc alatt" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Véglegesen törölve" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s visszaállítva" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Sikeresen ellenőrizve" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Sikeres aktiválás" diff --git a/assets/locales/id/default.po b/assets/locales/id/default.po index 125cb85df..c2c67e9a8 100644 --- a/assets/locales/id/default.po +++ b/assets/locales/id/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Indonesian \n" "Language: id\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Ada yang salah, coba lagi" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Tidak dapat melakukan itu" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Perubahan tidak dapat disimpan" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Tidak dapat dihapus" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s sudah ada" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Tidak ditemukan" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Berkas tidak ditemukan" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Berkas terlalu besar" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Tidak didukung" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Jenis tidak didukung" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Format yang tidak didukung" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Folder asli kosong" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Pilihan tidak ditemukan" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entitas tidak ditemukan" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Akun tidak ditemukan" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Pengguna tidak ditemukan" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Label tidak ditemukan" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera tidak ditemukan" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lensa tidak ditemukan" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album tidak ditemukan" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Subjek tidak ditemukan" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Orang tidak ditemukan" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Wajah tidak ditemukan" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Tidak tersedia dalam mode publik" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Tidak tersedia dalam mode hanya-baca" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Silakan masuk ke akun Anda" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Izin ditolak" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Diperlukan pembayaran" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Unggahan mungkin menyinggung" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Unggahan gagal" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Tidak ada item yang dipilih" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Gagal membuat file, silakan periksa izin" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Gagal membuat folder, harap periksa izin" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Tidak dapat terhubung, silakan coba lagi" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Masukkan kode verifikasi" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Kode verifikasi tidak valid, silakan coba lagi" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Kata sandi salah, silakan coba lagi" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Fitur dinonaktifkan" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Tidak ada label yang dipilih" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Tidak ada album yang dipilih" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Tidak ada file yang tersedia untuk diunduh" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Gagal membuat file zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Kredensial tidak valid" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Tautan tidak valid" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nama tidak valid" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Sibuk, silakan coba lagi nanti" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval wakeup adalah %s, tetapi harus 1 jam atau kurang" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Akun Anda tidak dapat terhubung" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Terlalu banyak permintaan" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Penyimpanan yang tidak memadai" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kuota terlampaui" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Pendaftaran dinonaktifkan" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Email terverifikasi diperlukan." - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Perubahan berhasil disimpan" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album dibuat" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album disimpan" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s dihapus" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Konten album dikloning" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "File dihapus dari tumpukan" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Berkas dihapus" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Pilihan ditambahkan ke %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Satu entri ditambahkan ke %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d entri ditambahkan ke %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Satu entri dihapus dari %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d entri dihapus dari %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Akun dibuat" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Akun disimpan" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Akun dihapus" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Pengaturan disimpan" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Kata sandi diubah" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Impor selesai dalam %d detik" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Impor dibatalkan" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Pengindeksan selesai dalam %d detik" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Mengindeks dokumen asli..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Mengindeks file dalam %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Pengindeksan dibatalkan" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Menghapus %d file dan %d foto" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Memindahkan file dari %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Menyalin file dari %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Label dihapus" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Label disimpan" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Subjek disimpan" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Subjek dihapus" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Orang disimpan" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Orang dihapus" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "File diunggah" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d file diupload di %d detik" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Memproses unggahan..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Unggahan telah diproses" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Pilihan disetujui" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Pilihan diarsipkan" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Pilihan dipulihkan" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Pilihan ditandai sebagai pribadi" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Koleksi album dihapus" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip dibuat dalam %d detik" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Dihapus permanen" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s telah dipulihkan" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Berhasil diverifikasi" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Berhasil diaktifkan" diff --git a/assets/locales/it/default.po b/assets/locales/it/default.po index 88d901080..2830904c1 100644 --- a/assets/locales/it/default.po +++ b/assets/locales/it/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: Italian \n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Qualcosa è andato storto, riprova" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Impossibile farlo" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Le modifiche non possono essere salvate" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Impossibile eliminare" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s esiste già" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Non trovato" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "File non trovato" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "File troppo grande" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Non supportato" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Formato non supportato" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Formato non supportato" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "La cartella degli originali è vuota" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Selezione non trovata" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entità non trovata" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Account non trovato" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Utente non trovato" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etichetta non trovata" -#: messages.go:129 -msgid "Camera not found" -msgstr "Fotocamera non trovata" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Obiettivo non trovato" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album non trovato" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Soggetto non trovato" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Persona non trovata" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Faccia non trovata" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Non disponibile in modalità pubblica" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Non disponibile in modalità di sola lettura" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Accedere al proprio account" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Permesso negato" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Pagamento obbligatorio" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "L'upload potrebbe essere offensivo" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Upload fallito" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nessun elemento selezionato" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Impossibile creare il file, si prega di controllare i permessi" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Impossibile creare la cartella, si prega di controllare i permessi" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Impossibile connettersi, si prega di riprovare" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Inserisci codice di verifca" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Codice di verifica errato, prova di nuovo" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Password non valida, si prega di riprovare" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funzionalità disabilitata" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nessuna etichetta selezionata" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nessun album selezionato" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Nessun file è disponibile per il download" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Impossibile creare il file zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Credenziali non valide" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Link non valido" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nome non valido" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Occupato, si prega di riprovare più tardi" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "L'intervallo di risveglio è %s, ma deve essere pari o inferiore a 1h" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Non è stato possibile collegare l'account" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Troppe richieste" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Stoccaggio insufficiente" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Quota superata" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrazione disabilitata" - -#: messages.go:164 -msgid "Verified email required" -msgstr "È necessario un indirizzo e-mail verificato" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Modifiche salvate con successo" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album creato" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album salvato" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s eliminato" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "I contenuti dell'album sono stati duplicati" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "File rimosso dallo stack" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "File eliminato" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Selezione aggiunta a %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Un elemento aggiunto a %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d elementi aggiunti a %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Un elemento rimosso da %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d elementi rimossi da %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Account creato" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Account salvato" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Account eliminato" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Impostazioni salvate" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Password cambiata" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importazione completata in %d secondi" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importazione cancellata" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indicizzazione completata in %d secondi" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indicizzando gli originali..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indicizzazione dei file in %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indicizzazione cancellata" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Rimossi %d file e %d foto" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Spostamento dei file da %s in corso" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Copia dei file da %s in corso" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etichette eliminate" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etichetta salvata" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Soggetto salvato" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Soggetto cancellato" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Persona salvata" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Persona cancellata" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "File caricato" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d file caricati in %d secondi" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Elaborazione del caricamento..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Il caricamento è stato elaborato" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Selezione approvata" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Selezione archiviata" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Selezione ripristinata" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Selezione impostata come privata" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Album eliminati" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip creato in %d secondi" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Eliminato permanentemente" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s è stato ripristinato" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verifica avvenuta con successo" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Attivazione avvenuta con successo" diff --git a/assets/locales/ja/default.po b/assets/locales/ja/default.po index c30334c9e..a0705c223 100644 --- a/assets/locales/ja/default.po +++ b/assets/locales/ja/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: Japanese \n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "何かが間違っています。もう一度やり直してください" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "その操作はできません" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "変更を保存できませんでした" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "削除できませんでした" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s は既に存在します" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "見つかりませんでした" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "ファイルが見つかりませんでした" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "ファイルが大きすぎます" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "サポートされていません" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "サポートされていない形式です" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "非対応のフォーマットです" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Originals フォルダーは空です" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "選択した項目は存在しません" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "エンティティが見つかりません" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "アカウントが存在しません" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "ユーザーが存在しません" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "ラベルが存在しません" -#: messages.go:129 -msgid "Camera not found" -msgstr "カメラが見つかりません" - -#: messages.go:130 -msgid "Lens not found" -msgstr "レンズが見つからない" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "アルバムが存在しません" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "件名が見つかりません" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "人が見つかりません" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "顔を検出できませんでした" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "公開モードでは利用できません" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "読み込み専用モードでは利用できません" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "アカウントにログインしてください" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "アクセスが拒否されました" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "要支払い" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "アップロードされた項目に過激なものが含まれている可能性があります" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "アップロードに失敗しました" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "項目が選択されていません" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "ファイルの作成に失敗しました。権限を確認してください" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "フォルダの作成に失敗しました。権限を確認してください" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "接続できませんでした。もう一度お試しください" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "認証コードを入力してください" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "認証コードが無効です。もう一度お試しください" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "不正なパスワードです。もう一度お試しください" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "機能が無効になりました" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "ラベルが選択されていません" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "アルバムが選択されていません" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "ダウンロードできるファイルはありません" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "zip ファイルの作成に失敗しました" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "正しくない認証情報です" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "正しくないリンクです" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "無効な名前です" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "他の処理中です。後で再試行してください" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "ウェイクアップ間隔は %s ですが、1時間以内で指定する必要があります" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "アカウントに接続できませんでした" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "リクエストが多すぎます" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "ストレージが不足しています" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "ノルマ超過" -#: messages.go:163 -msgid "Registration disabled" -msgstr "登録が無効になっている" - -#: messages.go:164 -msgid "Verified email required" -msgstr "確認済みのメールアドレスが必要だ" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "変更が正常に保存されました" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "アルバムが作成されました" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "アルバムが保存されました" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "アルバム %s が削除されました" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "アルバムの内容が複製されました" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "スタックからファイルが削除されました" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "ファイルが削除されました" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "選択した項目が %s に追加されました" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "1 件の項目が %s に追加されました" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d 件の項目が %s に追加されました" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "1 件の項目が %s から削除されました" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d 件の項目が %s から削除されました" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "アカウントが作成されました" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "アカウントが保存されました" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "アカウントが削除されました" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "設定が保存されました" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "パスワードが変更されました" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "インポートが %d 秒で完了しました" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "インポートが取り消されました" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "インデックスが %d 秒で完了しました" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "originals をインデックスしています..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "%s 内のファイルをインデックスしています" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "インデックスが取り消されました" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d 件のファイルと %d 件の写真が削除されました" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "%s からファイルを移動しています" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "%s からファイルをコピーしています" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "ラベルが削除されました" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "ラベルが保存されました" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "保存対象" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "件名を削除しました" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "保存された人" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "人を削除しました" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "ファイルがアップロードされました" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d 件のファイルを %d 秒でアップロードしました" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "アップロードの処理..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "アップロードが完了しました" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "選択した項目が承認されました" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "選択した項目がアーカイブされました" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "選択した項目が復元されました" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "選択した項目がプライベートに設定されました" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "アルバムが削除されました" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "%d 秒で zip ファイルを作成しました" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "完全に削除されました" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s が復元されました" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "検証に成功しました" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "正常に有効化されました" diff --git a/assets/locales/ko/default.po b/assets/locales/ko/default.po index f9b005989..d9549d987 100644 --- a/assets/locales/ko/default.po +++ b/assets/locales/ko/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: DeepL \n" "Language-Team: Korean \n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "문제가 발생했습니다. 다시 시도하세요." -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "그렇게 할 수 없습니다." -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "변경 사항을 저장할 수 없음" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "삭제할 수 없음" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s가 이미 존재함" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "찾을 수 없음" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "파일을 찾을 수 없음" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "파일이 너무 큽니다" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "지원되지 않음" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "지원되지 않는 유형" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "지원되지 않는 형식" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "원본 폴더가 비어 있습니다" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "선택 항목을 찾을 수 없음" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "항목을 찾을 수 없음" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "계정을 찾을 수 없음" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "사용자를 찾을 수 없음" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "라벨을 찾을 수 없음" -#: messages.go:129 -msgid "Camera not found" -msgstr "카메라를 찾을 수 없습니다" - -#: messages.go:130 -msgid "Lens not found" -msgstr "렌즈를 찾을 수 없습니다" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "앨범을 찾을 수 없음" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "제목을 찾을 수 없음" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "사람을 찾을 수 없음" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "얼굴을 찾을 수 없음" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "공개 모드에서는 사용할 수 없음" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "읽기 전용 모드에서는 사용할 수 없음" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "귀하의 계정에 로그인하십시오" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "권한이 없음" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "결제 필요" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "업로드가 불쾌할 수 있습니다" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "업로드 실패" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "선택된 항목이 없습니다" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "파일 생성에 실패했습니다. 권한을 확인하세요" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "폴더를 만들지 못했습니다. 권한을 확인하세요" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "연결할 수 없습니다. 다시 시도해 주세요" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "인증코드를 입력하세요" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "잘못된 인증 코드입니다. 다시 시도해 주세요." -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "비밀번호가 잘못되었습니다. 다시 시도해 주세요" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "기능 비활성화됨" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "선택한 라벨이 없습니다" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "앨범이 선택되지 않았습니다" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "다운로드할 수 있는 파일이 없습니다" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "zip 파일 생성 실패" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "잘못된 자격 증명" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "유효하지 않은 링크입니다" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "잘못된 이름" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "바쁘니 나중에 다시 시도해 주세요" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "깨우기 간격은 %s이지만 1시간 이하여야 합니다" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "계정을 연결할 수 없습니다" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "너무 많은 요청" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "저장 공간 부족" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "할당량 초과" -#: messages.go:163 -msgid "Registration disabled" -msgstr "등록이 비활성화되었습니다." - -#: messages.go:164 -msgid "Verified email required" -msgstr "인증된 이메일 주소가 필요합니다" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "변경사항이 성공적으로 저장되었습니다" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "앨범 생성됨" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "앨범 저장됨" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "앨범 %s이(가) 삭제됨" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "복제된 앨범 콘텐츠" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "스택에서 제거된 파일" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "파일이 삭제됨" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "선택 항목이 %s에 추가됨" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "%s에 항목 1개 추가됨" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d 항목이 %s에 추가됨" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "%s에서 항목 1개 삭제됨" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d 항목이 %s에서 제거됨" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "계정 생성됨" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "계정이 저장됨" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "계정 삭제됨" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "설정 저장됨" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "비밀번호 변경됨" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "%d초 후에 가져오기 완료" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "가져오기 취소됨" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "%d초 후에 인덱싱 완료" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "원본 색인 생성 중..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "%s에서 파일 색인 생성" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "인덱싱 취소됨" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "파일 %d개와 사진 %d개를 삭제했습니다" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "%s에서 파일 이동" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "%s에서 파일 복사" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "라벨 삭제됨" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "라벨이 저장되었습니다" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "주제가 저장됨" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "제목 삭제됨" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "사람이 저장됨" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "삭제된 사람" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "업로드된 파일 1개" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d개의 파일이 %d초에 업로드됨" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "업로드 처리 중..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "업로드가 처리되었습니다" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "선택 항목 승인됨" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "선택 항목 보관됨" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "선택 항목 복원됨" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "비공개로 표시된 선택" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "앨범 삭제됨" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "%d초에 생성된 우편번호" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "영구 삭제됨" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s이(가) 복원되었습니다" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "성공적으로 확인되었습니다" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "성공적으로 활성화되었습니다" diff --git a/assets/locales/ku/default.po b/assets/locales/ku/default.po index b9334a39e..afc08ba47 100644 --- a/assets/locales/ku/default.po +++ b/assets/locales/ku/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Kurdish \n" "Language-Team: none\n" "Language: lt\n" @@ -13,418 +13,402 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n % 10 == 1 && (n % 100 < 11 || n % 100 > " "19)) ? 0 : ((n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) ? " "1 : 2);\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Kažkas nepavyko, bandykite dar kartą" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Nepavyksta to padaryti" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Pakeitimų nepavyko išsaugoti" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Negalima ištrinti" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s jau egzistuoja" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nerasta" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Failo rasti nepavyko" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Per didelis failas" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Nepalaikoma" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Nepalaikomas tipas" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nepalaikomas formatas" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Originalų aplankas tuščias" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Pasirinkimas nerastas" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Subjektas nerastas" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Paskyra nerasta" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Vartotojas nerastas" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etiketė nerasta" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kameros nerasta" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektyvas nerastas" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Albumas nerastas" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Tema nerasta" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Asmuo nerastas" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Veidas nerastas" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Negalima naudoti viešuoju režimu" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Negalima naudoti tik skaitymo režimu" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Prisijunkite prie savo paskyros" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Priėjimas neimanomas" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Reikalingas mokėjimas" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Įkėlimas gali būti įžeidžiantis" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Įkelti nepavyko" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nėra pasirinktų elementų" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Nepavyko sukurti failo, patikrinkite leidimus" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Nepavyko sukurti aplanko, patikrinkite leidimus" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Nepavyko prisijungti, bandykite dar kartą" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Įveskite patvirtinimo kodą" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Neteisingas patvirtinimo kodas, bandykite dar kartą" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Netinkamas slaptažodis, bandykite dar kartą" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funkcija išjungta" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nėra pasirinktų etikečių" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nėra pasirinktų albumų" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Nėra parsisiunčiamų failų" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Nepavyko sukurti zip failo" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Neteisingi įgaliojimai" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Netinkama nuoroda" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Netinkamas pavadinimas" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Užimta, bandykite vėliau" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Budinimo intervalas yra %s, bet turi būti ne ilgesnis kaip 1 val" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Nepavyko prisijungti prie jūsų paskyros" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Per daug prašymų" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Nepakankama saugykla" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Viršyta kvota" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registracija išjungta" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Reikalingas patvirtintas el. pašto adresas" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Pakeitimai sėkmingai išsaugoti" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Sukurtas albumas" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Išsaugotas albumas" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Albumas %s pašalintas" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Klonuotas albumo turinys" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Failas pašalintas iš kamino" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Ištrintas failas" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Pasirinkimas pridėtas prie %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Vienas įrašas pridėtas prie %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d įrašai, įtraukti į %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Vienas įrašas pašalintas iš %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d įrašai pašalinti iš %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Sukurta paskyra" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Išsaugota paskyra" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Ištrinta paskyra" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Nustatymai išsaugoti" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Slaptažodis pakeistas" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importas baigtas per %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importas atšauktas" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksavimas baigtas per %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Originalų indeksavimas..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Failų indeksavimas %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksavimas atšauktas" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Pašalinti %d failai ir %d nuotraukos" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Failų perkėlimas iš %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Failų kopijavimas iš %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Ištrintos etiketės" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Išsaugota etiketė" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Tema - išsaugotas" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Išbrauktas objektas" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Išsaugotas asmuo" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Išbrauktas asmuo" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Įkeltas failas" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d failai įkelti per %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Įkėlimo apdorojimas..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Įkėlimas apdorotas" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Patvirtinta atranka" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Atranka archyvuota" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Atkurta atranka" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Atranka pažymėta kaip privati" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Ištrinti albumai" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip sukurta %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Visam laikui ištrintas" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s buvo atkurta" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Sėkmingai patvirtinta" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Sėkmingai suaktyvinta" diff --git a/assets/locales/lv/default.po b/assets/locales/lv/default.po index c50319237..d629e9d32 100644 --- a/assets/locales/lv/default.po +++ b/assets/locales/lv/default.po @@ -7,10 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2026-01-15 09:02+0000\n" +"Last-Translator: Janis Eglitis \n" "Language-Team: none\n" "Language: lv\n" "MIME-Version: 1.0\n" @@ -18,417 +17,401 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n % 10 == 0 || n % 100 >= 11 && n % 100 <= " "19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.15.1\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Kaut kas nogāja greizi, mēģiniet vēlreiz" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "To nevar izdarīt" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Izmaiņas nevarēja saglabāt" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Nevarēja izdzēst" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s jau pastāv" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nav atrasts" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fails nav atrasts" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Fails ir pārāk liels" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Neatbalstīts" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Neatbalstīts tips" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Neatbalstīts formāts" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Oriģinālu mape ir tukša" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Izvēle nav atrasta" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Vienība nav atrasta" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Konts nav atrasts" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Lietotājs nav atrasts" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Birka nav atrasta" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera nav atrasta" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektīvs nav atrasts" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Albums nav atrasts" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Tēma nav atrasta" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Persona nav atrasta" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Seja nav atrasta" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Nav pieejams publiskajā režīmā" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Nav pieejams lasīšanas režīmā" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Lūdzu, piesakieties savā kontā" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Atļauja liegta" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Nepieciešams maksājums" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Augšupielāde varētu būt aizskaroša" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Augšupielāde neizdevās" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nav izvēlēts neviens ieraksts" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Neizdevās izveidot failu, lūdzu, pārbaudiet atļaujas" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Neizdevās izveidot mapi, lūdzu, pārbaudiet atļaujas" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Nevarēja izveidot savienojumu, lūdzu, mēģiniet vēlreiz" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Ievadiet verifikācijas kodu" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Nederīgs verifikācijas kods, lūdzu, mēģiniet vēlreiz" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Nederīga parole, lūdzu, mēģiniet vēlreiz" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funkcionalitāte ir izslēgta" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nav atlasītas nevienas birkas" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nav atlasīts neviens albums" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Nav lejupielādei pieejamu failu" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Neizdevās izveidot zip failu" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Nederīgs lietotājvārds vai parole" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Nederīga saite" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nederīgs nosaukums" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Aizņemts, lūdzu, mēģiniet vēlreiz vēlāk" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Pamošanās intervāls ir %s, bet tam jābūt 1 h vai mazākam" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Jūsu kontu nevarēja savienot" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Pārāk daudz pieprasījumu" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Nepietiek brīvas vietas" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kvota pārsniegta" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Reģistrācija atspējota" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Nepieciešama verificēta e-pasta adrese" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Izmaiņas veiksmīgi saglabātas" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Albums izveidots" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Albums saglabāts" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Albums %s ir dzēsts" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albuma saturs ir dublēts" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fails izņemts no saraksta" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fails izdzēsts" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Atlasījums pievienots %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Viens ieraksts pievienots %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d ieraksti pievienoti %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Viens ieraksts noņemts no %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d ieraksti noņemti no %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Konts izveidots" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Konts saglabāts" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Konts ir dzēsts" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Iestatījumi saglabāti" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Parole nomainīta" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importēšana pabeigta %d s laikā" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importēšana atcelta" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksēšana pabeigta %d s laikā" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Notiek oriģinālu indeksēšana..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Notiek failu indeksēšana %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksēšana atcelta" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Noņemti %d faili un %d fotoattēli" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Failu pārvietošana no %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Failu kopēšana no %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Birkas ir dzēstas" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Birka saglabāta" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Tēma saglabāta" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Tēma dzēsta" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Persona saglabāta" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Persona dzēsta" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Fails augšupielādēts" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d faili augšupielādēti %d sekundēs" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Notiek augšupielādes apstrāde..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Augšupielāde ir apstrādāta" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Atlase apstiprināta" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Atlase arhivēta" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Atlase atjaunota" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Izvēle atzīmēta kā privāta" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumi ir dzēsti" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "ZIP fails izveidots %d sekundēs" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Neatgriezeniski dzēsts" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s ir atjaunots" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Veiksmīgi verificēts" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Veiksmīgi aktivizēts" diff --git a/assets/locales/messages.pot b/assets/locales/messages.pot index d6e4d5e67..e5b61e355 100644 --- a/assets/locales/messages.pot +++ b/assets/locales/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,415 +17,399 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "" -#: messages.go:129 -msgid "Camera not found" -msgstr "" - -#: messages.go:130 -msgid "Lens not found" -msgstr "" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "" -#: messages.go:163 -msgid "Registration disabled" -msgstr "" - -#: messages.go:164 -msgid "Verified email required" -msgstr "" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "" -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "" diff --git a/assets/locales/ms/default.po b/assets/locales/ms/default.po index fd02b78cb..3ce9fa2cb 100644 --- a/assets/locales/ms/default.po +++ b/assets/locales/ms/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Kesilapan telah berlaku, cuba lagi" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Tidak mampu berbuat demikian" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Perubahan tidak dapat disimpan" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Tidak dapat dipadamkan" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s sudah wujud" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Tidak ditemui" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fail tidak dijumpai" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Fail terlalu besar" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Tidak disokong" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Jenis tidak disokong" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Format yang tidak disokong" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Folder asal kosong" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Pilihan tidak ditemui" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entiti tidak ditemui" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "akaun tidak dijumpai" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Pengguna tidak dijumpai" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Label tidak ditemui" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera tidak ditemui" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lensa tidak ditemui" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album tidak ditemui" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Subjek tidak ditemui" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Orang tidak ditemui" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Wajah tidak ditemui" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Tidak tersedia dalam mod awam" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Tidak tersedia dalam mod baca sahaja" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Sila log masuk ke akaun anda" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Kebenaran ditolak" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Bayaran diperlukan" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Muat naik mungkin menyinggung perasaan" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Muat naik gagal" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Tiada item dipilih" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Gagal membuat fail, sila semak kebenaran" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Gagal membuat folder, sila semak kebenaran" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Tidak dapat menyambung, sila cuba lagi" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Masukkan kod pengesahan" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Kod pengesahan tidak sah, sila cuba lagi" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Kata laluan tidak sah, sila cuba lagi" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Ciri dilumpuhkan" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Tiada label dipilih" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Tiada album dipilih" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Tiada fail tersedia untuk dimuat turun" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Gagal membuat fail zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Bukti kelayakan tidak sah" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Pautan tidak sah" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nama tidak sah" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Sibuk, sila cuba lagi nanti" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Selang bangun ialah %s, tetapi mestilah 1j atau kurang" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Akaun anda tidak dapat disambungkan" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Terlalu banyak permintaan" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Storan tidak mencukupi" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kuota melebihi" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Pendaftaran dilumpuhkan" - -#: messages.go:164 -msgid "Verified email required" -msgstr "E-mel yang disahkan diperlukan" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Perubahan berjaya disimpan" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album dibuat" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album disimpan" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s dipadamkan" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Kandungan album diklon" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fail dialih keluar daripada timbunan" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fail dipadamkan" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Pilihan ditambahkan pada %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Satu entri ditambahkan pada %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "Entri %d ditambahkan pada %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Satu entri dialih keluar daripada %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d entri dialih keluar daripada %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Akaun dibuat" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Akaun disimpan" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Akaun dipadamkan" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Tetapan Disimpan" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Kata laluan ditukar" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import selesai dalam %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import dibatalkan" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Pengindeksan selesai dalam %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Mengindeks asal..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Mengindeks fail dalam %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Pengindeksan dibatalkan" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Mengalih keluar fail %d dan foto %d." -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Memindahkan fail dari %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Menyalin fail daripada %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Label dipadamkan" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Label disimpan" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Subjek disimpan" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Subjek dipadamkan" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Orang yang diselamatkan" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Orang dipadamkan" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Fail dimuat naik" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "Fail %d dimuat naik dalam %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Memproses muat naik..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Muat naik telah diproses" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Pemilihan diluluskan" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Pemilihan diarkibkan" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Pemilihan dipulihkan" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Pilihan ditandakan sebagai peribadi" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Album dipadamkan" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip dibuat dalam %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Dipadamkan secara kekal" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s telah dipulihkan" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Berjaya disahkan" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Berjaya diaktifkan" diff --git a/assets/locales/nb/default.po b/assets/locales/nb/default.po index ffda6d942..4163f3e9d 100644 --- a/assets/locales/nb/default.po +++ b/assets/locales/nb/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Norwegian Bokmål \n" "Language: nb\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Noe gikk galt, prøv igjen" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Ikke i stand til å gjøre det" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Kan ikke lagre endringer" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Kan ikke slettes" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s eksisterer allerede" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Ikke funnet" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fil ikke funnet" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Filen er for stor" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Ustøttet" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Ikke støttet type" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Ikke støttet format" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Originaler-mappen er tom" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Finner ikke utvalg" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Enheten ble ikke funnet" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Konto ikke funnet" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Bruker ikke funnet" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Merkelapp ikke funnet" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kameraet ble ikke funnet" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektivet ble ikke funnet" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album ikke funnet" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Emnet ble ikke funnet" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Person ikke funnet" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Ansikt ikke funnet" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Ikke tilgjengelig i offentlig modus" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "ikke tilgjengelig i skrivebeskyttet modus" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Logg inn på kontoen din" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Ingen tilgang" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Betaling kreves" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Opplastingen kan være støtende" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Opplasting mislyktes" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Ingen elementer valgt" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Kunne ikke opprette fil, vennligst sjekk tillatelser" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Kunne ikke opprette mappe, vennligst sjekk tillatelser" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Kunne ikke koble til, vennligst prøv igjen" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Angi verifikasjonskode" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Ugyldig bekreftelseskode. Prøv igjen" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Ugyldig passord, vennligst prøv igjen" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Tjeneste deaktivert" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Ingen merkelapper valgt" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Ingen albumer valgt" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Ingen filer tilgjengelig for nedlasting" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Kunne ikke opprette zip-arkiv" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Ugyldige innloggingsdetaljer" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Ugyldig lenke" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Ugyldig navn" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Opptatt. Prøv igjen senere" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Oppvåkningsintervallet er %s, men må være 1 time eller mindre" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Kontoen din kunne ikke kobles til" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "For mange forespørsler" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Utilstrekkelig lagringsplass" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kvote overskredet" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrering deaktivert" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Bekreftet e-post kreves" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Endringene ble lagret" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album opprettet" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album lagret" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s slettet" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albuminnhold duplisert" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fil fjernet fra samling" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fil slettet" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Utvalg lagt til %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "En oppføring lagt til %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d oppføringer lagt til %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "En oppføring fjernet fra %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d oppføringer fjernet fra %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Konto opprettet" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Konto lagret" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Konto slettet" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Innstillinger lagret" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Passord endret" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import fullført på %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import avbrutt" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksering fullført på %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indekserer originaler…" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indekserer filer i %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksering avbrutt" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Fjernet %d filer og %d foto" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Flytter filer fra %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopierer filer fra %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Merkelapper slettet" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Merkelapper lagret" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Emnet er lagret" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Emnet er slettet" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Person reddet" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Person slettet" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Fil lastet opp" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d filer lastet opp på %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Behandler opplasting..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Opplastingen er behandlet" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Utvalg godkjent" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Utvalg arkivert" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Utvalg gjenopprettet" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Utvalg markert som privat" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Album slettet" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip opprettet på %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Permanent slettet" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s har blitt gjenopprettet" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Vellykket verifisert" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Vellykket aktivert" diff --git a/assets/locales/nl/default.po b/assets/locales/nl/default.po index ab630b315..505e5b8ca 100644 --- a/assets/locales/nl/default.po +++ b/assets/locales/nl/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Dutch \n" "Language: nl\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Er ging iets mis, probeer het opnieuw" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Dat kan niet" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Wijzigingen kunnen niet worden opgeslagen" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Kan niet verwijderd worden" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s bestaat al" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Niet gevonden" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Bestand niet gevonden" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Bestand te groot" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Niet ondersteund" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Niet-ondersteund type" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Niet ondersteund formaat" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "De map Originelen is leeg" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Selectie niet gevonden" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entiteit niet gevonden" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Account niet gevonden" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Gebruiker niet gevonden" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Label niet gevonden" -#: messages.go:129 -msgid "Camera not found" -msgstr "Camera niet gevonden" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lens niet gevonden" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album niet gevonden" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Onderwerp niet gevonden" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Persoon niet gevonden" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Gezicht niet gevonden" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Niet beschikbaar in publieke modus" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Niet beschikbaar in alleen-lezen modus" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Log in op je account" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Toegang geweigerd" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Betaling vereist" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Upload kan aanstootgevend zijn" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Uploaden mislukt" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Geen items geselecteerd" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Bestand aanmaken mislukt, controleer alstublieft de rechten" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Folder aanmaken mislukt, controleer alstublieft de rechten" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Kan niet verbinden, probeer alstublieft opnieuw" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Verificatiecode invoeren" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Ongeldige verificatiecode. Probeer het opnieuw" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Fout wachtwoord, probeer alstublieft opnieuw" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Functie uitgeschakeld" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Geen labels geselecteerd" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Geen albums geselecteerd" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Geen bestanden beschikbaar om te downloaden" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Maken van zip-bestand is mislukt" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Ongeldige inloggegevens" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Ongeldige link" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Ongeldige mapnaam" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Bezet, probeer het later nog eens" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Het wekinterval is %s, maar moet 1 uur of minder zijn" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Uw account kon niet worden aangesloten" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Te veel verzoeken" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Onvoldoende opslag" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Quota overschreden" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registratie uitgeschakeld" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Geverifieerd e-mailadres vereist" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Wijzigingen succesvol opgeslagen" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album aangemaakt" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album opgeslagen" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s verwijderd" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albuminhoud gekopieerd" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Bestand uit stapel verwijderd" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Bestand verwijderd" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Selectie toegevoegd aan %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Eén item toegevoegd aan %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d items toegevoegd aan %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Eén item verwijderd uit %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d items verwijderd uit %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Account aangemaakt" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Account opgeslagen" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Account verwijderd" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Instellingen opgeslagen" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Wachtwoord gewijzigd" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importeren voltooid in %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importeren geannuleerd" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexeren voltooid in %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Originelen indexeren…" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Bestanden indexeren in %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexeren geannuleerd" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d bestanden en %d foto’s verwijderd" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Bestanden verplaatsen uit %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Bestanden kopiëren uit %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Labels verwijderd" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Labels opgeslagen" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Onderwerp opgeslagen" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Onderwerp verwijderd" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Persoon gered" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Persoon verwijderd" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Bestand geüpload" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d bestanden geüpload in %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Verwerking upload..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Upload is verwerkt" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Selectie goedgekeurd" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Selectie gearchiveerd" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Selectie hersteld" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Selectie gemarkeerd als privé" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albums verwijderd" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip gemaakt in %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Permanent verwijderd" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s is hersteld" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Met succes geverifieerd" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Met succes geactiveerd" diff --git a/assets/locales/pl/default.po b/assets/locales/pl/default.po index 6f13d5eb2..8df2c89ee 100644 --- a/assets/locales/pl/default.po +++ b/assets/locales/pl/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Polish \n" "Language: pl\n" @@ -14,420 +13,404 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Coś poszło nie tak, spróbuj jeszcze raz" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Nie da się tego zrobić" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Nie można zapisać zmian" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Nie można usunąć" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s już istnieje" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nie znaleziono" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Plik nie został znaleziony" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Plik jest zbyt duży" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Nieobsługiwane" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Nieobsługiwany typ" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nieobsługiwany format" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Folder oryginałów jest pusty" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Nie znaleziono wyboru" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Nie znaleziono podmiotu" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Konto nie znalezione" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Użytkownik nie znaleziony" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etykieta nie została odnaleziona" -#: messages.go:129 -msgid "Camera not found" -msgstr "Nie znaleziono kamery" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Nie znaleziono obiektywu" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nie został znaleziony" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Temat nie został znaleziony" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Osoba nie została znaleziona" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Twarz nie została znaleziona" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Niedostępne w trybie publicznym" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Niedostępne w trybie tylko do odczytu" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Proszę zalogować się na swoje konto" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Brak uprawnień" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Wymagana płatność" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Przesyłane dane mogą być obraźliwe" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Przesyłanie nie powiodło się" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Nie wybrano żadnych elementów" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Nie można utworzyć pliku, sprawdź uprawnienia" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Nie można utworzyć folderu, sprawdź uprawnienia" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Nie można się połączyć, spróbuj ponownie" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Wprowadź kod weryfikacyjny" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Nieprawidłowy kod weryfikacyjny. Spróbuj ponownie" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Nieprawidłowe hasło, spróbuj ponownie" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funkcja wyłączona" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nie wybrano etykiet" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nie wybrano albumów" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Brak plików do pobrania" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Nie udało się utworzyć pliku zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Nieprawidłowe dane logowania" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Nieprawidłowy link" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nieprawidłowa nazwa" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Zajęty, spróbuj ponownie później" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" "Interwał wybudzenia %s jest nieprawidłowy, powinien być równy lub mniejszy " "niż 1 godzina" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Twoje konto nie może być podłączone" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Zbyt wiele żądań" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Niewystarczająca pamięć" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Przekroczony limit" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Rejestracja wyłączona" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Wymagany zweryfikowany adres e-mail" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Zmiany zostały pomyślnie zapisane" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album został utworzony" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album został zapisany" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s został usunięty" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Album został sklonowany" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Plik został rozgrupowany" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Plik został usunięty" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Wybór dodany do %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Dodano jeden wpis do %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d wpisy dodane do %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Usunięto jeden wpis z %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d wpisy usunięte z %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Konto utworzone" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Konto zapisane" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Konto usunięte" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Ustawienia zapisane" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Hasło zostało zmienione" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import zakończony w %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import został anulowany" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksowanie zakończone w %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indeksowanie oryginałów…" -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indeksowanie plików w %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksowanie anulowane" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Usunięto %d plików i %d zdjęć" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Przenoszenie plików z %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopiowanie plików z %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Usunięto etykiety" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etykieta zapisana" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Przedmiot zapisany" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Przedmiot usunięty" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Osoba zapisana" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Osoba usunięta" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Przesłany plik" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d plików przesłano w %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Przetwarzanie uploadu..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Przesyłanie zostało przetworzone" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Wybór zatwierdzony" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Wybór zarchiwizowany" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Wybór został przywrócony" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Wybór oznaczony jako prywatny" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumy zostały usunięte" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip utworzony w %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Trwale usunięty" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s zostało przywrócone" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Pomyślnie zweryfikowano" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Pomyślnie aktywowano" diff --git a/assets/locales/pt/default.po b/assets/locales/pt/default.po index 1420728b7..cfaf6f910 100644 --- a/assets/locales/pt/default.po +++ b/assets/locales/pt/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Portuguese \n" "Language: pt\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Algo correu mal, tente novamente" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Incapaz de fazer isso" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "As mudanças não foram salvas" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Não foi possível excluir" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s já existe" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Não encontrado" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Arquivo não encontrado" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Arquivo muito grande" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Não compatível" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Tipo não suportado" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Formato sem suporte" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "A pasta dos originais está vazia" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Seleção não encontrada" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entidade não encontrada" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Conta não encontrada" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Usuário não encontrado" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etiqueta não encontrada" -#: messages.go:129 -msgid "Camera not found" -msgstr "Não foi encontrada nenhuma câmara" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lente não encontrada" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Álbum não encontrado" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Assunto não encontrado" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Pessoa não encontrada" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Rosto não encontrado" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Indisponível em modo público" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Não disponível no modo somente leitura" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Faça o login em sua conta" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Permissão negada" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Pagamento obrigatório" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Envio pode ser ofensivo" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Envio falhou" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Sem itens selecionados" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Falha ao criar arquivo, por favor cheque as permissões" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Falha ao criar pasta, por favor cheque as permissões" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Não foi possível conectar, por favor tente novamente" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Digite o código de verificação" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Código de verificação inválido, tente novamente" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Senha inválida, por favor tente novamente" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Recurso Desativado" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Sem etiquetas selecionadas" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Sem álbuns selecionados" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Sem arquivos disponíveis para baixar" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Falha ao criar arquivo zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Credenciais inválidas" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Link inválido" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nome inválido" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Em uso, por favor tente novamente mais tarde" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "O intervalo de despertar é %s, mas deve ser de 1h ou menos" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Sua conta não pôde ser conectada" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Demasiados pedidos" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Armazenamento insuficiente" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Quota excedida" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Cadastro desativado" - -#: messages.go:164 -msgid "Verified email required" -msgstr "É necessário um e-mail verificado." - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "As mudanças foram salvas com sucesso" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Álbum criado" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Álbum salvo" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Álbum %s excluído" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Conteúdo do álbum copiado" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Arquivo removido da pilha" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Arquivo excluído" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Seleção adicionada a %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Uma entrada adicionada a %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d entradas adicionadas a %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Uma entrada removida de %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d entradas removidas de %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Conta criada" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Conta salva" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Conta excluída" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Configurações salvas" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Senha alterada" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importação completa em %d" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importação cancelada" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexação completa em %d" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexando originais..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexando arquivos em %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexação cancelada" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Removidos %d arquivos e %d fotos" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Movendo arquivos de %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Copiando arquivos de %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etiquetas excluídas" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etiqueta salva" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Assunto salvo" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Assunto eliminado" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Pessoa salva" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Pessoa apagada" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Arquivo carregado" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d arquivos enviados em %d" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "A processar carregamento..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "O Upload foi processado" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Seleção aprovada" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Seleção arquivada" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Seleção restaurada" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Seleção marcada como privada" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Álbuns excluídos" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip criado em %d" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Permanentemente excluídas" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s foi restaurado" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verificado com sucesso" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Ativado com sucesso" diff --git a/assets/locales/pt_BR/default.po b/assets/locales/pt_BR/default.po index 1b9c612e9..5138e6ae0 100644 --- a/assets/locales/pt_BR/default.po +++ b/assets/locales/pt_BR/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Algo deu errado, tente novamente" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Incapaz de fazer isso" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "As mudanças não foram salvas" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Não foi possível excluir" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s já existe" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Não encontrado" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Arquivo não encontrado" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Arquivo muito grande" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Não compatível" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Tipo não suportado" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Formato sem suporte" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "A pasta dos originais está vazia" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Seleção não encontrada" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entidade não encontrada" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Conta não encontrada" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Usuário não encontrado" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etiqueta não encontrada" -#: messages.go:129 -msgid "Camera not found" -msgstr "Câmera não encontrada" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lente não encontrada" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Álbum não encontrado" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Assunto não encontrado" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Pessoa não encontrada" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Rosto não encontrado" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Indisponível em modo público" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Não disponível no modo somente leitura" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Faça o login em sua conta" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Permissão negada" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Pagamento obrigatório" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Envio pode ser ofensivo" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Envio falhou" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Sem itens selecionados" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Falha ao criar arquivo, por favor cheque as permissões" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Falha ao criar pasta, por favor cheque as permissões" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Não foi possível conectar, por favor tente novamente" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Digite o código de verificação" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Código de verificação inválido, tente novamente" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Senha inválida, por favor tente novamente" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Recurso Desativado" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Sem etiquetas selecionadas" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Sem álbuns selecionados" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Sem arquivos disponíveis para baixar" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Falha ao criar arquivo zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Credenciais inválidas" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Link inválido" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nome inválido" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Ocupado, por favor tente mais tarde" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "O intervalo de despertar é %s, mas deve ser de 1h ou menos" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Sua conta não pôde ser conectada" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Muitas solicitações" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Armazenamento insuficiente" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Cota excedida" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Cadastro desativado" - -#: messages.go:164 -msgid "Verified email required" -msgstr "É necessário um e-mail verificado." - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "As mudanças foram salvas com sucesso" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Álbum criado" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Álbum salvo" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Álbum %s excluído" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Conteúdo do álbum copiado" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Arquivo removido da pilha" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Arquivo excluído" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Seleção adicionada a %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Uma entrada adicionada a %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d entradas adicionadas a %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Uma entrada removida de %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d entradas removidas de %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Conta criada" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Conta salva" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Conta excluída" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Configurações salvas" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Senha alterada" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importação completa em %d" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importação cancelada" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexação completa em %d" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexando originais..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexando arquivos em %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexação cancelada" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Removidos %d arquivos e %d fotos" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Movendo arquivos de %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Copiando arquivos de %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etiquetas excluídas" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etiqueta salva" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Assunto salvo" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Assunto eliminado" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Pessoa salva" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Pessoa apagada" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Arquivo carregado" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d arquivos enviados em %d" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Processamento de upload..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "O Upload foi processado" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Seleção aprovada" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Seleção arquivada" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Seleção restaurada" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Seleção marcada como privada" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Álbuns excluídos" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip criado em %d" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Permanentemente excluídas" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s foi restaurado" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verificado com sucesso" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Ativado com sucesso" diff --git a/assets/locales/ro/default.po b/assets/locales/ro/default.po index d39ebbe00..2ede4f6fd 100644 --- a/assets/locales/ro/default.po +++ b/assets/locales/ro/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Romanian \n" "Language: ro\n" @@ -14,418 +13,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Ceva nu a mers bine, încercați din nou" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Nu se poate face asta" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Modificările nu au putut fi salvate" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Nu a putut fi șters" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s deja există" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nu a fost găsit" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Fișier nedescoperit" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Fișier prea mare" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Neacceptat" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Tip neacceptat" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Format neacceptat" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Dosarul Originals este gol" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Selecția nu a fost găsită" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entitatea nu a fost găsită" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Contul nu a fost găsit" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Utilizatorul nu a fost găsit" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Eticheta nu a fost găsită" -#: messages.go:129 -msgid "Camera not found" -msgstr "Nu s-a găsit camera" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Obiectivul nu a fost găsit" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nedescoperit" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Subiectul nu a fost găsit" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Persoana nu a fost găsită" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Fața nu a fost găsită" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Nu este disponibil în modul public" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Nu este disponibil în modul doar pentru citire" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Vă rugăm să vă conectați la contul dvs" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Permisiune refuzată" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Plata necesară" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Încărcarea poate fi ofensatoare" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Încărcarea a eșuat" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Niciun element selectat" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Nu a reușit să creeze fișierul, vă rugăm să verificați permisiunile" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Nu s-a reușit crearea dosarului, vă rugăm să verificați permisiunile" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Nu s-a putut conecta, vă rugăm să încercați din nou" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Introduceți codul de verificare" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Cod de verificare nevalid, încercați din nou" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Parolă invalidă, vă rugăm să încercați din nou" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Caracteristică dezactivată" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Nu sunt selectate etichete" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Nu sunt selectate albume" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Nu există fișiere disponibile pentru descărcare" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Nu a reușit să creeze fișierul zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Acreditări nevalabile" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Legătură invalidă" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Nume invalid" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Ocupat, vă rugăm să încercați din nou mai târziu" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Intervalul de trezire este %s, dar trebuie să fie de 1h sau mai puțin" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Contul dvs. nu a putut fi conectat" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Prea multe cereri" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Depozitare insuficientă" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Cota depășită" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Înregistrare dezactivată" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Adresă de e-mail verificată necesară" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Modificări salvate cu succes" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album creat" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album salvat" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s șters" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Conținutul albumului a fost clonat" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Fișier eliminat din stivă" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fișier șters" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Selecție adăugată la %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "O intrare adăugată la %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d intrări adăugate la %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "O intrare eliminată din %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d intrări eliminate din %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Cont creat" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Cont salvat" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Cont șters" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Setări salvate" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Parola a fost schimbată" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import finalizat în %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importul a fost anulat" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexare finalizată în %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexarea originalelor..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexarea fișierelor în %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexare anulată" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Sau eliminat %d fișiere și %d fotografii" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Mutarea fișierelor din %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Copierea fișierelor din %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etichete șterse" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etichetă salvată" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Subiect salvat" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Subiect eliminat" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Persoană salvată" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Persoană eliminată" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Fișier încărcat" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d fișiere încărcate în %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Procesarea încărcării..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Încărcarea a fost procesată" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Selecție aprobată" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Selecție arhivată" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Selecție restabilită" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Selecție marcată ca fiind privată" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albume șterse" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Fișierul Zip creat în %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Șterse definitiv" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s a fost restaurat" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verificat cu succes" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Activat cu succes" diff --git a/assets/locales/ru/default.po b/assets/locales/ru/default.po index 65da63537..41d933175 100644 --- a/assets/locales/ru/default.po +++ b/assets/locales/ru/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Russian \n" "Language: ru\n" @@ -14,418 +13,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Что-то пошло не так, попробуйте еще раз" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Невозможно сделать это" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Изменения не будут сохранены" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Не будет удалено" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s уже существует" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Не найдено" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Файл не найден" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Слишком большой файл" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Не поддерживается" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Неподдерживаемый тип" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Неподдерживаемый формат" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Папка оригиналов пуста" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Выделение не найдено" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Сущность не найдена" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Учетная запись не найдена" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Пользователь не найден" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Метка не найдена" -#: messages.go:129 -msgid "Camera not found" -msgstr "Камера не найдена" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Объектив не найден" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Альбом не найден" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Объект не найден" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Человек не найден" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Лицо не найдено" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Не доступно в публичном режиме" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Недоступно в режиме только для чтения" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Пожалуйста, войдите в свой аккаунт" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Доступ запрещен" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Требуется оплата" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Загрузка может быть оскорбительной" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Загрузка не удалась" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Нет выделенных элементов" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Не удалось создать файл, проверьте права доступа" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Не удалось создать папку, проверьте права доступа" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Нет соединения, попробуйте еще раз" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "введите код подтверждения" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Неверный код подтверждения. Повторите попытку." -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Неверный пароль, пожалуйста попробуйте еще раз" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Данная возможность отключена" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Нет выделенных меток" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Нет выделенных альбомов" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Нет файлов, доступных для скачивания" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Не удалось создать zip-файл" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Неверные учетные данные" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Неверная ссылка" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Неприемлемое имя" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Занят, повторите попытку позже" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Интервал пробуждения составляет %s, но должен быть 1 час или меньше" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Ваш аккаунт не удалось подключить" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Слишком много запросов" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Недостаточно места для хранения" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Квота превышена" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Регистрация отключена" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Требуется подтверждение адреса электронной почты." - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Изменения сохранены" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Альбом создан" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "\\альбом сохранен" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Альбом %s удален" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Содержимое альбома скоприровано" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Файл удален из очереди" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Файл удалён" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Выделение добавлено к %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Один элемент добавлен к %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d элементов добавлено к %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Один элемент удален из %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d элементов удалено из %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Учетная запись создана" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Учетная запись сохранена" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Учетная запись удалена" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Настройки сохранены" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Пароль изменен" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Импортирование завершено за %d c" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Импортирование отменено" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Индексирование завершено за %d с" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Индексирование Оригиналов..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Индексирование файлов в %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Индексирование отменено" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Удаление %d файлов и %d фотографий" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Перемещение файлов из %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Копирование файлов из %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Метки удалены" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Метки сохранены" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Тема сохранена" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Тема удалена" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Человек спасен" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Лицо удалено" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Файл загружен" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлов загружено за %d с" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Обработка загрузки..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Загрузка была обработана" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Утвержденный выбор" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Выбранное помещено в архив" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Выбранное восстановлено" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Выбранное помечено как приватное" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Альбом удален" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip архив создан за %d с" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Постоянно удаляется" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s был восстановлен" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Успешно проверено" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Успешно активировано" diff --git a/assets/locales/sk/default.po b/assets/locales/sk/default.po index 250c13b5a..5a5246fd2 100644 --- a/assets/locales/sk/default.po +++ b/assets/locales/sk/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Slovak \n" "Language: sk\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Niečo sa pokazilo, skúste to znova" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Nemožno to urobiť" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Zmeny sa neuložili" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Nepodarilo sa odstrániť" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s už existuje" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Nenájdené" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Súbor nenájdený" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Príliš veľký súbor" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Nepodporované" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Nepodporovaný typ" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nepodporovaný formát" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Priečinok Originály je prázdny" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Výber nenájdený" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Subjekt nenájdený" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Účet nenájdený" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Užívateľ nenájdený" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Štítok nenájdený" -#: messages.go:129 -msgid "Camera not found" -msgstr "Fotoaparát nebol nájdený" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektív nebol nájdený" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album nenájdený" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Predmet nenájdený" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Osoba nenájdená" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Tvár nenájdená" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Nedostupné vo verejnom móde" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "nedostupné v móde len pre čítanie" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Prosím prihláste sa a skúste znova" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Osoba odstránená" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Požadovaná platba" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Nahrané súbory môžu byť urážlivé" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Odovzdávanie zlyhalo" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Neboli vybraté žiadne položky" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Vytváranie súboru zlyhalo, prosím skontrolujte oprávnenia" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Vytváranie zložky zlyhalo, prosím skontrolujte oprávnenia" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Nebolo možné sa pripojiť, skúste to znova" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Zadajte overovací kód" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Neplatný overovací kód, skúste to znova" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Nesprávne heslo, skúste to znova" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funkcia vypnutá" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Neboli vybraté žiadne štítky" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Neboli vybraté žiadne albumy" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Žiadne súbory na stiahnutie k dispozícií" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Nebolo možné vytvoriť súbor ZIP" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Neplatné údaje" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Neplatný odkaz" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Neplatné meno" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Systém zaneprázdnený, prosím skúste znovu neskôr" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval prebúdzania je %s, ale musí byť najviac 1 h" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Vaše konto sa nepodarilo pripojiť" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Príliš veľa požiadaviek" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Nedostatočné skladovanie" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Prekročenie kvóty" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrácia zakázaná" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Vyžaduje sa overený e-mail" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Zmeny úspešne uložené" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album vytvorený" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album uložený" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s vymazaný" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Obsah albumu prekopírovaný" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Súbor odstránený zo stohu" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Súbor odstránený" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Výber pridaný do %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Jeden záznam pridaný do %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d záznamov pridaných do %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Jeden záznam odstránený z %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d záznamov odstránených z %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Účet vytvorený" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Účet uložený" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Účet odstránený" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Nastavenia uložené" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Heslo zmenené" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Import hotový za %d sekúnd" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Import zrušený" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexovanie hotové za %d sekúnd" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexovanie originálov..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexovanie súborov v %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexovanie zrušené" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Bolo odstránených %d súborov a %d fotiek" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Presúvanie súborov z %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopírovanie súborov z %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Štítky odstránené" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Štítok uložený" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Predmet uložený" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Predmet odstránený" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Osoba uložená" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Osoba odstránená" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Súbor odstránený" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d súborov nahraných za %d sekúnd" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Spracovanie nahrávania..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Nahrané súbory môžu byť urážlivé" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Označenie schválené" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Označenie archivované" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Označenie obnovené" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Označenie označené ako súkromné" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albumy odstránené" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Súbor ZIP vytvorený za %d sekúnd" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Trvalo odstránené" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s bolo obnovené" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Úspešne overené" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Úspešne aktivované" diff --git a/assets/locales/sl/default.po b/assets/locales/sl/default.po index 77a364e0e..f333eec41 100644 --- a/assets/locales/sl/default.po +++ b/assets/locales/sl/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: sl\n" "MIME-Version: 1.0\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " "n%100==4 ? 2 : 3;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Nekaj je šlo narobe, poskusite znova" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Tega ni mogoče storiti" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Sprememb ni bilo mogoče shraniti" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Ni bilo mogoče izbrisati" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s že obstaja" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Ga ni mogoče najti" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Datoteka ni najdena" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Prevelika datoteka" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Nepodprto" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Nepodprta vrsta" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Nepodprt format" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Mapa Originali je prazna" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Izbor ni najden" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entiteta ni bila najdena" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Račun ni najden" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Uporabnik ne obstaja" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Oznaka ni bila najdena" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera ni bila najdena" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Objektiv ni bil najden" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Album ni najden" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Zadeva ni bila najdena" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Oseba ni bila najdena" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Obraza ni mogoče najti" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Ni na voljo v javnem načinu" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Ni na voljo v načinu samo za branje" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Prijavite se v svoj račun" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Dovoljenje Zavrnjeno" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Zahtevano plačilo" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Nalaganje je lahko žaljivo" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Nalaganje neuspešno" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Ni izbranih elementov" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Neuspešno ustvarjanje datoteke, preverite dovoljenja" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Neuspešno ustvarjanje mape, preverite dovoljenja" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Ne morem vzpostaviti povezave, poskusite znova" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "vnesi potrditveno kodo" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Neveljavna koda za preverjanje, poskusite znova" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Nepravilno geslo, poskusite znova" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funkcija je onemogočena" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Ni izbranih nalepk" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Ni izbranih albumov" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Za prenos ni na voljo nobenih datotek" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Ni uspelo ustvariti datoteke zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Neveljavne poverilnice" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Neveljavna povezava" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Neveljavno ime" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Zaseden, poskusite znova pozneje" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Interval prebujanja je %s, vendar mora biti 1h ali manj" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Vašega računa ni bilo mogoče povezati" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Preveč zahtev" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Nezadostno skladiščenje" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kvota je presežena" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registracija onemogočena" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Zahtevan je potrjen e-poštni naslov" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Spremembe so bile uspešno shranjene" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Ustvarjen album" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Shranjen album" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s izbrisano" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Vsebina albuma klonirana" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Datoteka odstranjena iz sklada" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Izbrisana datoteka" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Izbor dodan v %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "En vnos dodan v %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d vnosi dodani v %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "En vnos odstranjen iz %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d vnosi odstranjeni iz %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Ustvarjen račun" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Shranjen račun" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Račun je izbrisan" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Nastavitve shranjene" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Geslo spremenjeno" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Uvoz se zaključi v %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Uvoz preklican" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indeksiranje je končano v %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indeksiranje izvirnikov..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indeksiranje datotek v %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indeksiranje preklicano" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Odstranjene %d datoteke in %d fotografije" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Premikanje datotek iz %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopiranje datotek iz %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etikete izbrisane" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Shranjena nalepka" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Zadeva je shranjena" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Predmet izbrisanih" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Rešena oseba" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Izbrisana oseba" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Prenesena datoteka" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d datoteke, naložene v %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Obdelava nalaganja..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Prenos je bil obdelan" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Odobren izbor" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Arhiviran izbor" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Obnovljen izbor" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Izbor označen kot zasebni" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Izbrisani albumi" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip, ustvarjen v %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Trajno izbrisano" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s je bil obnovljen" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Uspešno preverjeno" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Uspešno aktiviran" diff --git a/assets/locales/sv/default.po b/assets/locales/sv/default.po index 597497e1c..4073cf2d9 100644 --- a/assets/locales/sv/default.po +++ b/assets/locales/sv/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Något gick fel, försök igen" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Det går inte att göra" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Ändringarna kunde inte sparas" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Kunde inte raderas" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s finns redan" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Hittades inte" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Filen kunde inte hittas" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Filen är för stor" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Stöds ej" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Denna typ stöds ej" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Format som inte stöds" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Mappen med originalen är tom" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Urvalet kunde inte hittas" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Entitet kunde inte hittas" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Kontot kunde inte hittas" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Användaren kunde inte hittas" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etikett saknas" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kameran hittades inte" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Linsen hittades inte" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Albumet finns inte" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Ämnet finns inte" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Personen kunde inte hittas" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Ansiktet kunde inte hittas" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Inte tillgängligt i offentligt läge" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Inte tillgänglig i skrivskyddsläge" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Logga in på ditt konto" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Åtkomst nekades" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Betalning krävs" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Uppladdning kan vara stötande" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Uppladdning misslyckades" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Inga objekt har valts" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Det gick inte att skapa en fil, kontrollera behörigheter" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Det gick inte att skapa en mapp, kontrollera behörigheter" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Kunde inte ansluta, försök igen" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Ange verifieringskod" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Ogiltig verifieringskod, försök igen" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Felaktigt lösenord, försök igen" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Funktionen är inaktiverad" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Inga etiketter har valts" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Inga album har valts" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Inga filer finns tillgängliga för nedladdning" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Misslyckades med att skapa en zip-fil" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Ogiltiga autentiseringsuppgifter" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Ogiltig länk" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Felaktigt namn" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Upptagen, försök igen senare" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Uppvakningsintervallet är %s, men måste vara 1 timme eller mindre" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Ditt konto kunde inte anslutas" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "För många förfrågningar" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Otillräcklig lagring" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kvoten överskriden" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Registrering inaktiverad" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Verifierad e-postadress krävs" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Ändringarna har sparats" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Album skapat" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Album sparat" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s raderat" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Innehållet i albumet kopieras" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Filen tas bort från stapeln" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Fil raderad" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Urval tillagt i %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "En post tillagd i %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d poster tillagda till %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "En post borttagen från %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d poster raderade från %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Kontot har skapats" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Kontot sparat" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Kontot raderat" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Inställningarna har sparats" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Lösenordet har ändrats" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Importen slutfördes på %d s" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Importen avbruten" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Indexering slutförd på %d s" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Indexering av original..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Indexering av filer i %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Indexering avbruten" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Tog bort %d filer och %d bilder" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Flyttar filer från %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Kopierar filer från %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etiketter raderade" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etikett sparad" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Ämne sparat" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Ämne raderat" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Person sparad" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Person raderad" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Uppladdad fil" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d filer uppladdade på %d s" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Behandling av uppladdning..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Uppladdningen har behandlats" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Urvalet är godkänt" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Urval arkiverat" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Urvalet har återställts" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Urval markerat som privat" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Album raderade" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip skapad på %d s" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Permanent borttagen" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s har återställts" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Verifierad" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Lyckades aktiverad" diff --git a/assets/locales/th/default.po b/assets/locales/th/default.po index 500761ebe..93d744fbe 100644 --- a/assets/locales/th/default.po +++ b/assets/locales/th/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "เกิดข้อผิดพลาด โปรดลองอีกครั้ง" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "ไม่สามารถทำเช่นนั้นได้" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "ไม่สามารถบันทึกการเปลี่ยนแปลง" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "ไม่สามารถลบได้" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s มีอยู่แล้ว" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "ไม่พบ" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "ไม่พบไฟล์" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "ไฟล์ใหญ่เกินไป" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "ไม่รองรับ" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "ประเภทที่ไม่รองรับ" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "รูปแบบที่ไม่สนับสนุน" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "โฟลเดอร์ต้นฉบับว่างเปล่า" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "ไม่พบสิ่งที่เลือก" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "ไม่พบเอนทิตี" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "ไม่พบบัญชี" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "ไม่พบผู้ใช้" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "ไม่พบป้ายกำกับ" -#: messages.go:129 -msgid "Camera not found" -msgstr "ไม่พบกล้อง" - -#: messages.go:130 -msgid "Lens not found" -msgstr "ไม่พบเลนส์" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "ไม่พบอัลบั้ม" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "ไม่พบหัวเรื่อง" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "ไม่พบบุคคล" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "ไม่พบใบหน้า" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "ไม่พร้อมใช้งานในโหมดสาธารณะ" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "ไม่พร้อมใช้งานในโหมดอ่านอย่างเดียว" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "กรุณาเข้าสู่ระบบบัญชีของคุณ" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "ปฏิเสธการอนุญาต" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "ต้องชำระเงิน" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "การอัปโหลดอาจไม่เหมาะสม" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "การอัพโหลดล้มเหลว" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "ไม่มีรายการที่เลือก" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "สร้างไฟล์ไม่สำเร็จ โปรดตรวจสอบสิทธิ์" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "สร้างโฟลเดอร์ไม่สำเร็จ โปรดตรวจสอบสิทธิ์" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "ไม่สามารถเชื่อมต่อได้ โปรดลองอีกครั้ง" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "ระบุรหัสยืนยืน" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "รหัสยืนยันไม่ถูกต้อง โปรดลองอีกครั้ง" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "รหัสผ่านไม่ถูกต้อง โปรดลองอีกครั้ง" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "คุณลักษณะถูกปิดใช้งาน" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "ไม่ได้เลือกป้ายกำกับ" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "ไม่ได้เลือกอัลบั้ม" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "ไม่มีไฟล์สำหรับดาวน์โหลด" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "สร้างไฟล์ zip ไม่สำเร็จ" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "ข้อมูลประจำตัวที่ไม่ถูกต้อง" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "ลิงก์ไม่ถูกต้อง" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "ชื่อไม่ถูกต้อง" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "ไม่ว่าง โปรดลองอีกครั้งในภายหลัง" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "ช่วงเวลาปลุกคือ %s แต่ต้องเป็น 1 ชั่วโมงหรือน้อยกว่า" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "ไม่สามารถเชื่อมต่อบัญชีของคุณได้" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "คำขอมากเกินไป" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "พื้นที่เก็บข้อมูลไม่เพียงพอ" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "เกินโควตา" -#: messages.go:163 -msgid "Registration disabled" -msgstr "การลงทะเบียนถูกปิดใช้งาน" - -#: messages.go:164 -msgid "Verified email required" -msgstr "ต้องยืนยันอีเมล" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "บันทึกการเปลี่ยนแปลงเรียบร้อยแล้ว" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "สร้างอัลบั้มแล้ว" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "บันทึกอัลบั้มแล้ว" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "ลบอัลบั้ม %s แล้ว" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "โคลนเนื้อหาในอัลบั้ม" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "ไฟล์ถูกลบออกจากสแต็ค" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "ลบไฟล์แล้ว" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "เพิ่มการเลือกใน %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "เพิ่มหนึ่งรายการใน %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d รายการที่เพิ่มใน %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "ลบหนึ่งรายการจาก %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "รายการ %d ถูกลบออกจาก %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "สร้างบัญชีแล้ว" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "บันทึกบัญชีแล้ว" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "ลบบัญชีแล้ว" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "การตั้งค่าที่บันทึกไว้" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "เปลี่ยนรหัสผ่านแล้ว" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "การนำเข้าเสร็จสมบูรณ์ใน %d วินาที" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "ยกเลิกการนำเข้าแล้ว" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "การสร้างดัชนีเสร็จสิ้นใน %d วินาที" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "กำลังจัดทำดัชนีต้นฉบับ..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "การทำดัชนีไฟล์ใน %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "ยกเลิกการทำดัชนีแล้ว" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "ลบไฟล์ %d และภาพถ่าย %d" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "การย้ายไฟล์จาก %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "การคัดลอกไฟล์จาก %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "ลบป้ายกำกับแล้ว" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "บันทึกป้ายกำกับแล้ว" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "บันทึกหัวเรื่องแล้ว" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "ลบหัวเรื่องแล้ว" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "บุคคลที่บันทึกไว้" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "ลบบุคคลแล้ว" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "อัปโหลดไฟล์แล้ว" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "ไฟล์ %d ที่อัปโหลดใน %d วินาที" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "กำลังประมวลผลการอัปโหลด..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "อัปโหลดได้รับการดำเนินการ" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "การเลือกได้รับการอนุมัติ" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "เก็บถาวรการเลือกแล้ว" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "คืนค่าการเลือกแล้ว" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "การเลือกถูกทำเครื่องหมายเป็นส่วนตัว" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "ลบอัลบั้มแล้ว" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip สร้างใน %d วินาที" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "ลบอย่างถาวร" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s ได้รับการกู้คืนแล้ว" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "ตรวจสอบเรียบร้อยแล้ว" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "เปิดใช้งานสำเร็จแล้ว" diff --git a/assets/locales/tr/default.po b/assets/locales/tr/default.po index 4c7e03dc7..47f4aa57e 100644 --- a/assets/locales/tr/default.po +++ b/assets/locales/tr/default.po @@ -2,428 +2,411 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Bir şeyler ters gitti, tekrar deneyin" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Bunu yapmak mümkün değil" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Değişiklikler kaydedilemedi" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Silinemedi" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s zaten var" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Bulunamadı" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Dosya bulunamadı" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Dosya çok büyük" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Desteklenmiyor" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Desteklenmeyen tür" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Desteklenmeyen format" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Orijinaller klasörü boş" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Seçim bulunamadı" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Varlık bulunamadı" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Hesap bulunamadı" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Kullanıcı bulunamadı" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Etiket bulunamadı" -#: messages.go:129 -msgid "Camera not found" -msgstr "Kamera bulunamadı." - -#: messages.go:130 -msgid "Lens not found" -msgstr "Lens bulunamadı." - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Albüm bulunamadı" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Özne bulunamadı" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Kişi bulunamadı" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Yüz bulunamadı" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Genel modda mevcut değil" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Salt okunur modda kullanılamaz" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Lütfen hesabınıza giriş yapın" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "İzin reddedildi" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Ödeme gerekli" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Yükleme rahatsız edici olabilir" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Yükleme başarısız" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Seçili öğe yok" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Dosya oluşturulamadı, lütfen izinleri kontrol edin" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Klasör oluşturulamadı, lütfen izinleri kontrol edin" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Bağlanılamadı, lütfen tekrar deneyin" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Doğrulama kodunu giriniz" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Geçersiz doğrulama kodu, lütfen tekrar deneyin" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Geçersiz şifre, lütfen tekrar deneyin" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Özellik devre dışı" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Seçili etiket yok" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Seçili albüm yok" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "İndirilebilecek dosya yok" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Zip dosyası oluşturulamadı" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Geçersiz kimlik bilgileri" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Geçersiz link" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Geçersiz isim" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Meşgul, lütfen daha sonra tekrar deneyin" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Uyandırma aralığı %s'dır, ancak 1 saat veya daha az olmalıdır" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Hesabınız bağlanamadı" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Çok fazla talep var" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Yetersiz depolama" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Kota aşıldı" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Kayıt devre dışı bırakıldı" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Doğrulanmış e-posta adresi gereklidir." - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Değişiklikler başarıyla kaydedildi" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Albüm oluşturuldu" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Albüm kaydedildi" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Albüm %s silindi" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Albüm içeriği klonlandı" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Dosya yığından kaldırıldı" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Silinmiş dosya" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Seçim %s'a eklendi" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Bir giriş %s'a eklendi" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d girişleri %s'e eklendi" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Bir giriş %s'dan kaldırıldı" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d girişleri %s'den kaldırıldı" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Hesap eklendi" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Hesap kaydedildi" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Hesap silindi" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Ayarlar kaydedildi" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Şifre Değiştirildi" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "İçe aktarma %d s içinde tamamlandı" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "İçe aktarma iptal edildi" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "İndeksleme %d s içinde tamamlandı" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Orijinalleri dizinliyor..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "%s dosya yüklendi" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "İndeksleme iptal edildi" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "%d dosya ve %d fotoğraf kaldırıldı" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Dosyaları %s'dan taşıma" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Dosyaları %s'dan kopyalama" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Etiketler silindi" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Etiket kaydedildi" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Konu kaydedildi" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Konu silindi" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Kurtarılan kişi" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Kişi silindi" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Dosya yüklendi" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d dosyalar %d s içinde yüklendi" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Yükleme işlemi..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Yükleme işlemi tamamlandı" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Seçim onaylandı" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Seçim arşivlendi" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Seçim geri yüklendi" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Özel olarak işaretlenmiş seçim" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Albümler silindi" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip %d s içinde oluşturuldu" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Kalıcı olarak silindi" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s geri yüklendi" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Başarıyla doğrulandı" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Başarıyla etkinleştirildi" diff --git a/assets/locales/uk/default.po b/assets/locales/uk/default.po index f7f221440..71a75c2bf 100644 --- a/assets/locales/uk/default.po +++ b/assets/locales/uk/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: none\n" "Language: uk\n" "MIME-Version: 1.0\n" @@ -13,419 +12,403 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Щось пішло не так, спробуйте ще раз" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Неможливо це зробити" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Зміни не можливо зберегти" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Не можливо видалити" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s вже існує" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Не знайдено" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Файл не знайдено" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Файл занадто великий" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Не підтримується" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Непідтримуваний тип" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Непідтримуваний формат" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Папка з оригіналами порожня" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Вибір не знайдено" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Об'єкт не знайдено" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Обліковий запис не знайдено" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Користувача не знайдено" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Мітку не знайдено" -#: messages.go:129 -msgid "Camera not found" -msgstr "Камеру не знайдено" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Об'єктив не знайдено" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Альбом не знайдено" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Тема не знайдена" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Особистість не знайдена" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Обличчя не знайдено" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Недоступно в публічному режимі" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "не доступно в режимі \"тільки читання\"" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Будь ласка, увійдіть до свого облікового запису" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "В доступі відмовлено" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Потрібна оплата" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Завантаження може бути образливим" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Помилка вивантаження" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Нічого не вибрано" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Помилка створення файла, перевірте дозволи" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Не вдалося створити папку, перевірте права доступу" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Не можливо підключитися, спробуйте знову" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Введіть код верифікації" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Невірний код верифікації, спробуйте знову" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "Невірний пароль, спробуйте знову" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Функцію вимкнено" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Мітки не вибрано" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Альбоми не вибрано" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Немає доступних файлів для завантаження" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Не вдалося створити zip-файл" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Недійсні облікові дані" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Невірне посилання" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Невірне ім'я" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Зайнято, спробуйте пізніше" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" "Інтервал пробудження становить %s, але має становити 1 годину або менше" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Ваш обліковий запис не вдалося підключити" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "Занадто багато запитів" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Недостатнє зберігання" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Перевищено квоту" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Реєстрацію вимкнено" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Потрібна підтверджена електронна адреса" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Зміни успішно збережено" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Альбом створено" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Альбом збережено" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Альбом %s видалено" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Вміст альбому клоновано" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Файл видалено з стеку" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Файл видалено" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Вибір додано до %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Один запис додано до %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d записів додано до %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Один запис видалено з %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d записів видалено з %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Обліковий запис створено" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Обліковий запис збережено" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Обліковий запис видалено" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Налаштування збережено" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "Пароль змінено" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Імпортування тривало %d с" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Імпортування скасовано" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Індексування тривало %d с" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Індексуємо оригінали..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Індексуємо файли в %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Індексування скасовано" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Видалено %d файлів та %d фотографій" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Переносимо файли з %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Копіюємо файли з %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Мітки видалено" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Мітку збережено" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Тема збережена" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Тема видалена" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Людина збережена" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Людина видалена" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "Файл завантажено" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "%d файлів вивантажено за %d с" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Обробка завантаження..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Завантаження оброблено" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Вибір затверджено" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Вибране заархівовано" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Вибране відновлено" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Вибіране позначено як приватне" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Альбом видалено" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip створено за %d с" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Остаточно видалено" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s було відновлено" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Верифікація успішна" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Активація успішна" diff --git a/assets/locales/vi/default.po b/assets/locales/vi/default.po index 57c96b623..fed039aa6 100644 --- a/assets/locales/vi/default.po +++ b/assets/locales/vi/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: none\n" @@ -12,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "Đã xảy ra lỗi, hãy thử lại" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "Không thể làm điều đó" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "Không thể lưu các thay đổi" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "Không thể xóa được" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s đã tồn tại" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "Không tìm thấy" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "Không tìm thấy tập tin" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "Tệp quá lớn" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "Không được hỗ trợ" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "Loại không được hỗ trợ" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "Định dạng không được hỗ trợ" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "Thư mục gốc trống" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "Không tìm thấy lựa chọn" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "Không tìm thấy thực thể" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "Tài khoản không được tìm thấy" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "Không tìm thấy người dùng" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "Không tìm thấy nhãn" -#: messages.go:129 -msgid "Camera not found" -msgstr "Không tìm thấy máy ảnh" - -#: messages.go:130 -msgid "Lens not found" -msgstr "Không tìm thấy ống kính" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "Không tìm thấy album" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "Không tìm thấy chủ đề" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "Không tìm thấy người" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "Không tìm thấy khuôn mặt" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "Không khả dụng ở chế độ công khai" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "Không khả dụng ở chế độ chỉ đọc" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "Xin hãy đăng nhập vào tài khoản của bạn" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "Quyền bị từ chối" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "Yêu cầu thanh toán" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "Tải lên có thể gây khó chịu" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "Tải lên không thành công" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "Không có mục nào được chọn" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "Không tạo được tệp, vui lòng kiểm tra quyền" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "Không tạo được thư mục, vui lòng kiểm tra quyền" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "Không thể kết nối, vui lòng thử lại" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "Nhập mã xác nhận" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "Mã xác minh không hợp lệ, vui lòng thử lại" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "mật mã không hợp lệ, vui lòng thử lại" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "Tính năng bị tắt" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "Không có nhãn nào được chọn" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "Không có album nào được chọn" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "Không có tập tin nào để tải xuống" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "Không tạo được tệp zip" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "Thông tin không hợp lệ" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "Liên kết không hợp lệ" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "Tên không hợp lệ" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "Đang bận, vui lòng thử lại sau" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "Khoảng thời gian đánh thức là %s nhưng phải từ 1 giờ trở xuống" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "Tài khoản của bạn không thể kết nối được" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "quá nhiều yêu cầu" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "Không đủ dung lượng lưu trữ" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "Vượt quá hạn ngạch" -#: messages.go:163 -msgid "Registration disabled" -msgstr "Đăng ký bị vô hiệu hóa" - -#: messages.go:164 -msgid "Verified email required" -msgstr "Cần có email đã được xác minh." - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "Đã lưu thay đổi thành công" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "Đã tạo album" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "Đã lưu album" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "Album %s đã bị xóa" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "Nội dung album được sao chép" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "Đã xóa tệp khỏi ngăn xếp" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "Đã xóa tệp" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "Đã thêm lựa chọn vào %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "Đã thêm một mục vào %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "Các mục %d được thêm vào %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "Đã xóa một mục khỏi %s" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "Các mục %d đã bị xóa khỏi %s" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "Tài khoản đã được tạo" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "Đã lưu tài khoản" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "Tài khoản đã bị xóa" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "Đã lưu cài đặt" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "mật khẩu đã được thay đổi" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "Quá trình nhập hoàn tất sau %d giây" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "Đã hủy nhập" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "Việc lập chỉ mục hoàn tất sau %d giây" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "Lập chỉ mục bản gốc..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "Lập chỉ mục các tệp trong %s" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "Đã hủy lập chỉ mục" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "Đã xóa tệp %d và ảnh %d" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "Di chuyển tệp từ %s" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "Sao chép tập tin từ %s" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "Đã xóa nhãn" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "Đã lưu nhãn" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "Đã lưu chủ đề" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "Chủ đề đã bị xóa" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "Người đã được cứu" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "Người đã bị xóa" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "File đã được tải lên" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "Các tệp %d được tải lên trong %d giây" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "Đang xử lý tải lên..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "Tải lên đã được xử lý" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "Lựa chọn đã được phê duyệt" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "Đã lưu trữ lựa chọn" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "Đã khôi phục lựa chọn" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "Lựa chọn được đánh dấu là riêng tư" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "Album đã bị xóa" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip được tạo trong %d giây" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "Đã xóa vĩnh viễn" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s đã được khôi phục" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "Đã xác minh thành công" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "Đã kích hoạt thành công" diff --git a/assets/locales/zh/default.po b/assets/locales/zh/default.po index 36c0aa6d4..9a90cece8 100644 --- a/assets/locales/zh/default.po +++ b/assets/locales/zh/default.po @@ -2,10 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" -"Last-Translator: Google Cloud Translation Basic \n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" +"Last-Translator: DeepL \n" "Language-Team: Chinese (Simplified) \n" "Language: zh\n" @@ -13,418 +12,402 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2026.5\n" +"X-Generator: Weblate 5.13.3\n" -#: messages.go:112 +#: messages.go:104 msgid "Something went wrong, try again" msgstr "出错了,再试一次" -#: messages.go:113 +#: messages.go:105 msgid "Unable to do that" msgstr "无法做到这一点" -#: messages.go:114 +#: messages.go:106 msgid "Changes could not be saved" msgstr "无法保存变更" -#: messages.go:115 +#: messages.go:107 msgid "Could not be deleted" msgstr "无法删除" -#: messages.go:116 +#: messages.go:108 #, c-format msgid "%s already exists" msgstr "%s 已存在" -#: messages.go:117 +#: messages.go:109 msgid "Not found" msgstr "未找到" -#: messages.go:118 +#: messages.go:110 msgid "File not found" msgstr "未找到文件" -#: messages.go:119 +#: messages.go:111 msgid "File too large" msgstr "文件过大" -#: messages.go:120 +#: messages.go:112 msgid "Unsupported" msgstr "不支持" -#: messages.go:121 +#: messages.go:113 msgid "Unsupported type" msgstr "不支持的类型" -#: messages.go:122 +#: messages.go:114 msgid "Unsupported format" msgstr "不支持的格式" -#: messages.go:123 +#: messages.go:115 msgid "Originals folder is empty" msgstr "原件文件夹是空的" -#: messages.go:124 +#: messages.go:116 msgid "Selection not found" msgstr "未找到所选内容" -#: messages.go:125 +#: messages.go:117 msgid "Entity not found" msgstr "未找到实体" -#: messages.go:126 +#: messages.go:118 msgid "Account not found" msgstr "未找到账户" -#: messages.go:127 +#: messages.go:119 msgid "User not found" msgstr "未找到用户" -#: messages.go:128 +#: messages.go:120 msgid "Label not found" msgstr "未找到标签" -#: messages.go:129 -msgid "Camera not found" -msgstr "未找到摄像头" - -#: messages.go:130 -msgid "Lens not found" -msgstr "未找到镜头" - -#: messages.go:131 +#: messages.go:121 msgid "Album not found" msgstr "未找到相册" -#: messages.go:132 +#: messages.go:122 msgid "Subject not found" msgstr "未找到主题" -#: messages.go:133 +#: messages.go:123 msgid "Person not found" msgstr "未找到人物" -#: messages.go:134 +#: messages.go:124 msgid "Face not found" msgstr "未找到面孔" -#: messages.go:135 +#: messages.go:125 msgid "Not available in public mode" msgstr "在公开模式下不可用" -#: messages.go:136 +#: messages.go:126 msgid "Not available in read-only mode" msgstr "在只读模式下不可用" -#: messages.go:137 +#: messages.go:127 msgid "Please log in to your account" msgstr "请登录你的账户" -#: messages.go:138 +#: messages.go:128 msgid "Permission denied" msgstr "没有权限" -#: messages.go:139 +#: messages.go:129 msgid "Payment required" msgstr "需要付款" -#: messages.go:140 +#: messages.go:130 msgid "Upload might be offensive" msgstr "上传内容可能具有冒犯性" -#: messages.go:141 +#: messages.go:131 msgid "Upload failed" msgstr "上传失败" -#: messages.go:142 +#: messages.go:132 msgid "No items selected" msgstr "未选择任何项目" -#: messages.go:143 +#: messages.go:133 msgid "Failed creating file, please check permissions" msgstr "创建文件失败,请检查权限" -#: messages.go:144 +#: messages.go:134 msgid "Failed creating folder, please check permissions" msgstr "创建目录失败,请检查权限" -#: messages.go:145 +#: messages.go:135 msgid "Could not connect, please try again" msgstr "无法连接,请重试" -#: messages.go:146 +#: messages.go:136 msgid "Enter verification code" msgstr "输入验证码" -#: messages.go:147 +#: messages.go:137 msgid "Invalid verification code, please try again" msgstr "验证码无效,请重试" -#: messages.go:148 +#: messages.go:138 msgid "Invalid password, please try again" msgstr "无效密码,请重试" -#: messages.go:149 +#: messages.go:139 msgid "Feature disabled" msgstr "功能已禁用" -#: messages.go:150 +#: messages.go:140 msgid "No labels selected" msgstr "未选择标签" -#: messages.go:151 +#: messages.go:141 msgid "No albums selected" msgstr "未选择相册" -#: messages.go:152 +#: messages.go:142 msgid "No files available for download" msgstr "没有可供下载的文件" -#: messages.go:153 +#: messages.go:143 msgid "Failed to create zip file" msgstr "创建压缩文件失败" -#: messages.go:154 +#: messages.go:144 msgid "Invalid credentials" msgstr "无效凭证" -#: messages.go:155 +#: messages.go:145 msgid "Invalid link" msgstr "无效链接" -#: messages.go:156 +#: messages.go:146 msgid "Invalid name" msgstr "无效名称" -#: messages.go:157 +#: messages.go:147 msgid "Busy, please try again later" msgstr "忙碌中,请稍后重试" -#: messages.go:158 +#: messages.go:148 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "唤醒间隔为 %s,但必须小于等于 1 小时" -#: messages.go:159 +#: messages.go:149 msgid "Your account could not be connected" msgstr "你的账户无法连接" -#: messages.go:160 +#: messages.go:150 msgid "Too many requests" msgstr "请求太多" -#: messages.go:161 +#: messages.go:151 msgid "Insufficient storage" msgstr "存储不足" -#: messages.go:162 +#: messages.go:152 msgid "Quota exceeded" msgstr "超出配额" -#: messages.go:163 -msgid "Registration disabled" -msgstr "注册已禁用" - -#: messages.go:164 -msgid "Verified email required" -msgstr "需要已验证的电子邮件地址" - -#: messages.go:167 +#: messages.go:155 msgid "Changes successfully saved" msgstr "更改成功保存" -#: messages.go:168 +#: messages.go:156 msgid "Album created" msgstr "相册已创建" -#: messages.go:169 +#: messages.go:157 msgid "Album saved" msgstr "相册已保存" -#: messages.go:170 +#: messages.go:158 #, c-format msgid "Album %s deleted" msgstr "相册 %s 已删除" -#: messages.go:171 +#: messages.go:159 msgid "Album contents cloned" msgstr "相册内容已复制" -#: messages.go:172 +#: messages.go:160 msgid "File removed from stack" msgstr "文件已从堆中移除" -#: messages.go:173 +#: messages.go:161 msgid "File deleted" msgstr "文件已删除" -#: messages.go:174 +#: messages.go:162 #, c-format msgid "Selection added to %s" msgstr "所选项目已加入 %s" -#: messages.go:175 +#: messages.go:163 #, c-format msgid "One entry added to %s" msgstr "条目已添加到 %s" -#: messages.go:176 +#: messages.go:164 #, c-format msgid "%d entries added to %s" msgstr "%d 个条目已添加到 %s" -#: messages.go:177 +#: messages.go:165 #, c-format msgid "One entry removed from %s" msgstr "条目已从 %s 移除" -#: messages.go:178 +#: messages.go:166 #, c-format msgid "%d entries removed from %s" msgstr "%d 个条目已从 %s 移除" -#: messages.go:179 +#: messages.go:167 msgid "Account created" msgstr "账户已创建" -#: messages.go:180 +#: messages.go:168 msgid "Account saved" msgstr "账户已保存" -#: messages.go:181 +#: messages.go:169 msgid "Account deleted" msgstr "账户已删除" -#: messages.go:182 +#: messages.go:170 msgid "Settings saved" msgstr "设置已保存" -#: messages.go:183 +#: messages.go:171 msgid "Password changed" msgstr "密码已更改" -#: messages.go:184 +#: messages.go:172 #, c-format msgid "Import completed in %d s" msgstr "导入成功,耗时 %d 秒" -#: messages.go:185 +#: messages.go:173 msgid "Import canceled" msgstr "导入已取消" -#: messages.go:186 +#: messages.go:174 #, c-format msgid "Indexing completed in %d s" msgstr "索引成功,耗时 %d 秒" -#: messages.go:187 +#: messages.go:175 msgid "Indexing originals..." msgstr "索引源文件..." -#: messages.go:188 +#: messages.go:176 #, c-format msgid "Indexing files in %s" msgstr "索引 %s 中的文件" -#: messages.go:189 +#: messages.go:177 msgid "Indexing canceled" msgstr "索引已取消" -#: messages.go:190 +#: messages.go:178 #, c-format msgid "Removed %d files and %d photos" msgstr "移除了 %d 个文件和 %d 张照片" -#: messages.go:191 +#: messages.go:179 #, c-format msgid "Moving files from %s" msgstr "正在从 %s 中移动文件" -#: messages.go:192 +#: messages.go:180 #, c-format msgid "Copying files from %s" msgstr "正在从 %s 中复制文件" -#: messages.go:193 +#: messages.go:181 msgid "Labels deleted" msgstr "标签已移除" -#: messages.go:194 +#: messages.go:182 msgid "Label saved" msgstr "标签已保存" -#: messages.go:195 +#: messages.go:183 msgid "Subject saved" msgstr "主题已保存" -#: messages.go:196 +#: messages.go:184 msgid "Subject deleted" msgstr "主题已删除" -#: messages.go:197 +#: messages.go:185 msgid "Person saved" msgstr "人物已保存" -#: messages.go:198 +#: messages.go:186 msgid "Person deleted" msgstr "人物已删除" -#: messages.go:199 +#: messages.go:187 msgid "File uploaded" msgstr "已上传文件" -#: messages.go:200 +#: messages.go:188 #, c-format msgid "%d files uploaded in %d s" msgstr "已上传 %d 个文件,耗时 %d 秒" -#: messages.go:201 +#: messages.go:189 msgid "Processing upload..." msgstr "处理上传..." -#: messages.go:202 +#: messages.go:190 msgid "Upload has been processed" msgstr "上传已被处理" -#: messages.go:203 +#: messages.go:191 msgid "Selection approved" msgstr "所选项已批准" -#: messages.go:204 +#: messages.go:192 msgid "Selection archived" msgstr "所选项已归档" -#: messages.go:205 +#: messages.go:193 msgid "Selection restored" msgstr "所选项已恢复" -#: messages.go:206 +#: messages.go:194 msgid "Selection marked as private" msgstr "所选项已设为私有" -#: messages.go:207 +#: messages.go:195 msgid "Albums deleted" msgstr "相册已删除" -#: messages.go:208 +#: messages.go:196 #, c-format msgid "Zip created in %d s" msgstr "Zip 文件创建成功,耗时 %d 秒" -#: messages.go:209 +#: messages.go:197 msgid "Permanently deleted" msgstr "已永久删除" -#: messages.go:210 +#: messages.go:198 #, c-format msgid "%s has been restored" msgstr "%s 已恢复" -#: messages.go:211 +#: messages.go:199 msgid "Successfully verified" msgstr "验证成功" -#: messages.go:212 +#: messages.go:200 msgid "Successfully activated" msgstr "已成功激活" diff --git a/assets/locales/zh_TW/default.po b/assets/locales/zh_TW/default.po index 407b28f6c..41c199f89 100644 --- a/assets/locales/zh_TW/default.po +++ b/assets/locales/zh_TW/default.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-27 09:13+0000\n" -"PO-Revision-Date: 2026-06-27 10:28+0000\n" +"POT-Creation-Date: 2025-10-17 17:32+0000\n" +"PO-Revision-Date: 2025-10-22 08:25+0000\n" "Last-Translator: Google Cloud Translation Basic \n" "Language-Team: Chinese (Traditional) \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/app/maskable/192.png b/assets/static/icons/app/maskable/192.png deleted file mode 100644 index 1281bb4c8..000000000 Binary files a/assets/static/icons/app/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/app/maskable/512.png b/assets/static/icons/app/maskable/512.png deleted file mode 100644 index 7b0736060..000000000 Binary files a/assets/static/icons/app/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/bloom.svg b/assets/static/icons/bloom.svg deleted file mode 100644 index aad1ded16..000000000 --- a/assets/static/icons/bloom.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/static/icons/bloom/100.png b/assets/static/icons/bloom/100.png deleted file mode 100644 index af72bebf3..000000000 Binary files a/assets/static/icons/bloom/100.png and /dev/null differ diff --git a/assets/static/icons/bloom/1024.png b/assets/static/icons/bloom/1024.png deleted file mode 100644 index 272d536d7..000000000 Binary files a/assets/static/icons/bloom/1024.png and /dev/null differ diff --git a/assets/static/icons/bloom/114.png b/assets/static/icons/bloom/114.png deleted file mode 100644 index cb723ecec..000000000 Binary files a/assets/static/icons/bloom/114.png and /dev/null differ diff --git a/assets/static/icons/bloom/120.png b/assets/static/icons/bloom/120.png deleted file mode 100644 index aa88c900d..000000000 Binary files a/assets/static/icons/bloom/120.png and /dev/null differ diff --git a/assets/static/icons/bloom/128.png b/assets/static/icons/bloom/128.png deleted file mode 100644 index f1111e059..000000000 Binary files a/assets/static/icons/bloom/128.png and /dev/null differ diff --git a/assets/static/icons/bloom/144.png b/assets/static/icons/bloom/144.png deleted file mode 100644 index 0705fccdc..000000000 Binary files a/assets/static/icons/bloom/144.png and /dev/null differ diff --git a/assets/static/icons/bloom/152.png b/assets/static/icons/bloom/152.png deleted file mode 100644 index 258a09ce5..000000000 Binary files a/assets/static/icons/bloom/152.png and /dev/null differ diff --git a/assets/static/icons/bloom/16.png b/assets/static/icons/bloom/16.png deleted file mode 100644 index 4e219a818..000000000 Binary files a/assets/static/icons/bloom/16.png and /dev/null differ diff --git a/assets/static/icons/bloom/160.png b/assets/static/icons/bloom/160.png deleted file mode 100644 index 8215c8aab..000000000 Binary files a/assets/static/icons/bloom/160.png and /dev/null differ diff --git a/assets/static/icons/bloom/167.png b/assets/static/icons/bloom/167.png deleted file mode 100644 index 2a3177487..000000000 Binary files a/assets/static/icons/bloom/167.png and /dev/null differ diff --git a/assets/static/icons/bloom/172.png b/assets/static/icons/bloom/172.png deleted file mode 100644 index b7a0c2708..000000000 Binary files a/assets/static/icons/bloom/172.png and /dev/null differ diff --git a/assets/static/icons/bloom/175.png b/assets/static/icons/bloom/175.png deleted file mode 100644 index 26a67ed44..000000000 Binary files a/assets/static/icons/bloom/175.png and /dev/null differ diff --git a/assets/static/icons/bloom/180.png b/assets/static/icons/bloom/180.png deleted file mode 100644 index d4b4dc5fe..000000000 Binary files a/assets/static/icons/bloom/180.png and /dev/null differ diff --git a/assets/static/icons/bloom/192.png b/assets/static/icons/bloom/192.png deleted file mode 100644 index a4bc107d2..000000000 Binary files a/assets/static/icons/bloom/192.png and /dev/null differ diff --git a/assets/static/icons/bloom/196.png b/assets/static/icons/bloom/196.png deleted file mode 100644 index 8b7e58e2f..000000000 Binary files a/assets/static/icons/bloom/196.png and /dev/null differ diff --git a/assets/static/icons/bloom/20.png b/assets/static/icons/bloom/20.png deleted file mode 100644 index ff33168b2..000000000 Binary files a/assets/static/icons/bloom/20.png and /dev/null differ diff --git a/assets/static/icons/bloom/200.png b/assets/static/icons/bloom/200.png deleted file mode 100644 index cd8ae1cc6..000000000 Binary files a/assets/static/icons/bloom/200.png and /dev/null differ diff --git a/assets/static/icons/bloom/216.png b/assets/static/icons/bloom/216.png deleted file mode 100644 index 2be67e9bb..000000000 Binary files a/assets/static/icons/bloom/216.png and /dev/null differ diff --git a/assets/static/icons/bloom/256.png b/assets/static/icons/bloom/256.png deleted file mode 100644 index 227045b03..000000000 Binary files a/assets/static/icons/bloom/256.png and /dev/null differ diff --git a/assets/static/icons/bloom/267.png b/assets/static/icons/bloom/267.png deleted file mode 100644 index 14e9cb5bb..000000000 Binary files a/assets/static/icons/bloom/267.png and /dev/null differ diff --git a/assets/static/icons/bloom/29.png b/assets/static/icons/bloom/29.png deleted file mode 100644 index 27fb80774..000000000 Binary files a/assets/static/icons/bloom/29.png and /dev/null differ diff --git a/assets/static/icons/bloom/32.png b/assets/static/icons/bloom/32.png deleted file mode 100644 index f5d139074..000000000 Binary files a/assets/static/icons/bloom/32.png and /dev/null differ diff --git a/assets/static/icons/bloom/40.png b/assets/static/icons/bloom/40.png deleted file mode 100644 index 6f184869c..000000000 Binary files a/assets/static/icons/bloom/40.png and /dev/null differ diff --git a/assets/static/icons/bloom/400.png b/assets/static/icons/bloom/400.png deleted file mode 100644 index 8c2c9eb2e..000000000 Binary files a/assets/static/icons/bloom/400.png and /dev/null differ diff --git a/assets/static/icons/bloom/48.png b/assets/static/icons/bloom/48.png deleted file mode 100644 index f912b1bd5..000000000 Binary files a/assets/static/icons/bloom/48.png and /dev/null differ diff --git a/assets/static/icons/bloom/50.png b/assets/static/icons/bloom/50.png deleted file mode 100644 index fb7588e63..000000000 Binary files a/assets/static/icons/bloom/50.png and /dev/null differ diff --git a/assets/static/icons/bloom/512.png b/assets/static/icons/bloom/512.png deleted file mode 100644 index 34ed75302..000000000 Binary files a/assets/static/icons/bloom/512.png and /dev/null differ diff --git a/assets/static/icons/bloom/55.png b/assets/static/icons/bloom/55.png deleted file mode 100644 index e2f39e3c5..000000000 Binary files a/assets/static/icons/bloom/55.png and /dev/null differ diff --git a/assets/static/icons/bloom/56.png b/assets/static/icons/bloom/56.png deleted file mode 100644 index 2795dae4b..000000000 Binary files a/assets/static/icons/bloom/56.png and /dev/null differ diff --git a/assets/static/icons/bloom/60.png b/assets/static/icons/bloom/60.png deleted file mode 100644 index 0a5c97ee3..000000000 Binary files a/assets/static/icons/bloom/60.png and /dev/null differ diff --git a/assets/static/icons/bloom/64.png b/assets/static/icons/bloom/64.png deleted file mode 100644 index e5ac223f6..000000000 Binary files a/assets/static/icons/bloom/64.png and /dev/null differ diff --git a/assets/static/icons/bloom/72.png b/assets/static/icons/bloom/72.png deleted file mode 100644 index 55597e914..000000000 Binary files a/assets/static/icons/bloom/72.png and /dev/null differ diff --git a/assets/static/icons/bloom/76.png b/assets/static/icons/bloom/76.png deleted file mode 100644 index 40f5646b6..000000000 Binary files a/assets/static/icons/bloom/76.png and /dev/null differ diff --git a/assets/static/icons/bloom/80.png b/assets/static/icons/bloom/80.png deleted file mode 100644 index 8748add36..000000000 Binary files a/assets/static/icons/bloom/80.png and /dev/null differ diff --git a/assets/static/icons/bloom/maskable/192.png b/assets/static/icons/bloom/maskable/192.png deleted file mode 100644 index 8509e68b1..000000000 Binary files a/assets/static/icons/bloom/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/bloom/maskable/512.png b/assets/static/icons/bloom/maskable/512.png deleted file mode 100644 index 0fa8807ba..000000000 Binary files a/assets/static/icons/bloom/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/bold.svg b/assets/static/icons/bold.svg index f7ebb83d0..2c60c5021 100644 --- a/assets/static/icons/bold.svg +++ b/assets/static/icons/bold.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/bold/maskable/192.png b/assets/static/icons/bold/maskable/192.png deleted file mode 100644 index caccc9108..000000000 Binary files a/assets/static/icons/bold/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/bold/maskable/512.png b/assets/static/icons/bold/maskable/512.png deleted file mode 100644 index 1bc801990..000000000 Binary files a/assets/static/icons/bold/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/crisp.svg b/assets/static/icons/crisp.svg index 9d7133a1e..24d1adbe8 100644 --- a/assets/static/icons/crisp.svg +++ b/assets/static/icons/crisp.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/crisp/maskable/192.png b/assets/static/icons/crisp/maskable/192.png deleted file mode 100644 index 0760a5cdd..000000000 Binary files a/assets/static/icons/crisp/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/crisp/maskable/512.png b/assets/static/icons/crisp/maskable/512.png deleted file mode 100644 index 32c5e59a8..000000000 Binary files a/assets/static/icons/crisp/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/flower.svg b/assets/static/icons/flower.svg deleted file mode 100644 index e53141dec..000000000 --- a/assets/static/icons/flower.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/static/icons/flower/100.png b/assets/static/icons/flower/100.png deleted file mode 100644 index 334921d48..000000000 Binary files a/assets/static/icons/flower/100.png and /dev/null differ diff --git a/assets/static/icons/flower/1024.png b/assets/static/icons/flower/1024.png deleted file mode 100644 index 9858808e5..000000000 Binary files a/assets/static/icons/flower/1024.png and /dev/null differ diff --git a/assets/static/icons/flower/114.png b/assets/static/icons/flower/114.png deleted file mode 100644 index f17df1f7c..000000000 Binary files a/assets/static/icons/flower/114.png and /dev/null differ diff --git a/assets/static/icons/flower/120.png b/assets/static/icons/flower/120.png deleted file mode 100644 index 429ffd4c8..000000000 Binary files a/assets/static/icons/flower/120.png and /dev/null differ diff --git a/assets/static/icons/flower/128.png b/assets/static/icons/flower/128.png deleted file mode 100644 index 39538a066..000000000 Binary files a/assets/static/icons/flower/128.png and /dev/null differ diff --git a/assets/static/icons/flower/144.png b/assets/static/icons/flower/144.png deleted file mode 100644 index 774d41524..000000000 Binary files a/assets/static/icons/flower/144.png and /dev/null differ diff --git a/assets/static/icons/flower/152.png b/assets/static/icons/flower/152.png deleted file mode 100644 index bb87d5fbd..000000000 Binary files a/assets/static/icons/flower/152.png and /dev/null differ diff --git a/assets/static/icons/flower/16.png b/assets/static/icons/flower/16.png deleted file mode 100644 index 6a7f6fb3d..000000000 Binary files a/assets/static/icons/flower/16.png and /dev/null differ diff --git a/assets/static/icons/flower/160.png b/assets/static/icons/flower/160.png deleted file mode 100644 index aef462487..000000000 Binary files a/assets/static/icons/flower/160.png and /dev/null differ diff --git a/assets/static/icons/flower/167.png b/assets/static/icons/flower/167.png deleted file mode 100644 index f9fd23acb..000000000 Binary files a/assets/static/icons/flower/167.png and /dev/null differ diff --git a/assets/static/icons/flower/172.png b/assets/static/icons/flower/172.png deleted file mode 100644 index a59f3e98c..000000000 Binary files a/assets/static/icons/flower/172.png and /dev/null differ diff --git a/assets/static/icons/flower/175.png b/assets/static/icons/flower/175.png deleted file mode 100644 index 88128ebf8..000000000 Binary files a/assets/static/icons/flower/175.png and /dev/null differ diff --git a/assets/static/icons/flower/180.png b/assets/static/icons/flower/180.png deleted file mode 100644 index 133baa657..000000000 Binary files a/assets/static/icons/flower/180.png and /dev/null differ diff --git a/assets/static/icons/flower/192.png b/assets/static/icons/flower/192.png deleted file mode 100644 index 1b1a001bc..000000000 Binary files a/assets/static/icons/flower/192.png and /dev/null differ diff --git a/assets/static/icons/flower/196.png b/assets/static/icons/flower/196.png deleted file mode 100644 index c07d27f5c..000000000 Binary files a/assets/static/icons/flower/196.png and /dev/null differ diff --git a/assets/static/icons/flower/20.png b/assets/static/icons/flower/20.png deleted file mode 100644 index 9869b8623..000000000 Binary files a/assets/static/icons/flower/20.png and /dev/null differ diff --git a/assets/static/icons/flower/200.png b/assets/static/icons/flower/200.png deleted file mode 100644 index 393749059..000000000 Binary files a/assets/static/icons/flower/200.png and /dev/null differ diff --git a/assets/static/icons/flower/216.png b/assets/static/icons/flower/216.png deleted file mode 100644 index 795318931..000000000 Binary files a/assets/static/icons/flower/216.png and /dev/null differ diff --git a/assets/static/icons/flower/256.png b/assets/static/icons/flower/256.png deleted file mode 100644 index 7955f3eb0..000000000 Binary files a/assets/static/icons/flower/256.png and /dev/null differ diff --git a/assets/static/icons/flower/267.png b/assets/static/icons/flower/267.png deleted file mode 100644 index 4a52ef9ca..000000000 Binary files a/assets/static/icons/flower/267.png and /dev/null differ diff --git a/assets/static/icons/flower/29.png b/assets/static/icons/flower/29.png deleted file mode 100644 index 6cea5049f..000000000 Binary files a/assets/static/icons/flower/29.png and /dev/null differ diff --git a/assets/static/icons/flower/32.png b/assets/static/icons/flower/32.png deleted file mode 100644 index 4890afe5a..000000000 Binary files a/assets/static/icons/flower/32.png and /dev/null differ diff --git a/assets/static/icons/flower/40.png b/assets/static/icons/flower/40.png deleted file mode 100644 index 04a1c9d3f..000000000 Binary files a/assets/static/icons/flower/40.png and /dev/null differ diff --git a/assets/static/icons/flower/400.png b/assets/static/icons/flower/400.png deleted file mode 100644 index 23fc2ed79..000000000 Binary files a/assets/static/icons/flower/400.png and /dev/null differ diff --git a/assets/static/icons/flower/48.png b/assets/static/icons/flower/48.png deleted file mode 100644 index b09bfa248..000000000 Binary files a/assets/static/icons/flower/48.png and /dev/null differ diff --git a/assets/static/icons/flower/50.png b/assets/static/icons/flower/50.png deleted file mode 100644 index f96163474..000000000 Binary files a/assets/static/icons/flower/50.png and /dev/null differ diff --git a/assets/static/icons/flower/512.png b/assets/static/icons/flower/512.png deleted file mode 100644 index 2b42c07ca..000000000 Binary files a/assets/static/icons/flower/512.png and /dev/null differ diff --git a/assets/static/icons/flower/55.png b/assets/static/icons/flower/55.png deleted file mode 100644 index e72cc0ae1..000000000 Binary files a/assets/static/icons/flower/55.png and /dev/null differ diff --git a/assets/static/icons/flower/56.png b/assets/static/icons/flower/56.png deleted file mode 100644 index ac4433d45..000000000 Binary files a/assets/static/icons/flower/56.png and /dev/null differ diff --git a/assets/static/icons/flower/60.png b/assets/static/icons/flower/60.png deleted file mode 100644 index 66033b7cd..000000000 Binary files a/assets/static/icons/flower/60.png and /dev/null differ diff --git a/assets/static/icons/flower/64.png b/assets/static/icons/flower/64.png deleted file mode 100644 index b5276b945..000000000 Binary files a/assets/static/icons/flower/64.png and /dev/null differ diff --git a/assets/static/icons/flower/72.png b/assets/static/icons/flower/72.png deleted file mode 100644 index 7a8c1ea59..000000000 Binary files a/assets/static/icons/flower/72.png and /dev/null differ diff --git a/assets/static/icons/flower/76.png b/assets/static/icons/flower/76.png deleted file mode 100644 index 3342ea360..000000000 Binary files a/assets/static/icons/flower/76.png and /dev/null differ diff --git a/assets/static/icons/flower/80.png b/assets/static/icons/flower/80.png deleted file mode 100644 index c742673ae..000000000 Binary files a/assets/static/icons/flower/80.png and /dev/null differ diff --git a/assets/static/icons/flower/maskable/192.png b/assets/static/icons/flower/maskable/192.png deleted file mode 100644 index d93f44e23..000000000 Binary files a/assets/static/icons/flower/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/flower/maskable/512.png b/assets/static/icons/flower/maskable/512.png deleted file mode 100644 index dc45a123a..000000000 Binary files a/assets/static/icons/flower/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/logo.svg b/assets/static/icons/logo.svg index 9b77f9817..eefa5cde4 100644 --- a/assets/static/icons/logo.svg +++ b/assets/static/icons/logo.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/logo/maskable/192.png b/assets/static/icons/logo/maskable/192.png deleted file mode 100644 index d377ae492..000000000 Binary files a/assets/static/icons/logo/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/logo/maskable/512.png b/assets/static/icons/logo/maskable/512.png deleted file mode 100644 index 9c625a4af..000000000 Binary files a/assets/static/icons/logo/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/mint.svg b/assets/static/icons/mint.svg index e78e94af0..f02e9a793 100644 --- a/assets/static/icons/mint.svg +++ b/assets/static/icons/mint.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/static/icons/mint/maskable/192.png b/assets/static/icons/mint/maskable/192.png deleted file mode 100644 index 4f6ddc3d6..000000000 Binary files a/assets/static/icons/mint/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/mint/maskable/512.png b/assets/static/icons/mint/maskable/512.png deleted file mode 100644 index 01d26debf..000000000 Binary files a/assets/static/icons/mint/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/ring.svg b/assets/static/icons/ring.svg deleted file mode 100644 index 37a1ba85b..000000000 --- a/assets/static/icons/ring.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/static/icons/ring/100.png b/assets/static/icons/ring/100.png deleted file mode 100644 index d02e206f4..000000000 Binary files a/assets/static/icons/ring/100.png and /dev/null differ diff --git a/assets/static/icons/ring/1024.png b/assets/static/icons/ring/1024.png deleted file mode 100644 index 7f504ed9a..000000000 Binary files a/assets/static/icons/ring/1024.png and /dev/null differ diff --git a/assets/static/icons/ring/114.png b/assets/static/icons/ring/114.png deleted file mode 100644 index c46bb17fa..000000000 Binary files a/assets/static/icons/ring/114.png and /dev/null differ diff --git a/assets/static/icons/ring/120.png b/assets/static/icons/ring/120.png deleted file mode 100644 index 2e0805eca..000000000 Binary files a/assets/static/icons/ring/120.png and /dev/null differ diff --git a/assets/static/icons/ring/128.png b/assets/static/icons/ring/128.png deleted file mode 100644 index 46cebce21..000000000 Binary files a/assets/static/icons/ring/128.png and /dev/null differ diff --git a/assets/static/icons/ring/144.png b/assets/static/icons/ring/144.png deleted file mode 100644 index 06093c0ac..000000000 Binary files a/assets/static/icons/ring/144.png and /dev/null differ diff --git a/assets/static/icons/ring/152.png b/assets/static/icons/ring/152.png deleted file mode 100644 index 88402d14d..000000000 Binary files a/assets/static/icons/ring/152.png and /dev/null differ diff --git a/assets/static/icons/ring/16.png b/assets/static/icons/ring/16.png deleted file mode 100644 index 2aa8543e4..000000000 Binary files a/assets/static/icons/ring/16.png and /dev/null differ diff --git a/assets/static/icons/ring/160.png b/assets/static/icons/ring/160.png deleted file mode 100644 index 3f008c239..000000000 Binary files a/assets/static/icons/ring/160.png and /dev/null differ diff --git a/assets/static/icons/ring/167.png b/assets/static/icons/ring/167.png deleted file mode 100644 index 9373edc7d..000000000 Binary files a/assets/static/icons/ring/167.png and /dev/null differ diff --git a/assets/static/icons/ring/172.png b/assets/static/icons/ring/172.png deleted file mode 100644 index 2d3b54e90..000000000 Binary files a/assets/static/icons/ring/172.png and /dev/null differ diff --git a/assets/static/icons/ring/175.png b/assets/static/icons/ring/175.png deleted file mode 100644 index 8206d3f71..000000000 Binary files a/assets/static/icons/ring/175.png and /dev/null differ diff --git a/assets/static/icons/ring/180.png b/assets/static/icons/ring/180.png deleted file mode 100644 index c5c5f9873..000000000 Binary files a/assets/static/icons/ring/180.png and /dev/null differ diff --git a/assets/static/icons/ring/192.png b/assets/static/icons/ring/192.png deleted file mode 100644 index e12f8ab7c..000000000 Binary files a/assets/static/icons/ring/192.png and /dev/null differ diff --git a/assets/static/icons/ring/196.png b/assets/static/icons/ring/196.png deleted file mode 100644 index 2fd4f1024..000000000 Binary files a/assets/static/icons/ring/196.png and /dev/null differ diff --git a/assets/static/icons/ring/20.png b/assets/static/icons/ring/20.png deleted file mode 100644 index 38642f28e..000000000 Binary files a/assets/static/icons/ring/20.png and /dev/null differ diff --git a/assets/static/icons/ring/200.png b/assets/static/icons/ring/200.png deleted file mode 100644 index aaaadd912..000000000 Binary files a/assets/static/icons/ring/200.png and /dev/null differ diff --git a/assets/static/icons/ring/216.png b/assets/static/icons/ring/216.png deleted file mode 100644 index f21875a4d..000000000 Binary files a/assets/static/icons/ring/216.png and /dev/null differ diff --git a/assets/static/icons/ring/256.png b/assets/static/icons/ring/256.png deleted file mode 100644 index b43ca2f39..000000000 Binary files a/assets/static/icons/ring/256.png and /dev/null differ diff --git a/assets/static/icons/ring/267.png b/assets/static/icons/ring/267.png deleted file mode 100644 index 080e281d9..000000000 Binary files a/assets/static/icons/ring/267.png and /dev/null differ diff --git a/assets/static/icons/ring/29.png b/assets/static/icons/ring/29.png deleted file mode 100644 index 6e2f03246..000000000 Binary files a/assets/static/icons/ring/29.png and /dev/null differ diff --git a/assets/static/icons/ring/32.png b/assets/static/icons/ring/32.png deleted file mode 100644 index b333a7554..000000000 Binary files a/assets/static/icons/ring/32.png and /dev/null differ diff --git a/assets/static/icons/ring/40.png b/assets/static/icons/ring/40.png deleted file mode 100644 index d0eaad87e..000000000 Binary files a/assets/static/icons/ring/40.png and /dev/null differ diff --git a/assets/static/icons/ring/400.png b/assets/static/icons/ring/400.png deleted file mode 100644 index 0323a8d5a..000000000 Binary files a/assets/static/icons/ring/400.png and /dev/null differ diff --git a/assets/static/icons/ring/48.png b/assets/static/icons/ring/48.png deleted file mode 100644 index ba311055c..000000000 Binary files a/assets/static/icons/ring/48.png and /dev/null differ diff --git a/assets/static/icons/ring/50.png b/assets/static/icons/ring/50.png deleted file mode 100644 index 57844b771..000000000 Binary files a/assets/static/icons/ring/50.png and /dev/null differ diff --git a/assets/static/icons/ring/512.png b/assets/static/icons/ring/512.png deleted file mode 100644 index a7d689856..000000000 Binary files a/assets/static/icons/ring/512.png and /dev/null differ diff --git a/assets/static/icons/ring/55.png b/assets/static/icons/ring/55.png deleted file mode 100644 index f5a940af6..000000000 Binary files a/assets/static/icons/ring/55.png and /dev/null differ diff --git a/assets/static/icons/ring/56.png b/assets/static/icons/ring/56.png deleted file mode 100644 index 0f3f3ffae..000000000 Binary files a/assets/static/icons/ring/56.png and /dev/null differ diff --git a/assets/static/icons/ring/60.png b/assets/static/icons/ring/60.png deleted file mode 100644 index 527ef571d..000000000 Binary files a/assets/static/icons/ring/60.png and /dev/null differ diff --git a/assets/static/icons/ring/64.png b/assets/static/icons/ring/64.png deleted file mode 100644 index 6f9fbe250..000000000 Binary files a/assets/static/icons/ring/64.png and /dev/null differ diff --git a/assets/static/icons/ring/72.png b/assets/static/icons/ring/72.png deleted file mode 100644 index 714421c8a..000000000 Binary files a/assets/static/icons/ring/72.png and /dev/null differ diff --git a/assets/static/icons/ring/76.png b/assets/static/icons/ring/76.png deleted file mode 100644 index 79c76f225..000000000 Binary files a/assets/static/icons/ring/76.png and /dev/null differ diff --git a/assets/static/icons/ring/80.png b/assets/static/icons/ring/80.png deleted file mode 100644 index 62a611ffd..000000000 Binary files a/assets/static/icons/ring/80.png and /dev/null differ diff --git a/assets/static/icons/ring/maskable/192.png b/assets/static/icons/ring/maskable/192.png deleted file mode 100644 index 9d0a13264..000000000 Binary files a/assets/static/icons/ring/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/ring/maskable/512.png b/assets/static/icons/ring/maskable/512.png deleted file mode 100644 index 3fd39ef0a..000000000 Binary files a/assets/static/icons/ring/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/shutter.svg b/assets/static/icons/shutter.svg deleted file mode 100644 index df7d44caa..000000000 --- a/assets/static/icons/shutter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/static/icons/shutter/100.png b/assets/static/icons/shutter/100.png deleted file mode 100644 index d21876a1a..000000000 Binary files a/assets/static/icons/shutter/100.png and /dev/null differ diff --git a/assets/static/icons/shutter/1024.png b/assets/static/icons/shutter/1024.png deleted file mode 100644 index 05d142a51..000000000 Binary files a/assets/static/icons/shutter/1024.png and /dev/null differ diff --git a/assets/static/icons/shutter/114.png b/assets/static/icons/shutter/114.png deleted file mode 100644 index bf01fc249..000000000 Binary files a/assets/static/icons/shutter/114.png and /dev/null differ diff --git a/assets/static/icons/shutter/120.png b/assets/static/icons/shutter/120.png deleted file mode 100644 index b4345b1ab..000000000 Binary files a/assets/static/icons/shutter/120.png and /dev/null differ diff --git a/assets/static/icons/shutter/128.png b/assets/static/icons/shutter/128.png deleted file mode 100644 index 6117279d8..000000000 Binary files a/assets/static/icons/shutter/128.png and /dev/null differ diff --git a/assets/static/icons/shutter/144.png b/assets/static/icons/shutter/144.png deleted file mode 100644 index 7e94dc3c7..000000000 Binary files a/assets/static/icons/shutter/144.png and /dev/null differ diff --git a/assets/static/icons/shutter/152.png b/assets/static/icons/shutter/152.png deleted file mode 100644 index 722ea6a58..000000000 Binary files a/assets/static/icons/shutter/152.png and /dev/null differ diff --git a/assets/static/icons/shutter/16.png b/assets/static/icons/shutter/16.png deleted file mode 100644 index 7857de97c..000000000 Binary files a/assets/static/icons/shutter/16.png and /dev/null differ diff --git a/assets/static/icons/shutter/160.png b/assets/static/icons/shutter/160.png deleted file mode 100644 index 6fa8a66ed..000000000 Binary files a/assets/static/icons/shutter/160.png and /dev/null differ diff --git a/assets/static/icons/shutter/167.png b/assets/static/icons/shutter/167.png deleted file mode 100644 index 3863b6048..000000000 Binary files a/assets/static/icons/shutter/167.png and /dev/null differ diff --git a/assets/static/icons/shutter/172.png b/assets/static/icons/shutter/172.png deleted file mode 100644 index e0cd512cb..000000000 Binary files a/assets/static/icons/shutter/172.png and /dev/null differ diff --git a/assets/static/icons/shutter/175.png b/assets/static/icons/shutter/175.png deleted file mode 100644 index f7e12716d..000000000 Binary files a/assets/static/icons/shutter/175.png and /dev/null differ diff --git a/assets/static/icons/shutter/180.png b/assets/static/icons/shutter/180.png deleted file mode 100644 index ff6962023..000000000 Binary files a/assets/static/icons/shutter/180.png and /dev/null differ diff --git a/assets/static/icons/shutter/192.png b/assets/static/icons/shutter/192.png deleted file mode 100644 index e6f3067ad..000000000 Binary files a/assets/static/icons/shutter/192.png and /dev/null differ diff --git a/assets/static/icons/shutter/196.png b/assets/static/icons/shutter/196.png deleted file mode 100644 index 51792e7dc..000000000 Binary files a/assets/static/icons/shutter/196.png and /dev/null differ diff --git a/assets/static/icons/shutter/20.png b/assets/static/icons/shutter/20.png deleted file mode 100644 index e91dc2276..000000000 Binary files a/assets/static/icons/shutter/20.png and /dev/null differ diff --git a/assets/static/icons/shutter/200.png b/assets/static/icons/shutter/200.png deleted file mode 100644 index 0eef32efa..000000000 Binary files a/assets/static/icons/shutter/200.png and /dev/null differ diff --git a/assets/static/icons/shutter/216.png b/assets/static/icons/shutter/216.png deleted file mode 100644 index a2e182eaa..000000000 Binary files a/assets/static/icons/shutter/216.png and /dev/null differ diff --git a/assets/static/icons/shutter/256.png b/assets/static/icons/shutter/256.png deleted file mode 100644 index afbc9805d..000000000 Binary files a/assets/static/icons/shutter/256.png and /dev/null differ diff --git a/assets/static/icons/shutter/267.png b/assets/static/icons/shutter/267.png deleted file mode 100644 index de8f45bfe..000000000 Binary files a/assets/static/icons/shutter/267.png and /dev/null differ diff --git a/assets/static/icons/shutter/29.png b/assets/static/icons/shutter/29.png deleted file mode 100644 index 4b9a4e465..000000000 Binary files a/assets/static/icons/shutter/29.png and /dev/null differ diff --git a/assets/static/icons/shutter/32.png b/assets/static/icons/shutter/32.png deleted file mode 100644 index 91ed96306..000000000 Binary files a/assets/static/icons/shutter/32.png and /dev/null differ diff --git a/assets/static/icons/shutter/40.png b/assets/static/icons/shutter/40.png deleted file mode 100644 index a89499e15..000000000 Binary files a/assets/static/icons/shutter/40.png and /dev/null differ diff --git a/assets/static/icons/shutter/400.png b/assets/static/icons/shutter/400.png deleted file mode 100644 index 52b4fe19b..000000000 Binary files a/assets/static/icons/shutter/400.png and /dev/null differ diff --git a/assets/static/icons/shutter/48.png b/assets/static/icons/shutter/48.png deleted file mode 100644 index 403d4b8cc..000000000 Binary files a/assets/static/icons/shutter/48.png and /dev/null differ diff --git a/assets/static/icons/shutter/50.png b/assets/static/icons/shutter/50.png deleted file mode 100644 index b6b4d3f87..000000000 Binary files a/assets/static/icons/shutter/50.png and /dev/null differ diff --git a/assets/static/icons/shutter/512.png b/assets/static/icons/shutter/512.png deleted file mode 100644 index 5524decbb..000000000 Binary files a/assets/static/icons/shutter/512.png and /dev/null differ diff --git a/assets/static/icons/shutter/55.png b/assets/static/icons/shutter/55.png deleted file mode 100644 index 3df91b060..000000000 Binary files a/assets/static/icons/shutter/55.png and /dev/null differ diff --git a/assets/static/icons/shutter/56.png b/assets/static/icons/shutter/56.png deleted file mode 100644 index 7224951ba..000000000 Binary files a/assets/static/icons/shutter/56.png and /dev/null differ diff --git a/assets/static/icons/shutter/60.png b/assets/static/icons/shutter/60.png deleted file mode 100644 index f34694e1e..000000000 Binary files a/assets/static/icons/shutter/60.png and /dev/null differ diff --git a/assets/static/icons/shutter/64.png b/assets/static/icons/shutter/64.png deleted file mode 100644 index e7002ec3d..000000000 Binary files a/assets/static/icons/shutter/64.png and /dev/null differ diff --git a/assets/static/icons/shutter/72.png b/assets/static/icons/shutter/72.png deleted file mode 100644 index 0b9b09e74..000000000 Binary files a/assets/static/icons/shutter/72.png and /dev/null differ diff --git a/assets/static/icons/shutter/76.png b/assets/static/icons/shutter/76.png deleted file mode 100644 index 8fbe973f5..000000000 Binary files a/assets/static/icons/shutter/76.png and /dev/null differ diff --git a/assets/static/icons/shutter/80.png b/assets/static/icons/shutter/80.png deleted file mode 100644 index 083f18d8a..000000000 Binary files a/assets/static/icons/shutter/80.png and /dev/null differ diff --git a/assets/static/icons/shutter/maskable/192.png b/assets/static/icons/shutter/maskable/192.png deleted file mode 100644 index 33afdda95..000000000 Binary files a/assets/static/icons/shutter/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/shutter/maskable/512.png b/assets/static/icons/shutter/maskable/512.png deleted file mode 100644 index f87fc4ea4..000000000 Binary files a/assets/static/icons/shutter/maskable/512.png and /dev/null differ diff --git a/assets/static/icons/square.svg b/assets/static/icons/square.svg index 885a9fc63..31c513e43 100644 --- a/assets/static/icons/square.svg +++ b/assets/static/icons/square.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/assets/static/icons/square/maskable/192.png b/assets/static/icons/square/maskable/192.png deleted file mode 100644 index 227e932ae..000000000 Binary files a/assets/static/icons/square/maskable/192.png and /dev/null differ diff --git a/assets/static/icons/square/maskable/512.png b/assets/static/icons/square/maskable/512.png deleted file mode 100644 index 05f58c016..000000000 Binary files a/assets/static/icons/square/maskable/512.png and /dev/null differ diff --git a/assets/static/img/screenshots/narrow.jpg b/assets/static/img/screenshots/narrow.jpg deleted file mode 100644 index 93dc03ff2..000000000 Binary files a/assets/static/img/screenshots/narrow.jpg and /dev/null differ diff --git a/assets/static/img/screenshots/wide.jpg b/assets/static/img/screenshots/wide.jpg deleted file mode 100644 index 2cd9be15f..000000000 Binary files a/assets/static/img/screenshots/wide.jpg and /dev/null differ diff --git a/assets/templates/404.gohtml b/assets/templates/404.gohtml index 12d6d98b8..26d9fc057 100644 --- a/assets/templates/404.gohtml +++ b/assets/templates/404.gohtml @@ -26,7 +26,7 @@ .e973c102-193a-465f-a6ce-238077277871{stroke:#efefef;stroke-miterlimit:10;stroke-width:5px;} .f5ddff88-48c1-46f9-a031-aee9bce94bd6{clip-path:url(#a1251993-bbf1-4548-8238-fa794c0bb4e3);} .ead6f749-dce3-444a-a4f2-acc8f3078dec{clip-path:url(#be2d8169-fac1-479f-9595-ff9fe03b48a4);} - .a34fac52-8499-4455-a7f4-105abc9df09b,.f18ba0a9-054f-4ae5-b0d0-1c52cbadb98f{font-size:63px;fill:#efefef;direction:ltr;} + .a34fac52-8499-4455-a7f4-105abc9df09b,.f18ba0a9-054f-4ae5-b0d0-1c52cbadb98f{font-size:63px;fill:#efefef;} .a34fac52-8499-4455-a7f4-105abc9df09b{font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";} .beccc81f-4365-4373-9899-0d823daf22a9{letter-spacing:0.01em;} .f18ba0a9-054f-4ae5-b0d0-1c52cbadb98f{font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-weight:300;letter-spacing:0em;} diff --git a/assets/templates/auth.gohtml b/assets/templates/auth.gohtml index 8ac4ef709..51b3cad56 100644 --- a/assets/templates/auth.gohtml +++ b/assets/templates/auth.gohtml @@ -30,8 +30,6 @@ "session.provider", "session.scope", "session.error", - "session.messageId", - "session.messageParams", ]; const storages = [localStorage, sessionStorage].filter(Boolean); const preferredStorage = @@ -50,23 +48,27 @@ const setItem = (key, value) => { preferredStorage.setItem(namespacedKey(key), value); }; + const removeItem = (key) => { + storages.forEach((storage) => storage.removeItem(namespacedKey(key))); + }; - {{/* clearSessionData() removes every session.* key (including session.error, - session.messageId, and session.messageParams), so each branch only sets - the keys it wants to persist. */}} {{ if eq .status "success" }} clearSessionData(); setItem("session.id", {{ .session_id }}); setItem("session.token", {{ .access_token }}); setItem("session.provider", {{ .provider }}); setItem("session.user", JSON.stringify({{ .user }})); + removeItem("session.error"); {{ else if eq .status "failed" }} clearSessionData(); setItem("session.error", {{ .error }}); - {{ if .messageId }}setItem("session.messageId", {{ .messageId }});{{ end }} - {{ if .messageParams }}setItem("session.messageParams", JSON.stringify({{ .messageParams }}));{{ end }} {{ else }} clearSessionData(); + removeItem("session.id"); + removeItem("session.token"); + removeItem("session.provider"); + removeItem("session.user"); + removeItem("session.error"); {{ end }} })(); window.location.href = {{ .config.LoginUri }}; diff --git a/assets/templates/oauth-error.gohtml b/assets/templates/oauth-error.gohtml deleted file mode 100644 index 835752c2e..000000000 --- a/assets/templates/oauth-error.gohtml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - {{ .error }} – {{if and .config.SiteCaption .config.Sponsor }}{{ .config.SiteCaption }}{{else}}{{ .config.Name }}{{end}} - -{{template "favicons.gohtml" .}} -{{template "styles.gohtml" .}} - - - - -
-
-
- -
-
-
- - diff --git a/cmd/photoprism/photoprism.go b/cmd/photoprism/photoprism.go index d849b4c84..9abbdcb0a 100644 --- a/cmd/photoprism/photoprism.go +++ b/cmd/photoprism/photoprism.go @@ -1,5 +1,5 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -12,7 +12,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -23,7 +23,6 @@ Additional information can be found in our Developer Guide: package main import ( - "fmt" "os" "github.com/urfave/cli/v2" @@ -34,6 +33,7 @@ import ( ) var version = "development" +var log = event.Log const appName = "PhotoPrism" const appAbout = "PhotoPrism®" @@ -41,7 +41,7 @@ const appEdition = "ce" const appDescription = "PhotoPrism® is an AI-Powered Photos App for the Decentralized Web." + " It makes use of the latest technologies to tag and find pictures automatically without getting in your way." + " You can run it at home, on a private server, or in the cloud." -const appCopyright = "(c) 2018-2026 PhotoPrism UG. All rights reserved." +const appCopyright = "(c) 2018-2025 PhotoPrism UG. All rights reserved." // Metadata contains build specific information. var Metadata = map[string]any{ @@ -55,7 +55,6 @@ var Metadata = map[string]any{ func main() { defer func() { if r := recover(); r != nil { - event.LogPanic(r) os.Exit(1) } }() @@ -70,10 +69,7 @@ func main() { app.Commands = commands.PhotoPrism app.Metadata = Metadata - // urfave/cli prints and exits with the code of any cli.Exit(...) error - // before returning here, so only plain errors reach this point; report - // them on stderr without forcing a specific exit code. if err := app.Run(os.Args); err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) + log.Error(err) } } diff --git a/compose.intel.yaml b/compose.intel.yaml index 1bce61af7..bf95c530f 100644 --- a/compose.intel.yaml +++ b/compose.intel.yaml @@ -67,7 +67,6 @@ services: PHOTOPRISM_OIDC_URI: "https://keycloak.localssl.dev/realms/master" PHOTOPRISM_OIDC_CLIENT: "photoprism-develop" PHOTOPRISM_OIDC_SECRET: "9d8351a0-ca01-4556-9c37-85eb634869b9" - PHOTOPRISM_OIDC_PROMPT: "" # authorization prompt: login, select_account, or consent (empty = seamless SSO) PHOTOPRISM_OIDC_PROVIDER: "Keycloak" PHOTOPRISM_OIDC_REGISTER: "true" PHOTOPRISM_OIDC_WEBDAV: "true" @@ -88,10 +87,9 @@ services: PHOTOPRISM_DEFAULT_TLS: "true" ## Site Information: PHOTOPRISM_SITE_URL: "https://app.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster - PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" # short caption or tagline shown alongside the title - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag + PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "true" diff --git a/compose.latest.yaml b/compose.latest.yaml index 05b03509b..52bec2171 100644 --- a/compose.latest.yaml +++ b/compose.latest.yaml @@ -27,10 +27,9 @@ services: PHOTOPRISM_ADMIN_PASSWORD: "photoprism" # initial admin password (8-72 characters) PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password) PHOTOPRISM_SITE_URL: "https://latest.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster - PHOTOPRISM_SITE_CAPTION: "Latest" # short caption or tagline shown alongside the title - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag + PHOTOPRISM_SITE_CAPTION: "Latest" + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "false" diff --git a/compose.nvidia.yaml b/compose.nvidia.yaml index 12e47f8d1..1251a14d8 100644 --- a/compose.nvidia.yaml +++ b/compose.nvidia.yaml @@ -70,7 +70,6 @@ services: PHOTOPRISM_OIDC_URI: "https://keycloak.localssl.dev/realms/master" PHOTOPRISM_OIDC_CLIENT: "photoprism-develop" PHOTOPRISM_OIDC_SECRET: "9d8351a0-ca01-4556-9c37-85eb634869b9" - PHOTOPRISM_OIDC_PROMPT: "" # authorization prompt: login, select_account, or consent (empty = seamless SSO) PHOTOPRISM_OIDC_PROVIDER: "Keycloak" PHOTOPRISM_OIDC_REGISTER: "true" PHOTOPRISM_OIDC_WEBDAV: "true" @@ -91,10 +90,9 @@ services: PHOTOPRISM_DEFAULT_TLS: "true" ## Site Information: PHOTOPRISM_SITE_URL: "https://app.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster - PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" # short caption or tagline shown alongside the title - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag + PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "true" @@ -204,26 +202,12 @@ services: OLLAMA_MULTIUSER_CACHE: "false" # optimize prompt caching for multi-user scenarios OLLAMA_NOPRUNE: "false" # disables pruning of model blobs at startup OLLAMA_NOHISTORY: "true" # disables readline history - # OLLAMA_FLASH_ATTENTION — small speedup on supported architectures - # (gemma3, gptoss, mistral3, qwen3*). Silently no-op on unsupported - # architectures and on CPU. Required to enable OLLAMA_KV_CACHE_TYPE - # quantization. Set to "false" for Qwen3-2507 builds (gh#12432). - OLLAMA_FLASH_ATTENTION: "true" - # OLLAMA_KV_CACHE_TYPE — cache precision (f16 is the default): - # f16 — native precision, works on every architecture - # q8_0 — halves cache VRAM; clean for qwen3*/gpt-oss/mistral3; - # 5x slowdown on gemma3 (gh#9683/#11949); no-op for - # gemma4/qwen2.5vl (not on FA allowlist — gh#13337) - # q4_0 — quarters cache VRAM; usable on qwen, hurts gemma; - # only reach for it when VRAM-constrained - OLLAMA_KV_CACHE_TYPE: "f16" # cache precision: f16 (default), q8_0, q4_0 + OLLAMA_FLASH_ATTENTION: "false" # enables the experimental flash attention feature + OLLAMA_KV_CACHE_TYPE: "f16" # cache quantization (f16, q8_0, or q4_0) OLLAMA_SCHED_SPREAD: "false" # allows scheduling models across all GPUs. + OLLAMA_NEW_ENGINE: "true" # enables the new Ollama engine # OLLAMA_DEBUG: "true" # shows additional debug information # OLLAMA_INTEL_GPU: "true" # enables experimental Intel GPU detection - ## Telemetry / privacy opt-outs (containers do not inherit /etc/environment): - DO_NOT_TRACK: "true" - HF_HUB_DISABLE_TELEMETRY: "1" - # OLLAMA_NO_CLOUD: "1" # uncomment to disable Ollama Cloud models/features ## NVIDIA GPU Hardware Acceleration (see https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html): NVIDIA_VISIBLE_DEVICES: "all" NVIDIA_DRIVER_CAPABILITIES: "compute,utility" diff --git a/compose.preview.yaml b/compose.preview.yaml index 3168a5adc..d67c51340 100644 --- a/compose.preview.yaml +++ b/compose.preview.yaml @@ -27,10 +27,9 @@ services: PHOTOPRISM_ADMIN_PASSWORD: "photoprism" # initial admin password (8-72 characters) PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password) PHOTOPRISM_SITE_URL: "https://preview.localssl.dev/" # server URL in the format "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster - PHOTOPRISM_SITE_CAPTION: "Preview" # short caption or tagline shown alongside the title - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag + PHOTOPRISM_SITE_CAPTION: "Preview" + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "false" diff --git a/compose.yaml b/compose.yaml index c0a33880a..713350975 100644 --- a/compose.yaml +++ b/compose.yaml @@ -74,7 +74,6 @@ services: PHOTOPRISM_OIDC_URI: "https://keycloak.localssl.dev/realms/master" PHOTOPRISM_OIDC_CLIENT: "photoprism-develop" PHOTOPRISM_OIDC_SECRET: "9d8351a0-ca01-4556-9c37-85eb634869b9" - PHOTOPRISM_OIDC_PROMPT: "" # authorization prompt: login, select_account, or consent (empty = seamless SSO) PHOTOPRISM_OIDC_PROVIDER: "Keycloak" PHOTOPRISM_OIDC_REGISTER: "true" PHOTOPRISM_OIDC_WEBDAV: "true" @@ -95,10 +94,9 @@ services: PHOTOPRISM_DEFAULT_TLS: "true" ## Site Information: PHOTOPRISM_SITE_URL: "${PHOTOPRISM_SITE_URL:-https://app.localssl.dev/}" # "http(s)://domain.name(:port)/(path)" - PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster - PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" # short caption or tagline shown alongside the title - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags - PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" # site owner shown in the author meta tag + PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" + PHOTOPRISM_SITE_AUTHOR: "@photoprism_app" PHOTOPRISM_DEBUG: "true" PHOTOPRISM_READONLY: "false" PHOTOPRISM_EXPERIMENTAL: "true" @@ -145,11 +143,11 @@ services: ## Run/install on first startup (options: update tensorflow https intel gpu davfs yt-dlp): PHOTOPRISM_INIT: "https" ## Computer Vision (https://docs.photoprism.app/getting-started/config-options/#computer-vision): - PHOTOPRISM_VISION_API: "true" # server: enables service API endpoints under /api/v1/vision (requires access token) - PHOTOPRISM_VISION_URI: "${PHOTOPRISM_VISION_URI:-}" # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable) - PHOTOPRISM_VISION_KEY: "${PHOTOPRISM_VISION_KEY:-}" # client: service access token (for authentication) - OLLAMA_BASE_URL: "${OLLAMA_BASE_URL:-http://ollama:11434}" # use "https://ollama.com" for Ollama Cloud - OLLAMA_API_KEY: "${OLLAMA_API_KEY:-}" # optional API key for Ollama Cloud + PHOTOPRISM_VISION_API: "true" # server: enables service API endpoints under /api/v1/vision (requires access token) + PHOTOPRISM_VISION_URI: "" # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable) + PHOTOPRISM_VISION_KEY: "" # client: service access token (for authentication) + OLLAMA_BASE_URL: "http://ollama:11434" # use "https://ollama.com" for Ollama Cloud + OLLAMA_API_KEY: "" # API key required to access Ollama (optional) ## Additional dependencies and tools: TF_CPP_MIN_LOG_LEVEL: 1 GOCACHE: "${WORKING_DIR:-/go/src/github.com/photoprism/photoprism}/.local/gocache" @@ -175,14 +173,6 @@ services: stop_grace_period: 15s security_opt: - no-new-privileges:true - command: - - --api.dashboard=false - - --global.checknewversion=false - - --global.sendanonymoususage=false - - --providers.docker=true - - --providers.docker.exposedbydefault=false - - --entrypoints.web.address=:80 - - --entrypoints.websecure.address=:443 ## Publish Traefik's HTTP and HTTPS entrypoints on the host (bound to every interface ## by default; override TRAEFIK_BIND_HOST, TRAEFIK_HTTP_PORT, or TRAEFIK_HTTPS_PORT): ports: @@ -197,7 +187,7 @@ services: ## Docs: https://mariadb.com/docs/reference/ ## Release Notes: https://mariadb.com/kb/en/changes-improvements-in-mariadb-1011/ mariadb: - image: mariadb:12.3 + image: mariadb:11 stop_grace_period: 15s security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239 - seccomp:unconfined @@ -318,15 +308,12 @@ services: OLLAMA_MULTIUSER_CACHE: "false" # optimize prompt caching for multi-user scenarios OLLAMA_NOPRUNE: "false" # disables pruning of model blobs at startup OLLAMA_NOHISTORY: "true" # disables readline history - OLLAMA_FLASH_ATTENTION: "true" # required for OLLAMA_KV_CACHE_TYPE quantization - OLLAMA_KV_CACHE_TYPE: "f16" # cache precision: f16 (default), q8_0, q4_0 + OLLAMA_FLASH_ATTENTION: "false" # enables the experimental flash attention feature + OLLAMA_KV_CACHE_TYPE: "f16" # cache quantization (f16, q8_0, or q4_0) OLLAMA_SCHED_SPREAD: "false" # allows scheduling models across all GPUs. + OLLAMA_NEW_ENGINE: "true" # enables the new Ollama engine # OLLAMA_DEBUG: "true" # shows additional debug information # OLLAMA_INTEL_GPU: "true" # enables experimental Intel GPU detection - ## Telemetry / privacy opt-outs (containers do not inherit /etc/environment): - DO_NOT_TRACK: "true" - HF_HUB_DISABLE_TELEMETRY: "1" - # OLLAMA_NO_CLOUD: "1" # uncomment to disable Ollama Cloud models/features ## NVIDIA GPU Hardware Acceleration (optional): # NVIDIA_VISIBLE_DEVICES: "all" # NVIDIA_DRIVER_CAPABILITIES: "compute,utility" diff --git a/docker/README.md b/docker/README.md index d15849992..a0e5b83b9 100644 --- a/docker/README.md +++ b/docker/README.md @@ -30,6 +30,7 @@ A virtual machine with a dedicated operating system environment provides even mo | `demo/` | Build context for the public [demo site](https://demo.photoprism.app/), including Traefik and job configuration. | | `ddns/` | Minimal image for the Dynamic DNS updater used by our hosted services. | | `dummy/` | Test doubles for OIDC and WebDAV used by acceptance tests and local development. | +| `goproxy/` | Caching Go module proxy used to speed up CI and local builds. | ### Which Image Should I Use? diff --git a/docker/demo/compose.yaml b/docker/demo/compose.yaml index 20b1230af..6c1ef15c4 100644 --- a/docker/demo/compose.yaml +++ b/docker/demo/compose.yaml @@ -17,12 +17,11 @@ services: PHOTOPRISM_PUBLIC: "true" PHOTOPRISM_SITE_URL: "https://demo.yourdomain.com/" # PHOTOPRISM_CDN_URL: "https://demo-cdn.yourdomain.com/" - PHOTOPRISM_SITE_NAME: "" # short name for identifying this instance within a cluster - PHOTOPRISM_SITE_TITLE: "PhotoPrism" # main title shown in the web interface and meta tags - PHOTOPRISM_SITE_CAPTION: "Demo" # short caption or tagline shown alongside the title - PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" # longer description shown in SEO and social meta tags - PHOTOPRISM_SITE_PREVIEW: "https://i.photoprism.app/logo?cover=17&title=Demo" # sharing preview image URL - PHOTOPRISM_SITE_AUTHOR: "PhotoPrism" # site owner shown in the author meta tag + PHOTOPRISM_SITE_TITLE: "PhotoPrism" + PHOTOPRISM_SITE_CAPTION: "Demo" + PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!" + PHOTOPRISM_SITE_PREVIEW: "https://i.photoprism.app/logo?cover=17&title=Demo" + PHOTOPRISM_SITE_AUTHOR: "PhotoPrism" PHOTOPRISM_HTTP_COMPRESSION: "zstd,gzip" PHOTOPRISM_DEFAULT_LOCALE: "en" diff --git a/docker/develop/armv7/Dockerfile b/docker/develop/armv7/Dockerfile index b92705546..7a60b4dbd 100644 --- a/docker/develop/armv7/Dockerfile +++ b/docker/develop/armv7/Dockerfile @@ -85,9 +85,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/bookworm-slim/Dockerfile b/docker/develop/bookworm-slim/Dockerfile index 3641b3760..6eebaffa0 100644 --- a/docker/develop/bookworm-slim/Dockerfile +++ b/docker/develop/bookworm-slim/Dockerfile @@ -61,15 +61,17 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ apt-get -qq install \ libc6 ca-certificates sudo bash tzdata \ xz-utils gpg zip unzip wget curl rsync make nano \ - jq lsof lshw sqlite3 mariadb-client imagemagick libvips42 libyuv0 \ + jq lsof lshw sqlite3 mariadb-client imagemagick libvips-dev libyuv0 \ exiftool darktable rawtherapee libheif-examples librsvg2-bin librav1e-dev \ ffmpeg libavcodec-extra libdav1d-dev x264 x265 libvpx-dev libwebm-dev \ libmatroska-dev libdvdread-dev libebml5 libgav1-bin libatomic1 \ iputils-ping dnsutils binutils binutils-gold \ && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/bookworm/Dockerfile b/docker/develop/bookworm/Dockerfile index 2e785f025..54657e597 100644 --- a/docker/develop/bookworm/Dockerfile +++ b/docker/develop/bookworm/Dockerfile @@ -95,9 +95,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/bullseye-slim/Dockerfile b/docker/develop/bullseye-slim/Dockerfile index 5f196b32e..65f4e1d7e 100644 --- a/docker/develop/bullseye-slim/Dockerfile +++ b/docker/develop/bullseye-slim/Dockerfile @@ -77,7 +77,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ exiftool \ rawtherapee \ imagemagick \ - libvips42 \ + libvips-dev \ ffmpeg \ libavcodec-extra \ x264 \ @@ -87,9 +87,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/bullseye/Dockerfile b/docker/develop/bullseye/Dockerfile index efa0ef74a..c49965223 100644 --- a/docker/develop/bullseye/Dockerfile +++ b/docker/develop/bullseye/Dockerfile @@ -129,9 +129,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/buster/Dockerfile b/docker/develop/buster/Dockerfile index e77966c77..a44a199d2 100644 --- a/docker/develop/buster/Dockerfile +++ b/docker/develop/buster/Dockerfile @@ -125,9 +125,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/impish/Dockerfile b/docker/develop/impish/Dockerfile index 840156f2a..7002af3b0 100644 --- a/docker/develop/impish/Dockerfile +++ b/docker/develop/impish/Dockerfile @@ -123,9 +123,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-chrome.sh && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - /scripts/install-bashrc.sh && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/jammy-slim/Dockerfile b/docker/develop/jammy-slim/Dockerfile index d463e5d3d..e2224835c 100644 --- a/docker/develop/jammy-slim/Dockerfile +++ b/docker/develop/jammy-slim/Dockerfile @@ -70,11 +70,13 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ - /scripts/install-libvips.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + /scripts/install-libvips.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/jammy/Dockerfile b/docker/develop/jammy/Dockerfile index e54adf7ac..bbb9522a9 100644 --- a/docker/develop/jammy/Dockerfile +++ b/docker/develop/jammy/Dockerfile @@ -96,8 +96,8 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-onnx.sh && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ - /scripts/install-libvips.sh && \ /scripts/install-libheif.sh && \ + /scripts/install-libvips.sh && \ /scripts/install-chrome.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ mkdir -p /etc/skel/.config/go/telemetry && \ @@ -108,9 +108,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/lunar-slim/Dockerfile b/docker/develop/lunar-slim/Dockerfile index 6bcd4dd39..744a050e2 100644 --- a/docker/develop/lunar-slim/Dockerfile +++ b/docker/develop/lunar-slim/Dockerfile @@ -59,16 +59,18 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ apt-get update && apt-get -qq dist-upgrade && \ apt-get -qq install \ libc6 ca-certificates bash sudo nano avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 \ - exiftool sqlite3 tzdata gpg make zip unzip wget curl rsync imagemagick libvips42 rawtherapee \ + exiftool sqlite3 tzdata gpg make zip unzip wget curl rsync imagemagick libvips-dev rawtherapee \ ffmpeg libffmpeg-nvenc-dev libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra \ x264 x265 libde265-dev libaom-dev libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev \ && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/lunar/Dockerfile b/docker/develop/lunar/Dockerfile index b6b854512..c8380cf0f 100644 --- a/docker/develop/lunar/Dockerfile +++ b/docker/develop/lunar/Dockerfile @@ -91,9 +91,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/mantic-slim/Dockerfile b/docker/develop/mantic-slim/Dockerfile index 495155ddd..ea83bdac2 100644 --- a/docker/develop/mantic-slim/Dockerfile +++ b/docker/develop/mantic-slim/Dockerfile @@ -59,16 +59,18 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ apt-get update && apt-get -qq dist-upgrade && \ apt-get -qq install \ libc6 ca-certificates bash sudo nano avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 \ - exiftool sqlite3 tzdata gpg make zip unzip wget curl rsync imagemagick libvips42 rawtherapee \ + exiftool sqlite3 tzdata gpg make zip unzip wget curl rsync imagemagick libvips-dev rawtherapee \ ffmpeg libffmpeg-nvenc-dev libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra \ x264 x265 libde265-dev libaom-dev libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev \ && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/mantic/Dockerfile b/docker/develop/mantic/Dockerfile index ef21f5f66..e2997baae 100644 --- a/docker/develop/mantic/Dockerfile +++ b/docker/develop/mantic/Dockerfile @@ -91,9 +91,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/noble-slim/Dockerfile b/docker/develop/noble-slim/Dockerfile index 3a0891e81..c3c304707 100644 --- a/docker/develop/noble-slim/Dockerfile +++ b/docker/develop/noble-slim/Dockerfile @@ -60,7 +60,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ apt-get -qq install \ libc6 ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \ xz-utils avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 exiftool sqlite3 postgresql-client \ - ffmpeg imagemagick libvips42t64 rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ + ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \ libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \ iputils-ping dnsutils binutils binutils-gold \ @@ -68,9 +68,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/noble/Dockerfile b/docker/develop/noble/Dockerfile index 2e0cd0f20..1955331e1 100644 --- a/docker/develop/noble/Dockerfile +++ b/docker/develop/noble/Dockerfile @@ -96,9 +96,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/oracular-slim/Dockerfile b/docker/develop/oracular-slim/Dockerfile index 1e5d67bb1..5deb1b9d4 100644 --- a/docker/develop/oracular-slim/Dockerfile +++ b/docker/develop/oracular-slim/Dockerfile @@ -63,7 +63,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ apt-get -qq install \ libc6 ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \ xz-utils avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 exiftool sqlite3 postgresql-client \ - ffmpeg imagemagick libvips42t64 rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ + ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \ libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \ iputils-ping dnsutils \ @@ -71,9 +71,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/oracular/Dockerfile b/docker/develop/oracular/Dockerfile index e13bec082..ed4025267 100644 --- a/docker/develop/oracular/Dockerfile +++ b/docker/develop/oracular/Dockerfile @@ -99,9 +99,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-6/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/plucky-slim/Dockerfile b/docker/develop/plucky-slim/Dockerfile index a43ade159..93f47867e 100644 --- a/docker/develop/plucky-slim/Dockerfile +++ b/docker/develop/plucky-slim/Dockerfile @@ -63,7 +63,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ apt-get -qq install \ libc6 ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \ xz-utils avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 exiftool sqlite3 postgresql-client \ - ffmpeg imagemagick libvips42t64 rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ + ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \ libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \ va-driver-all libva2 iputils-ping dnsutils libmagic-mgc \ @@ -72,9 +72,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/plucky/Dockerfile b/docker/develop/plucky/Dockerfile index 97119449e..0e7fa2b52 100644 --- a/docker/develop/plucky/Dockerfile +++ b/docker/develop/plucky/Dockerfile @@ -109,9 +109,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ cp -r /etc/skel/.config /root/.config && \ /scripts/install-go.sh && \ /scripts/install-go-tools.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/questing-slim/Dockerfile b/docker/develop/questing-slim/Dockerfile index fd2a99e7b..9491ba432 100644 --- a/docker/develop/questing-slim/Dockerfile +++ b/docker/develop/questing-slim/Dockerfile @@ -63,7 +63,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ apt-get -qq install \ libc6 ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \ xz-utils avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 exiftool sqlite3 postgresql-client \ - ffmpeg imagemagick libvips42t64 rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ + ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \ libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \ va-driver-all libva2 iputils-ping dnsutils libmagic-mgc binutils binutils-gold \ @@ -72,9 +72,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/questing/Dockerfile b/docker/develop/questing/Dockerfile index c9a520650..8fffd816a 100644 --- a/docker/develop/questing/Dockerfile +++ b/docker/develop/questing/Dockerfile @@ -112,9 +112,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/resolute-slim/Dockerfile b/docker/develop/resolute-slim/Dockerfile index 0bcdf958a..e5659718e 100644 --- a/docker/develop/resolute-slim/Dockerfile +++ b/docker/develop/resolute-slim/Dockerfile @@ -59,23 +59,24 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ echo 'force-confold' > /etc/dpkg/dpkg.cfg.d/force-confold && \ - rm -f /usr/bin/pebble && rm -rf /var/lib/pebble && \ apt-get update && apt-get -qq dist-upgrade && \ apt-get -qq install \ libc6 ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \ xz-utils avahi-utils jq lsof lshw libebml5 libgav1-bin libatomic1 exiftool sqlite3 postgresql-client \ - ffmpeg imagemagick libvips42t64 rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ + ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \ libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \ + libheif-examples libheif-plugin-libde265 libheif-plugin-x265 libheif-plugin-aomdec libheif-plugin-aomenc libheif-plugin-dav1d \ va-driver-all libva2 iputils-ping dnsutils libmagic-mgc binutils binutils-gold \ && \ /scripts/install-mariadb.sh mariadb-client && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ - /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/resolute/Dockerfile b/docker/develop/resolute/Dockerfile index 29da35020..29af81671 100644 --- a/docker/develop/resolute/Dockerfile +++ b/docker/develop/resolute/Dockerfile @@ -69,7 +69,6 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/80forceyes && \ echo 'APT::Get::Fix-Missing "true";' > /etc/apt/apt.conf.d/80fixmissing && \ echo 'force-confold' > /etc/dpkg/dpkg.cfg.d/force-confold && \ - rm -f /usr/bin/pebble && rm -rf /var/lib/pebble && \ apt-get update && apt-get -qq dist-upgrade && \ apt-get -qq install \ libc6 libbsd-dev ca-certificates bash sudo nano tzdata gpg make zip unzip wget curl rsync \ @@ -77,6 +76,7 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ ffmpeg imagemagick libvips-dev rawtherapee libjxl-dev libjxl-tools libffmpeg-nvenc-dev librav1e-dev \ libswscale-dev libavfilter-extra libavformat-extra libavcodec-extra x264 x265 libde265-dev libaom-dev \ libvpx-dev libwebm-dev libjpeg-dev libmatroska-dev libdvdread-dev libdav1d-dev libsharpyuv0 \ + libheif-examples libheif-plugin-libde265 libheif-plugin-x265 libheif-plugin-aomdec libheif-plugin-aomenc libheif-plugin-dav1d \ va-driver-all libva2 iputils-ping dnsutils libmagic-mgc binutils binutils-gold \ && \ apt-get -qq install \ @@ -102,7 +102,6 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-onnx.sh && \ /scripts/install-darktable.sh && \ /scripts/install-yt-dlp.sh && \ - /scripts/install-libheif.sh && \ /scripts/install-chrome.sh && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: ALL" >> /etc/sudoers.d/all && \ mkdir -p /etc/skel/.config/go/telemetry && \ @@ -113,9 +112,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/develop/trixie-slim/Dockerfile b/docker/develop/trixie-slim/Dockerfile index 978d64cd7..35edc1312 100644 --- a/docker/develop/trixie-slim/Dockerfile +++ b/docker/develop/trixie-slim/Dockerfile @@ -65,15 +65,17 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ libc6 ca-certificates sudo bash tzdata \ xz-utils gpg zip unzip wget curl rsync make nano \ jq lsof lshw sqlite3 mariadb-client postgresql-client ripgrep \ - imagemagick libvips42t64 libyuv0 libjxl-dev libjxl-tools \ + imagemagick libvips-dev libyuv0 libjxl-dev libjxl-tools \ exiftool darktable rawtherapee libheif-examples librsvg2-bin librav1e-dev \ ffmpeg libavcodec-extra libffmpeg-nvenc-dev libdav1d-dev x264 x265 libvpx-dev libwebm-dev \ libmatroska-dev libdvdread-dev libebml5 libgav1-bin libatomic1 \ va-driver-all libva2 iputils-ping dnsutils binutils binutils-gold \ && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/develop/trixie/Dockerfile b/docker/develop/trixie/Dockerfile index 374abc881..801b62f8d 100644 --- a/docker/develop/trixie/Dockerfile +++ b/docker/develop/trixie/Dockerfile @@ -99,9 +99,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ /scripts/install-hadolint.sh && \ /scripts/install-osv-scanner.sh && \ /scripts/install-gitleaks.sh && \ - /scripts/install-bashrc.sh && \ - echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/bash.bashrc && \ + echo 'alias go=richgo ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ + echo 'export PATH="$PATH:$HOME/.local/bin"' >> /etc/skel/.bashrc && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ cp /scripts/convert/policy.xml /etc/ImageMagick-7/policy.xml && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ diff --git a/docker/dummy/oidc/app/go.mod b/docker/dummy/oidc/app/go.mod index 46f6ffaf4..388539a44 100644 --- a/docker/dummy/oidc/app/go.mod +++ b/docker/dummy/oidc/app/go.mod @@ -1,6 +1,6 @@ module caos-test-op -go 1.26.4 +go 1.26.3 require ( github.com/go-chi/chi/v5 v5.2.5 @@ -26,6 +26,6 @@ require ( go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sys v0.46.0 // indirect + golang.org/x/sys v0.42.0 // indirect golang.org/x/text v0.36.0 // indirect ) diff --git a/docker/dummy/oidc/app/go.sum b/docker/dummy/oidc/app/go.sum index 7ba02046b..840f26ee2 100644 --- a/docker/dummy/oidc/app/go.sum +++ b/docker/dummy/oidc/app/go.sum @@ -57,8 +57,8 @@ go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09 go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= -golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/docker/goproxy/Dockerfile b/docker/goproxy/Dockerfile new file mode 100644 index 000000000..122f55d50 --- /dev/null +++ b/docker/goproxy/Dockerfile @@ -0,0 +1,30 @@ +##################################################### BUILD STAGE ###################################################### +FROM golang:alpine AS build + +ENV DO_NOT_TRACK=true + +RUN apk add --no-cache -U make git mercurial subversion + +RUN git clone https://github.com/goproxyio/goproxy.git /src/goproxy && \ + cd /src/goproxy && \ + export CGO_ENABLED=0 && \ + make + +################################################## PRODUCTION STAGE #################################################### +FROM golang:alpine + +ENV DO_NOT_TRACK=true \ + TINI_VERSION=v0.19.0 + +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-amd64 /usr/bin/tini +RUN chmod +x /usr/bin/tini + +RUN apk add --no-cache -U git mercurial subversion + +COPY --from=build /src/goproxy/bin/goproxy /goproxy +VOLUME "/go" + +EXPOSE 8888 + +ENTRYPOINT ["/usr/bin/tini", "--"] +CMD ["/goproxy", "-listen", "0.0.0.0:8888"] diff --git a/docker/photoprism/armv7/Dockerfile b/docker/photoprism/armv7/Dockerfile index d057cfae3..abb932b92 100644 --- a/docker/photoprism/armv7/Dockerfile +++ b/docker/photoprism/armv7/Dockerfile @@ -115,9 +115,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ && \ /scripts/install-yt-dlp.sh && \ /scripts/install-libheif.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/photoprism/buster/Dockerfile b/docker/photoprism/buster/Dockerfile index 918371019..6e3276fef 100644 --- a/docker/photoprism/buster/Dockerfile +++ b/docker/photoprism/buster/Dockerfile @@ -118,9 +118,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ libavcodec-extra \ && \ /scripts/install-darktable.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/docker/photoprism/impish/Dockerfile b/docker/photoprism/impish/Dockerfile index ffd7b3d50..4a305bb1a 100644 --- a/docker/photoprism/impish/Dockerfile +++ b/docker/photoprism/impish/Dockerfile @@ -117,9 +117,11 @@ RUN echo 'APT::Acquire::Retries "3";' > /etc/apt/apt.conf.d/80retries && \ libavcodec-extra \ && \ /scripts/install-darktable.sh && \ - /scripts/install-bashrc.sh && \ + echo 'alias ll="ls -alh"' >> /etc/skel/.bashrc && \ + echo 'export PS1="\u@$DOCKER_TAG:\w\$ "' >> /etc/skel/.bashrc && \ echo "ALL ALL=(ALL) NOPASSWD:SETENV: /scripts/entrypoint-init.sh" >> /etc/sudoers.d/init && \ /scripts/install-dircolors.sh && \ + cp /etc/skel/.bashrc /root/.bashrc && \ /scripts/create-users.sh && \ install -d -m 0777 -o 1000 -g 1000 \ /photoprism/originals \ diff --git a/frontend/.testcaferc.cjs b/frontend/.testcaferc.cjs deleted file mode 100644 index 73796641a..000000000 --- a/frontend/.testcaferc.cjs +++ /dev/null @@ -1,34 +0,0 @@ -// Taken from https://testcafe.io/documentation/404388/guides/advanced-guides/modify-reporter-output -// And updated to show h m s ms time format. -function onBeforeWriteHook(writeInfo) { // This function will fire every time the reporter calls the "write" method. - if (writeInfo.initiator === 'reportTestDone') { // The "initiator" property contains the name of the reporter event that triggered the hook. - const { - name, - testRunInfo, - meta - } = writeInfo.data || {}; // If you attached this hook to a compatible reporter (such as "spec" or "list"), the hook can process data related to the event. - const testDuration = new Date(testRunInfo.durationMs).toISOString().slice(11, -1); // Save the duration of the test. - writeInfo.formattedText = writeInfo.formattedText + ' (' + testDuration + ')'; // Add test duration to the reporter output. - }; -} - - -module.exports = { // Attach the hook - hooks: { - reporter: { - onBeforeWrite: { - 'spec': onBeforeWriteHook, // This hook will fire when you use the default "spec" reporter. - }, - }, - }, - skipJsErrors: true, - quarantineMode: false, - selectorTimeout: 3500, - assertionTimeout: 3500, - hostname: "localhost", - retryTestPages: true, - screenshots: { - path: "tests/acceptance/screenshots/", - takeOnFails: true - }, -}; \ No newline at end of file diff --git a/frontend/AGENTS.md b/frontend/AGENTS.md index 3f88343a3..829664c2e 100644 --- a/frontend/AGENTS.md +++ b/frontend/AGENTS.md @@ -1,11 +1,11 @@ # Frontend Guidelines -**Last Updated:** June 10, 2026 +**Last Updated:** May 5, 2026 ## Dependencies & Pins - [`frontend/README.md`](README.md) is the canonical doc for dependency pin rationale, the `overrides` layer, ESM-only upgrade blockers, and the orphan-audit pattern. -- **Pins are intentional.** When a version has no caret (e.g., `"axios": "1.17.0"`, `"vuetify": "3.12.2"`), check `frontend/README.md` and `git log -p -S "" -- frontend/package.json` for the reason before changing it. +- **Pins are intentional.** When a version has no caret (e.g., `"axios": "1.16.1"`, `"vuetify": "3.12.2"`), check `frontend/README.md` and `git log -p -S "" -- frontend/package.json` for the reason before changing it. - npm is a workspace; run `npm install --ignore-scripts --no-audit --no-fund --no-update-notifier` from the **repo root** (not `frontend/`) so the root `package-lock.json` updates. - After dep changes run `make audit`, `make build-js`, `make test-js`, and `make notice`. - Before adding a new dep — and especially before declaring an existing one "unused" — verify with `rg -nF "" frontend …` plus `npm ls --all` that no consumer or peer-dep needs it. @@ -46,7 +46,7 @@ ## Playwright MCP Usage -- Default endpoint is `http://localhost:2342/`; default login routes are `/library/login` for CE, Plus, and Pro, and `/portal/login` for Portal. +- Default endpoint is `http://localhost:2342/`; default login routes are `/library/login` for CE, Plus, and Pro, and `/portal/admin/login` for Portal. - Use the local compose admin credentials; if login fails, inspect the active compose environment. - Desktop sessions default to `1280x900`; mobile sessions should use the mobile Playwright server with `375x667`. - Close the browser tab after scripted interactions. @@ -56,4 +56,4 @@ ## Frontend Test Gotchas -- Hidden-route UI checks under `/library/hidden` or `/portal/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. +- Hidden-route UI checks under `/library/hidden` or `/portal/admin/hidden` require both `files.file_error` and `photos.photo_quality = -1`; `file_error` alone will not surface the row. diff --git a/frontend/CODEMAP.md b/frontend/CODEMAP.md index d0b079f18..1679bd78e 100644 --- a/frontend/CODEMAP.md +++ b/frontend/CODEMAP.md @@ -18,7 +18,7 @@ Directory Map (src) - `src/app.js` — app bootstrap: creates Vue app, installs Vuetify + plugins, configures router, mounts to `#app` - `src/app/routes.js` — all route definitions (guards, titles, meta) - `src/app/session.js` — `$config` and `$session` singletons wired from server-provided `window.__CONFIG__` and storage -- `src/common/*` — framework-agnostic helpers: `$api` (Axios), `$notify`, `$view`, `$event` (PubSub), i18n (`gettext`), util, fullscreen, map utils, websocket, `sphere.js` (lazy-loaded 360° viewer wrapper) +- `src/common/*` — framework-agnostic helpers: `$api` (Axios), `$notify`, `$view`, `$event` (PubSub), i18n (`gettext`), util, fullscreen, map utils, websocket - `src/component/*` — Vue components; `src/component/components.js` registers global components - `src/page/*` — route views (Albums, Photos, Places, Settings, Admin, Discover, Help, Login, etc.) - `src/model/*` — REST models; base `Rest` class (`model/rest.js`) wraps Axios CRUD for collections and entities @@ -39,7 +39,7 @@ Runtime & Plugins - **Known caveats at 3.12.2:** - Vuetify upstream issue #22828 — `v-select`'s `@blur` fires when the menu opens (introduced by the 3.12.2 screenreader navigation fix). PhotoPrism is not affected because we only bind `@blur` on `v-text-field`, `v-textarea`, and `v-combobox`; if you ever attach `@blur` to a `v-select`, expect spurious calls until that upstream bug is fixed. - The `.v-field--focused` CSS class can linger on a previously-focused `v-autocomplete` input after the user clicks into another autocomplete (`document.activeElement` is correct, but Vuetify's internal `isFocused` is under-aggressive about clearing in 3.12.2). This is the inverse symptom of Vuetify #22697 — fixing it overshot in 3.12.3 and caused #5538. Functionally harmless in the photo edit dialog because the affected fields are not on screen together. -- Router: Vue Router 4, history base at `$config.frontendUri` (default `/library` for CE/Plus/Pro and `/portal` for Portal) +- Router: Vue Router 4, history base at `$config.frontendUri` (default `/library` for CE/Plus/Pro and `/portal/admin` for Portal) - I18n: `vue3-gettext` via `common/gettext.js`; canonical extraction via root `make gettext-extract` (scans `frontend/src` plus available overlays in `plus/frontend`, `pro/frontend`, and `portal/frontend`), compile with `npm run gettext-compile` - HTML sanitization: `vue-3-sanitize` + `vue-sanitize-directive` - Tooltips: Vuetify `` component + `v-tooltip` directive (auto-imported per SFC by `webpack-plugin-vuetify`) diff --git a/frontend/Makefile b/frontend/Makefile index 6fd809cf4..d8482f7e9 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -42,33 +42,31 @@ notice: license-report --only=prod --config=.report.json > NOTICE install-npm: # Split global installs and disable package scripts for safety. - sudo npm install -g --ignore-scripts --no-audit --no-fund --no-update-notifier npm@latest - sudo npm install -g --ignore-scripts --no-audit --no-fund --no-update-notifier npm-check-updates@latest license-report@latest + sudo npm install -g --ignore-scripts --no-fund --no-audit --no-update-notifier npm@latest + sudo npm install -g --ignore-scripts --no-fund --no-audit --no-update-notifier npm-check-updates@latest license-report@latest install-testcafe: - npm install -g --ignore-scripts --no-audit --no-fund --no-update-notifier testcafe@latest + npm install -g --ignore-scripts --no-fund --no-audit --no-update-notifier testcafe@latest install-eslint: - npm install -g --ignore-scripts --no-audit --no-fund --no-update-notifier eslint globals @eslint/eslintrc @eslint/js eslint-config-prettier eslint-formatter-pretty eslint-plugin-html eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-vue eslint-webpack-plugin vue-eslint-parser prettier + npm install -g --ignore-scripts --no-fund --no-audit --no-update-notifier eslint globals @eslint/eslintrc @eslint/js eslint-config-prettier eslint-formatter-pretty eslint-plugin-html eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-vue eslint-webpack-plugin vue-eslint-parser prettier upgrade: $(info Securely upgrading NPM dependencies...) - $(DOCKER_NPM) 'npx -y npm@latest update --save --package-lock --ignore-scripts --no-audit --no-fund --no-update-notifier && npx -y npm@latest install --ignore-scripts --no-audit --no-fund --no-update-notifier' -ci: npm-ci -npm-ci: - @$(MAKE) -C .. --no-print-directory npm-ci -install: npm-install + $(DOCKER_NPM) 'npx -y npm@latest update --save --package-lock --ignore-scripts --no-fund --no-audit --no-update-notifier && npx -y npm@latest install --ignore-scripts --no-audit --no-fund --no-update-notifier' npm-install: - @$(MAKE) -C .. --no-print-directory npm-install -update: npm-update npm-install + $(info Installing NPM dependencies...) + (cd .. && npm install --save --ignore-scripts --no-audit --no-fund --no-update-notifier) +install: npm-install npm-update: - @$(MAKE) -C .. --no-print-directory npm-update -audit: npm-audit -npm-audit: - @$(MAKE) -C .. --no-print-directory npm-audit + $(info Updating NPM dependencies in package-lock.json...) + (cd .. && npm update --save --package-lock --ignore-scripts --no-audit --no-fund --no-update-notifier) +update: npm-update npm-install security-check: # Scan for missing --ignore-scripts and unsafe v-html npm run -s security:scan watch: npm run watch build: npm run build +audit: + npm audit --ignore-scripts --no-fund --no-audit --no-update-notifier lint: npm run lint || true fmt: diff --git a/frontend/NOTICE b/frontend/NOTICE index f166e1814..d119c8420 100644 --- a/frontend/NOTICE +++ b/frontend/NOTICE @@ -1,94 +1,93 @@ -Package License Copyright -------- ------- --------- -@babel/cli MIT The Babel Team (https://babel.dev/team) -@babel/core MIT The Babel Team (https://babel.dev/team) -@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) -@babel/preset-env MIT The Babel Team (https://babel.dev/team) -@babel/register MIT The Babel Team (https://babel.dev/team) -@babel/runtime MIT The Babel Team (https://babel.dev/team) -@eslint/eslintrc MIT Nicholas C. Zakas -@eslint/js MIT n/a -@mdi/font Apache-2.0 Austin Andrews -@photo-sphere-viewer/core MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr -@photo-sphere-viewer/equirectangular-video-adapter MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr -@photo-sphere-viewer/video-plugin MIT Damien 'Mistic' Sorel contact@git.strangeplanet.fr -@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) -@vitejs/plugin-vue MIT Evan You -@vitest/coverage-v8 MIT Anthony Fu -@vue/compiler-sfc MIT Evan You -@vue/language-server MIT n/a -@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com -@vvo/tzdb MIT Vincent Voyer -axios MIT Matt Zabriskie -axios-mock-adapter MIT Colin Timmermans -babel-loader MIT Luis Couto -babel-plugin-polyfill-corejs3 MIT n/a -browserslist MIT Andrey Sitnik -core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru -cross-env MIT Kent C. Dodds (https://kentcdodds.com) -css-loader MIT Tobias Koppers @sokra -cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info -eslint MIT Nicholas C. Zakas -eslint-config-prettier MIT Simon Lydell -eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -eslint-plugin-html ISC n/a -eslint-plugin-import MIT Ben Mosher -eslint-plugin-node MIT Toru Nagashima -eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) -eslint-plugin-vuetify MIT Kael Watts-Deuchar -eslint-webpack-plugin MIT Ricardo Gobbo de Souza -eventsource-polyfill MIT amvtek -file-loader MIT Tobias Koppers @sokra -file-saver MIT Eli Grey -globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com -hls.js Apache-2.0 n/a -i MIT Pavan Kumar Sunkara (pksunkara.github.com) -jsdom MIT n/a -luxon MIT Isaac Cambron -maplibre-gl BSD-3-Clause n/a -memoize-one MIT Alex Reardon -mini-css-extract-plugin MIT Tobias Koppers @sokra -minimist MIT James Halliday mail@substack.net http://substack.net -node-storage-shim ISC Michael Nahkies -passive-events-support MIT Ignas Damunskis -photoswipe MIT Dmytro Semenov (https://dimsemenov.com) -playwright Apache-2.0 Microsoft Corporation -postcss MIT Andrey Sitnik -postcss-import MIT Maxime Thirouin -postcss-loader MIT Andrey Sitnik -postcss-preset-env MIT-0 n/a -postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com -prettier MIT James Long -pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk -regenerator-runtime MIT Ben Newman -resolve-url-loader MIT bholloway -sanitize-html MIT Apostrophe Technologies, Inc. -sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 -sass-loader MIT J. Tangelder -sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com -style-loader MIT Tobias Koppers @sokra -svg-url-loader MIT Hovhannes Babayan -tar BlueOak-1.0.0 Isaac Z. Schlueter -url-loader MIT Tobias Koppers @sokra -util MIT Joyent http://www.joyent.com -vite MIT Evan You -vitest MIT Anthony Fu -vue MIT Evan You -vue-3-sanitize MIT Vannsl, Vanessa Otto -vue-loader MIT Evan You -vue-loader-plugin ISC Ivan liu -vue-luxon MIT Cas Bloem -vue-router MIT Eduardo San Martin Morote posva13@gmail.com -vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com -vue-style-loader MIT Evan You -vue3-gettext MIT Leo Zurbriggen -vuetify MIT John Leider john@vuetifyjs.com -webpack MIT Tobias Koppers @sokra -webpack-bundle-analyzer MIT Yury Grunin -webpack-cli MIT n/a -webpack-hot-middleware MIT Glen Mailer -webpack-manifest-plugin MIT Dane Thurber -webpack-md5-hash MIT Kirill Ermolov -webpack-merge MIT Juho Vepsalainen -webpack-plugin-vuetify MIT Kael Watts-Deuchar -workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team +Package License Copyright +------- ------- --------- +@babel/cli MIT The Babel Team (https://babel.dev/team) +@babel/core MIT The Babel Team (https://babel.dev/team) +@babel/plugin-transform-runtime MIT The Babel Team (https://babel.dev/team) +@babel/preset-env MIT The Babel Team (https://babel.dev/team) +@babel/register MIT The Babel Team (https://babel.dev/team) +@babel/runtime MIT The Babel Team (https://babel.dev/team) +@eslint/eslintrc MIT Nicholas C. Zakas +@eslint/js MIT n/a +@mdi/font Apache-2.0 Austin Andrews +@testing-library/jest-dom MIT Ernesto Garcia (http://gnapse.github.io) +@vitejs/plugin-vue MIT Evan You +@vitest/browser MIT n/a +@vitest/coverage-v8 MIT Anthony Fu +@vitest/ui MIT n/a +@vue/compiler-sfc MIT Evan You +@vue/language-server MIT n/a +@vue/test-utils MIT Lachlan Miller lachlan.miller.1990@outlook.com +@vvo/tzdb MIT Vincent Voyer +axios MIT Matt Zabriskie +axios-mock-adapter MIT Colin Timmermans +babel-loader MIT Luis Couto +babel-plugin-istanbul BSD-3-Clause Thai Pangsakulyanont @dtinth +babel-plugin-polyfill-corejs3 MIT n/a +browserslist MIT Andrey Sitnik +core-js MIT Denis Pushkarev zloirock@zloirock.ru http://zloirock.ru +cross-env MIT Kent C. Dodds (https://kentcdodds.com) +css-loader MIT Tobias Koppers @sokra +cssnano MIT Ben Briggs beneb.info@gmail.com http://beneb.info +eslint MIT Nicholas C. Zakas +eslint-config-prettier MIT Simon Lydell +eslint-formatter-pretty MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +eslint-plugin-html ISC n/a +eslint-plugin-import MIT Ben Mosher +eslint-plugin-node MIT Toru Nagashima +eslint-plugin-vue MIT Toru Nagashima (https://github.com/mysticatea) +eslint-plugin-vuetify MIT Kael Watts-Deuchar +eslint-webpack-plugin MIT Ricardo Gobbo de Souza +eventsource-polyfill MIT amvtek +file-loader MIT Tobias Koppers @sokra +file-saver MIT Eli Grey +globals MIT Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com +hls.js Apache-2.0 n/a +i MIT Pavan Kumar Sunkara (pksunkara.github.com) +jsdom MIT n/a +luxon MIT Isaac Cambron +maplibre-gl BSD-3-Clause n/a +memoize-one MIT Alex Reardon +mini-css-extract-plugin MIT Tobias Koppers @sokra +minimist MIT James Halliday mail@substack.net http://substack.net +node-storage-shim ISC Michael Nahkies +passive-events-support MIT Ignas Damunskis +photoswipe MIT Dmytro Semenov (https://dimsemenov.com) +playwright Apache-2.0 Microsoft Corporation +postcss MIT Andrey Sitnik +postcss-import MIT Maxime Thirouin +postcss-loader MIT Andrey Sitnik +postcss-preset-env MIT-0 n/a +postcss-reporter MIT David Clark david.dave.clark@gmail.com https://davidtheclark.com +prettier MIT James Long +pubsub-js MIT Morgan Roderick morgan@roderick.dk http://roderick.dk +regenerator-runtime MIT Ben Newman +resolve-url-loader MIT bholloway +sanitize-html MIT Apostrophe Technologies, Inc. +sass MIT Natalie Weizenbaum nweiz@google.com https://github.com/nex3 +sass-loader MIT J. Tangelder +sockette MIT Luke Edwards luke.edwards05@gmail.com lukeed.com +style-loader MIT Tobias Koppers @sokra +svg-url-loader MIT Hovhannes Babayan +tar BlueOak-1.0.0 Isaac Z. Schlueter +url-loader MIT Tobias Koppers @sokra +util MIT Joyent http://www.joyent.com +vitest MIT Anthony Fu +vue MIT Evan You +vue-3-sanitize MIT Vannsl, Vanessa Otto +vue-loader MIT Evan You +vue-loader-plugin ISC Ivan liu +vue-luxon MIT Cas Bloem +vue-router MIT Eduardo San Martin Morote posva13@gmail.com +vue-sanitize-directive MIT Leonardo Piccioni de Almeida leopiccionia@gmail.com +vue-style-loader MIT Evan You +vue3-gettext MIT Leo Zurbriggen +vuetify MIT John Leider john@vuetifyjs.com +webpack MIT Tobias Koppers @sokra +webpack-bundle-analyzer MIT Yury Grunin +webpack-cli MIT n/a +webpack-hot-middleware MIT Glen Mailer +webpack-manifest-plugin MIT Dane Thurber +webpack-md5-hash MIT Kirill Ermolov +webpack-merge MIT Juho Vepsalainen +webpack-plugin-vuetify MIT Kael Watts-Deuchar +workbox-webpack-plugin MIT Google's Web DevRel Team and Google's Aurora Team diff --git a/frontend/README.md b/frontend/README.md index 162ca835b..3ce91fbde 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -27,14 +27,14 @@ Other frontend documentation lives next to this file: ## Dependency Pinning Policy -**Pins are intentional.** When a version is locked without a caret (e.g., `"axios": "1.18.1"`), it is intentional. Before adjusting any pin, check the table below, the inline `//` comments at the top of `package.json`, and the git log (`git log -p -- frontend/package.json | grep -B2 -A4 ""`). +**Pins are intentional.** When a version is locked without a caret (e.g., `"axios": "1.16.1"`), it is intentional. Before adjusting any pin, check the table below, the inline `//` comments at the top of `package.json`, and the git log (`git log -p -- frontend/package.json | grep -B2 -A4 ""`). ### Currently Pinned Packages -| Package | Pin | Reason | -|-----------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `vuetify` | `3.12.2` | 3.12.3+ added an `onFocusout` handler to `VAutocomplete`/`VSelect`/`VCombobox` that closes long autocomplete/select dropdowns on open (#5538). Still unfixed in 3.12.5; upstream development moved to v4. See the long `//vuetify` comment in `package.json` and `frontend/CODEMAP.md` for retest steps. | -| `axios` | `1.18.1` | High-risk package. Originally pinned to `1.14.0` after the March 2026 supply-chain compromise (malicious `1.14.1`/`0.30.4` from a hijacked maintainer account). Quarantine was unwound on 2026-04-27 once OSV-Scanner came back clean; bumped to `1.17.0` on 2026-06-10, then to `1.18.1` on 2026-06-22 (security-hardening minor: strips caller-supplied sensitive headers on cross-origin redirects, rejects malformed http/https URLs, tightens prototype-pollution defenses; no breaking changes; OSV-Scanner clean). Keep an exact pin (no caret) per industry guidance for high-risk packages. | +| Package | Pin | Reason | +|-----------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `vuetify` | `3.12.2` | 3.12.3+ added an `onFocusout` handler to `VAutocomplete`/`VSelect`/`VCombobox` that closes long autocomplete/select dropdowns on open (#5538). Still unfixed in 3.12.5; upstream development moved to v4. See the long `//vuetify` comment in `package.json` and `frontend/CODEMAP.md` for retest steps. | +| `axios` | `1.16.1` | High-risk package. Originally pinned to `1.14.0` after the March 2026 supply-chain compromise (malicious `1.14.1`/`0.30.4` from a hijacked maintainer account). Quarantine was unwound on 2026-04-27 once OSV-Scanner came back clean. Keep an exact pin (no caret) per industry guidance for high-risk packages. | ### Override Layer (Transitive Pins) @@ -48,49 +48,14 @@ When an upstream advisory is fully resolved, retire the override and rerun `make ## Major-Version Upgrades — Known Blockers -Some major upgrades are blocked by config-file module style (the configs referenced below are CommonJS today and need an ESM migration first) or by a bundler-level incompatibility in the package itself. Track each as its own change: +Some major upgrades are blocked by config-file module style. The configs referenced below are CommonJS today; an ESM migration is required before bumping these. Track each as its own change: -| Package | Latest | Blocker | -|-------------------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `postcss-preset-env` 11.x | ESM | `frontend/postcss.config.js` is CommonJS (`module.exports = { plugins: [require("postcss-preset-env"), ...] }`). | -| `webpack-manifest-plugin` 6.x | ESM | `frontend/webpack.config.js` is CommonJS (`require("webpack-manifest-plugin")`). Webpack accepts ESM configs, but the migration is non-trivial. | -| `vue3-gettext` 4.x | ESM | v4 is ESM-only and exports its extraction tooling from the same runtime entry: `dist/index.js` does an unconditional `import PO from "pofile"`, and `pofile` calls `require("fs")`. The `exports` map has no runtime-only subpath and the package sets no `sideEffects: false`, so webpack cannot tree-shake it — `make build-js` fails with `Can't resolve 'fs'` in `pofile/lib/po.js`. The runtime API itself (`createGettext({ translations, silent, defaultLanguage })`, the `$gettext`/`$ngettext`/`$pgettext`/`$npgettext` globals, `%{}` interpolation) is compatible and the removed `` component / `v-translate` directive are unused here, so the only fix needed is a bundler workaround (e.g. `resolve.fallback: { fs: false }`, which ships dead extraction code), an upstream split of runtime vs. tooling exports, or a [migration to Vite](#migrating-the-production-build-from-webpack-to-vite) (Rollup externalizes `fs` instead of failing). | -| `vuetify` 4.x | — | See the `vuetify` row in [Currently Pinned Packages](#currently-pinned-packages); also a separate v3 → v4 migration project. | -| `vue-router` 5.x | — | Major release with breaking changes across `frontend/src/app/routes.js` and dynamic imports. Needs its own evaluation pass with TestCafe verification. | - -## Migrating the Production Build From webpack to Vite - -**Status: not started — tracked in #5679.** The production bundle is built with webpack (`frontend/webpack.config.js`, run via `make build-js`); Vitest already runs on Vite (`frontend/vitest.config.js`), so a production migration would converge the two toolchains. This is its own project (related: #5659 test-side Vite v8, and the historical #838). It is *not* a prerequisite for any single dependency bump; treat the ESM-only unblock (e.g. `vue3-gettext` 4.x) as a side benefit, not the reason. - -**Why it helps the ESM-only blockers.** Vite/Rollup externalize Node built-ins for the browser — a `fs` import resolves to a stub that only throws if actually called at runtime — instead of failing the build the way webpack 5 does. Verified locally: a minimal Vite build of `vue3-gettext` 4's `createGettext` succeeds with a `Module "fs" has been externalized` warning. Caveat: Vite does **not** tree-shake the dead extraction tooling either (the package sets no `sideEffects: false`), so the runtime bundle still carries the `pofile`/parser code — migrate for the modernization, not as a bundle slimmer. - -**The contract that must not break.** The Go server reads a **flat** asset manifest: `internal/config/client_assets.go` (`ClientAssets`) unmarshals `assets/static/build/assets.json` keyed by logical name — `app.js`, `app.css`, `share.js`, `share.css`, `splash.js`, `splash.css`, plus named font/image entries (`MaterialIcons-Regular.*`, `default-skin.svg`, `preloader.gif`, …). That shape is `webpack-manifest-plugin`'s output. Vite's default `.vite/manifest.json` is keyed by **source path** with nested objects and is not interchangeable, so the migration must either emit the flat `assets.json` from a small post-build step or teach `ClientAssets.Load` the Vite shape. All editions (`plus`/`pro`/`portal`) read the same struct, so whatever shape is chosen must hold for every edition build. - -**Feature-by-feature mapping** (from `webpack.config.js`): - -| webpack today | Vite equivalent | -|-------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------| -| 3 entries `app`/`share`/`splash` | `build.rollupOptions.input` (3 inputs) | -| `output` → `../assets/static/build`, `[name].[contenthash].js`, `clean` | `build.outDir` + `emptyOutDir` + `entryFileNames`/`chunkFileNames`/`assetFileNames` with `[name].[hash]` | -| flat `assets.json` via `webpack-manifest-plugin` | `build.manifest` + post-build transform to the flat shape (see contract above) | -| `resolve.modules: [src]` + `preferRelative` | reuse the `resolve.alias` map already in `vitest.config.js` | -| `vue-loader`, `vue$` runtime alias, `whitespace: "preserve"` | `@vitejs/plugin-vue` (already a dep) + alias + `template.compilerOptions` | -| `webpack-plugin-vuetify` (auto-import) | `vite-plugin-vuetify` *(new dep)* | -| `babel-loader` + `@babel/preset-env` + `core-js` (browserslist Safari 13 / iOS 13) | `@vitejs/plugin-legacy` *(new dep; reads browserslist)* — esbuild alone won't downlevel to the iOS 13 baseline | -| `workbox-webpack-plugin` `GenerateSW` (`sw.js`, `importScripts` `sw-scope-cleanup.js`, `modifyURLPrefix: static/build/`, exclusions, 5 MiB cap) | `vite-plugin-pwa` *(new dep; workbox under the hood)* with the same options | -| CSS/PostCSS/Sass loader stack (`mini-css-extract-plugin`, `css-loader`, `postcss-loader`, `resolve-url-loader`, `sass-loader`) | Vite native CSS (reads `postcss.config.js`; keep the `sass` dep) | -| `DefinePlugin` Vue flags (`__VUE_OPTIONS_API__`, `__VUE_PROD_DEVTOOLS__`, `__VUE_PROD_HYDRATION_MISMATCH_DETAILS__`) | Vite `define` | -| `EmitStaticFilePlugin` (copies `sw-scope-cleanup.js`) | `publicDir` or a small emit plugin | -| `hls.js` → `hls.light.min.js` alias | same `resolve.alias` entry | -| png/jpg/svg/font `asset/resource` | Vite asset pipeline — confirm the named manifest entries still land in `assets.json` | -| `CUSTOM_SRC`/`CUSTOM_NAME` edition overlay | env-driven `resolve.alias`/input | -| `webpack-bundle-analyzer` (`BUILD_ENV=analyze`) | `rollup-plugin-visualizer` | -| `make watch-js` (`webpack --watch`) | `vite build --watch` — **not** the dev server; Go serves the embedded build output, so HMR isn't wired into the templates | -| `postbuild` `scripts/precompress.js` | unchanged; it operates on the output dir, not the bundler | - -**Dependency churn.** Retire `webpack`, `webpack-cli`, `webpack-manifest-plugin`, `webpack-plugin-vuetify`, `workbox-webpack-plugin`, `eslint-webpack-plugin`, `webpack-bundle-analyzer`, `vue-loader`, and the loader stack (`babel-loader`, `css-loader`, `postcss-loader`, `resolve-url-loader`, `mini-css-extract-plugin`, `vue-style-loader`, `file-loader`, `url-loader`, `svg-url-loader`). Add `vite-plugin-vuetify`, `@vitejs/plugin-legacy`, `vite-plugin-pwa`, and `rollup-plugin-visualizer` (`vite` and `@vitejs/plugin-vue` are already deps). Then `make audit` and `make notice`. - -**Validation.** `make build-js` emits `assets/static/build/assets.json` in the flat shape and the Go server renders the app/share/splash entrypoints without `cannot read assets.json`; `sw.js` is generated and the precompressed `.gz`/`.zst` siblings appear; smoke-test the Safari 13 / iOS 13 baseline; the `plus`/`pro`/`portal` edition builds still produce valid manifests; finally `make test-js` and the acceptance suite. +| Package | Latest | Blocker | +|-------------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------| +| `postcss-preset-env` 11.x | ESM | `frontend/postcss.config.js` is CommonJS (`module.exports = { plugins: [require("postcss-preset-env"), ...] }`). | +| `webpack-manifest-plugin` 6.x | ESM | `frontend/webpack.config.js` is CommonJS (`require("webpack-manifest-plugin")`). Webpack accepts ESM configs, but the migration is non-trivial. | +| `vuetify` 4.x | — | See the `vuetify` row in [Currently Pinned Packages](#currently-pinned-packages); also a separate v3 → v4 migration project. | +| `vue-router` 5.x | — | Major release with breaking changes across `frontend/src/app/routes.js` and dynamic imports. Needs its own evaluation pass with TestCafe verification. | ## Auditing for Orphaned Dependencies diff --git a/frontend/karma.conf.js b/frontend/karma.conf.js new file mode 100644 index 000000000..219f5be5e --- /dev/null +++ b/frontend/karma.conf.js @@ -0,0 +1,164 @@ +/* + +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. + + This program is free software: you can redistribute it and/or modify + it under Version 3 of the GNU Affero General Public License (the "AGPL"): + + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + The AGPL is supplemented by our Trademark and Brand Guidelines, + which describe how our Brand Assets may be used: + + +Feel free to send an email to hello@photoprism.app if you have questions, +want to support our work, or just want to say hello. + +Additional information can be found in our Developer Guide: + + +*/ + +const path = require("path"); +const findChrome = require("chrome-finder"); +const chromeBin = findChrome(); + +if (chromeBin) { + // proceed, chrome/chromium was found + process.env.CHROME_BIN = chromeBin; + console.log(`chrome-bin: ${chromeBin}`); +} else { + // abort, no chrome binary was found + console.error("Chrome/Chromium not found."); + process.exit(1); +} + +// test setup +module.exports = (config) => { + config.set({ + logLevel: config.LOG_ERROR, + webpackMiddleware: { + stats: "errors-only", + }, + + frameworks: ["mocha"], + + browsers: ["LocalChrome"], + + customLaunchers: { + LocalChrome: { + base: "ChromeHeadless", + flags: ["--disable-translate", "--disable-extensions", "--no-sandbox", "--disable-web-security", "--disable-dev-shm-usage"], + }, + }, + + files: [{ pattern: "tests/unit/**/*_test.js", watched: false }], + + // Preprocess through webpack + preprocessors: { + "tests/unit/**/*_test.js": ["webpack"], + }, + + reporters: ["progress", "coverage-istanbul", "html"], + + htmlReporter: { + outputFile: "tests/unit.html", + }, + + coverageIstanbulReporter: { + // reports can be any that are listed here: https://github.com/istanbuljs/istanbuljs/tree/aae256fb8b9a3d19414dcf069c592e88712c32c6/packages/istanbul-reports/lib + "reports": ["lcov", "text-summary"], + + // base output directory. If you include %browser% in the path it will be replaced with the karma browser name + "dir": path.join(__dirname, "coverage"), + + // Combines coverage information from multiple browsers into one report rather than outputting a report + // for each browser. + "combineBrowserReports": true, + + // if using webpack and pre-loaders, work around webpack breaking the source path + "fixWebpackSourcePaths": true, + + // Omit files with no statements, no functions and no branches from the report + "skipFilesWithNoCoverage": true, + + // Most reporters accept additional config options. You can pass these through the `report-config` option + "report-config": { + // all options available at: https://github.com/istanbuljs/istanbuljs/blob/aae256fb8b9a3d19414dcf069c592e88712c32c6/packages/istanbul-reports/lib/html/index.js#L135-L137 + html: { + // outputs the report in ./coverage/html + subdir: "html", + }, + }, + + // enforce percentage thresholds + // anything under these percentages will cause karma to fail with an exit code of 1 if not running in watch mode + "thresholds": { + emitWarning: true, // set to `true` to not fail the test command when thresholds are not met + // thresholds for all files + global: { + //statements: 90, + lines: 90, + //branches: 90, + //functions: 90, + }, + // thresholds per file + each: { + //statements: 90, + lines: 90, + //branches: 90, + //functions: 90, + overrides: { + "src/common/viewer.js": { + lines: 0, + functions: 0, + }, + }, + }, + }, + + "verbose": true, // output config used by istanbul for debugging + }, + + webpack: { + mode: "development", + resolve: { + fallback: { + util: require.resolve("util"), + }, + modules: [path.join(__dirname, "src"), path.join(__dirname, "node_modules"), path.join(__dirname, "tests/unit")], + preferRelative: true, + alias: { + vue$: "vue/dist/vue.runtime.esm-bundler.js", + }, + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: (file) => /node_modules/.test(file), + use: [ + { + loader: "babel-loader", + options: { + compact: false, + presets: ["@babel/preset-env"], + plugins: ["@babel/plugin-transform-runtime", ["istanbul", { exclude: ["**/*_test.js"] }]], + }, + }, + ], + }, + ], + }, + }, + + singleRun: true, + }); + + // Set default timezone. + process.env.TZ = "UTC"; +}; diff --git a/frontend/package.json b/frontend/package.json index 9007206e1..43065c0ff 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -38,30 +38,30 @@ ">0.25% and last 2 years" ], "dependencies": { - "@babel/cli": "^7.29.7", - "@babel/core": "^7.29.7", - "@babel/plugin-transform-runtime": "^7.29.7", - "@babel/preset-env": "^7.29.7", - "@babel/register": "^7.29.7", - "@babel/runtime": "^7.29.7", + "@babel/cli": "^7.28.6", + "@babel/core": "^7.29.0", + "@babel/plugin-transform-runtime": "^7.29.0", + "@babel/preset-env": "^7.29.5", + "@babel/register": "^7.29.3", + "@babel/runtime": "^7.29.2", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "^9.33.0", "@mdi/font": "^7.4.47", - "@photo-sphere-viewer/core": "^5.14.3", - "@photo-sphere-viewer/equirectangular-video-adapter": "^5.14.3", - "@photo-sphere-viewer/video-plugin": "^5.14.3", "@testing-library/jest-dom": "^6.9.1", "@vitejs/plugin-vue": "^6.0.7", - "@vitest/coverage-v8": "^4.1.10", - "@vue/compiler-sfc": "^3.5.39", - "@vue/language-server": "^3.3.6", - "@vue/test-utils": "^2.4.11", + "@vitest/browser": "^3.2.4", + "@vitest/coverage-v8": "^3.2.4", + "@vitest/ui": "^3.2.4", + "@vue/compiler-sfc": "^3.5.34", + "@vue/language-server": "^3.3.1", + "@vue/test-utils": "^2.4.10", "@vvo/tzdb": "^6.198.0", - "axios": "1.18.1", + "axios": "1.16.1", "axios-mock-adapter": "^2.1.0", "babel-loader": "^10.1.1", + "babel-plugin-istanbul": "^7.0.1", "babel-plugin-polyfill-corejs3": "^0.14.2", - "browserslist": "^4.28.5", + "browserslist": "^4.28.2", "core-js": "^3.49.0", "cross-env": "^10.1.0", "css-loader": "^7.1.4", @@ -72,13 +72,13 @@ "eslint-plugin-html": "^8.1.4", "eslint-plugin-import": "^2.32.0", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-vue": "^10.9.2", + "eslint-plugin-vue": "^10.9.1", "eslint-plugin-vuetify": "^2.7.2", "eslint-webpack-plugin": "^5.0.3", "eventsource-polyfill": "^0.9.6", "file-loader": "^6.2.0", "file-saver": "^2.0.5", - "globals": "^17.7.0", + "globals": "^17.6.0", "hls.js": "^1.6.16", "i": "^0.3.7", "jsdom": "^29.1.1", @@ -90,28 +90,27 @@ "node-storage-shim": "^2.0.1", "passive-events-support": "^1.1.0", "photoswipe": "^5.4.4", - "playwright": "^1.61.1", - "postcss": "^8.5.16", + "playwright": "^1.60.0", + "postcss": "^8.5.15", "postcss-import": "^16.1.1", "postcss-loader": "^8.2.1", "postcss-preset-env": "^10.6.1", "postcss-reporter": "^7.1.0", - "prettier": "^3.9.3", + "prettier": "^3.8.3", "pubsub-js": "^1.9.5", "regenerator-runtime": "^0.14.1", "resolve-url-loader": "^5.0.0", - "sanitize-html": "^2.17.5", - "sass": "^1.101.0", + "sanitize-html": "^2.17.4", + "sass": "^1.99.0", "sass-loader": "^16.0.8", "sockette": "^2.0.6", "style-loader": "^4.0.0", - "svg-url-loader": "^8.1.0", - "tar": "^7.5.19", + "svg-url-loader": "^8.0.0", + "tar": "^7.5.15", "url-loader": "^4.1.1", "util": "^0.12.5", - "vite": "^8.1.3", - "vitest": "^4.1.10", - "vue": "^3.5.39", + "vitest": "^3.2.4", + "vue": "^3.5.34", "vue-3-sanitize": "^0.1.4", "vue-loader": "^17.4.2", "vue-loader-plugin": "^1.3.0", @@ -121,7 +120,7 @@ "vue-style-loader": "^4.1.3", "vue3-gettext": "^2.4.0", "vuetify": "3.12.2", - "webpack": "5.107.2", + "webpack": "^5.107.0", "webpack-bundle-analyzer": "^5.3.0", "webpack-cli": "^6.0.1", "webpack-hot-middleware": "^2.26.1", diff --git a/frontend/src/app.js b/frontend/src/app.js index 372074ded..c2629c579 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/app/routes.js b/frontend/src/app/routes.js index fdc0a1ec2..3ffef3b85 100644 --- a/frontend/src/app/routes.js +++ b/frontend/src/app/routes.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -33,11 +33,9 @@ import Labels from "page/labels.vue"; import People from "page/people.vue"; import Library from "page/library.vue"; import Settings from "page/settings.vue"; -import Services from "page/services.vue"; import Admin from "page/admin.vue"; import Cluster from "page/cluster.vue"; import Login from "page/auth/login.vue"; -import Instances from "page/auth/instances.vue"; import Discover from "page/discover.vue"; import About from "page/about/about.vue"; import License from "page/about/license.vue"; @@ -50,38 +48,6 @@ const c = window.__CONFIG__; const siteTitle = c.siteTitle ? c.siteTitle : c.name; const loginRoute = "login"; -// safeReturnTo validates the `return_to` query parameter so callers can route -// the user back to a same-origin destination without enabling an open-redirect -// vector. Accepts root-relative paths or absolute URLs whose origin matches -// the browser's; rejects protocol-relative URLs and cross-origin absolutes. -export function safeReturnTo(value) { - if (!value || typeof value !== "string") { - return ""; - } - const trimmed = value.trim(); - if (!trimmed) { - return ""; - } - // Protocol-relative URLs (//evil.example) and backslash-prefixed paths - // (\\evil.example) can be misparsed by old browsers — reject up front. - if (trimmed.startsWith("//") || trimmed.startsWith("\\")) { - return ""; - } - if (trimmed.startsWith("/")) { - return trimmed; - } - try { - const here = typeof window !== "undefined" ? window.location?.origin : ""; - const parsed = new URL(trimmed, here || "http://localhost/"); - if (here && parsed.origin === here) { - return parsed.pathname + parsed.search + parsed.hash; - } - } catch { - // Fall through to reject. - } - return ""; -} - export default [ { name: "home", @@ -114,34 +80,18 @@ export default [ component: Login, meta: { title: siteTitle, requiresAuth: false, hideNav: true }, beforeEnter: (to, from, next) => { - // Honor an inbound `return_to` query param so cross-frontend hand-offs - // (e.g. the Portal OIDC OP redirecting an unauthenticated user from - // /api/v1/oauth/authorize) can land back on the originally-requested URL - // after a successful login. The value is recorded the same way the - // global router guard records internal deep links, so the rest of - // the flow (followLoginRedirectUrl on success) needs no further - // changes. - const returnTo = safeReturnTo(to.query?.return_to); - if (returnTo) { - $session.setLoginRedirectUrl(returnTo); - } - if ($session.loginRequired()) { - // Auto-OIDC fires only for deep-link arrivals (loginRedirectUrl set - // by the global router guard), and only once per browser tab: a prior - // attempt flag set on the way out clears here so a failed/abandoned - // IdP roundtrip falls back to the local form instead of looping. + // Auto-OIDC fires only for deep-link arrivals — the global router + // guard records the originally-requested URL via + // setLoginRedirectUrl() before sending the user here. A direct + // visit to /library/login leaves hasLoginRedirectUrl() false so + // the form stays visible and local/LDAP/AD credentials still work, + // even when PHOTOPRISM_OIDC_REDIRECT is enabled (the flag opts + // deep links into IdP SSO, it does not make OIDC the only path). + // The one-shot logout signal suppresses one auto-bounce so users + // can re-authenticate locally immediately after signing out. const oidc = $config.values?.ext?.oidc; - const oidcInFlight = $session.consumeOidcAttempt(); - if ( - oidc?.enabled && - oidc?.redirect && - oidc?.loginUri && - $session.hasLoginRedirectUrl() && - !$session.consumeLogoutSignal() && - !oidcInFlight - ) { - $session.markOidcAttempt(); + if (oidc?.enabled && oidc?.redirect && oidc?.loginUri && $session.hasLoginRedirectUrl() && !$session.consumeLogoutSignal()) { $session.followRedirect(oidc.loginUri); next(false); return; @@ -153,18 +103,8 @@ export default [ // hard-navigate to the deep link the router guard recorded so the // stored absolute path (incl. frontend base) is honored verbatim. if ($session.hasLoginRedirectUrl()) { - if ($session.loginRedirectLooping()) { - // We followed this redirect moments ago and bounced straight back — the - // target couldn't authenticate the navigation. Drop it and fall through - // to the default route instead of looping. - $session.clearLoginRedirectAttempt(); - $session.clearLoginRedirectUrl(); - next({ name: $session.getDefaultRoute() }); - } else { - $session.markLoginRedirectAttempt(); - $session.followLoginRedirectUrl(); - next(false); - } + $session.followLoginRedirectUrl(); + next(false); } else { next({ name: $session.getDefaultRoute() }); } @@ -175,35 +115,11 @@ export default [ path: "/logout", meta: { title: siteTitle, requiresAuth: false, hideNav: true }, beforeEnter: (to, from, next) => { - // Resolve the session kind and landing before sign-out clears the provider: - // a cluster-OIDC user returns to the Portal login (or the local form when the - // Portal login URL is unknown), everyone else to the local form. The cluster - // decision must not depend on the redirect target, or a node without a - // persisted Portal login URL would silently skip the cluster-wide sign-out. - const isClusterSession = $session.isClusterSession(); - // RP-initiated logout (OIDC + PHOTOPRISM_OIDC_LOGOUT) returns a provider logout URL - // that must be followed AFTER the async DELETE resolves; an OIDC node that is not a - // cluster session still needs this so direct /logout entry ends the upstream session, - // matching the nav-menu Sign-Out. - const rpInitiated = $session.getProvider() === "oidc" && $config.oidcLogout(); - const redirectUri = $session.logoutRedirectUri(); - if (isClusterSession || rpInitiated) { - // Await the cluster-wide sign-out (peer fan-out + Portal OP cookie clear) BEFORE - // redirecting; logoutEverywhere resolves to the provider logout URL when present (it - // ends the upstream session), else fall back to the local landing. A standalone OIDC - // node has no peers, so the fan-out is a no-op and only the RP-logout follow applies. - next(false); - $session - .logoutEverywhere(true) - .then((uri) => $session.followRedirect(uri || redirectUri)) - .catch(() => $session.followRedirect(redirectUri)); - } else { - // Local: signOut() resets client state synchronously so /login sees an - // unauthenticated user; the one-shot logout flag suppresses the next auto-OIDC - // bounce, and the DELETE fan-out (current + peers) runs best-effort. - $session.signOut(); - next({ name: loginRoute }); - } + // signOut() resets client state synchronously so /login sees an + // unauthenticated user; the one-shot logout flag suppresses the next + // auto-OIDC bounce. Server DELETE runs best-effort in the background. + $session.signOut(); + next({ name: loginRoute }); }, }, { @@ -239,33 +155,8 @@ export default [ beforeEnter: (to, from, next) => { if ($session.loginRequired()) { next({ name: loginRoute }); - } else { - // Any logged-in user may enter /cluster — the page filters which - // tabs are visible based on per-resource grants (Nodes / Activity - // gate on `cluster.access_all` and `cluster.audit`; the My - // Instances chooser is visible to everyone). When no tabs remain, - // cluster.vue redirects to the user's default route in `created()`. - next(); - } - }, - }, - { - name: "instances", - path: "/instances", - component: Instances, - meta: { - title: $gettext("Instances"), - requiresAuth: true, - hideNav: true, - settings: false, - background: "background", - }, - beforeEnter: (to, from, next) => { - // The instance selector is the durable landing page for non-operators; - // any signed-in user may enter, and unauthenticated requests fall through - // to login (the global guard records the return_to deep link). - if ($session.loginRequired()) { - next({ name: loginRoute }); + } else if ($config.deny("cluster", "access_all")) { + next({ name: $session.getDefaultRoute() }); } else { next(); } @@ -677,19 +568,6 @@ export default [ }, props: { tab: "settings_content" }, }, - { - name: "settings_collections", - path: "/settings/collections", - component: Settings, - meta: { - title: $gettext("Settings"), - requiresAuth: true, - admin: true, - settings: true, - background: "background", - }, - props: { tab: "settings_collections" }, - }, { name: "settings_media", path: "/settings/media", @@ -711,7 +589,7 @@ export default [ { name: "settings_services", path: "/settings/services", - component: Services, + component: Settings, meta: { title: $gettext("Settings"), requiresAuth: true, @@ -719,15 +597,7 @@ export default [ settings: true, background: "background", }, - beforeEnter: (to, from, next) => { - if ($session.loginRequired()) { - next({ name: loginRoute }); - } else if (!$config.feature("services") || $config.deny("services", "manage")) { - next({ name: $session.getDefaultRoute() }); - } else { - next(); - } - }, + props: { tab: "settings_services" }, }, { name: "settings_account", diff --git a/frontend/src/common/README.md b/frontend/src/common/README.md index 1ff1ddad1..a38b8a38a 100644 --- a/frontend/src/common/README.md +++ b/frontend/src/common/README.md @@ -27,7 +27,6 @@ When integrating third-party clients such as native mobile apps that embed the P - In the standard login UI, this preference is exposed through the `Stay signed in on this device` toggle. Checked means persistent namespaced `localStorage`; unchecked means ephemeral namespaced `sessionStorage`. - The login page initializes that toggle from the current session storage mode when available, and otherwise falls back to the stored namespaced `session` preference flag. - Logout and session reset clear the current app namespace from both `localStorage` and `sessionStorage`, and also remove deprecated raw legacy auth keys from both stores, without touching other namespaced instances on the same origin. -- When `PHOTOPRISM_OIDC_LOGOUT` is enabled, `DELETE /api/v1/session` returns a `providerLogoutUri`; `logout()` passes it to `onLogout()`, which redirects the browser to the provider's end-session endpoint (RP-initiated logout) instead of the local login page, so the provider's SSO session is ended too. `onLogout()` also resolves to that landing URL, so callers that pass `noRedirect` and navigate themselves — the `/logout` route guard and the Portal instance-chooser Sign-Out — follow the same provider URL rather than discarding it. Without the flag, sign-out lands on the local/Portal login page as before. - Regression tests for session restore should exercise both preferred `sessionStorage` and a real `Config`-shaped object so namespace resolution bugs cannot silently fall back to `pp:root:`. Preferred integration contract for new native or web view clients: diff --git a/frontend/src/common/api.js b/frontend/src/common/api.js index 53bdd1b20..c7a69c341 100644 --- a/frontend/src/common/api.js +++ b/frontend/src/common/api.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -25,7 +25,7 @@ Additional information can be found in our Developer Guide: import Axios from "axios"; import $notify from "common/notify"; -import { $gettext, Tp } from "common/gettext"; +import { $gettext } from "common/gettext"; import $event from "common/event"; import { getAppStorage } from "common/storage"; @@ -111,10 +111,7 @@ $api.interceptors.response.use( code = data.code; } - if (data.messageId) { - // Render the backend message in the current UI locale from its source id and params. - errorMessage = Tp(data.messageId, data.messageParams); - } else if (data.message) { + if (data.message) { errorMessage = data.message; } else if (data.error) { errorMessage = data.error; diff --git a/frontend/src/common/can.js b/frontend/src/common/can.js index 184c54733..4e8a7696e 100644 --- a/frontend/src/common/can.js +++ b/frontend/src/common/can.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/clipboard.js b/frontend/src/common/clipboard.js index bac2cd90e..61bacda95 100644 --- a/frontend/src/common/clipboard.js +++ b/frontend/src/common/clipboard.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/config.js b/frontend/src/common/config.js index 51666d88d..19ebd85ae 100644 --- a/frontend/src/common/config.js +++ b/frontend/src/common/config.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -24,13 +24,12 @@ Additional information can be found in our Developer Guide: */ import $api from "common/api"; -import $event from "common/event"; +import $event, { ACTION_CREATED, ACTION_UPDATED, ACTION_DELETED } from "common/event"; import * as themes from "options/themes"; import * as options from "options/options"; import { Photo } from "model/photo"; import { onInit, onSetTheme } from "common/hooks"; import { ref, reactive } from "vue"; -import memoizeOne from "memoize-one"; onInit(); @@ -48,9 +47,6 @@ const frontendLoginUri = (frontendUri) => { return `${frontendUri.replace(/\/+$/, "")}/login`; }; -// schemeUriRegExp matches a leading URI scheme ("https:", "data:") so absolute references are left untouched. -const schemeUriRegExp = /^[a-z][a-z0-9+.-]*:/i; - export default class Config { /** * @param {Storage} storage @@ -143,14 +139,13 @@ export default class Config { $event.subscribe("config.updated", (ev, data) => this.setValues(data.config)); $event.subscribe("config.tokens", (ev, data) => this.setTokens(data)); $event.subscribe("count", (ev, data) => this.onCount(ev, data)); + $event.subscribe("people", (ev, data) => this.onPeople(ev, data)); if (this.has("settings")) { this.setTheme(this.get("settings").ui.theme); } else { this.setTheme("default"); } - - this.setReduceMotion(this.getSettings()?.ui.reduceMotion); } loading() { @@ -211,7 +206,6 @@ export default class Config { this.setBatchSize(values.settings); await this.setLanguage(this.getLanguageLocale(), true); this.setTheme(values.settings.ui.theme); - this.setReduceMotion(values.settings.ui.reduceMotion); } // Adjust album counts by access level. @@ -236,6 +230,72 @@ export default class Config { } } + onPeople(ev, data) { + const type = ev.split(".")[1]; + + if (this.debug) { + console.log(ev, data); + } + + if (!this.values.people) { + this.values.people = []; + } + + if (!data || !data.entities || !Array.isArray(data.entities)) { + return; + } + + switch (type) { + case ACTION_CREATED: + this.values.people.unshift(...data.entities); + break; + case ACTION_UPDATED: + for (let i = 0; i < data.entities.length; i++) { + const values = data.entities[i]; + + this.values.people + .filter((m) => m.UID === values.UID) + .forEach((m) => { + for (let key in values) { + if (key !== "UID" && values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") { + m[key] = values[key]; + } + } + }); + } + break; + case ACTION_DELETED: + for (let i = 0; i < data.entities.length; i++) { + const index = this.values.people.findIndex((m) => m.UID === data.entities[i]); + + if (index >= 0) { + this.values.people.splice(index, 1); + } + } + break; + } + } + + // getPerson returns the details of a person by name + // (case-insensitive), or null if it does not exist. + getPerson(name) { + name = name.toLowerCase(); + + const result = this.values.people.filter((m) => m.Name.toLowerCase() === name); + const l = result ? result.length : 0; + + if (l === 0) { + return null; + } else if (l === 1) { + return result[0]; + } else { + if (this.debug) { + console.warn("more than one person having the same name", result); + } + return result[0]; + } + } + // onCount updates the media type, location, people and other // counters used e.g. in the expanded sidebar navigation. onCount(ev, data) { @@ -594,16 +654,6 @@ export default class Config { } } - // setReduceMotion toggles the "reduce-motion" class on the element so CSS can - // suppress interface animations and transitions when the accessibility setting is enabled. - setReduceMotion(enabled) { - if (document && document.documentElement) { - document.documentElement.classList.toggle("reduce-motion", !!enabled); - } - - return this; - } - // getSettings returns the current user's configuration settings. getSettings() { return this.values.settings; @@ -625,7 +675,6 @@ export default class Config { this.setBatchSize(settings); this.setLanguage(settings.ui.language, false); this.setTheme(settings.ui.theme); - this.setReduceMotion(settings.ui.reduceMotion); return this; } @@ -747,24 +796,9 @@ export default class Config { return this.values.settings.features[name] === true; } - // featAppPasswords checks if app passwords (app-specific passwords) are enabled. - featAppPasswords() { - return this.feature("appPasswords"); - } - // filesQuotaReached returns true if the filesystem quota is reached or exceeded. filesQuotaReached() { - return Boolean(this.values?.usage?.filesUsedPct >= 100); - } - - // storageLow returns true if the storage folder is almost full. - storageLow() { - return Boolean(this.values?.usage?.storageLow); - } - - // insufficientStorage returns true if the filesystem quota is reached or the storage folder is almost full. - insufficientStorage() { - return this.storageLow() || this.filesQuotaReached(); + return this.values?.usage?.filesUsedPct >= 100; } // setTokens sets the security tokens required to load thumbnails and download files from the server. @@ -820,36 +854,6 @@ export default class Config { return !!this.values?.portal; } - // isClusterOidc returns true when the OIDC provider is the cluster Portal (not an external IdP). - isClusterOidc() { - return !!this.values?.ext?.oidc?.cluster; - } - - // oidcEnabled returns true when OIDC single sign-on is configured. - oidcEnabled() { - return !!this.values?.ext?.oidc?.enabled; - } - - // ldapEnabled returns true when LDAP/AD directory authentication is configured. - ldapEnabled() { - return !!this.values?.ext?.ldap?.enabled; - } - - // oidcLoginUri returns the OIDC login endpoint that starts the provider roundtrip, or "" when off. - oidcLoginUri() { - return this.values?.ext?.oidc?.loginUri || ""; - } - - // oidcLogout returns true when sign-out should perform RP-initiated logout against the provider. - oidcLogout() { - return !!this.values?.ext?.oidc?.logout; - } - - // portalLoginUri returns the cluster Portal's browser-facing login page, or "" when unknown. - portalLoginUri() { - return this.values?.ext?.oidc?.portalLoginUri || ""; - } - // isPro returns true if this is team version. isPro() { return !!this.values?.ext["pro"]; @@ -929,36 +933,15 @@ export default class Config { return s; } - // themeAssetUri resolves a theme asset reference against the base URI (e.g. - // "logo.svg" → "{baseUri}/_theme/logo.svg"); memoized since the base URI is - // fixed once the config is loaded. - themeAssetUri = memoizeOne((uri) => { - if (typeof uri !== "string" || uri === "") { - return uri; - } else if (schemeUriRegExp.test(uri) || uri.startsWith("//")) { - return uri; // absolute, data:/blob:, or protocol-relative - } else if (!uri.startsWith("/")) { - return `${this.baseUri || ""}/_theme/${uri}`; // bare name → theme dir - } else if (this.baseUri && uri.startsWith(`${this.baseUri}/`)) { - return uri; // already prefixed - } - - return `${this.baseUri || ""}${uri}`; // other root path → add prefix - }); - getIcon() { if (this.theme?.variables?.icon) { - return this.themeAssetUri(this.theme.variables.icon); + return this.theme.variables.icon; } switch (this.get("appIcon")) { case "crisp": case "mint": case "bold": - case "bloom": - case "flower": - case "ring": - case "shutter": return `${this.staticUri}/icons/${this.get("appIcon")}.svg`; default: return `${this.staticUri}/icons/logo.svg`; @@ -968,7 +951,7 @@ export default class Config { getLoginIcon() { const loginTheme = themes.Get("login", false); if (loginTheme?.variables?.icon) { - return this.themeAssetUri(loginTheme?.variables?.icon); + return loginTheme?.variables?.icon; } return this.getIcon(); diff --git a/frontend/src/common/download.js b/frontend/src/common/download.js index a852c6b7f..64381668b 100644 --- a/frontend/src/common/download.js +++ b/frontend/src/common/download.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/event.js b/frontend/src/common/event.js index 3a74946fe..0300a400b 100644 --- a/frontend/src/common/event.js +++ b/frontend/src/common/event.js @@ -39,7 +39,7 @@ if (trace) { // Action-verb constants for the backend's entity-event helpers — // kept in sync with EntityCreated / EntityUpdated / EntityDeleted / -// EntityArchived / EntityRestored in +// EntityArchived / EntityRestored / EntityEdited in // internal/event/publish_entities.go. Exported as symbols (not just // strings in a Set) so that switch cases and grep / IDE find- // references can locate every event-handling site without having @@ -50,12 +50,13 @@ export const ACTION_UPDATED = "updated"; export const ACTION_DELETED = "deleted"; export const ACTION_ARCHIVED = "archived"; export const ACTION_RESTORED = "restored"; +export const ACTION_EDITED = "edited"; // ENTITY_MUTATIONS lists the action verbs the cache layers and // namespace-level subscribers treat as "something changed; evict". // Frozen so call sites can't mutate the shared default; pass a // different Set explicitly when a caller needs a narrower scope. -export const ENTITY_MUTATIONS = Object.freeze(new Set([ACTION_CREATED, ACTION_UPDATED, ACTION_DELETED, ACTION_ARCHIVED, ACTION_RESTORED])); +export const ENTITY_MUTATIONS = Object.freeze(new Set([ACTION_CREATED, ACTION_UPDATED, ACTION_DELETED, ACTION_ARCHIVED, ACTION_RESTORED, ACTION_EDITED])); // Subscribes to every . event whose action is // in `actions`. Mirrors the page/photos.vue onUpdate switch diff --git a/frontend/src/common/face-markers.js b/frontend/src/common/face-markers.js index 31f03f422..c84b52772 100644 --- a/frontend/src/common/face-markers.js +++ b/frontend/src/common/face-markers.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/form.js b/frontend/src/common/form.js index c42841ef2..91a394a07 100644 --- a/frontend/src/common/form.js +++ b/frontend/src/common/form.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/gettext.js b/frontend/src/common/gettext.js index c2a1a0061..2a3ffc2d0 100644 --- a/frontend/src/common/gettext.js +++ b/frontend/src/common/gettext.js @@ -21,37 +21,6 @@ function interpolate(message, params = {}) { }); } -// interpolatePositional substitutes Go printf verbs (%s, %d, %v, %%, …) sequentially from an -// ordered params array, bridging the backend's positional placeholders to the frontend runtime. -// The verb must be a real Go fmt letter and no space flag is allowed, so a literal percent in a -// translated string (e.g. "100% sicher") is not mistaken for a verb and corrupted. -function interpolatePositional(message, params) { - if (message === null || message === undefined) { - return ""; - } - - const text = String(message); - - if (!Array.isArray(params) || params.length === 0) { - return text; - } - - let i = 0; - - return text.replace(/%(%|[-+0#]*\d*(?:\.\d+)?[vTtbcdoOqxXUeEfFgGsp])/g, (match, verb) => { - if (verb === "%") { - return "%"; - } - - if (i >= params.length) { - return match; - } - - const value = params[i++]; - return value === undefined || value === null ? "" : String(value); - }); -} - export let gettext = { $gettext: (msgid, params) => interpolate(msgid, params), $ngettext: (msgid, plural, n, params) => interpolate(n > 1 ? plural : msgid, params), @@ -63,12 +32,6 @@ export function T(msgid, params) { return gettext.$gettext(msgid, params); } -// Tp translates a backend message by its English source id, then substitutes the ordered -// positional params, so backend notifications render in the current UI language. -export function Tp(msgid, params) { - return interpolatePositional(gettext.$gettext(msgid), params); -} - export function $gettext(msgid, params) { return gettext.$gettext(msgid, params); } diff --git a/frontend/src/common/input.js b/frontend/src/common/input.js index 67f63832d..8c948e8dd 100644 --- a/frontend/src/common/input.js +++ b/frontend/src/common/input.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/instances.js b/frontend/src/common/instances.js deleted file mode 100644 index 5a92dccbf..000000000 --- a/frontend/src/common/instances.js +++ /dev/null @@ -1,343 +0,0 @@ -/* - -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under Version 3 of the GNU Affero General Public License (the "AGPL"): - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - The AGPL is supplemented by our Trademark and Brand Guidelines, - which describe how our Brand Assets may be used: - - -Feel free to send an email to hello@photoprism.app if you have questions, -want to support our work, or just want to say hello. - -Additional information can be found in our Developer Guide: - - -*/ - -import { listAuthSessions, buildNamespace, createNamespacedStorage } from "common/storage"; - -// Storage suffixes under which each instance records its public identity, so -// peers on the same shared-domain origin can render a navigation switcher entry. -// The namespace is a SHA-256 hash of the SiteUrl and is not reversible, so the -// URL and title must be persisted explicitly under the instance's namespace. -const InstanceUrlKey = "instance.url"; -const InstanceTitleKey = "instance.title"; -const InstanceIconKey = "instance.icon"; -const InstanceRouteKey = "instance.route"; -const InstancePortalKey = "instance.portal"; - -// InstanceIdentityKeys lists the suffix keys written by persistInstanceIdentity, -// so callers (e.g. session logout) can clear them across storage backends. -export const InstanceIdentityKeys = [InstanceUrlKey, InstanceTitleKey, InstanceIconKey, InstanceRouteKey, InstancePortalKey]; - -// safeWindow returns the browser window if available, else null. -const safeWindow = () => (typeof window === "undefined" ? null : window); - -// isHttpUrl reports whether url is an absolute http(s) URL. Instance URLs are -// read from shared same-origin storage written by peer instances, so the -// switcher rejects any other scheme (javascript:, data:, …) before listing or -// navigating to them. -function isHttpUrl(url) { - if (!url || typeof url !== "string") { - return false; - } - try { - const protocol = new URL(url).protocol; - return protocol === "http:" || protocol === "https:"; - } catch { - return false; - } -} - -// instanceLabel derives a short, distinctive display name from a SiteUrl — the -// last base-path segment (e.g. "pro-1" for ".../i/pro-1/"). The switcher can -// only surface same-origin instances, which always differ by path, so the path -// segment is more distinctive than the frequently-generic site caption/title -// (multiple instances commonly share the default "PhotoPrism" caption). Returns -// "" for a root-path or unparseable URL so the caller falls back to the title. -export function instanceLabel(siteUrl) { - if (!siteUrl || typeof siteUrl !== "string") { - return ""; - } - try { - const segments = new URL(siteUrl).pathname.split("/").filter(Boolean); - return segments.length ? segments[segments.length - 1] : ""; - } catch { - return ""; - } -} - -// instanceTitle derives the switcher label from an instance's client config values, -// preferring the operator-configured site name so a distinctively branded instance -// shows its real name (e.g. "ACME") instead of the lowercase base-path slug. The -// backend siteName (Config.SiteName) resolves SITE_NAME → AppName → SiteTitle and is -// empty for an unbranded instance, so we then fall back to the distinctive base-path -// segment (instanceLabel) — which the menu still shows as a subtitle to keep peers -// that share a generic name distinguishable. Returns "" only when no field is usable. -export function instanceTitle(values) { - if (!values || typeof values !== "object") { - return ""; - } - return values.siteName || instanceLabel(values.siteUrl) || values.siteTitle || values.name || values.siteUrl || ""; -} - -// instancePath returns the base path of a SiteUrl (e.g. "/i/pro-1") so the -// switcher can show how same-origin peers differ without repeating the shared -// origin. Returns "/" for a root install and "" for an unparseable URL. -export function instancePath(siteUrl) { - if (!siteUrl || typeof siteUrl !== "string") { - return ""; - } - try { - const path = new URL(siteUrl).pathname.replace(/\/+$/, ""); - return path || "/"; - } catch { - return ""; - } -} - -// persistInstanceIdentity records this instance's SiteUrl, display title, app icon, -// and frontend route in the given (namespaced) store, so other instances on the same -// origin can list it in the navigation instance switcher and open it at its app entry -// point. The route is the frontend URI (e.g. "/portal" or "/i/pro-1/library"); -// the switcher opens it so a web-overlay landing page at the site root is bypassed. -// No-op without a URL or usable store. -export function persistInstanceIdentity(store, identity) { - if (!store || typeof store.setItem !== "function" || !identity || !identity.url) { - return; - } - - store.setItem(InstanceUrlKey, identity.url); - - if (identity.title) { - store.setItem(InstanceTitleKey, identity.title); - } else { - store.removeItem(InstanceTitleKey); - } - - if (identity.icon) { - store.setItem(InstanceIconKey, identity.icon); - } else { - store.removeItem(InstanceIconKey); - } - - if (identity.route) { - store.setItem(InstanceRouteKey, identity.route); - } else { - store.removeItem(InstanceRouteKey); - } - - // Mark the Portal's own session; Sign-Out delegates it to the Portal end-session endpoint. - if (identity.portal) { - store.setItem(InstancePortalKey, "true"); - } else { - store.removeItem(InstancePortalKey); - } -} - -// listReachableInstances returns the instances (other than currentNamespace) that -// have a live session token and a recorded identity in shared browser storage, -// for the navigation instance switcher. Both localStorage (persistent sessions) -// and sessionStorage (ephemeral sessions, shared across same-tab navigations) are -// scanned, since recordInstanceIdentity writes to whichever the instance uses. -// Results are ordered so the Portal (origin root path) leads, then co-located peers -// by ascending base-path. Returns an empty array on standalone or subdomain-isolated -// deployments where no peer sessions are discoverable. -export function listReachableInstances(options) { - const opts = options || {}; - - let stores; - if (opts.storage) { - stores = [opts.storage]; - } else if (Array.isArray(opts.stores)) { - stores = opts.stores; - } else { - const w = safeWindow(); - stores = [w?.localStorage, w?.sessionStorage]; - } - - const currentPrefix = buildNamespace(opts.currentNamespace); - const seen = new Set(); - const instances = []; - - stores.forEach((store) => { - if (!store || typeof store.getItem !== "function") { - return; - } - - listAuthSessions(store).forEach((session) => { - const namespace = session && session.namespace; - if (!namespace) { - return; - } - - const prefix = buildNamespace(namespace); - if (prefix === currentPrefix || seen.has(prefix)) { - return; - } - - const url = store.getItem(prefix + InstanceUrlKey); - if (!isHttpUrl(url)) { - return; - } - - // route is the app-entry URL to navigate to (the SiteUrl origin + the peer's - // frontend URI). Resolve the stored route against the SiteUrl and reject any - // non-http(s) result; fall back to the SiteUrl for legacy/empty entries. - const storedRoute = store.getItem(prefix + InstanceRouteKey); - let route = url; - if (storedRoute) { - try { - const resolved = new URL(storedRoute, url).href; - if (isHttpUrl(resolved)) { - route = resolved; - } - } catch { - // keep the SiteUrl when the stored route can't be resolved. - } - } - - seen.add(prefix); - instances.push({ - namespace, - url, - route, - title: store.getItem(prefix + InstanceTitleKey) || url, - icon: store.getItem(prefix + InstanceIconKey) || "", - }); - }); - }); - - // Order the switcher so the Portal (origin root path "/") leads, then peers by - // ascending base-path length: co-located instances live under distinct base paths - // (e.g. "/i/pro-1"), so the shortest path is always the Portal at the origin root. - instances.sort((a, b) => { - const pa = instancePath(a.url) || "/"; - const pb = instancePath(b.url) || "/"; - return pa.length - pb.length || pa.localeCompare(pb); - }); - - return instances; -} - -// instanceSessionUrl returns the absolute DELETE-session endpoint for a peer, -// derived from its recorded SiteUrl (api/v1/session), or "" when the -// SiteUrl is missing or not http(s). Same-origin by design (shared-domain proxy). -export function instanceSessionUrl(siteUrl) { - if (!isHttpUrl(siteUrl)) { - return ""; - } - try { - const base = siteUrl.endsWith("/") ? siteUrl : siteUrl + "/"; - const resolved = new URL("api/v1/session", base).href; - return isHttpUrl(resolved) ? resolved : ""; - } catch { - return ""; - } -} - -// listLogoutTargets returns the peer sessions a cluster-wide Sign-Out should revoke -// server-side — {namespace, authToken, url} each, excluding currentNamespace (signed -// out via the normal path). Scans both storage backends. A peer with an unresolvable -// URL is still returned (url === "") so its local storage is still cleared. -export function listLogoutTargets(options) { - const opts = options || {}; - - let stores; - if (opts.storage) { - stores = [opts.storage]; - } else if (Array.isArray(opts.stores)) { - stores = opts.stores; - } else { - const w = safeWindow(); - stores = [w?.localStorage, w?.sessionStorage]; - } - - const currentPrefix = buildNamespace(opts.currentNamespace); - const seen = new Set(); - const targets = []; - - stores.forEach((store) => { - if (!store || typeof store.getItem !== "function") { - return; - } - - listAuthSessions(store).forEach((session) => { - const namespace = session && session.namespace; - const authToken = session && session.authToken; - if (!namespace || !authToken) { - return; - } - - const prefix = buildNamespace(namespace); - if (prefix === currentPrefix || seen.has(prefix)) { - return; - } - - seen.add(prefix); - targets.push({ - namespace, - authToken, - url: instanceSessionUrl(store.getItem(prefix + InstanceUrlKey)), - // True for the cluster Portal's own session (delegated to its end-session endpoint). - portal: store.getItem(prefix + InstancePortalKey) === "true", - }); - }); - }); - - return targets; -} - -// signOutInstances best-effort revokes each target's session via a DELETE -// authenticated with the target's own token. Same-origin only; a target without a -// URL is skipped and failures (unreachable, 401) are swallowed so one bad peer -// can't block Sign-Out. Resolves once all settle; never rejects. -export function signOutInstances(targets, fetchImpl) { - const doFetch = fetchImpl || (typeof fetch === "function" ? fetch.bind(safeWindow() || undefined) : null); - - if (!doFetch || !Array.isArray(targets) || targets.length === 0) { - return Promise.resolve([]); - } - - return Promise.allSettled( - targets - .filter((t) => t && t.url && t.authToken) - .map((t) => - doFetch(t.url, { - method: "DELETE", - // Authenticate with the peer's own token; same-origin so the response - // Set-Cookie (clearing the Portal OP cookie) is honored. - headers: { "X-Auth-Token": t.authToken }, - credentials: "same-origin", - cache: "no-store", - }).catch(() => {}) - ) - ); -} - -// clearInstanceStorage removes every namespaced key for each of namespaces from the -// given raw storage backends, so a cluster-wide Sign-Out leaves no peer tokens or -// stale switcher entries. Each namespace is cleared via a NamespacedStorage wrapper. -export function clearInstanceStorage(namespaces, stores) { - if (!Array.isArray(namespaces) || namespaces.length === 0) { - return; - } - - const backends = (Array.isArray(stores) ? stores : [stores]).filter((s) => s && typeof s.removeItem === "function"); - - namespaces.forEach((namespace) => { - if (!namespace) { - return; - } - backends.forEach((store) => createNamespacedStorage(store, namespace).clear()); - }); -} diff --git a/frontend/src/common/links.js b/frontend/src/common/links.js index 30adf654b..01a6f262d 100644 --- a/frontend/src/common/links.js +++ b/frontend/src/common/links.js @@ -1,24 +1,23 @@ export default { docs: "https://link.photoprism.app/docs", userGuide: "https://docs.photoprism.app/user-guide/", - syncSettings: "https://docs.photoprism.app/user-guide/settings/sync/", developerGuide: "https://docs.photoprism.app/developer-guide/", developerSetup: "https://docs.photoprism.app/developer-guide/setup/", firstSteps: "https://docs.photoprism.app/user-guide/first-steps/", troubleshooting: "https://docs.photoprism.app/getting-started/troubleshooting/", missingPictures: "https://docs.photoprism.app/getting-started/troubleshooting/#missing-pictures", - kb: "https://www.photoprism.app/kb/", - bugs: "https://www.photoprism.app/kb/reporting-bugs/", + kb: "https://www.photoprism.app/kb", + bugs: "https://www.photoprism.app/kb/reporting-bugs", account: "https://my.photoprism.app/dashboard", connect: "https://my.photoprism.app/connect/", compare: "https://link.photoprism.app/personal-editions", - contact: "https://www.photoprism.app/contact/", + contact: "https://www.photoprism.app/contact", pro: { - kb: "https://www.photoprism.app/pro/kb/", - support: "https://www.photoprism.app/pro/support/", + kb: "https://www.photoprism.app/pro/kb", + support: "https://www.photoprism.app/pro/support", supportEmail: "mailto:support@photoprism.pro", register: "https://my.photoprism.app/register/pro", - activation: "https://www.photoprism.app/pro/kb/activation/", + activation: "https://www.photoprism.app/pro/kb/activation", compare: "https://link.photoprism.app/team-editions", }, }; diff --git a/frontend/src/common/log.js b/frontend/src/common/log.js index 686788a39..e4c8e2f26 100644 --- a/frontend/src/common/log.js +++ b/frontend/src/common/log.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/map.js b/frontend/src/common/map.js index 8cba93560..cbfd69a91 100644 --- a/frontend/src/common/map.js +++ b/frontend/src/common/map.js @@ -1,124 +1,6 @@ let loading = false; let maplibregl = null; -// Screen-space distance (in pixels) below which two photo markers are treated as sharing the -// same spot and merged into one stack. Roughly the marker size, so pictures that would -// otherwise overlap and hide each other are grouped until the map is zoomed in far enough to -// separate them. -const stackTolerancePx = 40; - -// projectCoords resolves a feature's [lng, lat] coordinate to a screen point using the given -// projection. It accepts maplibregl Point objects ({x, y}) as well as plain [x, y] arrays and -// falls back to the raw coordinate so the grouping stays testable without a live map. -function projectCoords(coords, project) { - if (typeof project === "function") { - const p = project(coords); - if (p && typeof p.x === "number" && typeof p.y === "number") { - return [p.x, p.y]; - } - if (Array.isArray(p) && p.length >= 2) { - return [p[0], p[1]]; - } - } - // No projection: compare raw [lng, lat] degrees. The tolerance is then in degrees, not - // pixels, and grouping is no longer zoom-aware — callers rendering on a live map MUST pass - // a projection. This path exists so the grouping can be unit-tested without a map. - return [coords[0], coords[1]]; -} - -// groupGeoFeatures groups point features that render close enough to overlap so that -// coincident or near-coincident pictures stack into a single marker with a counter instead of -// hiding each other once the map is zoomed past the clustering threshold. The optional -// `project` callback maps a feature's [lng, lat] coordinate to screen pixels, which keeps the -// grouping zoom-aware: truly coincident pictures always stack, while ones a few meters apart -// only separate once zoomed in far enough. Exact-coordinate keying is intentionally avoided -// because stored coordinates rarely match bit for bit (GPS jitter, tile quantization). -// Features are deduplicated by UID because querySourceFeatures may return the same point once -// per tile it overlaps. Each group carries the lat/lng bounding box of its members and a -// stable key (smallest UID) so a click opens exactly those pictures and the marker survives -// re-renders. -export function groupGeoFeatures(features, project, tolerance = stackTolerancePx) { - const groups = []; - - if (!Array.isArray(features)) { - return groups; - } - - const limit = tolerance * tolerance; - - for (let i = 0; i < features.length; i++) { - const feature = features[i]; - const coords = feature?.geometry?.coordinates; - - if (!Array.isArray(coords) || coords.length < 2) { - continue; - } - - const point = projectCoords(coords, project); - - // Join the first existing group whose anchor lies within the tolerance. - let group = null; - for (let g = 0; g < groups.length; g++) { - const dx = groups[g].point[0] - point[0]; - const dy = groups[g].point[1] - point[1]; - if (dx * dx + dy * dy <= limit) { - group = groups[g]; - break; - } - } - - if (!group) { - group = { - coords, - point, - features: [], - uids: {}, - bounds: { latN: coords[1], lngE: coords[0], latS: coords[1], lngW: coords[0] }, - }; - groups.push(group); - } - - const uid = feature.properties?.UID; - - // Skip duplicate features that reference the same picture. - if (uid) { - if (group.uids[uid]) { - continue; - } - group.uids[uid] = true; - } - - group.features.push(feature); - - // Expand the group's lat/lng bounding box to include this picture. - const lng = coords[0]; - const lat = coords[1]; - if (lat > group.bounds.latN) { - group.bounds.latN = lat; - } - if (lat < group.bounds.latS) { - group.bounds.latS = lat; - } - if (lng > group.bounds.lngE) { - group.bounds.lngE = lng; - } - if (lng < group.bounds.lngW) { - group.bounds.lngW = lng; - } - } - - // Derive a stable key from the smallest UID so the marker survives re-renders, even when - // querySourceFeatures returns the same pictures in a different order between frames. Fall - // back to the first feature's id (never the float coordinates, which drift between frames). - for (let g = 0; g < groups.length; g++) { - const group = groups[g]; - const uids = Object.keys(group.uids); - group.key = uids.length ? uids.sort()[0] : String(group.features[0]?.id ?? g); - } - - return groups; -} - // Loads the maplibregl library. export async function load() { if (maplibregl !== null || loading) { diff --git a/frontend/src/common/notify.js b/frontend/src/common/notify.js index 10692d7b5..c69ad2f28 100644 --- a/frontend/src/common/notify.js +++ b/frontend/src/common/notify.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -30,34 +30,26 @@ let ajaxPending = 0; let ajaxCallbacks = []; const $notify = { - // info publishes an info notification. - info: function (message, messageId, messageParams) { - $event.publish("notify.info", { message, messageId, messageParams }); + info: function (message) { + $event.publish("notify.info", { message }); }, - // warn publishes a warning notification. - warn: function (message, messageId, messageParams) { - $event.publish("notify.warning", { message, messageId, messageParams }); + warn: function (message) { + $event.publish("notify.warning", { message }); }, - // error publishes an error notification; the optional messageId/messageParams - // let notify.vue render it in the current UI locale via Tp. - error: function (message, messageId, messageParams) { - $event.publish("notify.error", { message, messageId, messageParams }); + error: function (message) { + $event.publish("notify.error", { message }); }, - // success publishes a success notification. - success: function (message, messageId, messageParams) { - $event.publish("notify.success", { message, messageId, messageParams }); + success: function (message) { + $event.publish("notify.success", { message }); }, - // logout publishes an error notification and triggers a session.logout event. - logout: function (message, messageId, messageParams) { - $event.publish("notify.error", { message, messageId, messageParams }); - $event.publish("session.logout", { message, messageId, messageParams }); + logout: function (message) { + $event.publish("notify.error", { message }); + $event.publish("session.logout", { message }); }, - // ajaxStart marks an AJAX request as started and emits ajax.start. ajaxStart: function () { ajaxPending++; $event.publish("ajax.start"); }, - // ajaxEnd marks an AJAX request as finished, emits ajax.end, and runs queued idle callbacks. ajaxEnd: function () { ajaxPending--; $event.publish("ajax.end"); @@ -68,7 +60,6 @@ const $notify = { callbacks.forEach((cb) => cb()); } }, - // ajaxBusy reports whether any AJAX requests are still pending. ajaxBusy: function () { if (ajaxPending < 0) { ajaxPending = 0; @@ -76,7 +67,6 @@ const $notify = { return ajaxPending > 0; }, - // ajaxWait resolves once no AJAX requests are pending or the timeout elapses. ajaxWait: function (idleDelay = 64, timeout = 8000) { return new Promise((resolve) => { const start = Date.now(); @@ -104,7 +94,6 @@ const $notify = { settle(); }); }, - // blockUI shows the busy overlay, optionally setting its CSS class. blockUI: function (className) { const el = document.getElementById("busy-overlay"); @@ -115,7 +104,6 @@ const $notify = { } } }, - // unblockUI hides the busy overlay. unblockUI: function () { const el = document.getElementById("busy-overlay"); @@ -124,11 +112,9 @@ const $notify = { el.className = ""; } }, - // wait shows a "Please wait" info notification. wait: function () { this.info($gettext("Please wait…")); }, - // busy shows a "Busy, please wait" warning notification. busy: function () { this.warn($gettext("Busy, please wait…")); }, diff --git a/frontend/src/common/pwa.js b/frontend/src/common/pwa.js index 95589321c..3ac7fc5fb 100644 --- a/frontend/src/common/pwa.js +++ b/frontend/src/common/pwa.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/selection.js b/frontend/src/common/selection.js index 39ac2510a..a153dd7fd 100644 --- a/frontend/src/common/selection.js +++ b/frontend/src/common/selection.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/common/server.js b/frontend/src/common/server.js index 489471be0..e724bb8db 100644 --- a/frontend/src/common/server.js +++ b/frontend/src/common/server.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -26,7 +26,6 @@ Additional information can be found in our Developer Guide: import $api from "common/api"; import { $config } from "app/session"; import $notify from "common/notify"; -import { $gettext } from "common/gettext"; function poll(interval, maxAttempts) { let attempts = 0; @@ -76,13 +75,13 @@ export function restart(uri) { }) .catch(() => { $notify.ajaxEnd(); - $notify.error($gettext("Failed to restart server")); + $notify.error("Failed to restart server"); $notify.unblockUI(); }); }) .catch(() => { $notify.ajaxEnd(); - $notify.error($gettext("Failed to restart server")); + $notify.error("Failed to restart server"); $notify.unblockUI(); }); } diff --git a/frontend/src/common/session.js b/frontend/src/common/session.js index 7eb06a4b5..f0025739d 100644 --- a/frontend/src/common/session.js +++ b/frontend/src/common/session.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -26,14 +26,6 @@ Additional information can be found in our Developer Guide: import $api from "common/api"; import $event from "common/event"; import { createNamespacedStorage } from "common/storage"; -import { - persistInstanceIdentity, - InstanceIdentityKeys, - instanceTitle, - listLogoutTargets, - signOutInstances, - clearInstanceStorage, -} from "common/instances"; import { $view } from "common/view"; import User from "model/user"; import Socket from "websocket.js"; @@ -46,16 +38,6 @@ const LoginPage = "login"; // login.* keys survive auth.gohtml's session.* wipe after the OIDC roundtrip. const LoginRedirectKey = "login.next"; const LogoutSignalKey = "login.logout"; -// One-shot flag (per browser tab) for the OIDC auto-redirect attempt. Stored -// in sessionStorage so a closed tab clears it, and so a failed/abandoned OIDC -// roundtrip can fall back to the local login form instead of looping. -const OidcAttemptKey = "login.oidc.attempt"; -// Loop guard for the post-login redirect (login.next): the timestamp of the last -// follow, and the window within which a re-entry counts as a bounce-back loop. -// Lets /login fall back to the default route instead of looping when the redirect -// target (e.g. the OIDC OP /api/v1/oauth/authorize) can't authenticate the navigation. -const LoginRedirectAttemptKey = "login.next.at"; -const LoginRedirectLoopWindow = 6000; const resolveStorageNamespace = (config) => { if (typeof config?.storageNamespace === "string" && config.storageNamespace !== "") { @@ -162,11 +144,6 @@ export default class Session { // Authenticated? this.auth = this.isUser(); - // Record this instance's identity so peers on a shared domain can switch to it. - if (this.auth) { - this.recordInstanceIdentity(); - } - // Subscribe to session events. $event.subscribe("session.logout", () => { return this.onLogout(); @@ -351,8 +328,6 @@ export default class Session { this.clearLegacyKey("session.scope"); this.clearLegacyKey("authError"); this.clearLegacyKey("session.error"); - this.clearLegacyKey("session.messageId"); - this.clearLegacyKey("session.messageParams"); delete $api.defaults.headers.common[RequestHeader]; } @@ -459,35 +434,6 @@ export default class Session { this.user = new User(user); this.storage.setItem(this.storageKey + ".user", JSON.stringify(user)); this.auth = this.isUser(); - - if (this.auth) { - this.recordInstanceIdentity(); - } - } - - // recordInstanceIdentity stores this instance's SiteUrl, display title, and app - // icon under the active namespace so other instances on the same origin can offer - // a switch entry. The title prefers the configured site name (see instanceTitle) - // and falls back to the distinctive base-path segment for unbranded instances; - // the icon is the root-relative app icon, which resolves on the shared origin from - // any peer. No-op when the site URL is unknown or storage is unavailable. - recordInstanceIdentity() { - const values = this.config?.values; - - if (!values || !values.siteUrl) { - return; - } - - persistInstanceIdentity(this.storage, { - url: values.siteUrl, - // Frontend URI (e.g. "/portal" or "/i/pro-1/library") so peers open the - // app entry point rather than a web-overlay landing page at the site root. - route: this.config?.frontendUri, - title: instanceTitle(values), - icon: this.config.getIcon(), - // Flag the Portal's own session so Sign-Out delegates it to the Portal end-session endpoint. - portal: !!this.config?.isPortal?.(), - }); } getUser() { @@ -560,17 +506,13 @@ export default class Session { clearLoginRedirectUrl() { this.loginRedirect = false; this.localStorage?.removeItem(LoginRedirectKey); - // The OIDC attempt flag is paired with the deep-link target: clearing - // the target (after successful login or logout) frees the next deep-link - // arrival to trigger a fresh OIDC roundtrip. - this.sessionStorage?.removeItem(OidcAttemptKey); return this; } // Records the post-login target. Persisted so it survives the OIDC roundtrip. setLoginRedirectUrl(url) { - if (this.invalidRedirectUrl(url)) { + if (!url) { return this.clearLoginRedirectUrl(); } @@ -580,37 +522,6 @@ export default class Session { return this; } - // invalidRedirectUrl reports whether url is unsafe to record as the - // post-login deep-link target. Rejects null/undefined, non-string, - // whitespace-only, and login-page URLs (a recorded login URL would either - // no-op the post-login redirect or re-trigger auto-OIDC indefinitely on a - // crafted `?return_to=/login`). - invalidRedirectUrl(url) { - if (typeof url !== "string") { - return true; - } - const trimmed = url.trim(); - if (trimmed === "") { - return true; - } - let path = trimmed; - try { - const origin = (typeof window !== "undefined" && window.location?.origin) || "http://localhost"; - path = new URL(trimmed, origin).pathname; - } catch { - path = trimmed.split("?")[0].split("#")[0]; - } - path = path.replace(/\/+$/, ""); - if (!path) { - return true; - } - const loginUri = (this.config?.loginUri || "").replace(/\/+$/, ""); - if (loginUri && path === loginUri) { - return true; - } - return path.endsWith("/login"); - } - // isUser returns true when the current session has a fully-loaded user record. isUser() { return !!this.user?.hasId(); @@ -659,9 +570,6 @@ export default class Session { this.clearNamespacedKey(this.storageKey + ".user"); this.clearLegacyKey("user"); this.clearLegacyKey("session.user"); - // Drop this instance's switcher identity so a logged-out instance is no - // longer offered as a switch target by peers on the same shared domain. - InstanceIdentityKeys.forEach((key) => this.clearNamespacedKey(key)); } deleteClipboard() { @@ -806,36 +714,7 @@ export default class Session { $view.redirect(url, delay, true); } - // isClusterSession reports whether the current session was signed in through the - // cluster Portal OIDC provider, so sign-out runs the cluster-wide fan-out and - // clears the Portal OP cookie. Read before reset()/signOut() clears the provider. - isClusterSession() { - return this.getProvider() === "oidc" && !!this.config?.isClusterOidc?.(); - } - - // logoutRedirectUri returns the post-sign-out landing URL: a cluster-OIDC session - // goes directly to the Portal login page (re-auth → instance chooser), everyone - // else to the local login. The instance OIDC roundtrip is never re-initiated on - // sign-out, since that would pin the Portal login's return_to to the just-left - // instance and dead-end accounts without a grant there; when the Portal login URL - // is unknown, the local form is the fallback landing. Read provider before reset(). - logoutRedirectUri() { - if (this.isClusterSession()) { - return this.config.portalLoginUri() || this.config.loginUri; - } - - return this.config.loginUri; - } - - // onLogout resets client state and resolves to the post-sign-out landing URL. It follows - // the redirect itself unless noRedirect is set, in which case the caller does (e.g. the - // /logout route guard), so the resolved URL — the provider logout URL when present — is - // returned either way. - onLogout(noRedirect, providerLogoutUri) { - // Prefer the backend's provider logout URL (RP-initiated logout); else the local target, - // resolved before reset() clears the auth provider. - const redirectUri = providerLogoutUri || this.logoutRedirectUri(); - + onLogout(noRedirect) { this.reset(); // Drop stale deep-link redirects; raise one-shot flag so /login skips @@ -844,10 +723,10 @@ export default class Session { this.localStorage?.setItem(LogoutSignalKey, "1"); if (noRedirect !== true && !this.isLogin()) { - this.followRedirect(redirectUri); + this.followRedirect(this.config.loginUri); } - return Promise.resolve(redirectUri); + return Promise.resolve(); } // Reads and clears the one-shot logout flag set by onLogout(). @@ -862,54 +741,12 @@ export default class Session { return raised; } - // Marks that an OIDC auto-redirect attempt is in flight for this tab. - markOidcAttempt() { - this.sessionStorage?.setItem(OidcAttemptKey, "1"); - return this; - } - - // Reads and clears the OIDC attempt flag. Returns true once per tab between - // markOidcAttempt() calls, so /login can fall back to the form when an OIDC - // roundtrip fails or is abandoned instead of looping back to the IdP. - consumeOidcAttempt() { - if (!this.sessionStorage) { - return false; - } - const raised = this.sessionStorage.getItem(OidcAttemptKey) === "1"; - if (raised) { - this.sessionStorage.removeItem(OidcAttemptKey); - } - return raised; - } - - // Records the time we last followed the post-login redirect, so a fast - // bounce-back can be recognized as a loop. Stored per browser tab. - markLoginRedirectAttempt() { - this.sessionStorage?.setItem(LoginRedirectAttemptKey, String(Date.now())); - return this; - } - - // loginRedirectLooping reports whether the post-login redirect was followed - // within the last LoginRedirectLoopWindow ms, i.e. the target bounced straight - // back without authenticating the navigation — used to break redirect loops. - loginRedirectLooping() { - const at = parseInt(this.sessionStorage?.getItem(LoginRedirectAttemptKey) || "0", 10); - return at > 0 && Date.now() - at < LoginRedirectLoopWindow; - } - - // Clears the post-login redirect loop guard. - clearLoginRedirectAttempt() { - this.sessionStorage?.removeItem(LoginRedirectAttemptKey); - return this; - } - logout(noRedirect) { if (this.isAuthenticated()) { return $api .delete("session") - .then((resp) => { - // providerLogoutUri (RP-initiated logout) redirects the browser to the provider. - return this.onLogout(noRedirect, resp?.data?.providerLogoutUri); + .then(() => { + return this.onLogout(noRedirect); }) .catch(() => { return this.onLogout(noRedirect); @@ -919,55 +756,10 @@ export default class Session { } } - // revokePeerSessions best-effort revokes every reachable peer instance's session - // server-side and clears their namespaced keys from local storage. The peer keys - // are cleared synchronously (the DELETEs hold their own tokens), so a route guard - // can fire-and-forget while the async revocation settles. Returns the fan-out - // promise. Shared by logoutEverywhere (awaits) and signOut (fire-and-forget). - // - // Unwraps to the raw underlying store first: this.localStorage / this.sessionStorage - // are NamespacedStorage wrappers (getAppStorage), so enumerating or clearing a - // cross-namespace key through one double-prefixes it (pp:a:pp:b:…) and misses it. - revokePeerSessions() { - const rawStore = (s) => (s && s.storage ? s.storage : s); - const stores = [rawStore(this.localStorage), rawStore(this.sessionStorage)]; - - let targets = []; - try { - targets = listLogoutTargets({ currentNamespace: this.storageNamespace, stores }); - } catch { - targets = []; - } - - // Cluster-OIDC Sign-Out delegates the Portal session to its end-session endpoint (which - // performs the upstream RP-logout); revoking it here would strip the session it needs. - let deleteTargets = targets; - if (this.isClusterSession() && this.config?.oidcLogout?.()) { - deleteTargets = targets.filter((t) => !t.portal); - } - - const revoked = signOutInstances(deleteTargets).catch(() => {}); - clearInstanceStorage( - targets.map((t) => t.namespace), - stores - ); - return revoked; - } - - // logoutEverywhere performs a cluster-wide Sign-Out (Tier 2): best-effort revokes - // every reachable peer instance's session server-side, drops their local tokens, - // then signs out the current instance (clearing the OP cookie) and redirects. - // Shared-domain (same-origin) clusters only; always resolves. - logoutEverywhere(noRedirect) { - return this.revokePeerSessions().then(() => this.logout(noRedirect)); - } - - // Synchronous cluster-wide logout for SPA route guards (/logout): revokes every - // reachable peer session and the current one (best-effort, in the background), - // clears shared storage, then resets client state. Firing the current DELETE with - // the captured token avoids a 401 echo that would re-raise the logout flag. + // Synchronous logout for SPA route guards (/logout): fires server DELETE + // with the captured token first (avoiding a 401 echo that would re-raise + // the logout flag), then resets client state. signOut() { - this.revokePeerSessions(); const token = this.getAuthToken(); if (token) { $api.delete("session", { headers: { [RequestHeader]: token } }).catch(() => {}); diff --git a/frontend/src/common/sphere.js b/frontend/src/common/sphere.js deleted file mode 100644 index 1d6503a3d..000000000 --- a/frontend/src/common/sphere.js +++ /dev/null @@ -1,114 +0,0 @@ -/* - -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. - - This program is free software: you can redistribute it and/or modify - it under Version 3 of the GNU Affero General Public License (the "AGPL"): - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - The AGPL is supplemented by our Trademark and Brand Guidelines, - which describe how our Brand Assets may be used: - - -Feel free to send an email to hello@photoprism.app if you have questions, -want to support our work, or just want to say hello. - -Additional information can be found in our Developer Guide: - - -*/ - -import * as media from "common/media"; - -// EQUIRECTANGULAR_RATIO_TOLERANCE bounds how far a video frame may deviate from the -// 2:1 equirectangular aspect ratio and still be treated as 360° media. -const EQUIRECTANGULAR_RATIO_TOLERANCE = 0.15; - -// is360Equirectangular reports whether a slide/thumb model is equirectangular 360° -// content that should open in the sphere viewer. An explicit "equirectangular" -// projection is authoritative, but a full sphere is ~2:1: when the frame size is known -// and clearly not 2:1 it stays in the flat viewer, since a partial/cylindrical panorama -// tagged equirectangular (or promoted from GPano markers) would otherwise render as a -// vertically distorted sphere. Any other non-empty projection (cubemap, …) is never 360°. -// Many 360° videos carry no projection tag PhotoPrism can read, so a panorama-flagged -// video with no projection falls back to the same 2:1 frame test — this keeps genuine -// spherical videos opening while cubemap (4:3, 6:1) and ultrawide (~2.35:1) clips stay flat. -export function is360Equirectangular(model) { - const projection = (model?.Projection || "").toLowerCase(); - const w = Number(model?.Width); - const h = Number(model?.Height); - const known = w > 0 && h > 0; - const is2to1 = known && Math.abs(w / h - 2) <= EQUIRECTANGULAR_RATIO_TOLERANCE; - if (projection === "equirectangular") { - return !known || is2to1; - } - if (projection) { - return false; - } - const isVideo = model?.Type === media.Video || model?.Type === media.Animated; - if (!isVideo || model?.Panorama !== true) { - return false; - } - return is2to1; -} - -// createSphereViewer mounts a Photo Sphere Viewer instance for an equirectangular photo or video. -// The renderer (and its ThreeJS dependency) is dynamic-imported on first call so the base bundle -// is unaffected when no 360° media is opened. -export async function createSphereViewer(container, src, opts = {}) { - const [coreMod, videoMod, videoAdapterMod] = await Promise.all([ - import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/core"), - opts.isVideo - ? import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/video-plugin") - : Promise.resolve(null), - opts.isVideo - ? import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/equirectangular-video-adapter") - : Promise.resolve(null), - ]); - - await import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/core/index.css"); - - if (opts.isVideo) { - await import(/* webpackChunkName: "sphere-viewer" */ "@photo-sphere-viewer/video-plugin/index.css"); - return new coreMod.Viewer({ - container, - adapter: [videoAdapterMod.EquirectangularVideoAdapter, { muted: !!opts.muted, autoplay: false }], - panorama: { source: src }, - plugins: [videoMod.VideoPlugin], - navbar: false, - keyboard: "always", - defaultYaw: 0, - defaultPitch: 0, - }); - } - - return new coreMod.Viewer({ - container, - panorama: src, - navbar: false, - keyboard: "always", - defaultYaw: 0, - defaultPitch: 0, - }); -} - -// findSphereVideoElement returns the underlying HTMLVideoElement that PSV's -// EquirectangularVideoAdapter uses as a WebGL texture source. The adapter does -// not insert the element into the DOM, so we read it off the adapter instance -// the viewer exposes after the panorama has finished loading. -export function findSphereVideoElement(viewer) { - return viewer?.adapter?.video || null; -} - -// destroySphereViewer tears down a viewer instance, releasing its WebGL context and textures. -// Safe to call on null or an already-destroyed viewer. -export function destroySphereViewer(viewer) { - if (viewer && typeof viewer.destroy === "function") { - viewer.destroy(); - } -} diff --git a/frontend/src/common/storage.js b/frontend/src/common/storage.js index d29909bdc..4bcbb3be0 100644 --- a/frontend/src/common/storage.js +++ b/frontend/src/common/storage.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -38,8 +38,6 @@ const defaultLegacyClearKeys = new Set([ "session.provider", "session.scope", "session.error", - "session.messageId", - "session.messageParams", "clipboard", "clipboard.photos", "clipboard.albums", diff --git a/frontend/src/common/typeahead-cache.js b/frontend/src/common/typeahead-cache.js index 0a2396abb..bc5ca0df2 100644 --- a/frontend/src/common/typeahead-cache.js +++ b/frontend/src/common/typeahead-cache.js @@ -1,11 +1,9 @@ -// Module-scope cache for the labels, albums, and people typeahead lists shared -// by the sidebar info panel, batch-edit dialog, edit-dialog tabs, and the -// people/face name pickers. getLabels / getAlbums / getPeople return a -// Promise and coalesce concurrent callers onto a single in-flight -// request. WS mutation events evict the matching slot. +// Module-scope cache for the labels and albums typeahead lists shared by the +// sidebar info panel, batch-edit dialog, and edit-dialog labels tab. +// getLabels / getAlbums return a Promise and coalesce concurrent callers +// onto a single in-flight request. WS mutation events evict the matching slot. import Album from "model/album"; import Label from "model/label"; -import Subject from "model/subject"; import $event, { subscribeEntityActions } from "common/event"; // Pragmatic ceiling shared by every consumer; over-cap libraries log a warning @@ -13,14 +11,10 @@ import $event, { subscribeEntityActions } from "common/event"; export const CAP = 5000; const state = { - labels: { data: null, fetch: null, epoch: 0 }, - albums: { data: null, fetch: null, epoch: 0 }, - people: { data: null, fetch: null, epoch: 0 }, + labels: { data: null, fetch: null }, + albums: { data: null, fetch: null }, }; -// Bumping the epoch invalidates any fetch that started before this point, so a -// request still in flight when the slot is evicted (or seeded) cannot resolve -// later and silently overwrite the slot with stale data. See get(). function evict(field) { const slot = state[field]; if (!slot) { @@ -28,61 +22,6 @@ function evict(field) { } slot.data = null; slot.fetch = null; - slot.epoch += 1; -} - -// upsertPeople merges saved subjects into a populated people slot so a freshly -// created or renamed name is suggestible immediately, without waiting for the -// subjects/people WS event (which can lag a quick re-entry). It only mutates an -// already-loaded slot; a cold slot is left untouched so the next getPeople() -// fetches the full, server-ordered list. Entries are matched by UID, falling -// back to a case-insensitive name match so an existing person is updated rather -// than duplicated. The merge is idempotent: re-saving an unchanged name leaves -// the slot and its epoch untouched, so a redundant save cannot invalidate a -// pending fetch or replace the list with an equivalent copy. -// -// Contract: Marker.setName() and Face.setName() seed automatically. Callers that -// create or rename a person through any other path (e.g. Subject.update() from -// the recognized-people page) must call upsertPerson() themselves. -function upsertPeople(items) { - const slot = state.people; - if (!Array.isArray(slot.data) || !Array.isArray(items)) { - return; - } - - const next = slot.data.slice(); - let changed = false; - - for (const raw of items) { - const name = (raw?.Name || "").trim(); - if (!name) { - continue; - } - - const uid = raw?.UID || ""; - let idx = uid ? next.findIndex((p) => p && p.UID === uid) : -1; - if (idx === -1) { - idx = next.findIndex((p) => p && p.Name && p.Name.localeCompare(name, undefined, { sensitivity: "base" }) === 0); - } - - if (idx >= 0) { - const existing = next[idx]; - const mergedUid = uid || existing.UID; - // Nothing to do when the slot already holds this exact UID and name. - if (existing.UID === mergedUid && existing.Name === name) { - continue; - } - next[idx] = { ...existing, UID: mergedUid, Name: name }; - } else { - next.push({ UID: uid, Name: name }); - } - changed = true; - } - - if (changed) { - slot.data = next; - slot.epoch += 1; - } } function fetchLabels() { @@ -105,16 +44,6 @@ function fetchAlbums() { }); } -function fetchPeople() { - return Subject.search({ count: CAP, order: "name", type: "person" }).then((resp) => { - const models = Array.isArray(resp?.models) ? resp.models : []; - if (models.length === CAP) { - console.warn(`Subject.search returned ${CAP} results — list may be truncated.`); - } - return models; - }); -} - function get(field, fetcher) { const slot = state[field]; if (slot.data) { @@ -123,21 +52,14 @@ function get(field, fetcher) { if (slot.fetch) { return slot.fetch; } - // Snapshot the epoch so a fetch that finishes after an evict/upsert (which - // bump the epoch) is discarded instead of caching now-stale results. - const epoch = slot.epoch; slot.fetch = fetcher() .then((data) => { - if (slot.epoch === epoch) { - slot.data = data; - slot.fetch = null; - } + slot.data = data; + slot.fetch = null; return data; }) .catch((err) => { - if (slot.epoch === epoch) { - slot.fetch = null; - } + slot.fetch = null; throw err; }); return slot.fetch; @@ -148,15 +70,11 @@ function get(field, fetcher) { export const typeaheadCache = { getLabels: () => get("labels", fetchLabels), getAlbums: () => get("albums", fetchAlbums), - getPeople: () => get("people", fetchPeople), - upsertPerson: (person) => upsertPeople([person]), evictLabels: () => evict("labels"), evictAlbums: () => evict("albums"), - evictPeople: () => evict("people"), clear: () => { evict("labels"); evict("albums"); - evict("people"); }, }; @@ -165,21 +83,15 @@ export const typeaheadCache = { subscribeEntityActions("labels", () => evict("labels")); subscribeEntityActions("albums", () => evict("albums")); -// People mutations surface on both the subjects and people channels (a rename -// publishes subjects.updated and people.updated); either evicts the people slot. -subscribeEntityActions("subjects", () => evict("people")); -subscribeEntityActions("people", () => evict("people")); - // Belt-and-braces eviction for album mutations that surface only as a config // reload (covers future config-touching mutations not on the entity channel). $event.subscribe("config.updated", () => evict("albums")); -// Drop all lists on logout so user A's data cannot be served to user B in +// Drop both lists on logout so user A's data cannot be served to user B in // the same tab; mirrors Photo.clearCache()'s session.logout path. $event.subscribe("session.logout", () => { evict("labels"); evict("albums"); - evict("people"); }); export default typeaheadCache; diff --git a/frontend/src/common/util.js b/frontend/src/common/util.js index 60a1bc698..0b6577cac 100644 --- a/frontend/src/common/util.js +++ b/frontend/src/common/util.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. @@ -470,27 +470,6 @@ export default class $util { return navigator.maxTouchPoints > 0; } - // shouldOpenOnHover reports whether menus should open on hover: the user's UI - // preference (default on) gated by the device having no touch input. - static shouldOpenOnHover() { - return ($config.getSettings()?.ui?.openOnHover ?? true) && !$util.hasTouch(); - } - - // mapAnimateDuration returns the map fly-to animation duration in milliseconds, forcing 0 - // (no animation) when the Reduce Motion accessibility setting is enabled. A non-negative - // overrideMs takes precedence over the global Maps.Animate preference. - static mapAnimateDuration(settings, overrideMs = -1) { - if (settings?.ui?.reduceMotion) { - return 0; - } - - if (overrideMs >= 0) { - return overrideMs; - } - - return settings?.maps?.animate ?? 0; - } - // isMobile returns true when the current user agent or touch capability indicates a mobile device. // The `> 2` touch check covers iPads in desktop mode, where the user agent omits the mobile hint. static isMobile() { diff --git a/frontend/src/common/view.js b/frontend/src/common/view.js index f2948479f..9a30af08c 100644 --- a/frontend/src/common/view.js +++ b/frontend/src/common/view.js @@ -5,15 +5,6 @@ import { getAppSessionStorage, getAppStorage } from "common/storage"; const TouchStartEvent = "touchstart"; const TouchMoveEvent = "touchmove"; -// Selector for the document's viewport meta tag. -const ViewportMetaSelector = 'meta[name="viewport"]'; - -// Viewport content that disables the browser's native pinch-zoom of the whole page. -const ViewportNoZoom = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"; - -// Token in a viewport content string indicating native zoom is already disabled. -const ViewportNoZoomToken = "user-scalable=no"; - // True if debug and/or trace logs should be recorded. const debug = window.__CONFIG__?.debug; const trace = window.__CONFIG__?.trace; @@ -414,7 +405,6 @@ export class View { this.scopes = []; this.hideScrollbar = false; this.preventNavigation = false; - this.savedViewportContent = ""; this.focusScopes = new Map(); // Tracks the most recent history position and derived navigation direction so components can @@ -565,7 +555,6 @@ export class View { let hideScrollbar = this.len() > 2 ? this.hideScrollbar : false; let disableScrolling = false; let disableNavigationGestures = false; - let disableViewportZoom = false; let preventNavigation = uid > 0 && !name.startsWith("PPage"); switch (name) { @@ -593,7 +582,6 @@ export class View { hideScrollbar = true; disableScrolling = true; disableNavigationGestures = true; - disableViewportZoom = true; preventNavigation = true; break; } @@ -673,14 +661,6 @@ export class View { } } - // Lock native pinch-zoom while a flagged overlay is active, restore it otherwise. - // Both helpers are idempotent, so re-applying the same state is a no-op. - if (disableViewportZoom) { - this.disableNativeZoom(); - } else { - this.restoreNativeZoom(); - } - if (debug) { console.groupEnd(); } @@ -838,47 +818,6 @@ export class View { return setFocus(el, selector, scroll); } - // disableNativeZoom locks the viewport so the browser can't pinch-zoom the whole page - // while an overlay (e.g. the lightbox) handles zoom itself; restoreNativeZoom restores - // the saved content. Idempotent; assumes one active overlay (savedViewportContent is - // app-global), which View.apply() upholds by locking only for the top-of-stack view. - disableNativeZoom() { - if (this.savedViewportContent) { - return; - } - - const viewport = document.querySelector(ViewportMetaSelector); - - if (!viewport) { - return; - } - - const content = viewport.getAttribute("content") || ""; - - // Nothing to restore if the base viewport already blocks zoom (e.g. the Zoom setting is off). - if (content.includes(ViewportNoZoomToken)) { - return; - } - - this.savedViewportContent = content; - viewport.setAttribute("content", ViewportNoZoom); - } - - // restoreNativeZoom restores the viewport content saved by disableNativeZoom, if any. - restoreNativeZoom() { - if (!this.savedViewportContent) { - return; - } - - const viewport = document.querySelector(ViewportMetaSelector); - - if (viewport) { - viewport.setAttribute("content", this.savedViewportContent); - } - - this.savedViewportContent = ""; - } - // Navigates to the specified URL, optionally with a delay set in milliseconds and a blocked user interface. redirect(url, delay, blockUI) { // Return if no URL was passed. diff --git a/frontend/src/common/websocket.js b/frontend/src/common/websocket.js index cc0e3514e..c50848552 100644 --- a/frontend/src/common/websocket.js +++ b/frontend/src/common/websocket.js @@ -1,6 +1,6 @@ /* -Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. +Copyright (c) 2018 - 2025 PhotoPrism UG. All rights reserved. This program is free software: you can redistribute it and/or modify it under Version 3 of the GNU Affero General Public License (the "AGPL"): @@ -13,7 +13,7 @@ Copyright (c) 2018 - 2026 PhotoPrism UG. All rights reserved. The AGPL is supplemented by our Trademark and Brand Guidelines, which describe how our Brand Assets may be used: - + Feel free to send an email to hello@photoprism.app if you have questions, want to support our work, or just want to say hello. diff --git a/frontend/src/component/about/footer.vue b/frontend/src/component/about/footer.vue index f9af06650..9d6cb444d 100644 --- a/frontend/src/component/about/footer.vue +++ b/frontend/src/component/about/footer.vue @@ -13,7 +13,7 @@ 3rd-party software packages - © 2018-2026 PhotoPrism UG + © 2018-2025 PhotoPrism UG diff --git a/frontend/src/component/action/menu.vue b/frontend/src/component/action/menu.vue index fb8d1608c..fe6c73dd4 100644 --- a/frontend/src/component/action/menu.vue +++ b/frontend/src/component/action/menu.vue @@ -63,15 +63,9 @@ export default { return { visible: false, actions: [], + openOnHover: !this.$util.hasTouch(), }; }, - computed: { - // openOnHover reactively reflects the user's menu open-on-hover preference so a settings - // change applies without a page reload (persistent menus keep no mount-time snapshot). - openOnHover() { - return this.$util.shouldOpenOnHover(); - }, - }, methods: { show() { this.actions = this.items().filter((action) => action.visible); diff --git a/frontend/src/component/album/edit/dialog.vue b/frontend/src/component/album/edit/dialog.vue index f8d0acb4b..bae854e20 100644 --- a/frontend/src/component/album/edit/dialog.vue +++ b/frontend/src/component/album/edit/dialog.vue @@ -96,7 +96,6 @@ diff --git a/frontend/src/component/defaults.js b/frontend/src/component/defaults.js index 0fe136e3d..0d1e3b69b 100644 --- a/frontend/src/component/defaults.js +++ b/frontend/src/component/defaults.js @@ -184,8 +184,7 @@ export default { ripple: false, }, VDataTable: { - // Forwarded to the footer only as the "items per page" select's active-item color (not the table). - color: "surface-variant", + color: "background", itemsPerPage: -1, hover: true, }, diff --git a/frontend/src/component/lightbox.vue b/frontend/src/component/lightbox.vue index 674eb0663..317eee70c 100644 --- a/frontend/src/component/lightbox.vue +++ b/frontend/src/component/lightbox.vue @@ -22,7 +22,6 @@ @keydown.tab="onTabKey" @click.capture="captureDialogClick" @pointerdown.capture="captureDialogPointerDown" - @wheel.capture="captureDialogWheel" > @@ -170,7 +128,6 @@ import * as media from "common/media"; import { getAppSessionStorage, getAppStorage } from "common/storage"; import * as contexts from "options/contexts"; import { $faceMarkers } from "common/face-markers"; -import { createSphereViewer, destroySphereViewer, findSphereVideoElement, is360Equirectangular } from "common/sphere"; const VIDEO_EVENT_TYPES = [ "loadstart", @@ -193,10 +150,6 @@ const VIDEO_EVENT_TYPES = [ const VIDEO_REMOTE_EVENT_TYPES = ["connect", "connecting", "disconnect"]; -// Max pointer travel (px) for a press on a 360° sphere to still count as a tap -// rather than a pan, used to toggle the lightbox controls on touch devices. -const SPHERE_TAP_SLOP = 10; - import PLightboxMenu from "component/lightbox/menu.vue"; import PLightboxSidebar from "component/lightbox/sidebar.vue"; import { Marker } from "model/marker"; @@ -217,11 +170,6 @@ const shouldHideCaption = () => { return appStorage.getItem("lightbox.caption") === "false"; }; -// Most recent Escape KeyboardEvent handled by onEscapeKey; comparing identity -// collapses the press's duplicate dispatch (see onEscapeKey) into one unwind. -// Module-scoped rather than instance state — PLightbox is mounted once per session. -let _lastEscapeEvent = null; - export default { name: "PLightbox", components: [PLightboxMenu, PLightboxSidebar], @@ -711,29 +659,6 @@ export default { loading: false, }; - // Route equirectangular 360° media to the lazy-loaded sphere viewer before the video branch, - // since panoramic videos are also Playable and would otherwise fall through. is360Equirectangular - // routes on the equirectangular projection when present, and falls back to the 2:1 frame for - // panorama-flagged videos that carry no readable projection tag — cubemap and ultrawide clips - // stay flat. See common/sphere.js for the discriminator. - const isEquirect = is360Equirectangular(model); - if (isEquirect && model?.Hash) { - const isVideo = model?.Type === media.Video || model?.Type === media.Animated; - // Request the largest available size so 360° photos stay crisp when zoomed; $util.thumb - // clamps to the biggest size the server advertises (fit_15360 when the on-demand limit allows). - const src = isVideo ? this.$util.videoUrl(model.Hash, model?.Codec, model?.Mime) : this.$util.thumb(model.Thumbs, 15360, 8640).src; - return { - type: "html", - html: `
`, - model: model, - isSphere: true, - isVideo: isVideo, - src: src, - msrc: img.src, - loading: true, - }; - } - // Check if content is playable and return the data needed to render it in "contentLoad". if (model?.Playable && model?.Hash) { /* @@ -769,164 +694,14 @@ export default { return img; }, isContentZoomable(isContentZoomable, content) { - if (content.data?.isSphere) { - return false; - } if (content.data?.model?.Type === media.Live) { isContentZoomable = true; } return isContentZoomable; }, - // slideZoomable reports whether a slide supports the flat zoom button and - // pinch/click-to-zoom. 360° sphere slides own their zoom/pan, and videos and - // animations are never flatly zoomable; the result drives the `.is-zoomable` - // class that shows or hides the PhotoSwipe zoom button. - slideZoomable(data) { - if (data?.isSphere) { - return false; - } - return data?.model?.Type !== media.Video && data?.model?.Type !== media.Animated; - }, - // trapSphereGestures stops PhotoSwipe's swipe/zoom gesture detection from running - // while the user interacts with a 360° sphere. It swallows pointer + wheel events - // on the sphere container during the bubble phase, before they reach PhotoSwipe's - // listeners on the scroll wrapper above it. - // - // Touch events are deliberately NOT trapped: PhotoSwipe binds pointer events on our - // browser baseline (it only falls back to touch when PointerEvent is unavailable), - // while Photo Sphere Viewer drives panning from touchmove/touchend listeners bound on - // `window`. A bubble-phase stopPropagation here would keep those events from reaching - // PSV and break 360° panning on touch devices. UI buttons (close, prev/next, sidebar) - // live on the PhotoSwipe wrapper outside this container and stay clickable. - // - // Trapping the pointer events also swallows PhotoSwipe's tap detection, which is what - // reveals the prev/next arrows and top bar on touch devices. To restore that, a short - // press without a pan toggles the controls here. Only touch/pen taps do so — mouse - // users still get the controls via mousemove, so desktop behavior is unchanged. - // - // Pausing a running slideshow on interaction is NOT done here — the dialog's capture - // handlers (captureDialogPointerDown / captureDialogWheel) own that for every slide type. - // The tap-toggle only reads the `_slideshowPausedByPointer` flag they set, so a tap that - // paused the slideshow lands on the paused view with the revealed controls left intact. - trapSphereGestures(el) { - const stop = (e) => e.stopPropagation(); - let tapX = 0; - let tapY = 0; - let tapping = false; - el.addEventListener( - "pointerdown", - (e) => { - e.stopPropagation(); - tapping = e.pointerType !== "mouse"; - tapX = e.clientX; - tapY = e.clientY; - }, - { capture: false } - ); - el.addEventListener( - "pointerup", - (e) => { - e.stopPropagation(); - // Skip the toggle when the dialog's capture handler paused the slideshow on this - // pointer: pauseSlideshow() already revealed the controls, so toggling would hide them. - if (tapping && !this._slideshowPausedByPointer && Math.abs(e.clientX - tapX) < SPHERE_TAP_SLOP && Math.abs(e.clientY - tapY) < SPHERE_TAP_SLOP) { - this.toggleControls(); - } - tapping = false; - }, - { capture: false } - ); - el.addEventListener( - "pointercancel", - (e) => { - e.stopPropagation(); - tapping = false; - }, - { capture: false } - ); - ["pointermove", "wheel"].forEach((type) => { - el.addEventListener(type, stop, { capture: false }); - }); - }, - // setSphereClass toggles the `pswp--sphere` marker on the PhotoSwipe root element so - // CSS can keep the prev/next arrows reachable on touch devices for 360° slides, where - // swipe is captured for panning instead of navigation. PhotoSwipe hides the arrows on - // touch by default, leaving such slides with no way to switch photos otherwise. - setSphereClass(enabled) { - const el = this.pswp()?.element; - if (el?.classList) { - el.classList.toggle("pswp--sphere", enabled); - } - }, onContentLoad(ev) { const { content } = ev; - if (content.data?.isSphere) { - ev.preventDefault(); - - try { - const sphereEl = document.createElement("div"); - sphereEl.setAttribute("class", "pswp__media pswp__media--sphere"); - sphereEl.style.width = "100%"; - sphereEl.style.height = "100%"; - sphereEl.style.touchAction = "none"; - this.trapSphereGestures(sphereEl); - - content.element = sphereEl; - content.state = "loading"; - content.data.loading = false; - content.onLoaded(); - - createSphereViewer(sphereEl, content.data.src, { isVideo: content.data.isVideo, muted: this.muted }) - .then((viewer) => { - content.data.sphereViewer = viewer; - // For 360° videos, expose the underlying