Compare commits

..

164 Commits

Author SHA1 Message Date
github-actions
45a0315606 chore: version v2.3.0 2025-11-19 17:46:53 +00:00
Weblate (bot)
3856d4053c chore(web): update translations (#23449)
Translate-URL: https://hosted.weblate.org/projects/immich/immich/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ar/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/be/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/bg/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/bi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ca/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/cs/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/da/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/de/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/es/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/et/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fa/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/gl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/he/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/id/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/it/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ja/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ko/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/lt/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/lv/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/mr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/nl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pt/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ro/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ru/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sk/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sv/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ta/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/te/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/th/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/tr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/uk/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/vi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/zh_SIMPLIFIED/
Translation: Immich/immich

Co-authored-by: 100daysummer <bobbydochev@gmail.com>
Co-authored-by: Abhijeet Bonde <abhijeetbonde19@gmail.com>
Co-authored-by: AbuKareem Tuffaha <abukareem.tuffaha@gmail.com>
Co-authored-by: Adam Uchmanowicz <auchmanowicz@gmail.com>
Co-authored-by: Adrian Jost <github@adrianjost.dev>
Co-authored-by: Aitor-RM <Aitor.Rufian@alu.uclm.es>
Co-authored-by: Alexander Lohnes <alex.lohnes@googlemail.com>
Co-authored-by: Alexis-Loskoutoff <alexis@pctraining.fr>
Co-authored-by: Alma Hassan <almahassan9988@gmail.com>
Co-authored-by: AndreiP28 <andreiprica28@gmail.com>
Co-authored-by: Artur Koziara <arturkoziara@gmail.com>
Co-authored-by: Bryan Saputra <bryananta@icloud.com>
Co-authored-by: Carlo_Mava <carlomavaracchio@gmail.com>
Co-authored-by: Cristian Florin Tănase <crissssty@gmail.com>
Co-authored-by: Cristiano Fagundes <fagundescristianof@gmail.com>
Co-authored-by: Daniel Rieiro <daniel@danielrieiro.com>
Co-authored-by: DevServs <bonov@mail.ru>
Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Fred <freddyfunk@users.noreply.hosted.weblate.org>
Co-authored-by: Hossein Fani <linr@users.noreply.hosted.weblate.org>
Co-authored-by: Hurricane-32 <rodrigorimo@hotmail.com>
Co-authored-by: Indrek Haav <indrek.haav@hotmail.com>
Co-authored-by: Ivan Dimitrov <idimitrov08@gmail.com>
Co-authored-by: Jeppe Nellemann <jepnel@proton.me>
Co-authored-by: Jesús Jiménez <jesjimenez@gmail.com>
Co-authored-by: Johannes Dorn <johannes@dorn.email>
Co-authored-by: Jordy H <jordy@hoebergen.net>
Co-authored-by: Jorge Tristan <trisjor1998@gmail.com>
Co-authored-by: Jozef Gaal <preklady@mayday.sk>
Co-authored-by: Juanma Sanchez <juxmix@gmail.com>
Co-authored-by: Junghyuk Kwon <kwon@junghy.uk>
Co-authored-by: Kai Heine <kai-heine@users.noreply.hosted.weblate.org>
Co-authored-by: Knight Hat <knightchanelgaming@gmail.com>
Co-authored-by: Krissada Singhakachain <46844213+OmsinKrissada@users.noreply.github.com>
Co-authored-by: Leigh van der merwe <palitu822@gmail.com>
Co-authored-by: Leo Bottaro <github@leobottaro.com>
Co-authored-by: Luca Segato <luspy89@hotmail.it>
Co-authored-by: Lucas Jaksys <lucas3033@gmail.com>
Co-authored-by: Luís Nunes <lmcnunes@gmail.com>
Co-authored-by: Macgyver <macgyver@users.noreply.hosted.weblate.org>
Co-authored-by: Marc Casillas <mcasillassu@gmail.com>
Co-authored-by: Marco Perrotta <leondaval18@gmail.com>
Co-authored-by: MatijaThe245th <matija245matakovic@gmail.com>
Co-authored-by: Matjaž T. <matjaz@moj-svet.si>
Co-authored-by: Matteo D. <alex3025game@gmail.com>
Co-authored-by: Matteo De Carli <matteo.de.carli01@gmail.com>
Co-authored-by: Mees Frensel <meesfrensel@gmail.com>
Co-authored-by: Melvin Snijders <mail@melvinsnijders.nl>
Co-authored-by: Mārtiņš Bruņenieks <martinsb@gmail.com>
Co-authored-by: Parms <shoppingpar+weblate@simplelogin.com>
Co-authored-by: Paul <paul.kunad@kabelmail.de>
Co-authored-by: Petri Hämäläinen <petri.hamalainen@mailbox.org>
Co-authored-by: Philip Goto <philip.goto@gmail.com>
Co-authored-by: Pitoune <p.dhebrail@proton.me>
Co-authored-by: Ponas <le.slab124@aleeas.com>
Co-authored-by: PontusÖsterlindh <pontus@osterlindh.com>
Co-authored-by: Rasmus Sehlin <rasmus@sehl.in>
Co-authored-by: Richard Gráčik <r.gracik@gmail.com>
Co-authored-by: Roi Gabay <roigby@gmail.com>
Co-authored-by: Runskrift <anders@rimfrost.nu>
Co-authored-by: Ryan Gleeson <gleeson.ryanj@gmail.com>
Co-authored-by: S M, Aravinth (A.) <asm1@ford.com>
Co-authored-by: Sai Athulith Neela <saiathulithn@gmail.com>
Co-authored-by: Sebastiano <sebastiano.romi@gmail.com>
Co-authored-by: Sergey Katsubo <skatsubo@gmail.com>
Co-authored-by: Shawn <xiaxinx@gmail.com>
Co-authored-by: Sylvain Pichon <service@spichon.fr>
Co-authored-by: TV Box <realceday.tvbox@gmail.com>
Co-authored-by: Tanishq <weblate.impure434@passinbox.com>
Co-authored-by: Tatsuhiko Kono <kono@takenoko.io>
Co-authored-by: Tedy25879 <tedy25879@gmail.com>
Co-authored-by: Thanh Tùng Nguyễn <tung.nguyent03@gmail.com>
Co-authored-by: Toine Rademacher <hi@toine.zip>
Co-authored-by: Tomi Pöyskö <tomi.poysko@gmail.com>
Co-authored-by: User 123456789 <user123456789@users.noreply.hosted.weblate.org>
Co-authored-by: Vegard Fladby <vegard@fladby.org>
Co-authored-by: anton garcias <isaga.percompartir@gmail.com>
Co-authored-by: eav5jhl0 <eav5jhl0@users.noreply.hosted.weblate.org>
Co-authored-by: gablilli <gabriele.lilli0511@gmail.com>
Co-authored-by: kiwinho <kiwicaja@gmail.com>
Co-authored-by: pyccl <changcongliang@163.com>
Co-authored-by: r64 <me@ruka64.dev>
Co-authored-by: ruka-64 <202770393+ruka-64@users.noreply.github.com>
Co-authored-by: sam ng <andy.sam@gmail.com>
Co-authored-by: sh4tteredd <llor22658@gmail.com>
Co-authored-by: shiuh67 <shiuh.cheng@gmail.com>
Co-authored-by: swever <swever@users.noreply.hosted.weblate.org>
Co-authored-by: thehijacker <thehijacker@gmail.com>
Co-authored-by: ti-guru <anders.egeland@outlook.com>
Co-authored-by: ume <bungoume@gmail.com>
Co-authored-by: waclaw66 <waclaw66@seznam.cz>
Co-authored-by: Максим Горпиніч <gorpinicmaksim0@gmail.com>
2025-11-19 17:44:39 +00:00
bo0tzz
8175b3b75b fix: allow adding new translations files (#23998) 2025-11-19 16:00:01 +00:00
Alex
56e431226f feat: show OCR bounding box (#23717)
* feat: ocr bounding box

* bounding boxes

* pr feedback

* pr feedback

* allow copy across text boxes

* pr feedback
2025-11-19 15:52:40 +00:00
Daniel Dietzler
f59417cc77 chore(web): refactor replace asset (#23972) 2025-11-19 08:49:15 -06:00
Min Idzelis
11cec56e80 refactor(web): consolidate timeline API - merge addAssets/updateAssets into upsertAssets (#23985) 2025-11-19 08:48:16 -06:00
bo0tzz
810f22057c fix: create release as draft (#23996) 2025-11-19 14:46:14 +00:00
Min Idzelis
2152f20b6c fix: unarchive action doesn't update archive page (#23987) 2025-11-19 12:29:02 +01:00
Matthew Momjian
a6c76e78d6 fix(docs): update Readme links (#23959)
* fix(docs): Update star history links and image sources

* Update star history link in README.md
2025-11-18 21:32:11 -06:00
renovate[bot]
644a3bf090 chore(deps): update github-actions (#23962)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-18 21:32:00 -06:00
Min Idzelis
42dd3315f8 refactor(web): fix TimelineManager import - use value import instead of type-only (#23983) 2025-11-18 21:26:15 -06:00
Kevin Puertas
3a694219bf feat: add originalPath for external library assets in dedupe (#23710)
* Add original path info row to duplicate asset component

View path of images, useful when using external Library

* Make if for not show path in internal images

* Update web/src/lib/components/utilities-page/duplicates/duplicate-asset.svelte

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

* Refactor original path display logic in duplicate-asset

* Update duplicate-asset.svelte

* Add full path localization string

* Change translated data

* format: fix

---------

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2025-11-19 03:24:17 +00:00
Min Idzelis
d9fd52ea18 feat: timeline e2e tests (#23895)
* feat: timeline e2e tests

* Fix flakiness, mock all apis, allow parallel tests

* Upload playwright reports

* wrong report path

* Add CI=true, disable flaky/failing tests

* Re-enable tests, fix worker thread config

* fix maintance e2e test

* increase retries
2025-11-18 21:08:55 -06:00
Brandon Wees
2a281e7906 feat(mobile): location edit from asset viewer (#23925)
* chore: break sheet tile into own file

* feat: set location from bottom sheet

* refactor: location picker

There was a lot of confusing controls here, simplified to 1 mode

* fix: local asset check

* chore: refactoring of location details widget

* fix: update currentAssetExifProvider when changing location

* chore: use SheetTile for location header

* chore: remove coordinate change check

* chore: remove comment
2025-11-18 21:06:51 -06:00
Daniel Dietzler
5f987a95f5 fix: feature flags manager race condition (#23973)
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-11-19 03:05:53 +00:00
bo0tzz
edf577d7f7 feat: publish on release pr merge (#23867) 2025-11-18 21:03:49 -06:00
Sergey Katsubo
5e482dabc6 feat(server): support running medium tests in devcontainer (#23882)
* Support running medium tests in devcontainer

* Add "pnpm run test:medium" to the devcontainer doc

* Fix indentation for inline comments in the doc

* Fix a couple of words in the doc
2025-11-18 21:03:21 -06:00
Mees Frensel
76c73549ae feat(web): always view original of animated images (#23842) 2025-11-18 21:02:52 -06:00
Mees Frensel
271a42ac7f fix(server): copy relevant panorama tags to preview image (#23953) 2025-11-19 03:02:12 +00:00
bo0tzz
4462952564 fix: proper docker caching for plugin mise deps (#23967)
* fix: proper docker caching for plugin mise deps

* fix: mount mise cache for build too
2025-11-19 03:00:03 +00:00
shenlong
38d4d1a573 chore: reset remote sync on app update (#23969)
reset remote sync on update

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-19 02:55:01 +00:00
Daniel Dietzler
d310c6f3cd feat: library details page (#23908)
* feat: library details page

* chore: clean up

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
2025-11-18 15:27:41 -05:00
Alex
c086a65fa8 chore: update drift (#23877)
* chore: update drift

* update drift dep

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-18 16:07:33 +00:00
renovate[bot]
7134dd29ca chore(deps): pin ghcr.io/jdx/mise docker tag to ac26f59 (#23961)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-18 12:21:28 +01:00
renovate[bot]
3e08953a43 chore(deps): update dependency @types/node to ^22.19.1 (#23963)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-18 12:20:52 +01:00
Min Idzelis
58c3c7e26b feat: run e2e server in dev mode (#23921)
* feat: run e2e server in dev mode

* Use bash syntax: [[ and ==
2025-11-17 14:16:39 -06:00
Min Idzelis
237ddcb648 fix: incorrect header height calculation in estimated month height (#23923) 2025-11-17 14:14:06 -06:00
Min Idzelis
fbaeffd65c fix: flaky user-admin.e2e-spec.ts (#23929)
* fix: flaky user-admin.e2e-spec.ts

* lint
2025-11-17 14:12:44 -06:00
Min Idzelis
d64c339b4f fix: null dereference when canceling bucket in album (#23924) 2025-11-17 14:12:28 -06:00
Min Idzelis
69880ee165 fix: deep link to last asset (#23920) 2025-11-17 14:12:07 -06:00
Paul Makles
15e00f82f0 feat: maintenance mode (#23431)
* feat: add a `maintenance.enabled` config flag

* feat: implement graceful restart
feat: restart when maintenance config is toggled

* feat: boot a stripped down maintenance api if enabled

* feat: cli command to toggle maintenance mode

* chore: fallback IMMICH_SERVER_URL environment variable in process

* chore: add additional routes to maintenance controller

* fix: don't wait for nest application to close to finish request response

* chore: add a failsafe on restart to prevent other exit codes from preventing restart

* feat: redirect into/from maintenance page

* refactor: use system metadata for maintenance status

* refactor: wait on WebSocket connection to refresh

* feat: broadcast websocket event on server restart
refactor: listen to WS instead of polling

* refactor: bubble up maintenance information instead of hijacking in fetch function
feat: show modal when server is restarting

* chore: increase timeout for ungraceful restart

* refactor: deduplicate code between api/maintenance workers

* fix: skip config check if database is not initialised

* fix: add `maintenanceMode` field to system config test

* refactor: move maintenance resolution code to static method in service

* chore: clean up linter issues

* chore: generate dart openapi

* refactor: use try{} block for maintenance mode check

* fix: logic error in server redirect

* chore: include `maintenanceMode` key in e2e test

* chore: add i18n entries for maintenance screens

* chore: remove negated condition from hook

* fix: should set default value not override in service

* fix: minor error in page

* feat: initial draft of maintenance module, repo., worker controller, worker service

* refactor: move broadcast code into notification service

* chore: connect websocket on client if in maintenance

* chore: set maintenance module app name

* refactor: rename repository to include worker
chore: configure websocket adapter

* feat: reimplement maintenance mode exit with new module

* refactor: add a constant enum for ExitCode

* refactor: remove redundant route for maintenance

* refactor: only spin up kysely on boot (rather than a Nest app)

* refactor(web): move redirect logic into +layout file where modal is setup

* feat: add Maintenance permission

* refactor: merge common code between api/maintenance

* fix: propagate changes from the CLI to servers

* feat: maintenance authentication guard

* refactor: unify maintenance code into repository
feat: add a step to generate maintenance mode token

* feat: jwt auth for maintenance

* refactor: switch from nest jwt to just jsonwebtokens

* feat: log into maintenance mode from CLI command

* refactor: use `secret` instead of `token` in jwt terminology
chore: log maintenance mode login URL on boot
chore: don't make CLI actions reload if already in target state

* docs: initial draft for maintenance mode page

* refactor: always validate the maintenance auth on the server

* feat: add a link to maintenance mode documentation

* feat: redirect users back to the last page they were on when exiting maintenance

* refactor: provide closeFn in both maintenance repos.

* refactor: ensure the user is also redirected by the server

* chore: swap jsonwebtoken for jose

* refactor: introduce AppRestartEvent w/o secret passing

* refactor: use navigation goto

* refactor: use `continue` instead of `next`

* chore: lint fixes for server

* chore: lint fixes for web

* test: add mock for maintenance repository

* test: add base service dependency to maintenance

* chore: remove @types/jsonwebtoken

* refactor: close database connection after startup check

* refactor: use `request#auth` key

* refactor: use service instead of repository
chore: read token from cookie if possible
chore: rename client event to AppRestartV1

* refactor: more concise redirect logic on web

* refactor: move redirect check into utils
refactor: update translation strings to be more sensible

* refactor: always validate login (i.e. check cookie)

* refactor: lint, open-api, remove old dto

* refactor: encode at point of usage

* refactor: remove business logic from repositories

* chore: fix server/web lints

* refactor: remove repository mock

* chore: fix formatting

* test: write service mocks for maintenance mode

* test: write cli service tests

* fix: catch errors when closing app

* fix: always report no maintenance when usual API is available

* test: api e2e maintenance spec

* chore: add response builder

* chore: add helper to set maint. auth cookie

* feat: add SSR to maintenance API

* test(e2e): write web spec for maintenance

* chore: clean up lint issues

* chore: format files

* feat: perform 302 redirect at server level during maintenance

* fix: keep trying to stop immich until it succeeds (CLI issue)

* chore: lint/format

* refactor: annotate references to other services in worker service

* chore: lint

* refactor: remove unnecessary await

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

* refactor: move static methods into util

* refactor: assert secret exists in maintenance worker

* refactor: remove assertion which isn't necessary anymore

* refactor: remove assertion

* refactor: remove outer try {} catch block from loadMaintenanceAuth

* refactor: undo earlier change to vite.config.ts

* chore: update tests due to refactors

* revert: vite.config.ts

* test: expect string jwt

* chore: move blanket exceptions into controllers

* test: update tests according with last change

* refactor: use respondWithCookie
refactor: merge start/end into one route
refactor: rename MaintenanceRepository to AppRepository
chore: use new ApiTag/Endpoint
refactor: apply other requested changes

* chore: regenerate openapi

* chore: lint/format

* chore: remove secureOnly for maint. cookie

* refactor: move maintenance worker code into src/maintenance\nfix: various test fixes

* refactor: use `action` property for setting maint. mode

* refactor: remove Websocket#restartApp in favour of individual methods

* chore: incomplete commit

* chore: remove stray log

* fix: call exitApp from maintenance worker on exit

* fix: add app repository mock

* fix: ensure maintenance cookies are secure

* fix: run playwright tests over secure context (localhost)

* test: update other references to 127.0.0.1

* refactor: use serverSideEmitWithAck

* chore: correct the logic in tryTerminate

* test: juggle cookies ourselves

* chore: fix lint error for e2e spec

* chore: format e2e test

* fix: set cookie secure/non-secure depending on context

* chore: format files

---------

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
2025-11-17 17:15:44 +00:00
Jason Rasmussen
ce82e27f4b fix: workflow medium tests (#23952) 2025-11-17 16:26:30 +00:00
Yaros
eeee5147cc fix(mobile): delete from device warning shows incorrectly (#23935)
fix(mobile): delete warning on multiple assets
2025-11-17 10:17:04 -06:00
100daysummer
af22f9b014 fix: word wrap on custom link preview (#23942)
Word break fix in create link

Adds the "break-all" tailwind style to the slug text under the custom link text box
2025-11-17 08:49:32 -05:00
Paul Makles
1086f22166 fix: devcontainer server not starting due to missing plugins mount (#23948) 2025-11-17 12:24:59 +01:00
Christian
e94eb5012f feat(mobile): add to album from asset viewer (#23608)
* feat: add action button in photo viewer for adding assets to albums, archiving, and moving to locked folders

* fix: use const constructors for icons in action button menu

* Update mobile/lib/presentation/widgets/action_buttons/add_action_button.widget.dart

Co-authored-by: Brandon Wees <brandonwees@gmail.com>

* Update mobile/lib/presentation/widgets/asset_viewer/bottom_bar.widget.dart

Co-authored-by: Brandon Wees <brandonwees@gmail.com>

* remove de translation

* fixed PR comments: https://github.com/immich-app/immich/pull/23608

* menu styling

* menu styling

* i18n

---------

Co-authored-by: Brandon Wees <brandonwees@gmail.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-11-14 15:11:47 -06:00
Alex
4dcc049465 feat: workflow foundation (#23621)
* feat: plugins

* feat: table definition

* feat: type and migration

* feat: add repositories

* feat: validate manifest with class-validator and load manifest info to database

* feat: workflow/plugin controller/service layer

* feat: implement workflow logic

* feat: make trigger static

* feat: dynamical instantiate plugin instances

* fix: access control and helper script

* feat: it works

* chore: simplify

* refactor: refactor and use queue for workflow execution

* refactor: remove unsused property in plugin-schema

* build wasm in prod

* feat: plugin loader in transaction

* fix: docker build arm64

* generated files

* shell check

* fix tests

* fix: waiting for migration to finish before loading plugin

* remove context reassignment

* feat: use mise to manage extism tools (#23760)

* pr feedback

* refactor: create workflow now including create filters and actions

* feat: workflow medium tests

* fix: broken medium test

* feat: medium tests

* chore: unify workflow job

* sign user id with jwt

* chore: query plugin with filters and action

* chore: read manifest in repository

* chore: load manifest from server configs

* merge main

* feat: endpoint documentation

* pr feedback

* load plugin from absolute path

* refactor:handle trigger

* throw error and return early

* pr feedback

* unify plugin services

* fix: plugins code

* clean up

* remove triggerConfig

* clean up

* displayName and methodName

---------

Co-authored-by: Jason Rasmussen <jason@rasm.me>
Co-authored-by: bo0tzz <git@bo0tzz.me>
2025-11-14 20:05:05 +00:00
Jason Rasmussen
d784d431d0 refactor: job vs queue naming (#23902) 2025-11-14 14:42:00 -05:00
Daniel Dietzler
1200bfad13 refactor: server config and feature flags managers (#23894) 2025-11-14 14:10:44 -05:00
Jason Rasmussen
f11bfb9581 fix(server): broken memories (#23896) 2025-11-14 11:46:32 -05:00
Daniel Dietzler
074fdb2b96 fix: out of sync pnpm lockfile (#23891) 2025-11-14 12:13:09 +01:00
Daniel Dietzler
f1f203719d refactor: admin settings (#23843) 2025-11-13 13:17:44 -05:00
zebrapurring
f73ca9d9c0 chore: build bcrypt dependency from source (#22145)
This may provide better performance on some cases and guarantee cross-platform compatibility

Co-authored-by: zebrapurring <>
2025-11-13 12:12:01 -05:00
renovate[bot]
ad3f4fb434 chore(deps): update dependency validator to v13.15.20 [security] (#23284)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-13 17:37:51 +01:00
Juan Roa
8001dedcbf fix(web): keep album timeline when selecting cover (#23819) 2025-11-13 16:30:24 +00:00
Hritik V
07a39226c5 chore: include link to discord server when referencing contribution channel (#23728)
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2025-11-13 16:27:26 +00:00
shenlong
88e7e21683 fix: prefer filename from body over path in mime validation (#23810)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-13 17:26:34 +01:00
idubnori
2cefbf8ca3 chore: add "pnpm run migrations:revert" command (#23869) 2025-11-13 10:12:59 -06:00
Jason Rasmussen
4a6c50cd81 feat: endpoint versioning (#23858) 2025-11-13 08:18:43 -05:00
Daniel Dietzler
e0535e20e6 chore: cleanup web (#23866) 2025-11-13 12:51:17 +00:00
bo0tzz
62580455af fix: use changelog file instead of PR body (#23864) 2025-11-13 10:35:30 +00:00
Daniel Dietzler
0e7e67efe1 fix: timeline scroll after navigate (#23664) 2025-11-13 11:28:42 +01:00
Sergey Katsubo
2c54b506b3 fix(server): include the previous year in memories for January 1, 2, 3 (#23832)
* Test memory creation in advance

Use year 2035 to make sure it's in the future of current time of a test run

* Use target year instead of current year when fetching assets during memory creation

This fixes an edge case of creating memories in advance when target year is
different from current year.
Example: job runs on 2025-12-31 (current year is 2025) and creates memories
to be shown on 2026-01-01 (target year is 2026). If using _current_ year in
calculation then range of years is capped at (2025 - 1 = 2024) thus excluding
2025-01-01 from created memories. With _target_ year it is (2026 - 1 = 2025),
so 2025-01-01 will be included in memories.

* Update sql queries
2025-11-12 15:38:03 -06:00
Alex
8969b8bdb2 fix: GHA build issue on iOS (#23849)
* fix: GHA build issue on iOS

* fix: resolve Swift Package dependencies in GitHub Actions

* fix: use Release configuration for iOS build

* fix: simplify code signing for build-only lane

* fix: explicitly resolve Swift packages before building

* fix: use specified XCode version
2025-11-12 15:32:08 -06:00
Alexander Sulfrian
5186092faa fix: Update module name for rapidocr DownloadFile (#23838) 2025-11-12 18:43:00 +00:00
bo0tzz
4c9142308f fix: use app token for github-script run (#23852) 2025-11-12 19:16:09 +01:00
bo0tzz
bea5d4fd37 fix: release-pr workflow fixes (#23850) 2025-11-12 18:25:32 +01:00
bo0tzz
74c24bfa88 fix: pump-version.sh flags (#23848) 2025-11-12 17:47:52 +01:00
bo0tzz
95834c68d9 fix: bump args order (#23846) 2025-11-12 17:31:25 +01:00
bo0tzz
09024c3558 fix: release-pr script name (#23844) 2025-11-12 16:24:39 +00:00
bo0tzz
137cb043ef feat: track next release in pull request (#23806) 2025-11-12 17:19:18 +01:00
Mees Frensel
edf21bae41 feat(web): disable searching by disabled features (#23798)
fix(web): disable searching by disabled features
2025-11-12 09:19:18 -06:00
shenlong
c958f9856d chore: bump background_downloader (#23839)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-12 09:17:44 -06:00
Daniel Dietzler
70ab8bc657 refactor: shared links modals (#23803) 2025-11-12 12:57:53 +01:00
Jason Rasmussen
edde0f93ae feat: endpoint descriptions (#23813) 2025-11-11 17:01:14 -05:00
Alex
896665bca9 fix: iOS release build dependency verification (#23814) 2025-11-11 15:35:44 -06:00
renovate[bot]
e8e9e7830e chore(deps): update github-actions (major) (#23812)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: bo0tzz <git@bo0tzz.me>
2025-11-11 20:04:22 +00:00
Mees Frensel
4fd9e42ce5 feat(web): animate gifs on hover (#23198) 2025-11-11 10:22:53 -06:00
idubnori
337e3a8dac feat(mobile): album activity deep link (#23737)
* feat: add activity deep link support in DeepLinkService

* test: add unit tests for DeepLinkService handling of activity deep links

* Revert "test: add unit tests for DeepLinkService handling of activity deep links"

This reverts commit 0b1914be9a.
2025-11-11 10:04:54 -06:00
renovate[bot]
2dc81e28fc chore(deps): update github-actions (#23582)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-11 16:25:36 +01:00
bo0tzz
f915d4cc90 fix: disable ruby updates (#23794)
Until https://github.com/fastlane/fastlane/issues/29183 is fixed
2025-11-11 14:51:21 +00:00
Mees Frensel
905f4375b0 fix(web): make sliding window cover all visible space to show small number of assets (#23796) 2025-11-11 08:50:31 -06:00
David Wolff
0b3633db4f fix(server): properly handle HEAD requests to SSR paths (#23788) 2025-11-11 07:47:11 -05:00
Jason Rasmussen
2f40f5aad8 refactor: user admin service (#23785) 2025-11-11 07:42:33 -05:00
renovate[bot]
2611e2ec20 chore(deps): update dependency exiftool-vendored to v31.3.0 (#23787)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-11 13:35:36 +01:00
renovate[bot]
433a3cd339 chore(deps): update dependency @types/node to ^22.19.0 (#23786)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-10 23:50:50 -05:00
Jason Rasmussen
0b487897a4 refactor: shared link service (#23775) 2025-11-10 16:17:18 -05:00
Jason Rasmussen
d5c5bdffcb refactor: album delete (#23773) 2025-11-10 16:10:29 -05:00
Jason Rasmussen
dea95ac2e6 refactor: shared-link service (#23770) 2025-11-10 20:49:02 +00:00
Mert
9e2208b8dd chore(mobile): add table schemas to swift (#23749)
* add schemas

* handle json, improve type safety

* formatting

* sync variants

* formatting
2025-11-10 20:21:08 +00:00
Alex
6922a92b69 feat: show update version info (#23698)
* feat: show update version info

* Apply suggestions from code review

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

---------

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
2025-11-10 14:19:27 -06:00
exelix
7a2c8e0662 feat(mobile): Quick date picker in the search page (#22653)
* Quick date picker

* Include current year in quick date picker

* Quick date picker: localization, fix datetime overflows

* Properly localized 'last_months'

* Move quick_date_picker.dart to lib/presentation/widgets/search

* Wrap the quick date picker state into its own class, improve the interaction patterns

* Fix last9Months value

* Improve method naming

* Subtitle for "custom range" in quick date picker

* Fix style warnings

* Fix lint warning

* fix:  mobile unawaited_futures lint (#21661)

* chore: add unawaited_futures lint as warning

* remove unused dcm lints

They will be added back later on a case by case basis

* fix warning

* auto gen file

* review changes

* conflict resolution

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>

* Quick date picker

* Wrap the quick date picker state into its own class, improve the interaction patterns

* chore: delete file from rebase

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: bwees <brandonwees@gmail.com>
2025-11-10 13:55:09 -06:00
renovate[bot]
787158247f fix(deps): update typescript-projects (#23588)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2025-11-10 19:50:19 +00:00
idubnori
b0a0b7c2e1 feat(mobile): chat-style for asset activity view (#23347)
* feat(mobile): open assetviewer via album activities page

* adjust ui behavior: keep current asset & disable initial forcus

* init of v2...

* refactoring...

* refactor: remove _DismissibleWrapper

* feat: initial scrolling to bottom

* refactor: use feature toggle

* refactor: new route page

* fix: file name, dcm analyze

* fix: test failure

* fix: remove toggle and the exisitng style based on review feedback

* refactorr: rename methods for clarity in comment bubble widget

* feat: (mobile) chat-style asset activity timeline

* chore: extract as a new file

* chore: styling (based on 2c12bc56)

* chore: clean up

* fix: albumActivityProvider parameter

* fix: review point

* fix
2025-11-10 13:26:27 -06:00
idubnori
cb6d81771d fix(mobile): sync album and asset activity state when add/remove asset level activity (#23484)
* fix; sync album-asset state when remove activity

* make build

* fix: support adding case

* make build

* Update mobile/lib/providers/activity.provider.dart

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>

* fix: add missing import for collection package

* make build

---------

Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
2025-11-10 13:25:43 -06:00
Jason Rasmussen
8de6ec1a1b refactor: album service (#23768) 2025-11-10 13:40:58 -05:00
Daniel Dietzler
d27c01ef70 chore: migrate remaining usages of the logo to use the UI lib (#23430) 2025-11-10 19:16:49 +01:00
Noel S
d6307b262f fix(mobile): Hide download button in asset viewer "immersive mode" (#23720)
* Hide download FAB in asset viewer immersive mode

* Remove commented out code

* Remove more comments
2025-11-10 12:13:04 -06:00
Viktor Mykhailiv
b2cbefe41e fix(mobile): Set dynamic height of actions row in BottomSheet (#23755)
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-11-10 12:03:12 -06:00
shenlong
da5a72f6de chore: patch MemoriesResponse (#23764)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-10 11:37:45 -06:00
Jason Rasmussen
45304f1211 refactor: view shared link (#23766) 2025-11-10 12:21:26 -05:00
Jason Rasmussen
a4e65a7ea8 refactor: albums-list (#23765) 2025-11-10 11:49:59 -05:00
Daniel Dietzler
dd393c8346 feat(web): event handler component (#23763) 2025-11-10 11:49:46 -05:00
Peter Ombodi
493cde9d55 feat: opt-in sync of deletes and restores from web to Android (beta timeline) (#20473)
* feature(mobile, beta, Android): handle remote asset trash/restore events and rescan media
- Handle move to trash and restore from trash for remote assets on Android
- Trigger MediaScannerConnection to rescan affected media files

* feature(mobile, beta, Android): fix rescan

* fix imports

* fix checking conditions

* refactor naming

* fix line breaks

* refactor code
rollback changes in BackgroundServicePlugin

* refactor code (use separate TrashService)

* refactor code

* parallelize restoreFromTrash calls with Future.wait
format trash.provider.dart

* try to re-format trash.provider.dart

* re-format trash.provider.dart

* rename TrashService to TrashSyncService to avoid duplicated names
revert changes in original trash.provider.dart

* refactor code (minor nitpicks)

* process restoreFromTrash sequentially instead of Future.wait

* group local assets by checksum before moving to trash
delete LocalAssetEntity records when moved to trash
refactor code

* fix format

* use checksum for asset restoration
refactro code

* fix format

* sync trash only for backup-selected assets

* feat(db): add local_trashed_asset table and integrate with restoration flow
- Add new `local_trashed_asset` table to store metadata of trashed assets
- Save trashed asset info into `local_trashed_asset` before deletion
- Use `local_trashed_asset` as source for asset restoration
- Implement file restoration by `mediaId`

* resolve merge conflicts

* fix index creating on migration

* rework trashed assets handling
- add new table trashed_local_asset
- mirror trashed assets data in trashed_local_asset.
- compute checksums for assets trashed out-of-app.
- restore assets present in trashed_local_asset and non-trashed in remote_asset.
- simplify moving-to-trash logic based on remote_asset events.

* resolve merge conflicts
use updated approach for calculating checksums

* use CurrentPlatform instead _platform
fix mocks

* revert redundant changes

* Include trashed items in getMediaChanges
Process trashed items delta during incremental sync

* fix merge conflicts

* fix format

* trashed_local_asset table mirror of local_asset table structure
trashed_local_asset<->local_asset transfer data on move to trash or restore
refactor code

* refactor and format code

* refactor TrashedAsset model
fix missed data transfering

* refactor code
remove unused model

* fix label

* fix merge conflicts

* optimize, refactor code
remove redundant code and checking
getTrashedAssetsForAlbum for iOS
tests for hash trashed assets

* format code

* fix migration
fix tests

* fix generated file

* reuse exist checksums on trash data update
handle restoration errors
fix import

* format code

* sync_stream.service depend on repos
refactor assets restoration
update dependencies in tests

* remove trashed asset model
remove trash_sync.service
refactor DriftTrashedLocalAssetRepository, LocalSyncService

* rework fetching trashed assets data on native side
optimize handling trashed assets in local sync service
refactor code

* update NativeSyncApi on iOS side
remove unused code

* optimize sync trashed assets call in full sync mode
refactor code

* fix format

* remove albumIds from getTrashedAssets params
fix upsert in trashed local asset repo
refactor code

* fix getTrashedAssets params

* fix(trash-sync): clean up NativeSyncApiImplBase and correct applyDelta

* refactor(trash-sync): optimize performance and fix minor issues

* refactor(trash-sync): add missed index

* feat(trash-sync): remove sinceLastCheckpoint param from getTrashedAssets

* fix(trash-sync): fix target table

* fix(trash-sync): remove unused extension

* fix(trash-sync): remove unused code

* fix(trash-sync): refactor code

* fix(trash-sync): reformat file

* fix(trash_sync): refactor code

* fix(trash_sync): improve moving to trash

* refactor(trash_sync): integrate MANAGE_MEDIA permission request into login flow and advanced settings

* refactor(trash_sync): add additional checking for experimental trash sync flag and MANAGE_MEDIA permission.

* refactor(trash_sync): resolve merge conflicts

* refactor(trash_sync): fix format

* resolve merge conflicts
add await for alert dialog
add missed request

* refactor(trash_sync): rework MANAGE_MEDIA info widget
show rationale text in permission request alert dialog
refactor setting getter

* fix(trash_sync): restore missing text values

* fix(trash_sync): format file

* fix(trash_sync): check backup enabled and remove remote asset existence check

* fix(trash_sync): remove checking backup enabled
test(trash_sync): cover sync-stream trash/restore paths and dedupe mocks

* test(trash_sync): cover trash/restore flows for local_sync_service

* chore(e2e): restore test-assets submodule pointer

---------

Co-authored-by: Peter Ombodi <peter.ombodi@gmail.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-11-10 16:20:51 +00:00
Jason Rasmussen
7705c84b04 refactor(web): album service (#23762) 2025-11-10 11:06:40 -05:00
Matthew Momjian
ce0172b8c1 fix(docs): bump docs for PG versions (#23714) 2025-11-10 10:56:18 -05:00
bo0tzz
718b3a7b52 fix: mise tf task scope (#23761) 2025-11-10 15:49:44 +00:00
bo0tzz
8a73de018c feat: mise monorepo tasks (#23691) 2025-11-10 15:55:15 +01:00
Jonathan Gilbert
d92df63f84 feat: random memories sort order (#20025) 2025-11-10 09:38:50 -05:00
Mees Frensel
6c6b00067b fix(web): i18n for admin>users>sessions (#23756) 2025-11-10 12:48:17 +00:00
Mees Frensel
9cc88ed2a6 feat: make memories slideshow duration configurable (#22783) 2025-11-08 17:46:43 -05:00
renovate[bot]
4905bba694 chore(deps): update base-image to v202511041104 (major) (#23718)
chore(deps): update base-image to v202511041104

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-08 13:48:35 -06:00
Noel S
853d19dc2d fix(mobile): Add fade-in to asset viewer transition (#23692)
Add fade-in animation
2025-11-07 17:13:43 -06:00
Lukas
c935ae47d0 feat: lazy load thumbnails on people and place list (#23682)
perf(web): lazy load thumbnails on people and place list
2025-11-07 14:22:02 -06:00
fabianbees
93ab42fa24 feat(mobile): Show lens model information in the asset viewer detail panel (#23601)
* feat(mobile): add lens info to details bottom sheet

* fix unrelated typo

* order same like in web app: first exposure time, than iso
2025-11-07 17:10:59 +00:00
Mert
6913697ad1 feat(ml): multilingual ocr (#23527)
* handle other languages in ml server

* add variants to model selector

* no need to override path

* unused import
2025-11-06 12:58:41 -05:00
Mert
a4ae86ce29 feat(ml): add preload and fp16 settings for ocr (#23576) 2025-11-06 17:55:11 +00:00
Snowknight26
2c50f2e244 fix(web): add URLs to results in large files utility (#23617)
fix(web): add URLs to results in large files
2025-11-06 09:24:47 -05:00
shenlong
365abd8906 fix: check if unmetered instead of wifi (#23380)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-11-05 13:27:38 -06:00
Alex
25fb43bbe3 fix: fully sync local library on app restart (#23323) 2025-11-05 14:09:50 +00:00
bo0tzz
125e8cee01 chore: update config.json example (#23471)
* chore: update config.json example

closes #23465

* fix: format, for real this time
2025-11-05 08:05:53 -06:00
Arnaud Wery
c15e9bfa72 fix(web): "select all" button in trash and permanently deleted count (#23594) 2025-11-05 14:05:48 +00:00
Dmitry
35e188e6e7 docs: sync ru docs with main README.md (#23627) 2025-11-05 08:05:03 -06:00
Sergey Katsubo
3cc9dd126c fix(web): fix timezone dropdown for timestamps lacking milliseconds (#23615)
Fix timezone selector for timestamps without milliseconds
2025-11-05 08:03:55 -06:00
Jason Rasmussen
aa69d89b9f fix: bad merge (#23610) 2025-11-04 16:22:45 -05:00
Jason Rasmussen
29c14a3f58 refactor: database column names (#23356) 2025-11-04 16:03:21 -05:00
Jason Rasmussen
0df70365d7 feat: exif medium tests (#23561) 2025-11-04 16:03:02 -05:00
Mees Frensel
c34be73d81 fix(web): consistently use mdiMotionPauseOutline icon (#23595) 2025-11-04 12:12:47 +01:00
renovate[bot]
f396e9e374 chore(deps): update prom/prometheus docker digest to 4921475 (#23578)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-04 11:49:12 +01:00
renovate[bot]
821a9d4691 chore(deps): update redis:6.2-alpine docker digest to 37e0024 (#23579)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-04 11:48:21 +01:00
renovate[bot]
cad654586f chore(deps): update dependency @types/node to ^22.18.13 (#23581)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-04 11:47:54 +01:00
github-actions
28eb1bc13c chore: version v2.2.3 2025-11-04 03:14:34 +00:00
Brandon Wees
1e4779cf48 fix(mobile): ignore patch releases for app version alerts (#23565)
* fix(mobile): ignore patch releases for app version alerts

* chore: make difference type nullable to indicate when versions match

* chore: add error handling for semver parsing

* chore: tests
2025-11-03 21:09:32 -06:00
Sergey Katsubo
0647c22956 fix(mobile): handle empty original filename (#23469)
* Handle empty original filename

* Handle TypeError from photo_manager titleAsync

* More compact exception log
2025-11-03 21:09:18 -06:00
Alex
b8087b4fa2 chore: ios prod build with correct argument, get version number from pubspec (#23554)
* chore: ios prod build with correct argument, get version number from pubspec

* Update mobile/ios/fastlane/Fastfile

Co-authored-by: bo0tzz <git@bo0tzz.me>

---------

Co-authored-by: bo0tzz <git@bo0tzz.me>
2025-11-03 10:11:11 -06:00
Jonathan S
d94cb9641b chore: correct hosted isar paths in fdroid_build_isar.sh (#23529)
This should hopefully unblock F-Droid builds, which are a few versions behind.

Based on the suggestion in https://github.com/immich-app/immich/pull/22757#issuecomment-3404516987
2025-11-03 08:35:56 -06:00
Daniel Dietzler
517c3e1d4c fix: exif gps parsing of malformed data (#23551)
* fix: exif gps parsing of malformed data

* chore: e2e test
2025-11-03 09:02:41 -05:00
Ben
619de2a5e4 fix(web): search bar accessibility (#23550)
* fix: always show search type when search bar is focused

* fix: indicate search type to screen reader users
2025-11-03 08:31:57 -05:00
Mert
79d0e3e1ed fix(ml): ocr inputs not resized correctly (#23541)
* fix resizing, use pillow

* unused import

* linting

* lanczos

* optimizations

fused operations

unused import
2025-11-03 07:21:30 +00:00
github-actions
f5ff36a1f8 chore: version v2.2.2 2025-11-02 21:56:36 +00:00
Alex
b5efc9c16e fix: passing secrets to trigger workflow (#23447)
* fix: passing secrets to trigger workflow

* pass secrets to workflow call
2025-11-02 15:54:35 -06:00
Alex
1036076b0d fix: disable prunning for more investigation (#23531) 2025-11-02 15:54:03 -06:00
Daniel Dietzler
c76324c611 fix(web): mobile scrubber on page load (#23488) 2025-11-01 22:15:33 -05:00
bo0tzz
0ddb92e1ec fix: use pnpm directly for fix-format (#23483) 2025-11-01 15:38:18 -04:00
Alex
d08a520aa2 chore: post release tasks (#23443) 2025-11-01 01:21:39 -05:00
dotlambda
7bdf0f6c50 chore(ml): remove setuptools from dependencies (#23446) 2025-10-31 21:34:10 +00:00
shenlong
2b33a58448 fix: show in timeline from search page (#23440)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2025-10-31 14:55:28 -05:00
github-actions
b35f00f768 chore: version v2.2.1 2025-10-31 18:04:27 +00:00
Weblate (bot)
86cc7c3c73 chore(web): update translations (#23375)
Translate-URL: https://hosted.weblate.org/projects/immich/immich/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/da/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/de/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pt/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ru/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sv/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ta/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/tr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/zh_Hant/
Translation: Immich/immich

Co-authored-by: Akhil Raj Baranwal <akhil.r.baranwal@gmail.com>
Co-authored-by: Dennis Kjær Jensen <weblate@signout.dk>
Co-authored-by: DevServs <bonov@mail.ru>
Co-authored-by: Florian Amsallem <florian.amsallem@gmail.com>
Co-authored-by: Hurricane-32 <rodrigorimo@hotmail.com>
Co-authored-by: Kai Heine <kai-heine@users.noreply.hosted.weblate.org>
Co-authored-by: Marrick Schröder <marrick.schroeder@gmail.com>
Co-authored-by: Michael <parieren.gefuehl5g@icloud.com>
Co-authored-by: PontusÖsterlindh <pontus@osterlindh.com>
Co-authored-by: S M, Aravinth (A.) <asm1@ford.com>
Co-authored-by: User 123456789 <user123456789@users.noreply.hosted.weblate.org>
Co-authored-by: Vegard Fladby <vegard@fladby.org>
Co-authored-by: linux-universe <lauro@dilorenzo.one>
Co-authored-by: shiuh67 <shiuh.cheng@gmail.com>
Co-authored-by: slick-daddy <129640104+slick-daddy@users.noreply.github.com>
Co-authored-by: ti-guru <anders.egeland@outlook.com>
2025-10-31 18:02:30 +00:00
Alex
5854cbbe97 fix: show close button on purchase modal (#23436) 2025-10-31 17:47:14 +00:00
Alex
ceb36a304d fix: view in timeline does not jump to the timeline correctly (#23428) 2025-10-31 17:24:41 +00:00
Daniel Dietzler
f5d7e5acca chore: cannonical tailwind classes (#23427) 2025-10-31 11:38:17 -04:00
luneth
be15a84f9b chore: update android signing fingerprints to docs (#23361)
* Update mobile-app.mdx

Add certificate fingerprint for android releases.

* chore: formatting

* Chore: Typo

---------

Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2025-10-31 09:40:53 -05:00
Alex
32791e98c2 chore: trigger prod build on prepare-release (#23424)
* chore: trigger prod build on prepare-release

* clean up
2025-10-31 14:26:03 +00:00
Alex
7ea443b3a9 chore: gha ios release | take 5 (#23203)
* chore: gha ios release | take 5

* code signing

* code signing 2

* manual signing for extensions

* chore(ios): add explicit code signing identity and debug output

* dev appbundle

* Deployment flow for development app

* skip waiting for change log

* refactor

* fix: ruby version

* fix: manual release lane

* build on main
2025-10-31 09:05:03 -05:00
Alex
c69786b039 fix: button condition rendering (#23400) 2025-10-31 08:42:01 -05:00
Mert
5c7d5539ea fix(mobile): video seeking on android (#23405)
use int for seeking
2025-10-31 08:41:09 -05:00
Daniel Dietzler
3531856d1c refactor: api key modals (#23420) 2025-10-31 08:58:52 -04:00
Mert
4abaad548a fix(ml): ocr failing with rootless docker (#23402)
don't download font
2025-10-31 02:41:49 -04:00
Jonathan Jogenfors
61a2c3ace3 chore(server): clarify asset copy parameters (#23396) 2025-10-30 23:55:39 +00:00
Daniel Dietzler
e9038193db fix: asset copy validation error (#23387) 2025-10-30 19:40:58 -04:00
bo0tzz
3f5cd48a59 fix: don't use app token for cli push (#23378) 2025-10-30 21:31:56 +01:00
idubnori
4cb094e7ae fix(mobile): regression - not displayed activity button in top bar (#23366) 2025-10-30 14:39:36 -05:00
github-actions
57c8378ca7 chore: version v2.2.0 2025-10-30 14:42:44 +00:00
Weblate (bot)
b073f9b802 chore(web): update translations (#22937)
Translate-URL: https://hosted.weblate.org/projects/immich/immich/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ar/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/bg/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ca/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/cs/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/da/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/de/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/el/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/es/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/et/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/eu/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fa/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fil/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/fr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/gl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/he/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hi/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/hu/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/id/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/it/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ko/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/lt/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/lv/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/mk/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/mr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/nl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pt/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ro/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ru/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sk/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sr_Cyrl/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/sv/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/ta/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/th/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/tr/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/uk/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/immich/immich/zh_SIMPLIFIED/
Translation: Immich/immich

Co-authored-by: 0xflotus <0xflotus@gmail.com>
Co-authored-by: Aarón Rosa Díaz <sraaronrock@tuta.io>
Co-authored-by: Abhijeet Bonde <abhijeetbonde19@gmail.com>
Co-authored-by: Abraham Escalona <abrahamescalona@live.com>
Co-authored-by: Adam Havránek <adamhavra@seznam.cz>
Co-authored-by: Aitor Astorga <a.astorga.sdv@protonmail.com>
Co-authored-by: Alberto Serluca <alberto.ser11@gmail.com>
Co-authored-by: Alejandro Gonzalez <alejandrok5@gmail.com>
Co-authored-by: Alejandro Moya <alejandro_moya_moya@hotmail.com>
Co-authored-by: Alex <alex.osheter@gmail.com>
Co-authored-by: Alexis-Loskoutoff <alexis@pctraining.fr>
Co-authored-by: AndreiP28 <andreiprica28@gmail.com>
Co-authored-by: Antonio <1628876+antonio-ivanovski@users.noreply.github.com>
Co-authored-by: Beans <leey0818@gmail.com>
Co-authored-by: Benjamin GOUPIL <benjamin@goupil.bzh>
Co-authored-by: Blomblo <mr.blomblo@gmail.com>
Co-authored-by: Cyril CHARLIER <cyril.charlier@gmail.com>
Co-authored-by: Davide Vegliante <davidevegliante@gmail.com>
Co-authored-by: Denis Pacquier <denis.pacquier@gmail.com>
Co-authored-by: DevServs <bonov@mail.ru>
Co-authored-by: Devansh Sehgal <devanshsehgal02@gmail.com>
Co-authored-by: Diego Heras <ngosang@hotmail.es>
Co-authored-by: Durneztj <thibault.durnez@telenet.be>
Co-authored-by: Eetu Mäenpää <me@eetumaenpaa.fi>
Co-authored-by: Emil Friis Osmann <Emilfriisosmann@gmail.com>
Co-authored-by: Espen Faale <espen@faale.no>
Co-authored-by: Flyingfufu <fabien.fuster@icloud.com>
Co-authored-by: Frederick “Fredyy” Behrends <frederick.behrends@gmail.com>
Co-authored-by: Hamed Hojjati <hamed334@gmail.com>
Co-authored-by: Hurricane-32 <rodrigorimo@hotmail.com>
Co-authored-by: Ignatius Liu <suitangi777@gmail.com>
Co-authored-by: Indrek Haav <indrek.haav@hotmail.com>
Co-authored-by: Ivan Dimitrov <idimitrov08@gmail.com>
Co-authored-by: Jacob Zhang <jacob-z@live.de>
Co-authored-by: Jason Song <songpeiheng@gmail.com>
Co-authored-by: Jasper van der Neut - Stulen <jasper@neutstulen.nl>
Co-authored-by: Jeppe Nellemann <jepnel@proton.me>
Co-authored-by: Jirapan <jirapan_yankhan@hotmail.com>
Co-authored-by: Jonas A <demo007@gmail.com>
Co-authored-by: Jozef Gaal <preklady@mayday.sk>
Co-authored-by: Junghyuk Kwon <kwon@junghy.uk>
Co-authored-by: Leo Bottaro <github@leobottaro.com>
Co-authored-by: Liviu Roman <contact@liviuroman.com>
Co-authored-by: Lotzi <info@lorenzmueller.de>
Co-authored-by: Lukas Konsin <lukaskonsin@proton.me>
Co-authored-by: MSDNicrosoft <wang3311835119@hotmail.com>
Co-authored-by: Marcelo Popper Costa <marcelo_popper@hotmail.com>
Co-authored-by: Mario Carlotti <info@carlotti.ch>
Co-authored-by: Marko Stanković <stankovic.marko@gmail.com>
Co-authored-by: Martin Piron <martin.piron@hotmail.com>
Co-authored-by: Matjaž T <matjaz@moj-svet.si>
Co-authored-by: Mees Frensel <meesfrensel@gmail.com>
Co-authored-by: Mehmet MENENGEÇ <mehmetmenengec+weblate@gmail.com>
Co-authored-by: Metin <durmus38metin@gmail.com>
Co-authored-by: Mohsin Bouhout <bouhout.mohsin@gmail.com>
Co-authored-by: Mārtiņš Bruņenieks <martinsb@gmail.com>
Co-authored-by: Nicolai Bonde <git@nicolaibonde.dk>
Co-authored-by: Ole Steinbrück <ole.steinbrueck@googlemail.com>
Co-authored-by: Paolo Forte <paoloforte71@gmail.com>
Co-authored-by: Passawish Paktiwong <passawishp@outlook.com>
Co-authored-by: Pedro Vendeira <vendeira.pedro@gmail.com>
Co-authored-by: Peter Dave Hello <hsu@peterdavehello.org>
Co-authored-by: Petri Hämäläinen <petri.hamalainen@mailbox.org>
Co-authored-by: PontusÖsterlindh <pontus@osterlindh.com>
Co-authored-by: Rasmus Sehlin <rasmus@sehl.in>
Co-authored-by: Robert Gonzales <bgonz808@gmail.com>
Co-authored-by: Ron Turner <admin@meetronturner.com>
Co-authored-by: Shawn <xiaxinx@gmail.com>
Co-authored-by: Stan P <g97d6liib@mozmail.com>
Co-authored-by: Steven Barash <stevenbarash6@gmail.com>
Co-authored-by: Sylvain Pichon <service@spichon.fr>
Co-authored-by: TMM4MN <tmgweb@yahoo.com>
Co-authored-by: TV Box <realceday.tvbox@gmail.com>
Co-authored-by: Tage Lauritsen <tage@tunenet.dk>
Co-authored-by: Theofilos Nikolaou <th.nikolaou@gmail.com>
Co-authored-by: Tjibbe Chris <github@tjibbechris.nl>
Co-authored-by: Tmpod <tom@tmpod.dev>
Co-authored-by: Tom Kay <kowalzik@proton.me>
Co-authored-by: User 123456789 <user123456789@users.noreply.hosted.weblate.org>
Co-authored-by: Valentino Harpa <valen.ginga@gmail.com>
Co-authored-by: Vegard Fladby <vegard@fladby.org>
Co-authored-by: Zsombor L <lzso1.lzso1@gmail.com>
Co-authored-by: anton garcias <isaga.percompartir@gmail.com>
Co-authored-by: aouani jaessin <aouanijaessin@gmail.com>
Co-authored-by: basti n00b0ss <n00b0ss@mailbox.org>
Co-authored-by: bilal-khendaf <bilalkhendaf@gmail.com>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: chamdim <chamdim@protonmail.com>
Co-authored-by: intothevolt <francesco.ferriero97@gmail.com>
Co-authored-by: khaled maayeh <maayehkhaled@gmail.com>
Co-authored-by: kiwinho <kiwicaja@gmail.com>
Co-authored-by: millallo <millallo@tiscali.it>
Co-authored-by: mkubant <marek@kubantovi.cz>
Co-authored-by: nachtpfoetchen <nachtpfoetchen@posteo.de>
Co-authored-by: om1s186 <om1s186@gmail.com>
Co-authored-by: pyccl <changcongliang@163.com>
Co-authored-by: rw-r-r-0644 <rw-r-r-0644@proton.me>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: vytautas <immichtranslation.a03gn@simplelogin.com>
Co-authored-by: waclaw66 <waclaw66@seznam.cz>
Co-authored-by: Àlex Bravo <alexbravobosch@gmail.com>
Co-authored-by: özcan karakuş <ozcan.krakus@gmail.com>
Co-authored-by: Александр Стельмах <aguhadug@gmail.com>
Co-authored-by: Вячеслав Лукьяненко <madeinchuguev@gmail.com>
Co-authored-by: Максим Горпиніч <gorpinicmaksim0@gmail.com>
Co-authored-by: தமிழ்நேரம் <tamilneram247@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>
2025-10-30 14:40:49 +00:00
Alex
1a2e7d06cb chore: make view similar photo button more discoverable (#23350) 2025-10-29 15:38:50 +00:00
Alex
217d719b0b chore: re-enable android build (#23349) 2025-10-29 10:22:07 -05:00
shenlong
cf75ad2f26 fix: prune stale assets (#22530)
Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-10-29 14:41:03 +00:00
Alex
2286444158 chore: css nits (#23330) 2025-10-29 09:20:04 -05:00
renovate[bot]
b489bdf8d3 chore(deps): update node.js to v24 (#23346)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-29 14:48:20 +01:00
idubnori
5e6087ea28 feat(mobile): chat-style album activities timeline (#23185)
* feat(mobile): open assetviewer via album activities page

* adjust ui behavior: keep current asset & disable initial forcus

* init of v2...

* refactoring...

* refactor: remove _DismissibleWrapper

* feat: initial scrolling to bottom

* refactor: use feature toggle

* refactor: new route page

* fix: file name, dcm analyze

* fix: test failure

* fix: remove toggle and the exisitng style based on review feedback

* refactorr: rename methods for clarity in comment bubble widget

* chore: styling

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
2025-10-29 13:45:28 +00:00
Daniel Dietzler
4ae7cadeae feat: asset copy (#23172) 2025-10-29 08:43:47 -05:00
renovate[bot]
fdfb04d83c fix(deps): update typescript-projects (#23311)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2025-10-29 11:34:20 +00:00
renovate[bot]
8273c822d7 chore(deps): pin dependencies (#23304)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-28 20:27:54 -05:00
779 changed files with 51028 additions and 14554 deletions

View File

@@ -29,6 +29,12 @@
]
}
},
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
// https://github.com/devcontainers/features/issues/1466
"moby": false
}
},
"forwardPorts": [3000, 9231, 9230, 2283],
"portsAttributes": {
"3000": {

View File

@@ -21,6 +21,7 @@ services:
- app-node_modules:/usr/src/app/node_modules
- sveltekit:/usr/src/app/web/.svelte-kit
- coverage:/usr/src/app/web/coverage
- ../plugins:/build/corePlugin
immich-web:
env_file: !reset []
immich-machine-learning:

2
.github/.nvmrc vendored
View File

@@ -1 +1 @@
22.21.0
24.11.0

10
.github/mise.toml vendored Normal file
View File

@@ -0,0 +1,10 @@
[tasks.install]
run = "pnpm install --filter github --frozen-lockfile"
[tasks.format]
env._.path = "./node_modules/.bin"
run = "prettier --check ."
[tasks."format-fix"]
env._.path = "./node_modules/.bin"
run = "prettier --write ."

View File

@@ -1,12 +1,16 @@
name: Build Mobile
on:
workflow_dispatch:
workflow_call:
inputs:
ref:
required: false
type: string
environment:
description: 'Target environment'
required: true
default: 'development'
type: string
secrets:
KEY_JKS:
required: true
@@ -16,6 +20,30 @@ on:
required: true
ANDROID_STORE_PASSWORD:
required: true
APP_STORE_CONNECT_API_KEY_ID:
required: true
APP_STORE_CONNECT_API_KEY_ISSUER_ID:
required: true
APP_STORE_CONNECT_API_KEY:
required: true
IOS_CERTIFICATE_P12:
required: true
IOS_CERTIFICATE_PASSWORD:
required: true
IOS_PROVISIONING_PROFILE:
required: true
IOS_PROVISIONING_PROFILE_SHARE_EXTENSION:
required: true
IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION:
required: true
IOS_DEVELOPMENT_PROVISIONING_PROFILE:
required: true
IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION:
required: true
IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION:
required: true
FASTLANE_TEAM_ID:
required: true
pull_request:
push:
branches: [main]
@@ -58,8 +86,7 @@ jobs:
permissions:
contents: read
# Skip when PR from a fork
# if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' && fromJSON(needs.pre-job.outputs.should_run).mobile == true }}
if: ${{ false }}
if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' && fromJSON(needs.pre-job.outputs.should_run).mobile == true }}
runs-on: mich
steps:
@@ -69,7 +96,7 @@ jobs:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
@@ -138,7 +165,7 @@ jobs:
fi
- name: Publish Android Artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: release-apk-signed
path: mobile/build/app/outputs/flutter-apk/*.apk
@@ -161,19 +188,19 @@ jobs:
needs: pre-job
permissions:
contents: read
# Run on main branch or workflow_dispatch
if: ${{ !github.event.pull_request.head.repo.fork && fromJSON(needs.pre-job.outputs.should_run).mobile == true && github.ref == 'refs/heads/main' }}
# Run on main branch or workflow_dispatch, or on PRs/other branches (build only, no upload)
if: ${{ !github.event.pull_request.head.repo.fork && fromJSON(needs.pre-job.outputs.should_run).mobile == true }}
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ inputs.ref || github.sha }}
persist-credentials: false
- name: Setup Flutter SDK
uses: subosito/flutter-action@v2
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2
with:
channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml
@@ -194,17 +221,22 @@ jobs:
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
ruby-version: '3.3'
working-directory: ./mobile/ios
- name: Install Fastlane
- name: Install CocoaPods dependencies
working-directory: ./mobile/ios
run: |
pod install
- name: Install Fastlane
working-directory: ./mobile/ios
run: |
cd mobile/ios
gem install bundler
bundle config set --local path 'vendor/bundle'
bundle install
- name: Create API Key JSON
- name: Create API Key
env:
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
@@ -213,35 +245,55 @@ jobs:
run: |
mkdir -p ~/.appstoreconnect/private_keys
echo "$API_KEY_CONTENT" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8
cat > api_key.json << EOF
{
"key_id": "${API_KEY_ID}",
"issuer_id": "${API_KEY_ISSUER_ID}",
"key": "$(cat ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8)",
"duration": 1200,
"in_house": false
}
EOF
- name: Import Certificate and Provisioning Profile
- name: Import Certificate and Provisioning Profiles
env:
IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }}
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }}
IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_SHARE_EXTENSION }}
IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
ENVIRONMENT: ${{ inputs.environment || 'development' }}
working-directory: ./mobile/ios
run: |
# Decode certificate
echo "$IOS_CERTIFICATE_P12" | base64 --decode > certificate.p12
echo "$IOS_PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision
- name: Create keychain
# Decode provisioning profiles based on environment
if [[ "$ENVIRONMENT" == "development" ]]; then
echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE" | base64 --decode > profile_dev.mobileprovision
echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION" | base64 --decode > profile_dev_share.mobileprovision
echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION" | base64 --decode > profile_dev_widget.mobileprovision
ls -lh profile_dev*.mobileprovision
else
echo "$IOS_PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision
echo "$IOS_PROVISIONING_PROFILE_SHARE_EXTENSION" | base64 --decode > profile_share.mobileprovision
echo "$IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION" | base64 --decode > profile_widget.mobileprovision
ls -lh profile*.mobileprovision
fi
- name: Create keychain and import certificate
env:
KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
working-directory: ./mobile/ios
run: |
# Create keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security set-keychain-settings -t 3600 -u build.keychain
# Import certificate
security import certificate.p12 -k build.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain
# Verify certificate was imported
security find-identity -v -p codesigning build.keychain
- name: Build and deploy to TestFlight
env:
FASTLANE_TEAM_ID: ${{ secrets.FASTLANE_TEAM_ID }}
@@ -250,8 +302,22 @@ jobs:
KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
ENVIRONMENT: ${{ inputs.environment || 'development' }}
BUNDLE_ID_SUFFIX: ${{ inputs.environment == 'production' && '' || 'development' }}
GITHUB_REF: ${{ github.ref }}
working-directory: ./mobile/ios
run: bundle exec fastlane release_ci
run: |
# Only upload to TestFlight on main branch
if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
if [[ "$ENVIRONMENT" == "development" ]]; then
bundle exec fastlane gha_testflight_dev
else
bundle exec fastlane gha_release_prod
fi
else
# Build only, no TestFlight upload for non-main branches
bundle exec fastlane gha_build_only
fi
- name: Clean up keychain
if: always()
@@ -259,7 +325,7 @@ jobs:
security delete-keychain build.keychain || true
- name: Upload IPA artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: ios-release-ipa
path: mobile/ios/Runner.ipa

View File

@@ -25,7 +25,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -35,7 +35,7 @@ jobs:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -78,13 +78,13 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
@@ -95,7 +95,7 @@ jobs:
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ steps.token.outputs.token }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get package version
id: package-version
@@ -105,7 +105,7 @@ jobs:
- name: Generate docker image tags
id: metadata
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 # v5.9.0
with:
flavor: |
latest=false
@@ -125,4 +125,3 @@ jobs:
cache-to: type=gha,mode=max
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
github-token: ${{ steps.token.outputs.token }}

View File

@@ -35,7 +35,7 @@ jobs:
needs: [get_body, should_run]
if: ${{ needs.should_run.outputs.should_run == 'true' }}
container:
image: ghcr.io/immich-app/mdq:main@sha256:6b8450bfc06770af1af66bce9bf2ced7d1d9b90df1a59fc4c83a17777a9f6723
image: ghcr.io/immich-app/mdq:main@sha256:9c905a4ff69f00c4b2f98b40b6090ab3ab18d1a15ed1379733b8691aa1fcb271
outputs:
checked: ${{ steps.get_checkbox.outputs.checked }}
steps:

View File

@@ -50,14 +50,14 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 # v4.30.9
uses: github/codeql-action/init@014f16e7ab1402f30e7c3329d33797e7948572db # v4.31.3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -70,7 +70,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 # v4.30.9
uses: github/codeql-action/autobuild@014f16e7ab1402f30e7c3329d33797e7948572db # v4.31.3
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -83,6 +83,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 # v4.30.9
uses: github/codeql-action/analyze@014f16e7ab1402f30e7c3329d33797e7948572db # v4.31.3
with:
category: '/language:${{matrix.language}}'

View File

@@ -60,7 +60,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -85,7 +85,7 @@ jobs:
run: pnpm build
- name: Upload build output
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: docs-build-output
path: docs/build/

View File

@@ -125,7 +125,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -174,7 +174,7 @@ jobs:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
working-directory: 'deployment/modules/cloudflare/docs'
run: 'mise run tf apply'
run: 'mise run //deployment:tf apply'
- name: Deploy Docs Subdomain Output
id: docs-output
@@ -186,7 +186,7 @@ jobs:
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
working-directory: 'deployment/modules/cloudflare/docs'
run: |
mise run tf output -- -json | jq -r '
mise run //deployment:tf output -- -json | jq -r '
"projectName=\(.pages_project_name.value)",
"subdomain=\(.immich_app_branch_subdomain.value)"
' >> $GITHUB_OUTPUT
@@ -211,7 +211,7 @@ jobs:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
working-directory: 'deployment/modules/cloudflare/docs-release'
run: 'mise run tf apply'
run: 'mise run //deployment:tf apply'
- name: Comment
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0

View File

@@ -23,7 +23,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -39,7 +39,7 @@ jobs:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
working-directory: 'deployment/modules/cloudflare/docs'
run: 'mise run tf destroy -- -refresh=false'
run: 'mise run //deployment:tf destroy -- -refresh=false'
- name: Comment
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0

View File

@@ -22,7 +22,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: 'Checkout'
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
ref: ${{ github.event.pull_request.head.ref }}
token: ${{ steps.generate-token.outputs.token }}
@@ -39,7 +39,7 @@ jobs:
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Fix formatting
run: make install-all && make format-all
run: pnpm --recursive install && pnpm run --recursive --parallel fix:format
- name: Commit and push
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4

View File

@@ -55,14 +55,14 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
persist-credentials: true
ref: main
- name: Install uv
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1
uses: astral-sh/setup-uv@5a7eac68fb9809dea845d802897dc5c723910fa3 # v7.1.3
- name: Setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
@@ -99,8 +99,23 @@ jobs:
ALIAS: ${{ secrets.ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
# iOS secrets
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }}
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }}
IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_SHARE_EXTENSION }}
IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
FASTLANE_TEAM_ID: ${{ secrets.FASTLANE_TEAM_ID }}
with:
ref: ${{ needs.bump_version.outputs.ref }}
environment: production
prepare_release:
runs-on: ubuntu-latest
@@ -117,19 +132,19 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
persist-credentials: false
- name: Download APK
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: release-apk-signed
github-token: ${{ steps.generate-token.outputs.token }}
- name: Create draft release
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
with:
draft: true
tag_name: ${{ env.IMMICH_VERSION }}

170
.github/workflows/release-pr.yml vendored Normal file
View File

@@ -0,0 +1,170 @@
name: Manage release PR
on:
workflow_dispatch:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
permissions: {}
jobs:
bump:
runs-on: ubuntu-latest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
persist-credentials: true
ref: main
- name: Install uv
uses: astral-sh/setup-uv@5a7eac68fb9809dea845d802897dc5c723910fa3 # v7.1.3
- name: Setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
- name: Setup Node
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version-file: './server/.nvmrc'
cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml'
- name: Determine release type
id: bump-type
uses: ietf-tools/semver-action@c90370b2958652d71c06a3484129a4d423a6d8a8 # v1.11.0
with:
token: ${{ steps.generate-token.outputs.token }}
- name: Bump versions
env:
TYPE: ${{ steps.bump-type.outputs.bump }}
run: |
if [ "$TYPE" == "none" ]; then
exit 1 # TODO: Is there a cleaner way to abort the workflow?
fi
misc/release/pump-version.sh -s $TYPE -m true
- name: Manage Outline release document
id: outline
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
OUTLINE_API_KEY: ${{ secrets.OUTLINE_API_KEY }}
NEXT_VERSION: ${{ steps.bump-type.outputs.next }}
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
const fs = require('fs');
const outlineKey = process.env.OUTLINE_API_KEY;
const parentDocumentId = 'da856355-0844-43df-bd71-f8edce5382d9'
const collectionId = 'e2910656-714c-4871-8721-447d9353bd73';
const baseUrl = 'https://outline.immich.cloud';
const listResponse = await fetch(`${baseUrl}/api/documents.list`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${outlineKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ parentDocumentId })
});
if (!listResponse.ok) {
throw new Error(`Outline list failed: ${listResponse.statusText}`);
}
const listData = await listResponse.json();
const allDocuments = listData.data || [];
const document = allDocuments.find(doc => doc.title === 'next');
let documentId;
let documentUrl;
let documentText;
if (!document) {
// Create new document
console.log('No existing document found. Creating new one...');
const notesTmpl = fs.readFileSync('misc/release/notes.tmpl', 'utf8');
const createResponse = await fetch(`${baseUrl}/api/documents.create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${outlineKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'next',
text: notesTmpl,
collectionId: collectionId,
parentDocumentId: parentDocumentId,
publish: true
})
});
if (!createResponse.ok) {
throw new Error(`Failed to create document: ${createResponse.statusText}`);
}
const createData = await createResponse.json();
documentId = createData.data.id;
const urlId = createData.data.urlId;
documentUrl = `${baseUrl}/doc/next-${urlId}`;
documentText = createData.data.text || '';
console.log(`Created new document: ${documentUrl}`);
} else {
documentId = document.id;
const docPath = document.url;
documentUrl = `${baseUrl}${docPath}`;
documentText = document.text || '';
console.log(`Found existing document: ${documentUrl}`);
}
// Generate GitHub release notes
console.log('Generating GitHub release notes...');
const releaseNotesResponse = await github.rest.repos.generateReleaseNotes({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: `${process.env.NEXT_VERSION}`,
});
// Combine the content
const changelog = `
# ${process.env.NEXT_VERSION}
${documentText}
${releaseNotesResponse.data.body}
---
`
const existingChangelog = fs.existsSync('CHANGELOG.md') ? fs.readFileSync('CHANGELOG.md', 'utf8') : '';
fs.writeFileSync('CHANGELOG.md', changelog + existingChangelog, 'utf8');
core.setOutput('document_url', documentUrl);
- name: Create PR
id: create-pr
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
token: ${{ steps.generate-token.outputs.token }}
commit-message: 'chore: release ${{ steps.bump-type.outputs.next }}'
title: 'chore: release ${{ steps.bump-type.outputs.next }}'
body: 'Release notes: ${{ steps.outline.outputs.document_url }}'
labels: 'changelog:skip'
branch: 'release/next'
draft: true

148
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,148 @@
name: release.yml
on:
pull_request:
types: [closed]
paths:
- CHANGELOG.md
jobs:
# Maybe double check PR source branch?
merge_translations:
uses: ./.github/workflows/merge-translations.yml
permissions:
pull-requests: write
secrets:
PUSH_O_MATIC_APP_ID: ${{ secrets.PUSH_O_MATIC_APP_ID }}
PUSH_O_MATIC_APP_KEY: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
build_mobile:
uses: ./.github/workflows/build-mobile.yml
needs: merge_translations
permissions:
contents: read
secrets:
KEY_JKS: ${{ secrets.KEY_JKS }}
ALIAS: ${{ secrets.ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
# iOS secrets
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }}
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }}
IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_SHARE_EXTENSION }}misc/release/notes.tmpl
IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION }}
IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
FASTLANE_TEAM_ID: ${{ secrets.FASTLANE_TEAM_ID }}
with:
ref: main
environment: production
prepare_release:
runs-on: ubuntu-latest
needs: build_mobile
permissions:
actions: read # To download the app artifact
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
persist-credentials: false
ref: main
- name: Extract changelog
id: changelog
run: |
CHANGELOG_PATH=$RUNNER_TEMP/changelog.md
sed -n '1,/^---$/p' CHANGELOG.md | head -n -1 > $CHANGELOG_PATH
echo "path=$CHANGELOG_PATH" >> $GITHUB_OUTPUT
VERSION=$(sed -n 's/^# //p' $CHANGELOG_PATH)
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Download APK
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: release-apk-signed
github-token: ${{ steps.generate-token.outputs.token }}
- name: Create draft release
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
with:
tag_name: ${{ steps.version.outputs.result }}
token: ${{ steps.generate-token.outputs.token }}
body_path: ${{ steps.changelog.outputs.path }}
draft: true
files: |
docker/docker-compose.yml
docker/example.env
docker/hwaccel.ml.yml
docker/hwaccel.transcoding.yml
docker/prometheus.yml
*.apk
- name: Rename Outline document
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
continue-on-error: true
env:
OUTLINE_API_KEY: ${{ secrets.OUTLINE_API_KEY }}
VERSION: ${{ steps.changelog.outputs.version }}
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
const outlineKey = process.env.OUTLINE_API_KEY;
const version = process.env.VERSION;
const parentDocumentId = 'da856355-0844-43df-bd71-f8edce5382d9';
const baseUrl = 'https://outline.immich.cloud';
const listResponse = await fetch(`${baseUrl}/api/documents.list`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${outlineKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ parentDocumentId })
});
if (!listResponse.ok) {
throw new Error(`Outline list failed: ${listResponse.statusText}`);
}
const listData = await listResponse.json();
const allDocuments = listData.data || [];
const document = allDocuments.find(doc => doc.title === 'next');
if (document) {
console.log(`Found document 'next', renaming to '${version}'...`);
const updateResponse = await fetch(`${baseUrl}/api/documents.update`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${outlineKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: document.id,
title: version
})
});
if (!updateResponse.ok) {
throw new Error(`Failed to rename document: ${updateResponse.statusText}`);
}
} else {
console.log('No document titled "next" found to rename');
}

View File

@@ -22,7 +22,7 @@ jobs:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -55,7 +55,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -69,7 +69,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -114,7 +114,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -161,7 +161,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -203,7 +203,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -247,7 +247,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -285,7 +285,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -333,7 +333,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -379,9 +379,10 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
submodules: 'recursive'
token: ${{ steps.token.outputs.token }}
- name: Setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
@@ -417,7 +418,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
submodules: 'recursive'
@@ -472,7 +473,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
submodules: 'recursive'
@@ -499,8 +500,16 @@ jobs:
run: docker compose build
if: ${{ !cancelled() }}
- name: Run e2e tests (web)
env:
CI: true
run: npx playwright test
if: ${{ !cancelled() }}
- name: Archive test results
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
if: success() || failure()
with:
name: e2e-web-test-results-${{ matrix.runner }}
path: e2e/playwright-report/
success-check-e2e:
name: End-to-End Tests Success
needs: [e2e-tests-server-cli, e2e-tests-web]
@@ -525,7 +534,7 @@ jobs:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -557,12 +566,12 @@ jobs:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
- name: Install uv
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1
uses: astral-sh/setup-uv@5a7eac68fb9809dea845d802897dc5c723910fa3 # v7.1.3
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
# TODO: add caching when supported (https://github.com/actions/setup-python/pull/818)
# with:
@@ -601,7 +610,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -630,7 +639,7 @@ jobs:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -652,7 +661,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}
@@ -714,7 +723,7 @@ jobs:
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false
token: ${{ steps.token.outputs.token }}

View File

@@ -36,8 +36,7 @@ jobs:
github-token: ${{ steps.token.outputs.token }}
filters: |
i18n:
- 'i18n/!(en)**\.json'
exclude-branches: 'chore/translations'
- modified: 'i18n/!(en)**\.json'
skip-force-logic: 'true'
enforce-lock:

View File

@@ -17,6 +17,9 @@ dev-docs:
e2e:
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans
e2e-dev:
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.dev.yml up --remove-orphans
e2e-update:
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans

View File

@@ -118,16 +118,16 @@ Read more about translations [here](https://docs.immich.app/developer/translatio
## Star history
<a href="https://star-history.com/#immich-app/immich&Date">
<a href="https://star-history.com/#immich-app/immich&type=date&legend=top-left">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=immich-app/immich&type=Date" width="100%" />
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=immich-app/immich&type=date" width="100%" />
</picture>
</a>
## Contributors
<a href="https://github.com/alextran1502/immich/graphs/contributors">
<a href="https://github.com/immich-app/immich/graphs/contributors">
<img src="https://contrib.rocks/image?repo=immich-app/immich" width="100%"/>
</a>

View File

@@ -1 +1 @@
22.21.0
24.11.0

29
cli/mise.toml Normal file
View File

@@ -0,0 +1,29 @@
[tasks.install]
run = "pnpm install --filter @immich/cli --frozen-lockfile"
[tasks.build]
env._.path = "./node_modules/.bin"
run = "vite build"
[tasks.test]
env._.path = "./node_modules/.bin"
run = "vite"
[tasks.lint]
env._.path = "./node_modules/.bin"
run = "eslint \"src/**/*.ts\" --max-warnings 0"
[tasks."lint-fix"]
run = { task = "lint --fix" }
[tasks.format]
env._.path = "./node_modules/.bin"
run = "prettier --check ."
[tasks."format-fix"]
env._.path = "./node_modules/.bin"
run = "prettier --write ."
[tasks.check]
env._.path = "./node_modules/.bin"
run = "tsc --noEmit"

View File

@@ -1,6 +1,6 @@
{
"name": "@immich/cli",
"version": "2.2.97",
"version": "2.2.102",
"description": "Command Line Interface (CLI) for Immich",
"type": "module",
"exports": "./dist/index.js",
@@ -20,7 +20,7 @@
"@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.9",
"@types/mock-fs": "^4.13.1",
"@types/node": "^22.18.12",
"@types/node": "^22.19.1",
"@vitest/coverage-v8": "^3.0.0",
"byte-size": "^9.0.0",
"cli-progress": "^3.12.0",
@@ -69,6 +69,6 @@
"micromatch": "^4.0.8"
},
"volta": {
"node": "22.21.0"
"node": "24.11.0"
}
}

20
deployment/mise.toml Normal file
View File

@@ -0,0 +1,20 @@
[tools]
terragrunt = "0.91.2"
opentofu = "1.10.6"
[tasks."tg:fmt"]
run = "terragrunt hclfmt"
description = "Format terragrunt files"
[tasks.tf]
run = "terragrunt run --all"
description = "Wrapper for terragrunt run-all"
dir = "{{cwd}}"
[tasks."tf:fmt"]
run = "tofu fmt -recursive tf/"
description = "Format terraform files"
[tasks."tf:init"]
run = { task = "tf init -- -reconfigure" }
dir = "{{cwd}}"

View File

@@ -41,6 +41,7 @@ services:
- app-node_modules:/usr/src/app/node_modules
- sveltekit:/usr/src/app/web/.svelte-kit
- coverage:/usr/src/app/web/coverage
- ../plugins:/build/corePlugin
env_file:
- .env
environment:

View File

@@ -83,7 +83,7 @@ services:
container_name: immich_prometheus
ports:
- 9090:9090
image: prom/prometheus@sha256:23031bfe0e74a13004252caaa74eccd0d62b6c6e7a04711d5b8bf5b7e113adc7
image: prom/prometheus@sha256:49214755b6153f90a597adcbff0252cc61069f8ab69ce8411285cd4a560e8038
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus

View File

@@ -1 +1 @@
22.21.0
24.11.0

View File

@@ -0,0 +1,18 @@
# Maintenance Mode
Maintenance mode is used to perform administrative tasks such as restoring backups to Immich.
You can enter maintenance mode by either:
- Selecting "enable maintenance mode" in system settings in administration.
- Running the enable maintenance mode [administration command](./server-commands.md).
## Logging in during maintenance
Maintenance mode uses a separate login system which is handled automatically behind the scenes in most cases. Enabling maintenance mode in settings will automatically log you into maintenance mode when the server comes back up.
If you find that you've been logged out, you can:
- Open the logs for the Immich server and look for _"🚧 Immich is in maintenance mode, you can log in using the following URL:"_
- Run the enable maintenance mode [administration command](./server-commands.md) again, this will give you a new URL to login with.
- Run the disable maintenance mode [administration command](./server-commands.md) then re-enter through system settings.

View File

@@ -10,16 +10,19 @@ Running with a pre-existing Postgres server can unlock powerful administrative f
## Prerequisites
You must install `pgvector` (`>= 0.7.0, < 1.0.0`), as it is a prerequisite for `vchord`.
You must install pgvector as it is a prerequisite for VectorChord.
The easiest way to do this on Debian/Ubuntu is by adding the [PostgreSQL Apt repository][pg-apt] and then
running `apt install postgresql-NN-pgvector`, where `NN` is your Postgres version (e.g., `16`).
You must install VectorChord into your instance of Postgres using their [instructions][vchord-install]. After installation, add `shared_preload_libraries = 'vchord.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vchord.so'`.
:::note
Immich is known to work with Postgres versions `>= 14, < 18`.
:::note Supported versions
Immich is known to work with Postgres versions `>= 14, < 19`.
Make sure the installed version of VectorChord is compatible with your version of Immich. The current accepted range for VectorChord is `>= 0.3.0, < 0.5.0`.
VectorChord is known to work with pgvector versions `>= 0.7, < 0.9`.
The Immich server will check the VectorChord version on startup to ensure compatibility, and refuse to start if a compatible version is not found.
The current accepted range for VectorChord is `>= 0.3, < 0.6`.
:::
## Specifying the connection URL

View File

@@ -2,17 +2,19 @@
The `immich-server` docker image comes preinstalled with an administrative CLI (`immich-admin`) that supports the following commands:
| Command | Description |
| ------------------------ | ------------------------------------------------------------- |
| `help` | Display help |
| `reset-admin-password` | Reset the password for the admin user |
| `disable-password-login` | Disable password login |
| `enable-password-login` | Enable password login |
| `enable-oauth-login` | Enable OAuth login |
| `disable-oauth-login` | Disable OAuth login |
| `list-users` | List Immich users |
| `version` | Print Immich version |
| `change-media-location` | Change database file paths to align with a new media location |
| Command | Description |
| -------------------------- | ------------------------------------------------------------- |
| `help` | Display help |
| `reset-admin-password` | Reset the password for the admin user |
| `disable-password-login` | Disable password login |
| `enable-password-login` | Enable password login |
| `disable-maintenance-mode` | Disable maintenance mode |
| `enable-maintenance-mode` | Enable maintenance mode |
| `enable-oauth-login` | Enable OAuth login |
| `disable-oauth-login` | Disable OAuth login |
| `list-users` | List Immich users |
| `version` | Print Immich version |
| `change-media-location` | Change database file paths to align with a new media location |
## How to run a command
@@ -47,6 +49,23 @@ immich-admin enable-password-login
Password login has been enabled.
```
Disable Maintenance Mode
```
immich-admin disable-maintenace-mode
Maintenance mode has been disabled.
```
Enable Maintenance Mode
```
immich-admin enable-maintenance-mode
Maintenance mode has been enabled.
Log in using the following URL:
https://my.immich.app/maintenance?token=<token>
```
Enable OAuth login
```

View File

@@ -12,3 +12,13 @@ pnpm run migrations:generate <migration-name>
3. Move the migration file to folder `./server/src/schema/migrations` in your code editor.
The server will automatically detect `*.ts` file changes and restart. Part of the server start-up process includes running any new migrations, so it will be applied immediately.
## Reverting a Migration
If you need to undo the most recently applied migration—for example, when developing or testing on schema changes—run:
```bash
pnpm run migrations:revert
```
This command rolls back the latest migration and brings the database schema back to its previous state.

View File

@@ -256,7 +256,7 @@ The Dev Container supports multiple ways to run tests:
```bash
# Run tests for specific components
make test-server # Server unit tests
make test-server # Server unit tests
make test-web # Web unit tests
make test-e2e # End-to-end tests
make test-cli # CLI tests
@@ -268,12 +268,13 @@ make test-all # Runs tests for all components
make test-medium-dev # End-to-end tests
```
#### Using NPM Directly
#### Using PNPM Directly
```bash
# Server tests
cd /workspaces/immich/server
pnpm test # Run all tests
pnpm test # Run all tests
pnpm run test:medium # Medium tests (integration tests)
pnpm run test:watch # Watch mode
pnpm run test:cov # Coverage report
@@ -293,21 +294,21 @@ pnpm run test:web # Run web UI tests
```bash
# Linting
make lint-server # Lint server code
make lint-web # Lint web code
make lint-all # Lint all components
make lint-web # Lint web code
make lint-all # Lint all components
# Formatting
make format-server # Format server code
make format-web # Format web code
make format-all # Format all code
make format-web # Format web code
make format-all # Format all code
# Type checking
make check-server # Type check server
make check-web # Type check web
make check-all # Check all components
make check-web # Type check web
make check-all # Check all components
# Complete hygiene check
make hygiene-all # Runs lint, format, check, SQL sync, and audit
make hygiene-all # Run lint, format, check, SQL sync, and audit
```
### Additional Make Commands
@@ -315,21 +316,21 @@ make hygiene-all # Runs lint, format, check, SQL sync, and audit
```bash
# Build commands
make build-server # Build server
make build-web # Build web app
make build-all # Build everything
make build-web # Build web app
make build-all # Build everything
# API generation
make open-api # Generate OpenAPI specs
make open-api # Generate OpenAPI specs
make open-api-typescript # Generate TypeScript SDK
make open-api-dart # Generate Dart SDK
make open-api-dart # Generate Dart SDK
# Database
make sql # Sync database schema
make sql # Sync database schema
# Dependencies
make install-server # Install server dependencies
make install-web # Install web dependencies
make install-all # Install all dependencies
make install-server # Install server dependencies
make install-web # Install web dependencies
make install-all # Install all dependencies
```
### Debugging

View File

@@ -5,7 +5,7 @@ sidebar_position: 2
# Setup
:::note
If there's a feature you're planning to work on, just give us a heads up in [Discord](https://discord.com/channels/979116623879368755/1071165397228855327) so we can:
If there's a feature you're planning to work on, just give us a heads up in [#contributing](https://discord.com/channels/979116623879368755/1071165397228855327) on [our Discord](https://discord.immich.app) so we can:
1. Let you know if it's something we would accept into Immich
2. Provide any guidance on how something like that would ideally be implemented

View File

@@ -10,6 +10,16 @@ import MobileAppBackup from '/docs/partials/_mobile-app-backup.md';
<MobileAppDownload />
:::info Android verification
Below are the SHA-256 fingerprints for the certificates signing the android applications.
- Playstore / Github releases:
`86:C5:C4:55:DF:AF:49:85:92:3A:8F:35:AD:B3:1D:0C:9E:0B:95:7D:7F:94:C2:D2:AF:6A:24:38:AA:96:00:20`
- F-Droid releases:
`FA:8B:43:95:F4:A6:47:71:A0:53:D1:C7:57:73:5F:A2:30:13:74:F5:3D:58:0D:D1:75:AA:F7:A1:35:72:9C:BF`
:::
:::info Beta Program
The beta release channel allows users to test upcoming changes before they are officially released. To join the channel use the links below.

View File

@@ -106,14 +106,14 @@ SELECT "user"."email", "asset"."type", COUNT(*) FROM "asset"
```sql title="Count by tag"
SELECT "t"."value" AS "tag_name", COUNT(*) AS "number_assets" FROM "tag" "t"
JOIN "tag_asset" "ta" ON "t"."id" = "ta"."tagsId" JOIN "asset" "a" ON "ta"."assetsId" = "a"."id"
JOIN "tag_asset" "ta" ON "t"."id" = "ta"."tagId" JOIN "asset" "a" ON "ta"."assetId" = "a"."id"
WHERE "a"."visibility" != 'hidden'
GROUP BY "t"."value" ORDER BY "number_assets" DESC;
```
```sql title="Count by tag (per user)"
SELECT "t"."value" AS "tag_name", "u"."email" as "user_email", COUNT(*) AS "number_assets" FROM "tag" "t"
JOIN "tag_asset" "ta" ON "t"."id" = "ta"."tagsId" JOIN "asset" "a" ON "ta"."assetsId" = "a"."id" JOIN "user" "u" ON "a"."ownerId" = "u"."id"
JOIN "tag_asset" "ta" ON "t"."id" = "ta"."tagId" JOIN "asset" "a" ON "ta"."assetId" = "a"."id" JOIN "user" "u" ON "a"."ownerId" = "u"."id"
WHERE "a"."visibility" != 'hidden'
GROUP BY "t"."value", "u"."email" ORDER BY "number_assets" DESC;
```

View File

@@ -16,48 +16,76 @@ The default configuration looks like this:
```json
{
"ffmpeg": {
"crf": 23,
"threads": 0,
"preset": "ultrafast",
"targetVideoCodec": "h264",
"acceptedVideoCodecs": ["h264"],
"targetAudioCodec": "aac",
"acceptedAudioCodecs": ["aac", "mp3", "libopus", "pcm_s16le"],
"acceptedContainers": ["mov", "ogg", "webm"],
"targetResolution": "720",
"maxBitrate": "0",
"bframes": -1,
"refs": 0,
"gopSize": 0,
"temporalAQ": false,
"cqMode": "auto",
"twoPass": false,
"preferredHwDevice": "auto",
"transcode": "required",
"tonemap": "hable",
"accel": "disabled",
"accelDecode": false
},
"backup": {
"database": {
"enabled": true,
"cronExpression": "0 02 * * *",
"enabled": true,
"keepLastAmount": 14
}
},
"ffmpeg": {
"accel": "disabled",
"accelDecode": false,
"acceptedAudioCodecs": ["aac", "mp3", "libopus"],
"acceptedContainers": ["mov", "ogg", "webm"],
"acceptedVideoCodecs": ["h264"],
"bframes": -1,
"cqMode": "auto",
"crf": 23,
"gopSize": 0,
"maxBitrate": "0",
"preferredHwDevice": "auto",
"preset": "ultrafast",
"refs": 0,
"targetAudioCodec": "aac",
"targetResolution": "720",
"targetVideoCodec": "h264",
"temporalAQ": false,
"threads": 0,
"tonemap": "hable",
"transcode": "required",
"twoPass": false
},
"image": {
"colorspace": "p3",
"extractEmbedded": false,
"fullsize": {
"enabled": false,
"format": "jpeg",
"quality": 80
},
"preview": {
"format": "jpeg",
"quality": 80,
"size": 1440
},
"thumbnail": {
"format": "webp",
"quality": 80,
"size": 250
}
},
"job": {
"backgroundTask": {
"concurrency": 5
},
"smartSearch": {
"faceDetection": {
"concurrency": 2
},
"library": {
"concurrency": 5
},
"metadataExtraction": {
"concurrency": 5
},
"faceDetection": {
"concurrency": 2
"migration": {
"concurrency": 5
},
"notifications": {
"concurrency": 5
},
"ocr": {
"concurrency": 1
},
"search": {
"concurrency": 5
@@ -65,20 +93,23 @@ The default configuration looks like this:
"sidecar": {
"concurrency": 5
},
"library": {
"concurrency": 5
},
"migration": {
"concurrency": 5
"smartSearch": {
"concurrency": 2
},
"thumbnailGeneration": {
"concurrency": 3
},
"videoConversion": {
"concurrency": 1
}
},
"library": {
"scan": {
"cronExpression": "0 0 * * *",
"enabled": true
},
"notifications": {
"concurrency": 5
"watch": {
"enabled": false
}
},
"logging": {
@@ -86,8 +117,11 @@ The default configuration looks like this:
"level": "log"
},
"machineLearning": {
"enabled": true,
"urls": ["http://immich-machine-learning:3003"],
"availabilityChecks": {
"enabled": true,
"interval": 30000,
"timeout": 2000
},
"clip": {
"enabled": true,
"modelName": "ViT-B-32__openai"
@@ -96,27 +130,59 @@ The default configuration looks like this:
"enabled": true,
"maxDistance": 0.01
},
"enabled": true,
"facialRecognition": {
"enabled": true,
"modelName": "buffalo_l",
"minScore": 0.7,
"maxDistance": 0.5,
"minFaces": 3
}
"minFaces": 3,
"minScore": 0.7,
"modelName": "buffalo_l"
},
"ocr": {
"enabled": true,
"maxResolution": 736,
"minDetectionScore": 0.5,
"minRecognitionScore": 0.8,
"modelName": "PP-OCRv5_mobile"
},
"urls": ["http://immich-machine-learning:3003"]
},
"map": {
"darkStyle": "https://tiles.immich.cloud/v1/style/dark.json",
"enabled": true,
"lightStyle": "https://tiles.immich.cloud/v1/style/light.json",
"darkStyle": "https://tiles.immich.cloud/v1/style/dark.json"
},
"reverseGeocoding": {
"enabled": true
"lightStyle": "https://tiles.immich.cloud/v1/style/light.json"
},
"metadata": {
"faces": {
"import": false
}
},
"newVersionCheck": {
"enabled": true
},
"nightlyTasks": {
"clusterNewFaces": true,
"databaseCleanup": true,
"generateMemories": true,
"missingThumbnails": true,
"startTime": "00:00",
"syncQuotaUsage": true
},
"notifications": {
"smtp": {
"enabled": false,
"from": "",
"replyTo": "",
"transport": {
"host": "",
"ignoreCert": false,
"password": "",
"port": 587,
"secure": false,
"username": ""
}
}
},
"oauth": {
"autoLaunch": false,
"autoRegister": true,
@@ -128,70 +194,44 @@ The default configuration looks like this:
"issuerUrl": "",
"mobileOverrideEnabled": false,
"mobileRedirectUri": "",
"profileSigningAlgorithm": "none",
"roleClaim": "immich_role",
"scope": "openid email profile",
"signingAlgorithm": "RS256",
"profileSigningAlgorithm": "none",
"storageLabelClaim": "preferred_username",
"storageQuotaClaim": "immich_quota"
"storageQuotaClaim": "immich_quota",
"timeout": 30000,
"tokenEndpointAuthMethod": "client_secret_post"
},
"passwordLogin": {
"enabled": true
},
"reverseGeocoding": {
"enabled": true
},
"server": {
"externalDomain": "",
"loginPageMessage": "",
"publicUsers": true
},
"storageTemplate": {
"enabled": false,
"hashVerificationEnabled": true,
"template": "{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}"
},
"image": {
"thumbnail": {
"format": "webp",
"size": 250,
"quality": 80
},
"preview": {
"format": "jpeg",
"size": 1440,
"quality": 80
},
"colorspace": "p3",
"extractEmbedded": false
},
"newVersionCheck": {
"enabled": true
},
"trash": {
"enabled": true,
"days": 30
"templates": {
"email": {
"albumInviteTemplate": "",
"albumUpdateTemplate": "",
"welcomeTemplate": ""
}
},
"theme": {
"customCss": ""
},
"library": {
"scan": {
"enabled": true,
"cronExpression": "0 0 * * *"
},
"watch": {
"enabled": false
}
},
"server": {
"externalDomain": "",
"loginPageMessage": ""
},
"notifications": {
"smtp": {
"enabled": false,
"from": "",
"replyTo": "",
"transport": {
"ignoreCert": false,
"host": "",
"port": 587,
"username": "",
"password": ""
}
}
"trash": {
"days": 30,
"enabled": true
},
"user": {
"deleteDelay": 7

View File

@@ -149,29 +149,31 @@ Redis (Sentinel) URL example JSON before encoding:
## Machine Learning
| Variable | Description | Default | Containers |
| :---------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | :-----------------------------: | :--------------- |
| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning |
| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning |
| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning |
| `MACHINE_LEARNING_REQUEST_THREADS`<sup>\*1</sup> | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning |
| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning |
| `MACHINE_LEARNING_WORKERS`<sup>\*2</sup> | Number of worker processes to spawn | `1` | machine learning |
| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`<sup>\*3</sup> | HTTP Keep-alive time in seconds | `2` | machine learning |
| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `120` (`300` if using OpenVINO) | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning |
| `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning |
| `MACHINE_LEARNING_DEVICE_IDS`<sup>\*4</sup> | Device IDs to use in multi-GPU environments | `0` | machine learning |
| `MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION` | Set the maximum number of faces that will be processed at once by the facial recognition model | None (`1` if using OpenVINO) | machine learning |
| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spinned up while inferencing. | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning |
| Variable | Description | Default | Containers |
| :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------------: | :--------------- |
| `MACHINE_LEARNING_MODEL_TTL` | Inactivity time (s) before a model is unloaded (disabled if \<= 0) | `300` | machine learning |
| `MACHINE_LEARNING_MODEL_TTL_POLL_S` | Interval (s) between checks for the model TTL (disabled if \<= 0) | `10` | machine learning |
| `MACHINE_LEARNING_CACHE_FOLDER` | Directory where models are downloaded | `/cache` | machine learning |
| `MACHINE_LEARNING_REQUEST_THREADS`<sup>\*1</sup> | Thread count of the request thread pool (disabled if \<= 0) | number of CPU cores | machine learning |
| `MACHINE_LEARNING_MODEL_INTER_OP_THREADS` | Number of parallel model operations | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_INTRA_OP_THREADS` | Number of threads for each model operation | `2` | machine learning |
| `MACHINE_LEARNING_WORKERS`<sup>\*2</sup> | Number of worker processes to spawn | `1` | machine learning |
| `MACHINE_LEARNING_HTTP_KEEPALIVE_TIMEOUT_S`<sup>\*3</sup> | HTTP Keep-alive time in seconds | `2` | machine learning |
| `MACHINE_LEARNING_WORKER_TIMEOUT` | Maximum time (s) of unresponsiveness before a worker is killed | `120` (`300` if using OpenVINO) | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__TEXTUAL` | Comma-separated list of (textual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__CLIP__VISUAL` | Comma-separated list of (visual) CLIP model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__RECOGNITION` | Comma-separated list of (recognition) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_PRELOAD__FACIAL_RECOGNITION__DETECTION` | Comma-separated list of (detection) facial recognition model(s) to preload and cache | | machine learning |
| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning |
| `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning |
| `MACHINE_LEARNING_DEVICE_IDS`<sup>\*4</sup> | Device IDs to use in multi-GPU environments | `0` | machine learning |
| `MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION` | Set the maximum number of faces that will be processed at once by the facial recognition model | None (`1` if using OpenVINO) | machine learning |
| `MACHINE_LEARNING_MAX_BATCH_SIZE__OCR` | Set the maximum number of boxes that will be processed at once by the OCR model | `6` | machine learning |
| `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spun up while inferencing. | `1` | machine learning |
| `MACHINE_LEARNING_MODEL_ARENA` | Pre-allocates CPU memory to avoid memory fragmentation | true | machine learning |
| `MACHINE_LEARNING_OPENVINO_PRECISION` | If set to FP16, uses half-precision floating-point operations for faster inference with reduced accuracy (one of [`FP16`, `FP32`], applies only to OpenVINO) | `FP32` | machine learning |
\*1: It is recommended to begin with this parameter when changing the concurrency levels of the machine learning service and then tune the other ones.

25
docs/mise.toml Normal file
View File

@@ -0,0 +1,25 @@
[tasks.install]
run = "pnpm install --filter documentation --frozen-lockfile"
[tasks.start]
env._.path = "./node_modules/.bin"
run = "docusaurus --port 3005"
[tasks.build]
env._.path = "./node_modules/.bin"
run = [
"jq -c < ../open-api/immich-openapi-specs.json > ./static/openapi.json || exit 0",
"docusaurus build",
]
[tasks.preview]
env._.path = "./node_modules/.bin"
run = "docusaurus serve"
[tasks.format]
env._.path = "./node_modules/.bin"
run = "prettier --check ."
[tasks."format-fix"]
env._.path = "./node_modules/.bin"
run = "prettier --write ."

View File

@@ -57,6 +57,6 @@
"node": ">=20"
},
"volta": {
"node": "22.21.0"
"node": "24.11.0"
}
}

View File

@@ -1,4 +1,24 @@
[
{
"label": "v2.3.0",
"url": "https://docs.v2.3.0.archive.immich.app"
},
{
"label": "v2.2.3",
"url": "https://docs.v2.2.3.archive.immich.app"
},
{
"label": "v2.2.2",
"url": "https://docs.v2.2.2.archive.immich.app"
},
{
"label": "v2.2.1",
"url": "https://docs.v2.2.1.archive.immich.app"
},
{
"label": "v2.2.0",
"url": "https://docs.v2.2.0.archive.immich.app"
},
{
"label": "v2.1.0",
"url": "https://docs.v2.1.0.archive.immich.app"

1
e2e/.gitignore vendored
View File

@@ -4,3 +4,4 @@ node_modules/
/blob-report/
/playwright/.cache/
/dist
.env

View File

@@ -1 +1 @@
22.21.0
24.11.0

105
e2e/docker-compose.dev.yml Normal file
View File

@@ -0,0 +1,105 @@
name: immich-e2e
services:
immich-server:
container_name: immich-e2e-server
command: ['immich-dev']
image: immich-server-dev:latest
build:
context: ../
dockerfile: server/Dockerfile.dev
target: dev
environment:
- DB_HOSTNAME=database
- DB_USERNAME=postgres
- DB_PASSWORD=postgres
- DB_DATABASE_NAME=immich
- IMMICH_MACHINE_LEARNING_ENABLED=false
- IMMICH_TELEMETRY_INCLUDE=all
- IMMICH_ENV=testing
- IMMICH_PORT=2285
- IMMICH_IGNORE_MOUNT_CHECK_ERRORS=true
volumes:
- ./test-assets:/test-assets
- ..:/usr/src/app
- ${UPLOAD_LOCATION}/photos:/data
- /etc/localtime:/etc/localtime:ro
- pnpm-store:/usr/src/app/.pnpm-store
- server-node_modules:/usr/src/app/server/node_modules
- web-node_modules:/usr/src/app/web/node_modules
- github-node_modules:/usr/src/app/.github/node_modules
- cli-node_modules:/usr/src/app/cli/node_modules
- docs-node_modules:/usr/src/app/docs/node_modules
- e2e-node_modules:/usr/src/app/e2e/node_modules
- sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
- app-node_modules:/usr/src/app/node_modules
- sveltekit:/usr/src/app/web/.svelte-kit
- coverage:/usr/src/app/web/coverage
- ../plugins:/build/corePlugin
depends_on:
redis:
condition: service_started
database:
condition: service_healthy
immich-web:
container_name: immich-e2e-web
image: immich-web-dev:latest
build:
context: ../
dockerfile: server/Dockerfile.dev
target: dev
command: ['immich-web']
ports:
- 2285:3000
environment:
- IMMICH_SERVER_URL=http://immich-server:2285/
volumes:
- ..:/usr/src/app
- pnpm-store:/usr/src/app/.pnpm-store
- server-node_modules:/usr/src/app/server/node_modules
- web-node_modules:/usr/src/app/web/node_modules
- github-node_modules:/usr/src/app/.github/node_modules
- cli-node_modules:/usr/src/app/cli/node_modules
- docs-node_modules:/usr/src/app/docs/node_modules
- e2e-node_modules:/usr/src/app/e2e/node_modules
- sdk-node_modules:/usr/src/app/open-api/typescript-sdk/node_modules
- app-node_modules:/usr/src/app/node_modules
- sveltekit:/usr/src/app/web/.svelte-kit
- coverage:/usr/src/app/web/coverage
restart: unless-stopped
redis:
image: redis:6.2-alpine@sha256:37e002448575b32a599109664107e374c8709546905c372a34d64919043b9ceb
database:
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0@sha256:6f3e9d2c2177af16c2988ff71425d79d89ca630ec2f9c8db03209ab716542338
command: -c fsync=off -c shared_preload_libraries=vchord.so -c config_file=/var/lib/postgresql/data/postgresql.conf
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: immich
ports:
- 5435:5432
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres -d immich']
interval: 1s
timeout: 5s
retries: 30
start_period: 10s
volumes:
model-cache:
prometheus-data:
grafana-data:
pnpm-store:
server-node_modules:
web-node_modules:
github-node_modules:
cli-node_modules:
docs-node_modules:
e2e-node_modules:
sdk-node_modules:
app-node_modules:
sveltekit:
coverage:

View File

@@ -35,7 +35,7 @@ services:
- 2285:2285
redis:
image: redis:6.2-alpine@sha256:77697a75da9f94e9357b61fcaf8345f69e3d9d32e9d15032c8415c21263977dc
image: redis:6.2-alpine@sha256:37e002448575b32a599109664107e374c8709546905c372a34d64919043b9ceb
database:
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0@sha256:6f3e9d2c2177af16c2988ff71425d79d89ca630ec2f9c8db03209ab716542338

29
e2e/mise.toml Normal file
View File

@@ -0,0 +1,29 @@
[tasks.install]
run = "pnpm install --filter immich-e2e --frozen-lockfile"
[tasks.test]
env._.path = "./node_modules/.bin"
run = "vitest --run"
[tasks."test-web"]
env._.path = "./node_modules/.bin"
run = "playwright test"
[tasks.format]
env._.path = "./node_modules/.bin"
run = "prettier --check ."
[tasks."format-fix"]
env._.path = "./node_modules/.bin"
run = "prettier --write ."
[tasks.lint]
env._.path = "./node_modules/.bin"
run = "eslint \"src/**/*.ts\" --max-warnings 0"
[tasks."lint-fix"]
run = { task = "lint --fix" }
[tasks.check]
env._.path = "./node_modules/.bin"
run = "tsc --noEmit"

View File

@@ -1,6 +1,6 @@
{
"name": "immich-e2e",
"version": "2.1.0",
"version": "2.3.0",
"description": "",
"main": "index.js",
"type": "module",
@@ -20,16 +20,18 @@
"license": "GNU Affero General Public License version 3",
"devDependencies": {
"@eslint/js": "^9.8.0",
"@faker-js/faker": "^10.1.0",
"@immich/cli": "file:../cli",
"@immich/sdk": "file:../open-api/typescript-sdk",
"@playwright/test": "^1.44.1",
"@socket.io/component-emitter": "^3.1.2",
"@types/luxon": "^3.4.2",
"@types/node": "^22.18.12",
"@types/node": "^22.19.1",
"@types/oidc-provider": "^9.0.0",
"@types/pg": "^8.15.1",
"@types/pngjs": "^6.0.4",
"@types/supertest": "^6.0.2",
"dotenv": "^17.2.3",
"eslint": "^9.14.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.1.3",
@@ -52,6 +54,6 @@
"vitest": "^3.0.0"
},
"volta": {
"node": "22.21.0"
"node": "24.11.0"
}
}

View File

@@ -1,23 +1,50 @@
import { defineConfig, devices } from '@playwright/test';
import { defineConfig, devices, PlaywrightTestConfig } from '@playwright/test';
import dotenv from 'dotenv';
import { cpus } from 'node:os';
import { resolve } from 'node:path';
export default defineConfig({
dotenv.config({ path: resolve(import.meta.dirname, '.env') });
export const playwrightHost = process.env.PLAYWRIGHT_HOST ?? '127.0.0.1';
export const playwrightDbHost = process.env.PLAYWRIGHT_DB_HOST ?? '127.0.0.1';
export const playwriteBaseUrl = process.env.PLAYWRIGHT_BASE_URL ?? `http://${playwrightHost}:2285`;
export const playwriteSlowMo = parseInt(process.env.PLAYWRIGHT_SLOW_MO ?? '0');
export const playwrightDisableWebserver = process.env.PLAYWRIGHT_DISABLE_WEBSERVER;
process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS = '1';
const config: PlaywrightTestConfig = {
testDir: './src/web/specs',
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: 1,
retries: process.env.CI ? 4 : 0,
reporter: 'html',
use: {
baseURL: 'http://127.0.0.1:2285',
baseURL: playwriteBaseUrl,
trace: 'on-first-retry',
screenshot: 'only-on-failure',
launchOptions: {
slowMo: playwriteSlowMo,
},
},
testMatch: /.*\.e2e-spec\.ts/,
workers: process.env.CI ? 4 : Math.round(cpus().length * 0.75),
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
testMatch: /.*\.e2e-spec\.ts/,
workers: 1,
},
{
name: 'parallel tests',
use: { ...devices['Desktop Chrome'] },
testMatch: /.*\.parallel-e2e-spec\.ts/,
fullyParallel: true,
workers: process.env.CI ? 3 : Math.max(1, Math.round(cpus().length * 0.75) - 1),
},
// {
@@ -59,4 +86,8 @@ export default defineConfig({
stderr: 'pipe',
reuseExistingServer: true,
},
});
};
if (playwrightDisableWebserver) {
delete config.webServer;
}
export default defineConfig(config);

View File

@@ -15,7 +15,6 @@ import { DateTime } from 'luxon';
import { randomBytes } from 'node:crypto';
import { readFile, writeFile } from 'node:fs/promises';
import { basename, join } from 'node:path';
import sharp from 'sharp';
import { Socket } from 'socket.io-client';
import { createUserDto, uuidDto } from 'src/fixtures';
import { makeRandomImage } from 'src/generators';
@@ -41,40 +40,6 @@ const today = DateTime.fromObject({
}) as DateTime<true>;
const yesterday = today.minus({ days: 1 });
const createTestImageWithExif = async (filename: string, exifData: Record<string, any>) => {
// Generate unique color to ensure different checksums for each image
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
// Create a 100x100 solid color JPEG using Sharp
const imageBytes = await sharp({
create: {
width: 100,
height: 100,
channels: 3,
background: { r, g, b },
},
})
.jpeg({ quality: 90 })
.toBuffer();
// Add random suffix to filename to avoid collisions
const uniqueFilename = filename.replace('.jpg', `-${randomBytes(4).toString('hex')}.jpg`);
const filepath = join(tempDir, uniqueFilename);
await writeFile(filepath, imageBytes);
// Filter out undefined values before writing EXIF
const cleanExifData = Object.fromEntries(Object.entries(exifData).filter(([, value]) => value !== undefined));
await exiftool.write(filepath, cleanExifData);
// Re-read the image bytes after EXIF has been written
const finalImageBytes = await readFile(filepath);
return { filepath, imageBytes: finalImageBytes, filename: uniqueFilename };
};
describe('/asset', () => {
let admin: LoginResponseDto;
let websocket: Socket;
@@ -1249,411 +1214,6 @@ describe('/asset', () => {
});
});
describe('EXIF metadata extraction', () => {
describe('Additional date tag extraction', () => {
describe('Date-time vs time-only tag handling', () => {
it('should fall back to file timestamps when only time-only tags are available', async () => {
const { imageBytes, filename } = await createTestImageWithExif('time-only-fallback.jpg', {
TimeCreated: '2023:11:15 14:30:00', // Time-only tag, should not be used for dateTimeOriginal
// Exclude all date-time tags to force fallback to file timestamps
SubSecDateTimeOriginal: undefined,
DateTimeOriginal: undefined,
SubSecCreateDate: undefined,
SubSecMediaCreateDate: undefined,
CreateDate: undefined,
MediaCreateDate: undefined,
CreationDate: undefined,
DateTimeCreated: undefined,
GPSDateTime: undefined,
DateTimeUTC: undefined,
SonyDateTime2: undefined,
GPSDateStamp: undefined,
});
const oldDate = new Date('2020-01-01T00:00:00.000Z');
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
fileCreatedAt: oldDate.toISOString(),
fileModifiedAt: oldDate.toISOString(),
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
// Should fall back to file timestamps, which we set to 2020-01-01
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2020-01-01T00:00:00.000Z').getTime(),
);
});
it('should prefer DateTimeOriginal over time-only tags', async () => {
const { imageBytes, filename } = await createTestImageWithExif('datetime-over-time.jpg', {
DateTimeOriginal: '2023:10:10 10:00:00', // Should be preferred
TimeCreated: '2023:11:15 14:30:00', // Should be ignored (time-only)
});
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
// Should use DateTimeOriginal, not TimeCreated
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2023-10-10T10:00:00.000Z').getTime(),
);
});
});
describe('GPSDateTime tag extraction', () => {
it('should extract GPSDateTime with GPS coordinates', async () => {
const { imageBytes, filename } = await createTestImageWithExif('gps-datetime.jpg', {
GPSDateTime: '2023:11:15 12:30:00Z',
GPSLatitude: 37.7749,
GPSLongitude: -122.4194,
// Exclude other date tags
SubSecDateTimeOriginal: undefined,
DateTimeOriginal: undefined,
SubSecCreateDate: undefined,
SubSecMediaCreateDate: undefined,
CreateDate: undefined,
MediaCreateDate: undefined,
CreationDate: undefined,
DateTimeCreated: undefined,
TimeCreated: undefined,
});
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
expect(assetInfo.exifInfo?.latitude).toBeCloseTo(37.7749, 4);
expect(assetInfo.exifInfo?.longitude).toBeCloseTo(-122.4194, 4);
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2023-11-15T12:30:00.000Z').getTime(),
);
});
});
describe('CreateDate tag extraction', () => {
it('should extract CreateDate when available', async () => {
const { imageBytes, filename } = await createTestImageWithExif('create-date.jpg', {
CreateDate: '2023:11:15 10:30:00',
// Exclude other higher priority date tags
SubSecDateTimeOriginal: undefined,
DateTimeOriginal: undefined,
SubSecCreateDate: undefined,
SubSecMediaCreateDate: undefined,
MediaCreateDate: undefined,
CreationDate: undefined,
DateTimeCreated: undefined,
TimeCreated: undefined,
GPSDateTime: undefined,
});
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2023-11-15T10:30:00.000Z').getTime(),
);
});
});
describe('GPSDateStamp tag extraction', () => {
it('should fall back to file timestamps when only date-only tags are available', async () => {
const { imageBytes, filename } = await createTestImageWithExif('gps-datestamp.jpg', {
GPSDateStamp: '2023:11:15', // Date-only tag, should not be used for dateTimeOriginal
// Note: NOT including GPSTimeStamp to avoid automatic GPSDateTime creation
GPSLatitude: 51.5074,
GPSLongitude: -0.1278,
// Explicitly exclude all testable date-time tags to force fallback to file timestamps
DateTimeOriginal: undefined,
CreateDate: undefined,
CreationDate: undefined,
GPSDateTime: undefined,
});
const oldDate = new Date('2020-01-01T00:00:00.000Z');
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
fileCreatedAt: oldDate.toISOString(),
fileModifiedAt: oldDate.toISOString(),
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
expect(assetInfo.exifInfo?.latitude).toBeCloseTo(51.5074, 4);
expect(assetInfo.exifInfo?.longitude).toBeCloseTo(-0.1278, 4);
// Should fall back to file timestamps, which we set to 2020-01-01
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2020-01-01T00:00:00.000Z').getTime(),
);
});
});
/*
* NOTE: The following EXIF date tags are NOT effectively usable with JPEG test files:
*
* NOT WRITABLE to JPEG:
* - MediaCreateDate: Can be read from video files but not written to JPEG
* - DateTimeCreated: Read-only tag in JPEG format
* - DateTimeUTC: Cannot be written to JPEG files
* - SonyDateTime2: Proprietary Sony tag, not writable to JPEG
* - SubSecMediaCreateDate: Tag not defined for JPEG format
* - SourceImageCreateTime: Non-standard insta360 tag, not writable to JPEG
*
* WRITABLE but NOT READABLE from JPEG:
* - SubSecDateTimeOriginal: Can be written but not read back from JPEG
* - SubSecCreateDate: Can be written but not read back from JPEG
*
* EFFECTIVELY TESTABLE TAGS (writable and readable):
* - DateTimeOriginal ✓
* - CreateDate ✓
* - CreationDate ✓
* - GPSDateTime ✓
*
* The metadata service correctly handles non-readable tags and will fall back to
* file timestamps when only non-readable tags are present.
*/
describe('Date tag priority order', () => {
it('should respect the complete date tag priority order', async () => {
// Test cases using only EFFECTIVELY TESTABLE tags (writable AND readable from JPEG)
const testCases = [
{
name: 'DateTimeOriginal has highest priority among testable tags',
exifData: {
DateTimeOriginal: '2023:04:04 04:00:00', // TESTABLE - highest priority among readable tags
CreateDate: '2023:05:05 05:00:00', // TESTABLE
CreationDate: '2023:07:07 07:00:00', // TESTABLE
GPSDateTime: '2023:10:10 10:00:00', // TESTABLE
},
expectedDate: '2023-04-04T04:00:00.000Z',
},
{
name: 'CreationDate when DateTimeOriginal missing',
exifData: {
CreationDate: '2023:05:05 05:00:00', // TESTABLE
CreateDate: '2023:07:07 07:00:00', // TESTABLE
GPSDateTime: '2023:10:10 10:00:00', // TESTABLE
},
expectedDate: '2023-05-05T05:00:00.000Z',
},
{
name: 'CreationDate when standard EXIF tags missing',
exifData: {
CreationDate: '2023:07:07 07:00:00', // TESTABLE
GPSDateTime: '2023:10:10 10:00:00', // TESTABLE
},
expectedDate: '2023-07-07T07:00:00.000Z',
},
{
name: 'GPSDateTime when no other testable date tags present',
exifData: {
GPSDateTime: '2023:10:10 10:00:00', // TESTABLE
Make: 'SONY',
},
expectedDate: '2023-10-10T10:00:00.000Z',
},
];
for (const testCase of testCases) {
const { imageBytes, filename } = await createTestImageWithExif(
`${testCase.name.replaceAll(/\s+/g, '-').toLowerCase()}.jpg`,
testCase.exifData,
);
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal, `Failed for: ${testCase.name}`).toBeDefined();
expect(
new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime(),
`Date mismatch for: ${testCase.name}`,
).toBe(new Date(testCase.expectedDate).getTime());
}
});
});
describe('Edge cases for date tag handling', () => {
it('should fall back to file timestamps with GPSDateStamp alone', async () => {
const { imageBytes, filename } = await createTestImageWithExif('gps-datestamp-only.jpg', {
GPSDateStamp: '2023:08:08', // Date-only tag, should not be used for dateTimeOriginal
// Intentionally no GPSTimeStamp
// Exclude all other date tags
SubSecDateTimeOriginal: undefined,
DateTimeOriginal: undefined,
SubSecCreateDate: undefined,
SubSecMediaCreateDate: undefined,
CreateDate: undefined,
MediaCreateDate: undefined,
CreationDate: undefined,
DateTimeCreated: undefined,
TimeCreated: undefined,
GPSDateTime: undefined,
DateTimeUTC: undefined,
});
const oldDate = new Date('2020-01-01T00:00:00.000Z');
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
fileCreatedAt: oldDate.toISOString(),
fileModifiedAt: oldDate.toISOString(),
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
// Should fall back to file timestamps, which we set to 2020-01-01
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2020-01-01T00:00:00.000Z').getTime(),
);
});
it('should handle all testable date tags present to verify complete priority order', async () => {
const { imageBytes, filename } = await createTestImageWithExif('all-testable-date-tags.jpg', {
// All TESTABLE date tags to JPEG format (writable AND readable)
DateTimeOriginal: '2023:04:04 04:00:00', // TESTABLE - highest priority among readable tags
CreateDate: '2023:05:05 05:00:00', // TESTABLE
CreationDate: '2023:07:07 07:00:00', // TESTABLE
GPSDateTime: '2023:10:10 10:00:00', // TESTABLE
// Note: Excluded non-testable tags:
// SubSec tags: writable but not readable from JPEG
// Non-writable tags: MediaCreateDate, DateTimeCreated, DateTimeUTC, SonyDateTime2, etc.
// Time-only/date-only tags: already excluded from EXIF_DATE_TAGS
});
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
// Should use DateTimeOriginal as it has the highest priority among testable tags
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2023-04-04T04:00:00.000Z').getTime(),
);
});
it('should use CreationDate when SubSec tags are missing', async () => {
const { imageBytes, filename } = await createTestImageWithExif('creation-date-priority.jpg', {
CreationDate: '2023:07:07 07:00:00', // WRITABLE
GPSDateTime: '2023:10:10 10:00:00', // WRITABLE
// Note: DateTimeCreated, DateTimeUTC, SonyDateTime2 are NOT writable to JPEG
// Note: TimeCreated and GPSDateStamp are excluded from EXIF_DATE_TAGS (time-only/date-only)
// Exclude SubSec and standard EXIF tags
SubSecDateTimeOriginal: undefined,
DateTimeOriginal: undefined,
SubSecCreateDate: undefined,
CreateDate: undefined,
});
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
// Should use CreationDate when available
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2023-07-07T07:00:00.000Z').getTime(),
);
});
it('should skip invalid date formats and use next valid tag', async () => {
const { imageBytes, filename } = await createTestImageWithExif('invalid-date-handling.jpg', {
// Note: Testing invalid date handling with only WRITABLE tags
GPSDateTime: '2023:10:10 10:00:00', // WRITABLE - Valid date
CreationDate: '2023:13:13 13:00:00', // WRITABLE - Valid date
// Note: TimeCreated excluded (time-only), DateTimeCreated not writable to JPEG
// Exclude other date tags
SubSecDateTimeOriginal: undefined,
DateTimeOriginal: undefined,
SubSecCreateDate: undefined,
CreateDate: undefined,
});
const asset = await utils.createAsset(admin.accessToken, {
assetData: {
filename,
bytes: imageBytes,
},
});
await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id });
const assetInfo = await getAssetInfo({ id: asset.id }, { headers: asBearerAuth(admin.accessToken) });
expect(assetInfo.exifInfo?.dateTimeOriginal).toBeDefined();
// Should skip invalid dates and use the first valid one (GPSDateTime)
expect(new Date(assetInfo.exifInfo!.dateTimeOriginal!).getTime()).toBe(
new Date('2023-10-10T10:00:00.000Z').getTime(),
);
});
});
});
});
describe('POST /assets/exist', () => {
it('ignores invalid deviceAssetIds', async () => {
const response = await utils.checkExistingAssets(user1.accessToken, {

View File

@@ -1,4 +1,4 @@
import { JobCommand, JobName, LoginResponseDto, updateConfig } from '@immich/sdk';
import { LoginResponseDto, QueueCommand, QueueName, updateConfig } from '@immich/sdk';
import { cpSync, rmSync } from 'node:fs';
import { readFile } from 'node:fs/promises';
import { basename } from 'node:path';
@@ -17,28 +17,28 @@ describe('/jobs', () => {
describe('PUT /jobs', () => {
afterEach(async () => {
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.MetadataExtraction, {
command: QueueCommand.Resume,
force: false,
});
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.ThumbnailGeneration, {
command: QueueCommand.Resume,
force: false,
});
await utils.jobCommand(admin.accessToken, JobName.FaceDetection, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.FaceDetection, {
command: QueueCommand.Resume,
force: false,
});
await utils.jobCommand(admin.accessToken, JobName.SmartSearch, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.SmartSearch, {
command: QueueCommand.Resume,
force: false,
});
await utils.jobCommand(admin.accessToken, JobName.DuplicateDetection, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.DuplicateDetection, {
command: QueueCommand.Resume,
force: false,
});
@@ -59,8 +59,8 @@ describe('/jobs', () => {
it('should queue metadata extraction for missing assets', async () => {
const path = `${testAssetDir}/formats/raw/Nikon/D700/philadelphia.nef`;
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
command: JobCommand.Pause,
await utils.queueCommand(admin.accessToken, QueueName.MetadataExtraction, {
command: QueueCommand.Pause,
force: false,
});
@@ -77,20 +77,20 @@ describe('/jobs', () => {
expect(asset.exifInfo?.make).toBeNull();
}
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
command: JobCommand.Empty,
await utils.queueCommand(admin.accessToken, QueueName.MetadataExtraction, {
command: QueueCommand.Empty,
force: false,
});
await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction');
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.MetadataExtraction, {
command: QueueCommand.Resume,
force: false,
});
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
command: JobCommand.Start,
await utils.queueCommand(admin.accessToken, QueueName.MetadataExtraction, {
command: QueueCommand.Start,
force: false,
});
@@ -124,8 +124,8 @@ describe('/jobs', () => {
cpSync(`${testAssetDir}/formats/raw/Nikon/D80/glarus.nef`, path);
await utils.jobCommand(admin.accessToken, JobName.MetadataExtraction, {
command: JobCommand.Start,
await utils.queueCommand(admin.accessToken, QueueName.MetadataExtraction, {
command: QueueCommand.Start,
force: false,
});
@@ -144,8 +144,8 @@ describe('/jobs', () => {
it('should queue thumbnail extraction for assets missing thumbs', async () => {
const path = `${testAssetDir}/albums/nature/tanners_ridge.jpg`;
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
command: JobCommand.Pause,
await utils.queueCommand(admin.accessToken, QueueName.ThumbnailGeneration, {
command: QueueCommand.Pause,
force: false,
});
@@ -153,32 +153,32 @@ describe('/jobs', () => {
assetData: { bytes: await readFile(path), filename: basename(path) },
});
await utils.waitForQueueFinish(admin.accessToken, JobName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, JobName.ThumbnailGeneration);
await utils.waitForQueueFinish(admin.accessToken, QueueName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, QueueName.ThumbnailGeneration);
const assetBefore = await utils.getAssetInfo(admin.accessToken, id);
expect(assetBefore.thumbhash).toBeNull();
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
command: JobCommand.Empty,
await utils.queueCommand(admin.accessToken, QueueName.ThumbnailGeneration, {
command: QueueCommand.Empty,
force: false,
});
await utils.waitForQueueFinish(admin.accessToken, JobName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, JobName.ThumbnailGeneration);
await utils.waitForQueueFinish(admin.accessToken, QueueName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, QueueName.ThumbnailGeneration);
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.ThumbnailGeneration, {
command: QueueCommand.Resume,
force: false,
});
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
command: JobCommand.Start,
await utils.queueCommand(admin.accessToken, QueueName.ThumbnailGeneration, {
command: QueueCommand.Start,
force: false,
});
await utils.waitForQueueFinish(admin.accessToken, JobName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, JobName.ThumbnailGeneration);
await utils.waitForQueueFinish(admin.accessToken, QueueName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, QueueName.ThumbnailGeneration);
const assetAfter = await utils.getAssetInfo(admin.accessToken, id);
expect(assetAfter.thumbhash).not.toBeNull();
@@ -193,26 +193,26 @@ describe('/jobs', () => {
assetData: { bytes: await readFile(path), filename: basename(path) },
});
await utils.waitForQueueFinish(admin.accessToken, JobName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, JobName.ThumbnailGeneration);
await utils.waitForQueueFinish(admin.accessToken, QueueName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, QueueName.ThumbnailGeneration);
const assetBefore = await utils.getAssetInfo(admin.accessToken, id);
cpSync(`${testAssetDir}/albums/nature/notocactus_minimus.jpg`, path);
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
command: JobCommand.Resume,
await utils.queueCommand(admin.accessToken, QueueName.ThumbnailGeneration, {
command: QueueCommand.Resume,
force: false,
});
// This runs the missing thumbnail job
await utils.jobCommand(admin.accessToken, JobName.ThumbnailGeneration, {
command: JobCommand.Start,
await utils.queueCommand(admin.accessToken, QueueName.ThumbnailGeneration, {
command: QueueCommand.Start,
force: false,
});
await utils.waitForQueueFinish(admin.accessToken, JobName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, JobName.ThumbnailGeneration);
await utils.waitForQueueFinish(admin.accessToken, QueueName.MetadataExtraction);
await utils.waitForQueueFinish(admin.accessToken, QueueName.ThumbnailGeneration);
const assetAfter = await utils.getAssetInfo(admin.accessToken, id);

View File

@@ -0,0 +1,172 @@
import { LoginResponseDto } from '@immich/sdk';
import { createUserDto } from 'src/fixtures';
import { errorDto } from 'src/responses';
import { app, utils } from 'src/utils';
import request from 'supertest';
import { beforeAll, describe, expect, it } from 'vitest';
describe('/admin/maintenance', () => {
let cookie: string | undefined;
let admin: LoginResponseDto;
let nonAdmin: LoginResponseDto;
beforeAll(async () => {
await utils.resetDatabase();
admin = await utils.adminSetup();
nonAdmin = await utils.userSetup(admin.accessToken, createUserDto.user1);
});
// => outside of maintenance mode
describe('GET ~/server/config', async () => {
it('should indicate we are out of maintenance mode', async () => {
const { status, body } = await request(app).get('/server/config');
expect(status).toBe(200);
expect(body.maintenanceMode).toBeFalsy();
});
});
describe('POST /login', async () => {
it('should not work out of maintenance mode', async () => {
const { status, body } = await request(app).post('/admin/maintenance/login').send({ token: 'token' });
expect(status).toBe(400);
expect(body).toEqual(errorDto.badRequest('Not in maintenance mode'));
});
});
// => enter maintenance mode
describe.sequential('POST /', () => {
it('should require authentication', async () => {
const { status, body } = await request(app).post('/admin/maintenance').send({
action: 'end',
});
expect(status).toBe(401);
expect(body).toEqual(errorDto.unauthorized);
});
it('should only work for admins', async () => {
const { status, body } = await request(app)
.post('/admin/maintenance')
.set('Authorization', `Bearer ${nonAdmin.accessToken}`)
.send({ action: 'end' });
expect(status).toBe(403);
expect(body).toEqual(errorDto.forbidden);
});
it('should be a no-op if try to exit maintenance mode', async () => {
const { status } = await request(app)
.post('/admin/maintenance')
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({ action: 'end' });
expect(status).toBe(201);
});
it('should enter maintenance mode', async () => {
const { status, headers } = await request(app)
.post('/admin/maintenance')
.set('Authorization', `Bearer ${admin.accessToken}`)
.send({
action: 'start',
});
expect(status).toBe(201);
cookie = headers['set-cookie'][0].split(';')[0];
expect(cookie).toEqual(
expect.stringMatching(/^immich_maintenance_token=[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_]*$/),
);
await expect
.poll(
async () => {
const { body } = await request(app).get('/server/config');
return body.maintenanceMode;
},
{
interval: 5e2,
timeout: 1e4,
},
)
.toBeTruthy();
});
});
// => in maintenance mode
describe.sequential('in maintenance mode', () => {
describe('GET ~/server/config', async () => {
it('should indicate we are in maintenance mode', async () => {
const { status, body } = await request(app).get('/server/config');
expect(status).toBe(200);
expect(body.maintenanceMode).toBeTruthy();
});
});
describe('POST /login', async () => {
it('should fail without cookie or token in body', async () => {
const { status, body } = await request(app).post('/admin/maintenance/login').send({});
expect(status).toBe(401);
expect(body).toEqual(errorDto.unauthorizedWithMessage('Missing JWT Token'));
});
it('should succeed with cookie', async () => {
const { status, body } = await request(app).post('/admin/maintenance/login').set('cookie', cookie!).send({});
expect(status).toBe(201);
expect(body).toEqual(
expect.objectContaining({
username: 'Immich Admin',
}),
);
});
it('should succeed with token', async () => {
const { status, body } = await request(app)
.post('/admin/maintenance/login')
.send({
token: cookie!.split('=')[1].trim(),
});
expect(status).toBe(201);
expect(body).toEqual(
expect.objectContaining({
username: 'Immich Admin',
}),
);
});
});
describe('POST /', async () => {
it('should be a no-op if try to enter maintenance mode', async () => {
const { status } = await request(app)
.post('/admin/maintenance')
.set('cookie', cookie!)
.send({ action: 'start' });
expect(status).toBe(201);
});
});
});
// => exit maintenance mode
describe.sequential('POST /', () => {
it('should exit maintenance mode', async () => {
const { status } = await request(app).post('/admin/maintenance').set('cookie', cookie!).send({
action: 'end',
});
expect(status).toBe(201);
await expect
.poll(
async () => {
const { body } = await request(app).get('/server/config');
return body.maintenanceMode;
},
{
interval: 5e2,
timeout: 1e4,
},
)
.toBeFalsy();
});
});
});

View File

@@ -136,6 +136,7 @@ describe('/server', () => {
externalDomain: '',
publicUsers: true,
isOnboarded: false,
maintenanceMode: false,
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json',
});

View File

@@ -1,6 +1,6 @@
import {
JobName,
LoginResponseDto,
QueueName,
createStack,
deleteUserAdmin,
getMyUser,
@@ -328,7 +328,7 @@ describe('/admin/users', () => {
{ headers: asBearerAuth(user.accessToken) },
);
await utils.waitForQueueFinish(admin.accessToken, JobName.BackgroundTask);
await utils.waitForQueueFinish(admin.accessToken, QueueName.BackgroundTask);
const { status, body } = await request(app)
.delete(`/admin/users/${user.userId}`)

View File

@@ -1,178 +0,0 @@
#!/usr/bin/env node
/**
* Script to generate test images with additional EXIF date tags
* This creates actual JPEG images with embedded metadata for testing
* Images are generated into e2e/test-assets/metadata/dates/
*/
import { execSync } from 'node:child_process';
import { writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import sharp from 'sharp';
interface TestImage {
filename: string;
description: string;
exifTags: Record<string, string>;
}
const testImages: TestImage[] = [
{
filename: 'time-created.jpg',
description: 'Image with TimeCreated tag',
exifTags: {
TimeCreated: '2023:11:15 14:30:00',
Make: 'Canon',
Model: 'EOS R5',
},
},
{
filename: 'gps-datetime.jpg',
description: 'Image with GPSDateTime and coordinates',
exifTags: {
GPSDateTime: '2023:11:15 12:30:00Z',
GPSLatitude: '37.7749',
GPSLongitude: '-122.4194',
GPSLatitudeRef: 'N',
GPSLongitudeRef: 'W',
},
},
{
filename: 'datetime-utc.jpg',
description: 'Image with DateTimeUTC tag',
exifTags: {
DateTimeUTC: '2023:11:15 10:30:00',
Make: 'Nikon',
Model: 'D850',
},
},
{
filename: 'gps-datestamp.jpg',
description: 'Image with GPSDateStamp and GPSTimeStamp',
exifTags: {
GPSDateStamp: '2023:11:15',
GPSTimeStamp: '08:30:00',
GPSLatitude: '51.5074',
GPSLongitude: '-0.1278',
GPSLatitudeRef: 'N',
GPSLongitudeRef: 'W',
},
},
{
filename: 'sony-datetime2.jpg',
description: 'Sony camera image with SonyDateTime2 tag',
exifTags: {
SonyDateTime2: '2023:11:15 06:30:00',
Make: 'SONY',
Model: 'ILCE-7RM5',
},
},
{
filename: 'date-priority-test.jpg',
description: 'Image with multiple date tags to test priority',
exifTags: {
SubSecDateTimeOriginal: '2023:01:01 01:00:00',
DateTimeOriginal: '2023:02:02 02:00:00',
SubSecCreateDate: '2023:03:03 03:00:00',
CreateDate: '2023:04:04 04:00:00',
CreationDate: '2023:05:05 05:00:00',
DateTimeCreated: '2023:06:06 06:00:00',
TimeCreated: '2023:07:07 07:00:00',
GPSDateTime: '2023:08:08 08:00:00',
DateTimeUTC: '2023:09:09 09:00:00',
GPSDateStamp: '2023:10:10',
SonyDateTime2: '2023:11:11 11:00:00',
},
},
{
filename: 'new-tags-only.jpg',
description: 'Image with only additional date tags (no standard tags)',
exifTags: {
TimeCreated: '2023:12:01 15:45:30',
GPSDateTime: '2023:12:01 13:45:30Z',
DateTimeUTC: '2023:12:01 13:45:30',
GPSDateStamp: '2023:12:01',
SonyDateTime2: '2023:12:01 08:45:30',
GPSLatitude: '40.7128',
GPSLongitude: '-74.0060',
GPSLatitudeRef: 'N',
GPSLongitudeRef: 'W',
},
},
];
const generateTestImages = async (): Promise<void> => {
// Target directory: e2e/test-assets/metadata/dates/
// Current file is in: e2e/src/
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const targetDir = join(__dirname, '..', 'test-assets', 'metadata', 'dates');
console.log('Generating test images with additional EXIF date tags...');
console.log(`Target directory: ${targetDir}`);
for (const image of testImages) {
try {
const imagePath = join(targetDir, image.filename);
// Create unique JPEG file using Sharp
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
const jpegData = await sharp({
create: {
width: 100,
height: 100,
channels: 3,
background: { r, g, b },
},
})
.jpeg({ quality: 90 })
.toBuffer();
writeFileSync(imagePath, jpegData);
// Build exiftool command to add EXIF data
const exifArgs = Object.entries(image.exifTags)
.map(([tag, value]) => `-${tag}="${value}"`)
.join(' ');
const command = `exiftool ${exifArgs} -overwrite_original "${imagePath}"`;
console.log(`Creating ${image.filename}: ${image.description}`);
execSync(command, { stdio: 'pipe' });
// Verify the tags were written
const verifyCommand = `exiftool -json "${imagePath}"`;
const result = execSync(verifyCommand, { encoding: 'utf8' });
const metadata = JSON.parse(result)[0];
console.log(` ✓ Created with ${Object.keys(image.exifTags).length} EXIF tags`);
// Log first date tag found for verification
const firstDateTag = Object.keys(image.exifTags).find(
(tag) => tag.includes('Date') || tag.includes('Time') || tag.includes('Created'),
);
if (firstDateTag && metadata[firstDateTag]) {
console.log(` ✓ Verified ${firstDateTag}: ${metadata[firstDateTag]}`);
}
} catch (error) {
console.error(`Failed to create ${image.filename}:`, (error as Error).message);
}
}
console.log('\nTest image generation complete!');
console.log('Files created in:', targetDir);
console.log('\nTo test these images:');
console.log(`cd ${targetDir} && exiftool -time:all -gps:all *.jpg`);
};
export { generateTestImages };
// Run the generator if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
generateTestImages().catch(console.error);
}

View File

@@ -0,0 +1,37 @@
export { generateTimelineData } from './timeline/model-objects';
export { createDefaultTimelineConfig, validateTimelineConfig } from './timeline/timeline-config';
export type {
MockAlbum,
MonthSpec,
SerializedTimelineData,
MockTimelineAsset as TimelineAssetConfig,
TimelineConfig,
MockTimelineData as TimelineData,
} from './timeline/timeline-config';
export {
getAlbum,
getAsset,
getTimeBucket,
getTimeBuckets,
toAssetResponseDto,
toColumnarFormat,
} from './timeline/rest-response';
export type { Changes } from './timeline/rest-response';
export { randomImage, randomImageFromString, randomPreview, randomThumbnail } from './timeline/images';
export {
SeededRandom,
getMockAsset,
parseTimeBucketKey,
selectRandom,
selectRandomDays,
selectRandomMultiple,
} from './timeline/utils';
export { ASSET_DISTRIBUTION, DAY_DISTRIBUTION } from './timeline/distribution-patterns';
export type { DayPattern, MonthDistribution } from './timeline/distribution-patterns';

View File

@@ -0,0 +1,183 @@
import { generateConsecutiveDays, generateDayAssets } from 'src/generators/timeline/model-objects';
import { SeededRandom, selectRandomDays } from 'src/generators/timeline/utils';
import type { MockTimelineAsset } from './timeline-config';
import { GENERATION_CONSTANTS } from './timeline-config';
type AssetDistributionStrategy = (rng: SeededRandom) => number;
type DayDistributionStrategy = (
year: number,
month: number,
daysInMonth: number,
totalAssets: number,
ownerId: string,
rng: SeededRandom,
) => MockTimelineAsset[];
/**
* Strategies for determining total asset count per month
*/
export const ASSET_DISTRIBUTION: Record<MonthDistribution, AssetDistributionStrategy | null> = {
empty: null, // Special case - handled separately
sparse: (rng) => rng.nextInt(3, 9), // 3-8 assets
medium: (rng) => rng.nextInt(15, 31), // 15-30 assets
dense: (rng) => rng.nextInt(50, 81), // 50-80 assets
'very-dense': (rng) => rng.nextInt(80, 151), // 80-150 assets
};
/**
* Strategies for distributing assets across days within a month
*/
export const DAY_DISTRIBUTION: Record<DayPattern, DayDistributionStrategy> = {
'single-day': (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// All assets on one day in the middle of the month
const day = Math.floor(daysInMonth / 2);
return generateDayAssets(year, month, day, totalAssets, ownerId, rng);
},
'consecutive-large': (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// 3-5 consecutive days with evenly distributed assets
const numDays = Math.min(5, Math.floor(totalAssets / 15));
const startDay = rng.nextInt(1, daysInMonth - numDays + 2);
return generateConsecutiveDays(year, month, startDay, numDays, totalAssets, ownerId, rng);
},
'consecutive-small': (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// Multiple consecutive days with 1-3 assets each (side-by-side layout)
const assets: MockTimelineAsset[] = [];
const numDays = Math.min(totalAssets, Math.floor(daysInMonth / 2));
const startDay = rng.nextInt(1, daysInMonth - numDays + 2);
let assetIndex = 0;
for (let i = 0; i < numDays && assetIndex < totalAssets; i++) {
const dayAssets = Math.min(3, rng.nextInt(1, 4));
const actualAssets = Math.min(dayAssets, totalAssets - assetIndex);
// Create a new RNG for this day
const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000));
assets.push(...generateDayAssets(year, month, startDay + i, actualAssets, ownerId, dayRng));
assetIndex += actualAssets;
}
return assets;
},
alternating: (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// Alternate between large (15-25) and small (1-3) days
const assets: MockTimelineAsset[] = [];
let day = 1;
let isLarge = true;
let assetIndex = 0;
while (assetIndex < totalAssets && day <= daysInMonth) {
const dayAssets = isLarge ? Math.min(25, rng.nextInt(15, 26)) : rng.nextInt(1, 4);
const actualAssets = Math.min(dayAssets, totalAssets - assetIndex);
// Create a new RNG for this day
const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000));
assets.push(...generateDayAssets(year, month, day, actualAssets, ownerId, dayRng));
assetIndex += actualAssets;
day += isLarge ? 1 : 1; // Could add gaps here
isLarge = !isLarge;
}
return assets;
},
'sparse-scattered': (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// Spread assets across random days with gaps
const assets: MockTimelineAsset[] = [];
const numDays = Math.min(totalAssets, Math.floor(daysInMonth * GENERATION_CONSTANTS.SPARSE_DAY_COVERAGE));
const daysWithPhotos = selectRandomDays(daysInMonth, numDays, rng);
let assetIndex = 0;
for (let i = 0; i < daysWithPhotos.length && assetIndex < totalAssets; i++) {
const dayAssets =
Math.floor(totalAssets / numDays) + (i === daysWithPhotos.length - 1 ? totalAssets % numDays : 0);
// Create a new RNG for this day
const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000));
assets.push(...generateDayAssets(year, month, daysWithPhotos[i], dayAssets, ownerId, dayRng));
assetIndex += dayAssets;
}
return assets;
},
'start-heavy': (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// Most assets in first week
const assets: MockTimelineAsset[] = [];
const firstWeekAssets = Math.floor(totalAssets * 0.7);
const remainingAssets = totalAssets - firstWeekAssets;
// First 7 days
assets.push(...generateConsecutiveDays(year, month, 1, 7, firstWeekAssets, ownerId, rng));
// Remaining scattered
if (remainingAssets > 0) {
const midDay = Math.floor(daysInMonth / 2);
// Create a new RNG for the remaining assets
const remainingRng = new SeededRandom(rng.nextInt(0, 1_000_000));
assets.push(...generateDayAssets(year, month, midDay, remainingAssets, ownerId, remainingRng));
}
return assets;
},
'end-heavy': (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// Most assets in last week
const assets: MockTimelineAsset[] = [];
const lastWeekAssets = Math.floor(totalAssets * 0.7);
const remainingAssets = totalAssets - lastWeekAssets;
// Remaining at start
if (remainingAssets > 0) {
// Create a new RNG for the start assets
const startRng = new SeededRandom(rng.nextInt(0, 1_000_000));
assets.push(...generateDayAssets(year, month, 2, remainingAssets, ownerId, startRng));
}
// Last 7 days
const startDay = daysInMonth - 6;
assets.push(...generateConsecutiveDays(year, month, startDay, 7, lastWeekAssets, ownerId, rng));
return assets;
},
'mid-heavy': (year, month, daysInMonth, totalAssets, ownerId, rng) => {
// Most assets in middle of month
const assets: MockTimelineAsset[] = [];
const midAssets = Math.floor(totalAssets * 0.7);
const sideAssets = Math.floor((totalAssets - midAssets) / 2);
// Start
if (sideAssets > 0) {
// Create a new RNG for the start assets
const startRng = new SeededRandom(rng.nextInt(0, 1_000_000));
assets.push(...generateDayAssets(year, month, 2, sideAssets, ownerId, startRng));
}
// Middle
const midStart = Math.floor(daysInMonth / 2) - 3;
assets.push(...generateConsecutiveDays(year, month, midStart, 7, midAssets, ownerId, rng));
// End
const endAssets = totalAssets - midAssets - sideAssets;
if (endAssets > 0) {
// Create a new RNG for the end assets
const endRng = new SeededRandom(rng.nextInt(0, 1_000_000));
assets.push(...generateDayAssets(year, month, daysInMonth - 1, endAssets, ownerId, endRng));
}
return assets;
},
};
export type MonthDistribution =
| 'empty' // 0 assets
| 'sparse' // 3-8 assets
| 'medium' // 15-30 assets
| 'dense' // 50-80 assets
| 'very-dense'; // 80-150 assets
export type DayPattern =
| 'single-day' // All images in one day
| 'consecutive-large' // Multiple days with 15-25 images each
| 'consecutive-small' // Multiple days with 1-3 images each (side-by-side)
| 'alternating' // Alternating large/small days
| 'sparse-scattered' // Few images scattered across month
| 'start-heavy' // Most images at start of month
| 'end-heavy' // Most images at end of month
| 'mid-heavy'; // Most images in middle of month

View File

@@ -0,0 +1,111 @@
import sharp from 'sharp';
import { SeededRandom } from 'src/generators/timeline/utils';
export const randomThumbnail = async (seed: string, ratio: number) => {
const height = 235;
const width = Math.round(height * ratio);
return randomImageFromString(seed, { width, height });
};
export const randomPreview = async (seed: string, ratio: number) => {
const height = 500;
const width = Math.round(height * ratio);
return randomImageFromString(seed, { width, height });
};
export const randomImageFromString = async (
seed: string = '',
{ width = 100, height = 100 }: { width: number; height: number },
) => {
// Convert string to number for seeding
let seedNumber = 0;
for (let i = 0; i < seed.length; i++) {
seedNumber = (seedNumber << 5) - seedNumber + (seed.codePointAt(i) ?? 0);
seedNumber = seedNumber & seedNumber; // Convert to 32bit integer
}
return randomImage(new SeededRandom(Math.abs(seedNumber)), { width, height });
};
export const randomImage = async (rng: SeededRandom, { width, height }: { width: number; height: number }) => {
const r1 = rng.nextInt(0, 256);
const g1 = rng.nextInt(0, 256);
const b1 = rng.nextInt(0, 256);
const r2 = rng.nextInt(0, 256);
const g2 = rng.nextInt(0, 256);
const b2 = rng.nextInt(0, 256);
const patternType = rng.nextInt(0, 5);
let svgPattern = '';
switch (patternType) {
case 0: {
// Solid color
svgPattern = `<svg width="${width}" height="${height}">
<rect x="0" y="0" width="${width}" height="${height}" fill="rgb(${r1},${g1},${b1})"/>
</svg>`;
break;
}
case 1: {
// Horizontal stripes
const stripeHeight = 10;
svgPattern = `<svg width="${width}" height="${height}">
${Array.from(
{ length: height / stripeHeight },
(_, i) =>
`<rect x="0" y="${i * stripeHeight}" width="${width}" height="${stripeHeight}"
fill="rgb(${i % 2 ? r1 : r2},${i % 2 ? g1 : g2},${i % 2 ? b1 : b2})"/>`,
).join('')}
</svg>`;
break;
}
case 2: {
// Vertical stripes
const stripeWidth = 10;
svgPattern = `<svg width="${width}" height="${height}">
${Array.from(
{ length: width / stripeWidth },
(_, i) =>
`<rect x="${i * stripeWidth}" y="0" width="${stripeWidth}" height="${height}"
fill="rgb(${i % 2 ? r1 : r2},${i % 2 ? g1 : g2},${i % 2 ? b1 : b2})"/>`,
).join('')}
</svg>`;
break;
}
case 3: {
// Checkerboard
const squareSize = 10;
svgPattern = `<svg width="${width}" height="${height}">
${Array.from({ length: height / squareSize }, (_, row) =>
Array.from({ length: width / squareSize }, (_, col) => {
const isEven = (row + col) % 2 === 0;
return `<rect x="${col * squareSize}" y="${row * squareSize}"
width="${squareSize}" height="${squareSize}"
fill="rgb(${isEven ? r1 : r2},${isEven ? g1 : g2},${isEven ? b1 : b2})"/>`;
}).join(''),
).join('')}
</svg>`;
break;
}
case 4: {
// Diagonal stripes
svgPattern = `<svg width="${width}" height="${height}">
<defs>
<pattern id="diagonal" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<rect x="0" y="0" width="10" height="20" fill="rgb(${r1},${g1},${b1})"/>
<rect x="10" y="0" width="10" height="20" fill="rgb(${r2},${g2},${b2})"/>
</pattern>
</defs>
<rect x="0" y="0" width="${width}" height="${height}" fill="url(#diagonal)" transform="rotate(45 50 50)"/>
</svg>`;
break;
}
}
const svgBuffer = Buffer.from(svgPattern);
const jpegData = await sharp(svgBuffer).jpeg({ quality: 50 }).toBuffer();
return jpegData;
};

View File

@@ -0,0 +1,265 @@
/**
* Generator functions for timeline model objects
*/
import { faker } from '@faker-js/faker';
import { AssetVisibility } from '@immich/sdk';
import { DateTime } from 'luxon';
import { writeFileSync } from 'node:fs';
import { SeededRandom } from 'src/generators/timeline/utils';
import type { DayPattern, MonthDistribution } from './distribution-patterns';
import { ASSET_DISTRIBUTION, DAY_DISTRIBUTION } from './distribution-patterns';
import type { MockTimelineAsset, MockTimelineData, SerializedTimelineData, TimelineConfig } from './timeline-config';
import { ASPECT_RATIO_WEIGHTS, GENERATION_CONSTANTS, validateTimelineConfig } from './timeline-config';
/**
* Generate a random aspect ratio based on weighted probabilities
*/
export function generateAspectRatio(rng: SeededRandom): string {
const random = rng.next();
let cumulative = 0;
for (const [ratio, weight] of Object.entries(ASPECT_RATIO_WEIGHTS)) {
cumulative += weight;
if (random < cumulative) {
return ratio;
}
}
return '16:9'; // Default fallback
}
export function generateThumbhash(rng: SeededRandom): string {
return Array.from({ length: 10 }, () => rng.nextInt(0, 256).toString(16).padStart(2, '0')).join('');
}
export function generateDuration(rng: SeededRandom): string {
return `${rng.nextInt(GENERATION_CONSTANTS.MIN_VIDEO_DURATION_SECONDS, GENERATION_CONSTANTS.MAX_VIDEO_DURATION_SECONDS)}.${rng.nextInt(0, 1000).toString().padStart(3, '0')}`;
}
export function generateUUID(): string {
return faker.string.uuid();
}
export function generateAsset(
year: number,
month: number,
day: number,
ownerId: string,
rng: SeededRandom,
): MockTimelineAsset {
const from = DateTime.fromObject({ year, month, day }).setZone('UTC');
const to = from.endOf('day');
const date = faker.date.between({ from: from.toJSDate(), to: to.toJSDate() });
const isVideo = rng.next() < GENERATION_CONSTANTS.VIDEO_PROBABILITY;
const assetId = generateUUID();
const hasGPS = rng.next() < GENERATION_CONSTANTS.GPS_PERCENTAGE;
const ratio = generateAspectRatio(rng);
const asset: MockTimelineAsset = {
id: assetId,
ownerId,
ratio: Number.parseFloat(ratio.split(':')[0]) / Number.parseFloat(ratio.split(':')[1]),
thumbhash: generateThumbhash(rng),
localDateTime: date.toISOString(),
fileCreatedAt: date.toISOString(),
isFavorite: rng.next() < GENERATION_CONSTANTS.FAVORITE_PROBABILITY,
isTrashed: false,
isVideo,
isImage: !isVideo,
duration: isVideo ? generateDuration(rng) : null,
projectionType: null,
livePhotoVideoId: null,
city: hasGPS ? faker.location.city() : null,
country: hasGPS ? faker.location.country() : null,
people: null,
latitude: hasGPS ? faker.location.latitude() : null,
longitude: hasGPS ? faker.location.longitude() : null,
visibility: AssetVisibility.Timeline,
stack: null,
fileSizeInByte: faker.number.int({ min: 510, max: 5_000_000 }),
checksum: faker.string.alphanumeric({ length: 5 }),
};
return asset;
}
/**
* Generate assets for a specific day
*/
export function generateDayAssets(
year: number,
month: number,
day: number,
assetCount: number,
ownerId: string,
rng: SeededRandom,
): MockTimelineAsset[] {
return Array.from({ length: assetCount }, () => generateAsset(year, month, day, ownerId, rng));
}
/**
* Distribute assets evenly across consecutive days
*
* @returns Array of generated timeline assets
*/
export function generateConsecutiveDays(
year: number,
month: number,
startDay: number,
numDays: number,
totalAssets: number,
ownerId: string,
rng: SeededRandom,
): MockTimelineAsset[] {
const assets: MockTimelineAsset[] = [];
const assetsPerDay = Math.floor(totalAssets / numDays);
for (let i = 0; i < numDays; i++) {
const dayAssets =
i === numDays - 1
? totalAssets - assetsPerDay * (numDays - 1) // Remainder on last day
: assetsPerDay;
// Create a new RNG with a different seed for each day
const dayRng = new SeededRandom(rng.nextInt(0, 1_000_000) + i * 100);
assets.push(...generateDayAssets(year, month, startDay + i, dayAssets, ownerId, dayRng));
}
return assets;
}
/**
* Generate assets for a month with specified distribution pattern
*/
export function generateMonthAssets(
year: number,
month: number,
ownerId: string,
distribution: MonthDistribution = 'medium',
pattern: DayPattern = 'consecutive-large',
rng: SeededRandom,
): MockTimelineAsset[] {
const daysInMonth = new Date(year, month, 0).getDate();
if (distribution === 'empty') {
return [];
}
const distributionStrategy = ASSET_DISTRIBUTION[distribution];
if (!distributionStrategy) {
console.warn(`Unknown distribution: ${distribution}, defaulting to medium`);
return [];
}
const totalAssets = distributionStrategy(rng);
const dayStrategy = DAY_DISTRIBUTION[pattern];
if (!dayStrategy) {
console.warn(`Unknown pattern: ${pattern}, defaulting to consecutive-large`);
// Fallback to consecutive-large pattern
const numDays = Math.min(5, Math.floor(totalAssets / 15));
const startDay = rng.nextInt(1, daysInMonth - numDays + 2);
const assets = generateConsecutiveDays(year, month, startDay, numDays, totalAssets, ownerId, rng);
assets.sort((a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds);
return assets;
}
const assets = dayStrategy(year, month, daysInMonth, totalAssets, ownerId, rng);
assets.sort((a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds);
return assets;
}
/**
* Main generator function for timeline data
*/
export function generateTimelineData(config: TimelineConfig): MockTimelineData {
validateTimelineConfig(config);
const buckets = new Map<string, MockTimelineAsset[]>();
const monthStats: Record<string, { count: number; distribution: MonthDistribution; pattern: DayPattern }> = {};
const globalRng = new SeededRandom(config.seed || GENERATION_CONSTANTS.DEFAULT_SEED);
faker.seed(globalRng.nextInt(0, 1_000_000));
for (const monthConfig of config.months) {
const { year, month, distribution, pattern } = monthConfig;
const monthSeed = globalRng.nextInt(0, 1_000_000);
const monthRng = new SeededRandom(monthSeed);
const monthAssets = generateMonthAssets(
year,
month,
config.ownerId || generateUUID(),
distribution,
pattern,
monthRng,
);
if (monthAssets.length > 0) {
const monthKey = `${year}-${month.toString().padStart(2, '0')}`;
monthStats[monthKey] = {
count: monthAssets.length,
distribution,
pattern,
};
// Create bucket key (YYYY-MM-01)
const bucketKey = `${year}-${month.toString().padStart(2, '0')}-01`;
buckets.set(bucketKey, monthAssets);
}
}
// Create a mock album from random assets
const allAssets = [...buckets.values()].flat();
// Select 10-30 random assets for the album (or all assets if less than 10)
const albumSize = Math.min(allAssets.length, globalRng.nextInt(10, 31));
const selectedAssetConfigs: MockTimelineAsset[] = [];
const usedIndices = new Set<number>();
while (selectedAssetConfigs.length < albumSize && usedIndices.size < allAssets.length) {
const randomIndex = globalRng.nextInt(0, allAssets.length);
if (!usedIndices.has(randomIndex)) {
usedIndices.add(randomIndex);
selectedAssetConfigs.push(allAssets[randomIndex]);
}
}
// Sort selected assets by date (newest first)
selectedAssetConfigs.sort(
(a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds,
);
const selectedAssets = selectedAssetConfigs.map((asset) => asset.id);
const now = new Date().toISOString();
const album = {
id: generateUUID(),
albumName: 'Test Album',
description: 'A mock album for testing',
assetIds: selectedAssets,
thumbnailAssetId: selectedAssets.length > 0 ? selectedAssets[0] : null,
createdAt: now,
updatedAt: now,
};
// Write to file if configured
if (config.writeToFile) {
const outputPath = config.outputPath || '/tmp/timeline-data.json';
// Convert Map to object for serialization
const serializedData: SerializedTimelineData = {
buckets: Object.fromEntries(buckets),
album,
};
try {
writeFileSync(outputPath, JSON.stringify(serializedData, null, 2));
console.log(`Timeline data written to ${outputPath}`);
} catch (error) {
console.error(`Failed to write timeline data to ${outputPath}:`, error);
}
}
return { buckets, album };
}

View File

@@ -0,0 +1,436 @@
/**
* REST API output functions for converting timeline data to API response formats
*/
import {
AssetTypeEnum,
AssetVisibility,
UserAvatarColor,
type AlbumResponseDto,
type AssetResponseDto,
type ExifResponseDto,
type TimeBucketAssetResponseDto,
type TimeBucketsResponseDto,
type UserResponseDto,
} from '@immich/sdk';
import { DateTime } from 'luxon';
import { signupDto } from 'src/fixtures';
import { parseTimeBucketKey } from 'src/generators/timeline/utils';
import type { MockTimelineAsset, MockTimelineData } from './timeline-config';
/**
* Convert timeline/asset models to columnar format (parallel arrays)
*/
export function toColumnarFormat(assets: MockTimelineAsset[]): TimeBucketAssetResponseDto {
const result: TimeBucketAssetResponseDto = {
id: [],
ownerId: [],
ratio: [],
thumbhash: [],
fileCreatedAt: [],
localOffsetHours: [],
isFavorite: [],
isTrashed: [],
isImage: [],
duration: [],
projectionType: [],
livePhotoVideoId: [],
city: [],
country: [],
visibility: [],
};
for (const asset of assets) {
result.id.push(asset.id);
result.ownerId.push(asset.ownerId);
result.ratio.push(asset.ratio);
result.thumbhash.push(asset.thumbhash);
result.fileCreatedAt.push(asset.fileCreatedAt);
result.localOffsetHours.push(0); // Assuming UTC for mocks
result.isFavorite.push(asset.isFavorite);
result.isTrashed.push(asset.isTrashed);
result.isImage.push(asset.isImage);
result.duration.push(asset.duration);
result.projectionType.push(asset.projectionType);
result.livePhotoVideoId.push(asset.livePhotoVideoId);
result.city.push(asset.city);
result.country.push(asset.country);
result.visibility.push(asset.visibility);
}
if (assets.some((a) => a.latitude !== null || a.longitude !== null)) {
result.latitude = assets.map((a) => a.latitude);
result.longitude = assets.map((a) => a.longitude);
}
result.stack = assets.map(() => null);
return result;
}
/**
* Extract a single bucket from timeline data (mimics getTimeBucket API)
* Automatically handles both ISO timestamp and simple month formats
* Returns data in columnar format matching the actual API
* When albumId is provided, only returns assets from that album
*/
export function getTimeBucket(
timelineData: MockTimelineData,
timeBucket: string,
isTrashed: boolean | undefined,
isArchived: boolean | undefined,
isFavorite: boolean | undefined,
albumId: string | undefined,
changes: Changes,
): TimeBucketAssetResponseDto {
const bucketKey = parseTimeBucketKey(timeBucket);
let assets = timelineData.buckets.get(bucketKey);
if (!assets) {
return toColumnarFormat([]);
}
// Create sets for quick lookups
const deletedAssetIds = new Set(changes.assetDeletions);
const archivedAssetIds = new Set(changes.assetArchivals);
const favoritedAssetIds = new Set(changes.assetFavorites);
// Filter assets based on trashed/archived status
assets = assets.filter((asset) =>
shouldIncludeAsset(asset, isTrashed, isArchived, isFavorite, deletedAssetIds, archivedAssetIds, favoritedAssetIds),
);
// Filter to only include assets from the specified album
if (albumId) {
const album = timelineData.album;
if (!album || album.id !== albumId) {
return toColumnarFormat([]);
}
// Create a Set for faster lookup
const albumAssetIds = new Set([...album.assetIds, ...changes.albumAdditions]);
assets = assets.filter((asset) => albumAssetIds.has(asset.id));
}
// Override properties for assets in changes arrays
const assetsWithOverrides = assets.map((asset) => {
if (deletedAssetIds.has(asset.id) || archivedAssetIds.has(asset.id) || favoritedAssetIds.has(asset.id)) {
return {
...asset,
isFavorite: favoritedAssetIds.has(asset.id) ? true : asset.isFavorite,
isTrashed: deletedAssetIds.has(asset.id) ? true : asset.isTrashed,
visibility: archivedAssetIds.has(asset.id) ? AssetVisibility.Archive : asset.visibility,
};
}
return asset;
});
return toColumnarFormat(assetsWithOverrides);
}
export type Changes = {
// ids of assets that are newly added to the album
albumAdditions: string[];
// ids of assets that are newly deleted
assetDeletions: string[];
// ids of assets that are newly archived
assetArchivals: string[];
// ids of assets that are newly favorited
assetFavorites: string[];
};
/**
* Helper function to determine if an asset should be included based on filter criteria
* @param asset - The asset to check
* @param isTrashed - Filter for trashed status (undefined means no filter)
* @param isArchived - Filter for archived status (undefined means no filter)
* @param isFavorite - Filter for favorite status (undefined means no filter)
* @param deletedAssetIds - Set of IDs for assets that have been deleted
* @param archivedAssetIds - Set of IDs for assets that have been archived
* @param favoritedAssetIds - Set of IDs for assets that have been favorited
* @returns true if the asset matches all filter criteria
*/
function shouldIncludeAsset(
asset: MockTimelineAsset,
isTrashed: boolean | undefined,
isArchived: boolean | undefined,
isFavorite: boolean | undefined,
deletedAssetIds: Set<string>,
archivedAssetIds: Set<string>,
favoritedAssetIds: Set<string>,
): boolean {
// Determine actual status (property or in changes)
const actuallyTrashed = asset.isTrashed || deletedAssetIds.has(asset.id);
const actuallyArchived = asset.visibility === 'archive' || archivedAssetIds.has(asset.id);
const actuallyFavorited = asset.isFavorite || favoritedAssetIds.has(asset.id);
// Apply filters
if (isTrashed !== undefined && actuallyTrashed !== isTrashed) {
return false;
}
if (isArchived !== undefined && actuallyArchived !== isArchived) {
return false;
}
if (isFavorite !== undefined && actuallyFavorited !== isFavorite) {
return false;
}
return true;
}
/**
* Get summary for all buckets (mimics getTimeBuckets API)
* When albumId is provided, only includes buckets that contain assets from that album
*/
export function getTimeBuckets(
timelineData: MockTimelineData,
isTrashed: boolean | undefined,
isArchived: boolean | undefined,
isFavorite: boolean | undefined,
albumId: string | undefined,
changes: Changes,
): TimeBucketsResponseDto[] {
const summary: TimeBucketsResponseDto[] = [];
// Create sets for quick lookups
const deletedAssetIds = new Set(changes.assetDeletions);
const archivedAssetIds = new Set(changes.assetArchivals);
const favoritedAssetIds = new Set(changes.assetFavorites);
// If no albumId is specified, return summary for all assets
if (albumId) {
// Filter to only include buckets with assets from the specified album
const album = timelineData.album;
if (!album || album.id !== albumId) {
return [];
}
// Create a Set for faster lookup
const albumAssetIds = new Set([...album.assetIds, ...changes.albumAdditions]);
for (const removed of changes.assetDeletions) {
albumAssetIds.delete(removed);
}
for (const [bucketKey, assets] of timelineData.buckets) {
// Count how many assets in this bucket are in the album and match trashed/archived filters
const albumAssetsInBucket = assets.filter((asset) => {
// Must be in the album
if (!albumAssetIds.has(asset.id)) {
return false;
}
return shouldIncludeAsset(
asset,
isTrashed,
isArchived,
isFavorite,
deletedAssetIds,
archivedAssetIds,
favoritedAssetIds,
);
});
if (albumAssetsInBucket.length > 0) {
summary.push({
timeBucket: bucketKey,
count: albumAssetsInBucket.length,
});
}
}
} else {
for (const [bucketKey, assets] of timelineData.buckets) {
// Filter assets based on trashed/archived status
const filteredAssets = assets.filter((asset) =>
shouldIncludeAsset(
asset,
isTrashed,
isArchived,
isFavorite,
deletedAssetIds,
archivedAssetIds,
favoritedAssetIds,
),
);
if (filteredAssets.length > 0) {
summary.push({
timeBucket: bucketKey,
count: filteredAssets.length,
});
}
}
}
// Sort summary by date (newest first) using luxon
summary.sort((a, b) => {
const dateA = DateTime.fromISO(a.timeBucket);
const dateB = DateTime.fromISO(b.timeBucket);
return dateB.diff(dateA).milliseconds;
});
return summary;
}
const createDefaultOwner = (ownerId: string) => {
const defaultOwner: UserResponseDto = {
id: ownerId,
email: signupDto.admin.email,
name: signupDto.admin.name,
profileImagePath: '',
profileChangedAt: new Date().toISOString(),
avatarColor: UserAvatarColor.Blue,
};
return defaultOwner;
};
/**
* Convert a TimelineAssetConfig to a full AssetResponseDto
* This matches the response from GET /api/assets/:id
*/
export function toAssetResponseDto(asset: MockTimelineAsset, owner?: UserResponseDto): AssetResponseDto {
const now = new Date().toISOString();
// Default owner if not provided
const defaultOwner = createDefaultOwner(asset.ownerId);
const exifInfo: ExifResponseDto = {
make: null,
model: null,
exifImageWidth: asset.ratio > 1 ? 4000 : 3000,
exifImageHeight: asset.ratio > 1 ? Math.round(4000 / asset.ratio) : Math.round(3000 * asset.ratio),
fileSizeInByte: asset.fileSizeInByte,
orientation: '1',
dateTimeOriginal: asset.fileCreatedAt,
modifyDate: asset.fileCreatedAt,
timeZone: asset.latitude === null ? null : 'UTC',
lensModel: null,
fNumber: null,
focalLength: null,
iso: null,
exposureTime: null,
latitude: asset.latitude,
longitude: asset.longitude,
city: asset.city,
country: asset.country,
state: null,
description: null,
};
return {
id: asset.id,
deviceAssetId: `device-${asset.id}`,
ownerId: asset.ownerId,
owner: owner || defaultOwner,
libraryId: `library-${asset.ownerId}`,
deviceId: `device-${asset.ownerId}`,
type: asset.isVideo ? AssetTypeEnum.Video : AssetTypeEnum.Image,
originalPath: `/original/${asset.id}.${asset.isVideo ? 'mp4' : 'jpg'}`,
originalFileName: `${asset.id}.${asset.isVideo ? 'mp4' : 'jpg'}`,
originalMimeType: asset.isVideo ? 'video/mp4' : 'image/jpeg',
thumbhash: asset.thumbhash,
fileCreatedAt: asset.fileCreatedAt,
fileModifiedAt: asset.fileCreatedAt,
localDateTime: asset.localDateTime,
updatedAt: now,
createdAt: asset.fileCreatedAt,
isFavorite: asset.isFavorite,
isArchived: false,
isTrashed: asset.isTrashed,
visibility: asset.visibility,
duration: asset.duration || '0:00:00.00000',
exifInfo,
livePhotoVideoId: asset.livePhotoVideoId,
tags: [],
people: [],
unassignedFaces: [],
stack: asset.stack,
isOffline: false,
hasMetadata: true,
duplicateId: null,
resized: true,
checksum: asset.checksum,
};
}
/**
* Get a single asset by ID from timeline data
* This matches the response from GET /api/assets/:id
*/
export function getAsset(
timelineData: MockTimelineData,
assetId: string,
owner?: UserResponseDto,
): AssetResponseDto | undefined {
// Search through all buckets for the asset
const buckets = [...timelineData.buckets.values()];
for (const assets of buckets) {
const asset = assets.find((a) => a.id === assetId);
if (asset) {
return toAssetResponseDto(asset, owner);
}
}
return undefined;
}
/**
* Get a mock album from timeline data
* This matches the response from GET /api/albums/:id
*/
export function getAlbum(
timelineData: MockTimelineData,
ownerId: string,
albumId: string | undefined,
changes: Changes,
): AlbumResponseDto | undefined {
if (!timelineData.album) {
return undefined;
}
// If albumId is provided and doesn't match, return undefined
if (albumId && albumId !== timelineData.album.id) {
return undefined;
}
const album = timelineData.album;
const albumOwner = createDefaultOwner(ownerId);
// Get the actual asset objects from the timeline data
const albumAssets: AssetResponseDto[] = [];
const allAssets = [...timelineData.buckets.values()].flat();
for (const assetId of album.assetIds) {
const assetConfig = allAssets.find((a) => a.id === assetId);
if (assetConfig) {
albumAssets.push(toAssetResponseDto(assetConfig, albumOwner));
}
}
for (const assetId of changes.albumAdditions ?? []) {
const assetConfig = allAssets.find((a) => a.id === assetId);
if (assetConfig) {
albumAssets.push(toAssetResponseDto(assetConfig, albumOwner));
}
}
albumAssets.sort((a, b) => DateTime.fromISO(b.localDateTime).diff(DateTime.fromISO(a.localDateTime)).milliseconds);
// For a basic mock album, we don't include any albumUsers (shared users)
// The owner is represented by the owner field, not in albumUsers
const response: AlbumResponseDto = {
id: album.id,
albumName: album.albumName,
description: album.description,
albumThumbnailAssetId: album.thumbnailAssetId,
createdAt: album.createdAt,
updatedAt: album.updatedAt,
ownerId: albumOwner.id,
owner: albumOwner,
albumUsers: [], // Empty array for non-shared album
shared: false,
hasSharedLink: false,
isActivityEnabled: true,
assetCount: albumAssets.length,
assets: albumAssets,
startDate: albumAssets.length > 0 ? albumAssets.at(-1)?.fileCreatedAt : undefined,
endDate: albumAssets.length > 0 ? albumAssets[0].fileCreatedAt : undefined,
lastModifiedAssetTimestamp: albumAssets.length > 0 ? albumAssets[0].fileCreatedAt : undefined,
};
return response;
}

View File

@@ -0,0 +1,200 @@
import type { AssetVisibility } from '@immich/sdk';
import { DayPattern, MonthDistribution } from 'src/generators/timeline/distribution-patterns';
// Constants for generation parameters
export const GENERATION_CONSTANTS = {
VIDEO_PROBABILITY: 0.15, // 15% of assets are videos
GPS_PERCENTAGE: 0.7, // 70% of assets have GPS data
FAVORITE_PROBABILITY: 0.1, // 10% of assets are favorited
MIN_VIDEO_DURATION_SECONDS: 5,
MAX_VIDEO_DURATION_SECONDS: 300,
DEFAULT_SEED: 12_345,
DEFAULT_OWNER_ID: 'user-1',
MAX_SELECT_ATTEMPTS: 10,
SPARSE_DAY_COVERAGE: 0.4, // 40% of days have photos in sparse pattern
} as const;
// Aspect ratio distribution weights (must sum to 1)
export const ASPECT_RATIO_WEIGHTS = {
'4:3': 0.35, // 35% 4:3 landscape
'3:2': 0.25, // 25% 3:2 landscape
'16:9': 0.2, // 20% 16:9 landscape
'2:3': 0.1, // 10% 2:3 portrait
'1:1': 0.09, // 9% 1:1 square
'3:1': 0.01, // 1% 3:1 panorama
} as const;
export type AspectRatio = {
width: number;
height: number;
ratio: number;
name: string;
};
// Mock configuration for asset generation - will be transformed to API response formats
export type MockTimelineAsset = {
id: string;
ownerId: string;
ratio: number;
thumbhash: string | null;
localDateTime: string;
fileCreatedAt: string;
isFavorite: boolean;
isTrashed: boolean;
isVideo: boolean;
isImage: boolean;
duration: string | null;
projectionType: string | null;
livePhotoVideoId: string | null;
city: string | null;
country: string | null;
people: string[] | null;
latitude: number | null;
longitude: number | null;
visibility: AssetVisibility;
stack: null;
checksum: string;
fileSizeInByte: number;
};
export type MonthSpec = {
year: number;
month: number; // 1-12
distribution: MonthDistribution;
pattern: DayPattern;
};
/**
* Configuration for timeline data generation
*/
export type TimelineConfig = {
ownerId?: string;
months: MonthSpec[];
seed?: number;
writeToFile?: boolean;
outputPath?: string;
};
export type MockAlbum = {
id: string;
albumName: string;
description: string;
assetIds: string[]; // IDs of assets in the album
thumbnailAssetId: string | null;
createdAt: string;
updatedAt: string;
};
export type MockTimelineData = {
buckets: Map<string, MockTimelineAsset[]>;
album: MockAlbum; // Mock album created from random assets
};
export type SerializedTimelineData = {
buckets: Record<string, MockTimelineAsset[]>;
album: MockAlbum;
};
/**
* Validates a TimelineConfig object to ensure all values are within expected ranges
*/
export function validateTimelineConfig(config: TimelineConfig): void {
if (!config.months || config.months.length === 0) {
throw new Error('TimelineConfig must contain at least one month');
}
const seenMonths = new Set<string>();
for (const month of config.months) {
if (month.month < 1 || month.month > 12) {
throw new Error(`Invalid month: ${month.month}. Must be between 1 and 12`);
}
if (month.year < 1900 || month.year > 2100) {
throw new Error(`Invalid year: ${month.year}. Must be between 1900 and 2100`);
}
const monthKey = `${month.year}-${month.month}`;
if (seenMonths.has(monthKey)) {
throw new Error(`Duplicate month found: ${monthKey}`);
}
seenMonths.add(monthKey);
// Validate distribution if provided
if (month.distribution && !['empty', 'sparse', 'medium', 'dense', 'very-dense'].includes(month.distribution)) {
throw new Error(
`Invalid distribution: ${month.distribution}. Must be one of: empty, sparse, medium, dense, very-dense`,
);
}
const validPatterns = [
'single-day',
'consecutive-large',
'consecutive-small',
'alternating',
'sparse-scattered',
'start-heavy',
'end-heavy',
'mid-heavy',
];
if (month.pattern && !validPatterns.includes(month.pattern)) {
throw new Error(`Invalid pattern: ${month.pattern}. Must be one of: ${validPatterns.join(', ')}`);
}
}
// Validate seed if provided
if (config.seed !== undefined && (config.seed < 0 || !Number.isInteger(config.seed))) {
throw new Error('Seed must be a non-negative integer');
}
// Validate ownerId if provided
if (config.ownerId !== undefined && config.ownerId.trim() === '') {
throw new Error('Owner ID cannot be an empty string');
}
}
/**
* Create a default timeline configuration
*/
export function createDefaultTimelineConfig(): TimelineConfig {
const months: MonthSpec[] = [
// 2024 - Mix of patterns
{ year: 2024, month: 12, distribution: 'very-dense', pattern: 'alternating' },
{ year: 2024, month: 11, distribution: 'dense', pattern: 'consecutive-large' },
{ year: 2024, month: 10, distribution: 'medium', pattern: 'mid-heavy' },
{ year: 2024, month: 9, distribution: 'sparse', pattern: 'consecutive-small' },
{ year: 2024, month: 8, distribution: 'empty', pattern: 'single-day' },
{ year: 2024, month: 7, distribution: 'dense', pattern: 'start-heavy' },
{ year: 2024, month: 6, distribution: 'medium', pattern: 'sparse-scattered' },
{ year: 2024, month: 5, distribution: 'sparse', pattern: 'single-day' },
{ year: 2024, month: 4, distribution: 'very-dense', pattern: 'consecutive-large' },
{ year: 2024, month: 3, distribution: 'empty', pattern: 'single-day' },
{ year: 2024, month: 2, distribution: 'medium', pattern: 'end-heavy' },
{ year: 2024, month: 1, distribution: 'dense', pattern: 'alternating' },
// 2023 - Testing year boundaries and more patterns
{ year: 2023, month: 12, distribution: 'very-dense', pattern: 'end-heavy' },
{ year: 2023, month: 11, distribution: 'sparse', pattern: 'consecutive-small' },
{ year: 2023, month: 10, distribution: 'empty', pattern: 'single-day' },
{ year: 2023, month: 9, distribution: 'medium', pattern: 'alternating' },
{ year: 2023, month: 8, distribution: 'dense', pattern: 'mid-heavy' },
{ year: 2023, month: 7, distribution: 'sparse', pattern: 'sparse-scattered' },
{ year: 2023, month: 6, distribution: 'medium', pattern: 'consecutive-large' },
{ year: 2023, month: 5, distribution: 'empty', pattern: 'single-day' },
{ year: 2023, month: 4, distribution: 'sparse', pattern: 'single-day' },
{ year: 2023, month: 3, distribution: 'dense', pattern: 'start-heavy' },
{ year: 2023, month: 2, distribution: 'medium', pattern: 'alternating' },
{ year: 2023, month: 1, distribution: 'very-dense', pattern: 'consecutive-large' },
];
for (let year = 2022; year >= 2000; year--) {
for (let month = 12; month >= 1; month--) {
months.push({ year, month, distribution: 'medium', pattern: 'sparse-scattered' });
}
}
return {
months,
seed: 42,
};
}

View File

@@ -0,0 +1,186 @@
import { DateTime } from 'luxon';
import { GENERATION_CONSTANTS, MockTimelineAsset } from 'src/generators/timeline/timeline-config';
/**
* Linear Congruential Generator for deterministic pseudo-random numbers
*/
export class SeededRandom {
private seed: number;
constructor(seed: number) {
this.seed = seed;
}
/**
* Generate next random number in range [0, 1)
*/
next(): number {
// LCG parameters from Numerical Recipes
this.seed = (this.seed * 1_664_525 + 1_013_904_223) % 2_147_483_647;
return this.seed / 2_147_483_647;
}
/**
* Generate random integer in range [min, max)
*/
nextInt(min: number, max: number): number {
return Math.floor(this.next() * (max - min)) + min;
}
/**
* Generate random boolean with given probability
*/
nextBoolean(probability = 0.5): boolean {
return this.next() < probability;
}
}
/**
* Select random days using seed variation to avoid collisions.
*
* @param daysInMonth - Total number of days in the month
* @param numDays - Number of days to select
* @param rng - Random number generator instance
* @returns Array of selected day numbers, sorted in descending order
*/
export function selectRandomDays(daysInMonth: number, numDays: number, rng: SeededRandom): number[] {
const selectedDays = new Set<number>();
const maxAttempts = numDays * GENERATION_CONSTANTS.MAX_SELECT_ATTEMPTS; // Safety limit
let attempts = 0;
while (selectedDays.size < numDays && attempts < maxAttempts) {
const day = rng.nextInt(1, daysInMonth + 1);
selectedDays.add(day);
attempts++;
}
// Fallback: if we couldn't select enough random days, fill with sequential days
if (selectedDays.size < numDays) {
for (let day = 1; day <= daysInMonth && selectedDays.size < numDays; day++) {
selectedDays.add(day);
}
}
return [...selectedDays].sort((a, b) => b - a);
}
/**
* Select item from array using seeded random
*/
export function selectRandom<T>(arr: T[], rng: SeededRandom): T {
if (arr.length === 0) {
throw new Error('Cannot select from empty array');
}
const index = rng.nextInt(0, arr.length);
return arr[index];
}
/**
* Select multiple random items from array using seeded random without duplicates
*/
export function selectRandomMultiple<T>(arr: T[], count: number, rng: SeededRandom): T[] {
if (arr.length === 0) {
throw new Error('Cannot select from empty array');
}
if (count < 0) {
throw new Error('Count must be non-negative');
}
if (count > arr.length) {
throw new Error('Count cannot exceed array length');
}
const result: T[] = [];
const selectedIndices = new Set<number>();
while (result.length < count) {
const index = rng.nextInt(0, arr.length);
if (!selectedIndices.has(index)) {
selectedIndices.add(index);
result.push(arr[index]);
}
}
return result;
}
/**
* Parse timeBucket parameter to extract year-month key
* Handles both formats:
* - ISO timestamp: "2024-12-01T00:00:00.000Z" -> "2024-12-01"
* - Simple format: "2024-12-01" -> "2024-12-01"
*/
export function parseTimeBucketKey(timeBucket: string): string {
if (!timeBucket) {
throw new Error('timeBucket parameter cannot be empty');
}
const dt = DateTime.fromISO(timeBucket, { zone: 'utc' });
if (!dt.isValid) {
// Fallback to regex if not a valid ISO string
const match = timeBucket.match(/^(\d{4}-\d{2}-\d{2})/);
return match ? match[1] : timeBucket;
}
// Format as YYYY-MM-01 (first day of month)
return `${dt.year}-${String(dt.month).padStart(2, '0')}-01`;
}
export function getMockAsset(
asset: MockTimelineAsset,
sortedDescendingAssets: MockTimelineAsset[],
direction: 'next' | 'previous',
unit: 'day' | 'month' | 'year' = 'day',
): MockTimelineAsset | null {
const currentDateTime = DateTime.fromISO(asset.localDateTime, { zone: 'utc' });
const currentIndex = sortedDescendingAssets.findIndex((a) => a.id === asset.id);
if (currentIndex === -1) {
return null;
}
const step = direction === 'next' ? 1 : -1;
const startIndex = currentIndex + step;
if (direction === 'next' && currentIndex >= sortedDescendingAssets.length - 1) {
return null;
}
if (direction === 'previous' && currentIndex <= 0) {
return null;
}
const isInDifferentPeriod = (date1: DateTime, date2: DateTime): boolean => {
if (unit === 'day') {
return !date1.startOf('day').equals(date2.startOf('day'));
} else if (unit === 'month') {
return date1.year !== date2.year || date1.month !== date2.month;
} else {
return date1.year !== date2.year;
}
};
if (direction === 'next') {
// Search forward in array (backwards in time)
for (let i = startIndex; i < sortedDescendingAssets.length; i++) {
const nextAsset = sortedDescendingAssets[i];
const nextDate = DateTime.fromISO(nextAsset.localDateTime, { zone: 'utc' });
if (isInDifferentPeriod(nextDate, currentDateTime)) {
return nextAsset;
}
}
} else {
// Search backward in array (forwards in time)
for (let i = startIndex; i >= 0; i--) {
const prevAsset = sortedDescendingAssets[i];
const prevDate = DateTime.fromISO(prevAsset.localDateTime, { zone: 'utc' });
if (isInDifferentPeriod(prevDate, currentDateTime)) {
return prevAsset;
}
}
}
return null;
}

View File

@@ -0,0 +1,285 @@
import { BrowserContext } from '@playwright/test';
import { playwrightHost } from 'playwright.config';
export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserId: string) => {
await context.addCookies([
{
name: 'immich_is_authenticated',
value: 'true',
domain: playwrightHost,
path: '/',
},
]);
await context.route('**/api/users/me', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: {
id: adminUserId,
email: 'admin@immich.cloud',
name: 'Immich Admin',
profileImagePath: '',
avatarColor: 'orange',
profileChangedAt: '2025-01-22T21:31:23.996Z',
storageLabel: 'admin',
shouldChangePassword: true,
isAdmin: true,
createdAt: '2025-01-22T21:31:23.996Z',
deletedAt: null,
updatedAt: '2025-11-14T00:00:00.369Z',
oauthId: '',
quotaSizeInBytes: null,
quotaUsageInBytes: 20_849_000_159,
status: 'active',
license: null,
},
});
});
await context.route('**/users/me/preferences', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: {
albums: {
defaultAssetOrder: 'desc',
},
folders: {
enabled: false,
sidebarWeb: false,
},
memories: {
enabled: true,
duration: 5,
},
people: {
enabled: true,
sidebarWeb: false,
},
sharedLinks: {
enabled: true,
sidebarWeb: false,
},
ratings: {
enabled: false,
},
tags: {
enabled: false,
sidebarWeb: false,
},
emailNotifications: {
enabled: true,
albumInvite: true,
albumUpdate: true,
},
download: {
archiveSize: 4_294_967_296,
includeEmbeddedVideos: false,
},
purchase: {
showSupportBadge: true,
hideBuyButtonUntil: '2100-02-12T00:00:00.000Z',
},
cast: {
gCastEnabled: false,
},
},
});
});
await context.route('**/server/about', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: {
version: 'v2.2.3',
versionUrl: 'https://github.com/immich-app/immich/releases/tag/v2.2.3',
licensed: false,
build: '1234567890',
buildUrl: 'https://github.com/immich-app/immich/actions/runs/1234567890',
buildImage: 'e2e',
buildImageUrl: 'https://github.com/immich-app/immich/pkgs/container/immich-server',
repository: 'immich-app/immich',
repositoryUrl: 'https://github.com/immich-app/immich',
sourceRef: 'e2e',
sourceCommit: 'e2eeeeeeeeeeeeeeeeee',
sourceUrl: 'https://github.com/immich-app/immich/commit/e2eeeeeeeeeeeeeeeeee',
nodejs: 'v22.18.0',
exiftool: '13.41',
ffmpeg: '7.1.1-6',
libvips: '8.17.2',
imagemagick: '7.1.2-2',
},
});
});
await context.route('**/api/server/features', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: {
smartSearch: false,
facialRecognition: false,
duplicateDetection: false,
map: true,
reverseGeocoding: true,
importFaces: false,
sidecar: true,
search: true,
trash: true,
oauth: false,
oauthAutoLaunch: false,
ocr: false,
passwordLogin: true,
configFile: false,
email: false,
},
});
});
await context.route('**/api/server/config', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: {
loginPageMessage: '',
trashDays: 30,
userDeleteDelay: 7,
oauthButtonText: 'Login with OAuth',
isInitialized: true,
isOnboarded: true,
externalDomain: '',
publicUsers: true,
mapDarkStyleUrl: 'https://tiles.immich.cloud/v1/style/dark.json',
mapLightStyleUrl: 'https://tiles.immich.cloud/v1/style/light.json',
maintenanceMode: false,
},
});
});
await context.route('**/api/server/media-types', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: {
video: [
'.3gp',
'.3gpp',
'.avi',
'.flv',
'.insv',
'.m2t',
'.m2ts',
'.m4v',
'.mkv',
'.mov',
'.mp4',
'.mpe',
'.mpeg',
'.mpg',
'.mts',
'.vob',
'.webm',
'.wmv',
],
image: [
'.3fr',
'.ari',
'.arw',
'.cap',
'.cin',
'.cr2',
'.cr3',
'.crw',
'.dcr',
'.dng',
'.erf',
'.fff',
'.iiq',
'.k25',
'.kdc',
'.mrw',
'.nef',
'.nrw',
'.orf',
'.ori',
'.pef',
'.psd',
'.raf',
'.raw',
'.rw2',
'.rwl',
'.sr2',
'.srf',
'.srw',
'.x3f',
'.avif',
'.gif',
'.jpeg',
'.jpg',
'.png',
'.webp',
'.bmp',
'.heic',
'.heif',
'.hif',
'.insp',
'.jp2',
'.jpe',
'.jxl',
'.svg',
'.tif',
'.tiff',
],
sidecar: ['.xmp'],
},
});
});
await context.route('**/api/notifications*', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: [],
});
});
await context.route('**/api/albums*', async (route, request) => {
if (request.url().endsWith('albums?shared=true') || request.url().endsWith('albums')) {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: [],
});
}
await route.fallback();
});
await context.route('**/api/memories*', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: [],
});
});
await context.route('**/api/server/storage', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: {
diskSize: '100.0 GiB',
diskUse: '74.4 GiB',
diskAvailable: '25.6 GiB',
diskSizeRaw: 107_374_182_400,
diskUseRaw: 79_891_660_800,
diskAvailableRaw: 27_482_521_600,
diskUsagePercentage: 74.4,
},
});
});
await context.route('**/api/server/version-history', async (route) => {
return route.fulfill({
status: 200,
contentType: 'application/json',
json: [
{
id: 'd1fbeadc-cb4f-4db3-8d19-8c6a921d5d8e',
createdAt: '2025-11-15T20:14:01.935Z',
version: '2.2.3',
},
],
});
});
};

View File

@@ -0,0 +1,139 @@
import { BrowserContext, Page, Request, Route } from '@playwright/test';
import { basename } from 'node:path';
import {
Changes,
getAlbum,
getAsset,
getTimeBucket,
getTimeBuckets,
randomPreview,
randomThumbnail,
TimelineData,
} from 'src/generators/timeline';
import { sleep } from 'src/web/specs/timeline/utils';
export class TimelineTestContext {
slowBucket = false;
adminId = '';
}
export const setupTimelineMockApiRoutes = async (
context: BrowserContext,
timelineRestData: TimelineData,
changes: Changes,
testContext: TimelineTestContext,
) => {
await context.route('**/api/timeline**', async (route, request) => {
const url = new URL(request.url());
const pathname = url.pathname;
if (pathname === '/api/timeline/buckets') {
const albumId = url.searchParams.get('albumId') || undefined;
const isTrashed = url.searchParams.get('isTrashed') ? url.searchParams.get('isTrashed') === 'true' : undefined;
const isFavorite = url.searchParams.get('isFavorite') ? url.searchParams.get('isFavorite') === 'true' : undefined;
const isArchived = url.searchParams.get('visibility')
? url.searchParams.get('visibility') === 'archive'
: undefined;
return route.fulfill({
status: 200,
contentType: 'application/json',
json: getTimeBuckets(timelineRestData, isTrashed, isArchived, isFavorite, albumId, changes),
});
} else if (pathname === '/api/timeline/bucket') {
const timeBucket = url.searchParams.get('timeBucket');
if (!timeBucket) {
return route.continue();
}
const isTrashed = url.searchParams.get('isTrashed') ? url.searchParams.get('isTrashed') === 'true' : undefined;
const isArchived = url.searchParams.get('visibility')
? url.searchParams.get('visibility') === 'archive'
: undefined;
const isFavorite = url.searchParams.get('isFavorite') ? url.searchParams.get('isFavorite') === 'true' : undefined;
const albumId = url.searchParams.get('albumId') || undefined;
const assets = getTimeBucket(timelineRestData, timeBucket, isTrashed, isArchived, isFavorite, albumId, changes);
if (testContext.slowBucket) {
await sleep(5000);
}
return route.fulfill({
status: 200,
contentType: 'application/json',
json: assets,
});
}
return route.continue();
});
await context.route('**/api/assets/**', async (route, request) => {
const pattern = /\/api\/assets\/(?<assetId>[^/]+)\/thumbnail\?size=(?<size>preview|thumbnail)/;
const match = request.url().match(pattern);
if (!match) {
const url = new URL(request.url());
const pathname = url.pathname;
const assetId = basename(pathname);
const asset = getAsset(timelineRestData, assetId);
return route.fulfill({
status: 200,
contentType: 'application/json',
json: asset,
});
}
if (match.groups?.size === 'preview') {
if (!route.request().serviceWorker()) {
return route.continue();
}
const asset = getAsset(timelineRestData, match.groups?.assetId);
return route.fulfill({
status: 200,
headers: { 'content-type': 'image/jpeg', ETag: 'abc123', 'Cache-Control': 'public, max-age=3600' },
body: await randomPreview(
match.groups?.assetId,
(asset?.exifInfo?.exifImageWidth ?? 0) / (asset?.exifInfo?.exifImageHeight ?? 1),
),
});
}
if (match.groups?.size === 'thumbnail') {
if (!route.request().serviceWorker()) {
return route.continue();
}
const asset = getAsset(timelineRestData, match.groups?.assetId);
return route.fulfill({
status: 200,
headers: { 'content-type': 'image/jpeg' },
body: await randomThumbnail(
match.groups?.assetId,
(asset?.exifInfo?.exifImageWidth ?? 0) / (asset?.exifInfo?.exifImageHeight ?? 1),
),
});
}
return route.continue();
});
await context.route('**/api/albums/**', async (route, request) => {
const pattern = /\/api\/albums\/(?<albumId>[^/?]+)/;
const match = request.url().match(pattern);
if (!match) {
return route.continue();
}
const album = getAlbum(timelineRestData, testContext.adminId, match.groups?.albumId, changes);
return route.fulfill({
status: 200,
contentType: 'application/json',
json: album,
});
});
};
export const pageRoutePromise = async (
page: Page,
route: string,
callback: (route: Route, request: Request) => Promise<void>,
) => {
let resolveRequest: ((value: unknown | PromiseLike<unknown>) => void) | undefined;
const deleteRequest = new Promise((resolve) => {
resolveRequest = resolve;
});
await page.route(route, async (route, request) => {
await callback(route, request);
const requestJson = request.postDataJSON();
resolveRequest?.(requestJson);
});
return deleteRequest;
};

View File

@@ -7,6 +7,12 @@ export const errorDto = {
message: 'Authentication required',
correlationId: expect.any(String),
},
unauthorizedWithMessage: (message: string) => ({
error: 'Unauthorized',
statusCode: 401,
message,
correlationId: expect.any(String),
}),
forbidden: {
error: 'Forbidden',
statusCode: 403,

View File

@@ -1,5 +1,4 @@
import {
AllJobStatusResponseDto,
AssetMediaCreateDto,
AssetMediaResponseDto,
AssetResponseDto,
@@ -7,11 +6,13 @@ import {
CheckExistingAssetsDto,
CreateAlbumDto,
CreateLibraryDto,
JobCommandDto,
JobName,
MaintenanceAction,
MetadataSearchDto,
Permission,
PersonCreateDto,
QueueCommandDto,
QueueName,
QueuesResponseDto,
SharedLinkCreateDto,
UpdateLibraryDto,
UserAdminCreateDto,
@@ -27,15 +28,16 @@ import {
createStack,
createUserAdmin,
deleteAssets,
getAllJobsStatus,
getAssetInfo,
getConfig,
getConfigDefaults,
getQueuesLegacy,
login,
runQueueCommandLegacy,
scanLibrary,
searchAssets,
sendJobCommand,
setBaseUrl,
setMaintenanceMode,
signUpAdmin,
tagAssets,
updateAdminOnboarding,
@@ -52,7 +54,7 @@ import { exec, spawn } from 'node:child_process';
import { createHash } from 'node:crypto';
import { existsSync, mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path, { dirname } from 'node:path';
import { dirname, resolve } from 'node:path';
import { setTimeout as setAsyncTimeout } from 'node:timers/promises';
import { promisify } from 'node:util';
import pg from 'pg';
@@ -60,6 +62,8 @@ import { io, type Socket } from 'socket.io-client';
import { loginDto, signupDto } from 'src/fixtures';
import { makeRandomImage } from 'src/generators';
import request from 'supertest';
import { playwrightDbHost, playwrightHost, playwriteBaseUrl } from '../playwright.config';
export type { Emitter } from '@socket.io/component-emitter';
type CommandResponse = { stdout: string; stderr: string; exitCode: number | null };
@@ -68,12 +72,12 @@ type WaitOptions = { event: EventType; id?: string; total?: number; timeout?: nu
type AdminSetupOptions = { onboarding?: boolean };
type FileData = { bytes?: Buffer; filename: string };
const dbUrl = 'postgres://postgres:postgres@127.0.0.1:5435/immich';
export const baseUrl = 'http://127.0.0.1:2285';
const dbUrl = `postgres://postgres:postgres@${playwrightDbHost}:5435/immich`;
export const baseUrl = playwriteBaseUrl;
export const shareUrl = `${baseUrl}/share`;
export const app = `${baseUrl}/api`;
// TODO move test assets into e2e/assets
export const testAssetDir = path.resolve('./test-assets');
export const testAssetDir = resolve(import.meta.dirname, '../test-assets');
export const testAssetDirInternal = '/test-assets';
export const tempDir = tmpdir();
export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` });
@@ -477,10 +481,10 @@ export const utils = {
tagAssets: (accessToken: string, tagId: string, assetIds: string[]) =>
tagAssets({ id: tagId, bulkIdsDto: { ids: assetIds } }, { headers: asBearerAuth(accessToken) }),
jobCommand: async (accessToken: string, jobName: JobName, jobCommandDto: JobCommandDto) =>
sendJobCommand({ id: jobName, jobCommandDto }, { headers: asBearerAuth(accessToken) }),
queueCommand: async (accessToken: string, name: QueueName, queueCommandDto: QueueCommandDto) =>
runQueueCommandLegacy({ name, queueCommandDto }, { headers: asBearerAuth(accessToken) }),
setAuthCookies: async (context: BrowserContext, accessToken: string, domain = '127.0.0.1') =>
setAuthCookies: async (context: BrowserContext, accessToken: string, domain = playwrightHost) =>
await context.addCookies([
{
name: 'immich_access_token',
@@ -514,6 +518,42 @@ export const utils = {
},
]),
setMaintenanceAuthCookie: async (context: BrowserContext, token: string, domain = '127.0.0.1') =>
await context.addCookies([
{
name: 'immich_maintenance_token',
value: token,
domain,
path: '/',
expires: 2_058_028_213,
httpOnly: true,
secure: false,
sameSite: 'Lax',
},
]),
enterMaintenance: async (accessToken: string) => {
let setCookie: string[] | undefined;
await setMaintenanceMode(
{
setMaintenanceModeDto: {
action: MaintenanceAction.Start,
},
},
{
headers: asBearerAuth(accessToken),
fetch: (...args: Parameters<typeof fetch>) =>
fetch(...args).then((response) => {
setCookie = response.headers.getSetCookie();
return response;
}),
},
);
return setCookie;
},
resetTempFolder: () => {
rmSync(`${testAssetDir}/temp`, { recursive: true, force: true });
mkdirSync(`${testAssetDir}/temp`, { recursive: true });
@@ -524,13 +564,13 @@ export const utils = {
await updateConfig({ systemConfigDto: defaultConfig }, { headers: asBearerAuth(accessToken) });
},
isQueueEmpty: async (accessToken: string, queue: keyof AllJobStatusResponseDto) => {
const queues = await getAllJobsStatus({ headers: asBearerAuth(accessToken) });
isQueueEmpty: async (accessToken: string, queue: keyof QueuesResponseDto) => {
const queues = await getQueuesLegacy({ headers: asBearerAuth(accessToken) });
const jobCounts = queues[queue].jobCounts;
return !jobCounts.active && !jobCounts.waiting;
},
waitForQueueFinish: (accessToken: string, queue: keyof AllJobStatusResponseDto, ms?: number) => {
waitForQueueFinish: (accessToken: string, queue: keyof QueuesResponseDto, ms?: number) => {
// eslint-disable-next-line no-async-promise-executor
return new Promise<void>(async (resolve, reject) => {
const timeout = setTimeout(() => reject(new Error('Timed out waiting for queue to empty')), ms || 10_000);

View File

@@ -0,0 +1,51 @@
import { LoginResponseDto } from '@immich/sdk';
import { expect, test } from '@playwright/test';
import { utils } from 'src/utils';
test.describe.configure({ mode: 'serial' });
test.describe('Maintenance', () => {
let admin: LoginResponseDto;
test.beforeAll(async () => {
utils.initSdk();
await utils.resetDatabase();
admin = await utils.adminSetup();
});
test('enter and exit maintenance mode', async ({ context, page }) => {
await utils.setAuthCookies(context, admin.accessToken);
await page.goto('/admin/system-settings?isOpen=maintenance');
await page.getByRole('button', { name: 'Start maintenance mode' }).click();
await expect(page.getByText('Temporarily Unavailable')).toBeVisible({ timeout: 10_000 });
await page.getByRole('button', { name: 'End maintenance mode' }).click();
await page.waitForURL('**/admin/system-settings*', { timeout: 10_000 });
});
test('maintenance shows no options to users until they authenticate', async ({ page }) => {
const setCookie = await utils.enterMaintenance(admin.accessToken);
const cookie = setCookie
?.map((cookie) => cookie.split(';')[0].split('='))
?.find(([name]) => name === 'immich_maintenance_token');
expect(cookie).toBeTruthy();
await expect(async () => {
await page.goto('/');
await page.waitForURL('**/maintenance?**', {
timeout: 1000,
});
}).toPass({ timeout: 10_000 });
await expect(page.getByText('Temporarily Unavailable')).toBeVisible();
await expect(page.getByRole('button', { name: 'End maintenance mode' })).toHaveCount(0);
await page.goto(`/maintenance?${new URLSearchParams({ token: cookie![1] })}`);
await expect(page.getByText('Temporarily Unavailable')).toBeVisible();
await expect(page.getByRole('button', { name: 'End maintenance mode' })).toBeVisible();
await page.getByRole('button', { name: 'End maintenance mode' }).click();
await page.waitForURL('**/auth/login');
});
});

View File

@@ -0,0 +1,775 @@
import { faker } from '@faker-js/faker';
import { expect, test } from '@playwright/test';
import { DateTime } from 'luxon';
import {
Changes,
createDefaultTimelineConfig,
generateTimelineData,
getAsset,
getMockAsset,
SeededRandom,
selectRandom,
selectRandomMultiple,
TimelineAssetConfig,
TimelineData,
} from 'src/generators/timeline';
import { setupBaseMockApiRoutes } from 'src/mock-network/base-network';
import { pageRoutePromise, setupTimelineMockApiRoutes, TimelineTestContext } from 'src/mock-network/timeline-network';
import { utils } from 'src/utils';
import {
assetViewerUtils,
cancelAllPollers,
padYearMonth,
pageUtils,
poll,
thumbnailUtils,
timelineUtils,
} from 'src/web/specs/timeline/utils';
test.describe.configure({ mode: 'parallel' });
test.describe('Timeline', () => {
let adminUserId: string;
let timelineRestData: TimelineData;
const assets: TimelineAssetConfig[] = [];
const yearMonths: string[] = [];
const testContext = new TimelineTestContext();
const changes: Changes = {
albumAdditions: [],
assetDeletions: [],
assetArchivals: [],
assetFavorites: [],
};
test.beforeAll(async () => {
test.fail(
process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS !== '1',
'This test requires env var: PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1',
);
utils.initSdk();
adminUserId = faker.string.uuid();
testContext.adminId = adminUserId;
timelineRestData = generateTimelineData({ ...createDefaultTimelineConfig(), ownerId: adminUserId });
for (const timeBucket of timelineRestData.buckets.values()) {
assets.push(...timeBucket);
}
for (const yearMonth of timelineRestData.buckets.keys()) {
const [year, month] = yearMonth.split('-');
yearMonths.push(`${year}-${Number(month)}`);
}
});
test.beforeEach(async ({ context }) => {
await setupBaseMockApiRoutes(context, adminUserId);
await setupTimelineMockApiRoutes(context, timelineRestData, changes, testContext);
});
test.afterEach(() => {
cancelAllPollers();
testContext.slowBucket = false;
changes.albumAdditions = [];
changes.assetDeletions = [];
changes.assetArchivals = [];
changes.assetFavorites = [];
});
test.describe('/photos', () => {
test('Open /photos', async ({ page }) => {
await page.goto(`/photos`);
await page.waitForSelector('#asset-grid');
await thumbnailUtils.expectTimelineHasOnScreenAssets(page);
});
test('Deep link to last photo', async ({ page }) => {
const lastAsset = assets.at(-1)!;
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
await thumbnailUtils.expectTimelineHasOnScreenAssets(page);
await thumbnailUtils.expectInViewport(page, lastAsset.id);
});
const rng = new SeededRandom(529);
for (let i = 0; i < 10; i++) {
test('Deep link to random asset ' + i, async ({ page }) => {
const asset = selectRandom(assets, rng);
await pageUtils.deepLinkPhotosPage(page, asset.id);
await thumbnailUtils.expectTimelineHasOnScreenAssets(page);
await thumbnailUtils.expectInViewport(page, asset.id);
});
}
test('Open /photos, open asset-viewer, browser back', async ({ page }) => {
const rng = new SeededRandom(22);
const asset = selectRandom(assets, rng);
await pageUtils.deepLinkPhotosPage(page, asset.id);
const scrollTopBefore = await timelineUtils.getScrollTop(page);
await thumbnailUtils.clickAssetId(page, asset.id);
await assetViewerUtils.waitForViewerLoad(page, asset);
await page.goBack();
await timelineUtils.locator(page).waitFor();
const scrollTopAfter = await timelineUtils.getScrollTop(page);
expect(scrollTopAfter).toBe(scrollTopBefore);
});
test('Open /photos, open asset-viewer, next photo, browser back, back', async ({ page }) => {
const rng = new SeededRandom(49);
const asset = selectRandom(assets, rng);
const assetIndex = assets.indexOf(asset);
const nextAsset = assets[assetIndex + 1];
await pageUtils.deepLinkPhotosPage(page, asset.id);
const scrollTopBefore = await timelineUtils.getScrollTop(page);
await thumbnailUtils.clickAssetId(page, asset.id);
await assetViewerUtils.waitForViewerLoad(page, asset);
await expect.poll(() => new URL(page.url()).pathname).toBe(`/photos/${asset.id}`);
await page.getByLabel('View next asset').click();
await assetViewerUtils.waitForViewerLoad(page, nextAsset);
await expect.poll(() => new URL(page.url()).pathname).toBe(`/photos/${nextAsset.id}`);
await page.goBack();
await assetViewerUtils.waitForViewerLoad(page, asset);
await page.goBack();
await page.waitForURL('**/photos?at=*');
const scrollTopAfter = await timelineUtils.getScrollTop(page);
expect(Math.abs(scrollTopAfter - scrollTopBefore)).toBeLessThan(5);
});
test('Open /photos, open asset-viewer, next photo 15x, backwardsArrow', async ({ page }) => {
await pageUtils.deepLinkPhotosPage(page, assets[0].id);
await thumbnailUtils.clickAssetId(page, assets[0].id);
await assetViewerUtils.waitForViewerLoad(page, assets[0]);
for (let i = 1; i <= 15; i++) {
await page.getByLabel('View next asset').click();
await assetViewerUtils.waitForViewerLoad(page, assets[i]);
}
await page.getByLabel('Go back').click();
await page.waitForURL('**/photos?at=*');
await thumbnailUtils.expectInViewport(page, assets[15].id);
await thumbnailUtils.expectBottomIsTimelineBottom(page, assets[15]!.id);
});
test('Open /photos, open asset-viewer, previous photo 15x, backwardsArrow', async ({ page }) => {
const lastAsset = assets.at(-1)!;
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
await thumbnailUtils.clickAssetId(page, lastAsset.id);
await assetViewerUtils.waitForViewerLoad(page, lastAsset);
for (let i = 1; i <= 15; i++) {
await page.getByLabel('View previous asset').click();
await assetViewerUtils.waitForViewerLoad(page, assets.at(-1 - i)!);
}
await page.getByLabel('Go back').click();
await page.waitForURL('**/photos?at=*');
await thumbnailUtils.expectInViewport(page, assets.at(-1 - 15)!.id);
await thumbnailUtils.expectTopIsTimelineTop(page, assets.at(-1 - 15)!.id);
});
});
test.describe('keyboard', () => {
/**
* This text tests keyboard nativation, and also ensures that the scroll-to-asset behavior
* scrolls the minimum amount. That is, if you are navigating using right arrow (auto scrolling
* as necessary downwards), then the asset should always be at the lowest row of the grid.
*/
test('Next/previous asset - ArrowRight/ArrowLeft', async ({ page }) => {
await pageUtils.openPhotosPage(page);
await thumbnailUtils.withAssetId(page, assets[0].id).focus();
const rightKey = 'ArrowRight';
const leftKey = 'ArrowLeft';
for (let i = 1; i < 15; i++) {
await page.keyboard.press(rightKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
}
for (let i = 15; i <= 20; i++) {
await page.keyboard.press(rightKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
expect(await thumbnailUtils.expectBottomIsTimelineBottom(page, assets.at(i)!.id));
}
// now test previous asset
for (let i = 19; i >= 15; i--) {
await page.keyboard.press(leftKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
}
for (let i = 14; i > 0; i--) {
await page.keyboard.press(leftKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
expect(await thumbnailUtils.expectTopIsTimelineTop(page, assets.at(i)!.id));
}
});
test('Next/previous asset - Tab/Shift+Tab', async ({ page }) => {
await pageUtils.openPhotosPage(page);
await thumbnailUtils.withAssetId(page, assets[0].id).focus();
const rightKey = 'Tab';
const leftKey = 'Shift+Tab';
for (let i = 1; i < 15; i++) {
await page.keyboard.press(rightKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
}
for (let i = 15; i <= 20; i++) {
await page.keyboard.press(rightKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
}
// now test previous asset
for (let i = 19; i >= 15; i--) {
await page.keyboard.press(leftKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
}
for (let i = 14; i > 0; i--) {
await page.keyboard.press(leftKey);
await assetViewerUtils.expectActiveAssetToBe(page, assets[i].id);
}
});
test('Next/previous day - d, Shift+D', async ({ page }) => {
await pageUtils.openPhotosPage(page);
let asset = assets[0];
await timelineUtils.locator(page).hover();
await page.keyboard.press('d');
await assetViewerUtils.expectActiveAssetToBe(page, asset.id);
for (let i = 0; i < 15; i++) {
await page.keyboard.press('d');
const next = getMockAsset(asset, assets, 'next', 'day')!;
await assetViewerUtils.expectActiveAssetToBe(page, next.id);
asset = next;
}
for (let i = 0; i < 15; i++) {
await page.keyboard.press('Shift+D');
const previous = getMockAsset(asset, assets, 'previous', 'day')!;
await assetViewerUtils.expectActiveAssetToBe(page, previous.id);
asset = previous;
}
});
test('Next/previous month - m, Shift+M', async ({ page }) => {
await pageUtils.openPhotosPage(page);
let asset = assets[0];
await timelineUtils.locator(page).hover();
await page.keyboard.press('m');
await assetViewerUtils.expectActiveAssetToBe(page, asset.id);
for (let i = 0; i < 15; i++) {
await page.keyboard.press('m');
const next = getMockAsset(asset, assets, 'next', 'month')!;
await assetViewerUtils.expectActiveAssetToBe(page, next.id);
asset = next;
}
for (let i = 0; i < 15; i++) {
await page.keyboard.press('Shift+M');
const previous = getMockAsset(asset, assets, 'previous', 'month')!;
await assetViewerUtils.expectActiveAssetToBe(page, previous.id);
asset = previous;
}
});
test('Next/previous year - y, Shift+Y', async ({ page }) => {
await pageUtils.openPhotosPage(page);
let asset = assets[0];
await timelineUtils.locator(page).hover();
await page.keyboard.press('y');
await assetViewerUtils.expectActiveAssetToBe(page, asset.id);
for (let i = 0; i < 15; i++) {
await page.keyboard.press('y');
const next = getMockAsset(asset, assets, 'next', 'year')!;
await assetViewerUtils.expectActiveAssetToBe(page, next.id);
asset = next;
}
for (let i = 0; i < 15; i++) {
await page.keyboard.press('Shift+Y');
const previous = getMockAsset(asset, assets, 'previous', 'year')!;
await assetViewerUtils.expectActiveAssetToBe(page, previous.id);
asset = previous;
}
});
test('Navigate to time - g', async ({ page }) => {
const rng = new SeededRandom(4782);
await pageUtils.openPhotosPage(page);
for (let i = 0; i < 10; i++) {
const asset = selectRandom(assets, rng);
await pageUtils.goToAsset(page, asset.fileCreatedAt);
await thumbnailUtils.expectInViewport(page, asset.id);
}
});
});
test.describe('selection', () => {
test('Select day, unselect day', async ({ page }) => {
await pageUtils.openPhotosPage(page);
await pageUtils.selectDay(page, 'Wed, Dec 11, 2024');
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(4);
await pageUtils.selectDay(page, 'Wed, Dec 11, 2024');
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(0);
});
test('Select asset, click asset to select', async ({ page }) => {
await pageUtils.openPhotosPage(page);
await thumbnailUtils.withAssetId(page, assets[1].id).hover();
await thumbnailUtils.selectButton(page, assets[1].id).click();
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(1);
// no need to hover, once selection is active
await thumbnailUtils.clickAssetId(page, assets[2].id);
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(2);
});
test('Select asset, click unselect asset', async ({ page }) => {
await pageUtils.openPhotosPage(page);
await thumbnailUtils.withAssetId(page, assets[1].id).hover();
await thumbnailUtils.selectButton(page, assets[1].id).click();
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(1);
await thumbnailUtils.clickAssetId(page, assets[1].id);
// the hover uses a checked button too, so just move mouse away
await page.mouse.move(0, 0);
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(0);
});
test('Select asset, shift-hover candidates, shift-click end', async ({ page }) => {
await pageUtils.openPhotosPage(page);
const asset = assets[0];
await thumbnailUtils.withAssetId(page, asset.id).hover();
await thumbnailUtils.selectButton(page, asset.id).click();
await page.keyboard.down('Shift');
await thumbnailUtils.withAssetId(page, assets[2].id).hover();
await expect(
thumbnailUtils.locator(page).locator('.absolute.top-0.h-full.w-full.bg-immich-primary.opacity-40'),
).toHaveCount(3);
await thumbnailUtils.selectButton(page, assets[2].id).click();
await page.keyboard.up('Shift');
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(3);
});
test('Add multiple to selection - Select day, shift-click end', async ({ page }) => {
await pageUtils.openPhotosPage(page);
await thumbnailUtils.withAssetId(page, assets[0].id).hover();
await thumbnailUtils.selectButton(page, assets[0].id).click();
await thumbnailUtils.clickAssetId(page, assets[2].id);
await page.keyboard.down('Shift');
await thumbnailUtils.clickAssetId(page, assets[4].id);
await page.mouse.move(0, 0);
await expect(thumbnailUtils.selectedAsset(page)).toHaveCount(4);
});
});
test.describe('scroll', () => {
test('Open /photos, random click scrubber 20x', async ({ page }) => {
test.slow();
await pageUtils.openPhotosPage(page);
const rng = new SeededRandom(6637);
const selectedMonths = selectRandomMultiple(yearMonths, 20, rng);
for (const month of selectedMonths) {
await page.locator(`[data-segment-year-month="${month}"]`).click({ force: true });
const visibleMockAssetsYearMonths = await poll(page, async () => {
const assetIds = await thumbnailUtils.getAllInViewport(
page,
(assetId: string) => getYearMonth(assets, assetId) === month,
);
const visibleMockAssetsYearMonths: string[] = [];
for (const assetId of assetIds!) {
const yearMonth = getYearMonth(assets, assetId);
visibleMockAssetsYearMonths.push(yearMonth);
if (yearMonth === month) {
return [yearMonth];
}
}
});
if (page.isClosed()) {
return;
}
expect(visibleMockAssetsYearMonths).toContain(month);
}
});
test('Deep link to last photo, scroll up', async ({ page }) => {
const lastAsset = assets.at(-1)!;
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
await timelineUtils.locator(page).hover();
for (let i = 0; i < 100; i++) {
await page.mouse.wheel(0, -100);
await page.waitForTimeout(25);
}
await thumbnailUtils.expectInViewport(page, '14e5901f-fd7f-40c0-b186-4d7e7fc67968');
});
test('Deep link to first bucket, scroll down', async ({ page }) => {
const lastAsset = assets.at(0)!;
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
await timelineUtils.locator(page).hover();
for (let i = 0; i < 100; i++) {
await page.mouse.wheel(0, 100);
await page.waitForTimeout(25);
}
await thumbnailUtils.expectInViewport(page, 'b7983a13-4b4e-4950-a731-f2962d9a1555');
});
test('Deep link to last photo, drag scrubber to scroll up', async ({ page }) => {
const lastAsset = assets.at(-1)!;
await pageUtils.deepLinkPhotosPage(page, lastAsset.id);
const lastMonth = yearMonths.at(-1);
const firstScrubSegment = page.locator(`[data-segment-year-month="${yearMonths[0]}"]`);
const lastScrubSegment = page.locator(`[data-segment-year-month="${lastMonth}"]`);
const sourcebox = (await lastScrubSegment.boundingBox())!;
const targetBox = (await firstScrubSegment.boundingBox())!;
await firstScrubSegment.hover();
const currentY = sourcebox.y;
await page.mouse.move(sourcebox.x + sourcebox?.width / 2, currentY);
await page.mouse.down();
await page.mouse.move(sourcebox.x + sourcebox?.width / 2, targetBox.y, { steps: 100 });
await page.mouse.up();
await thumbnailUtils.expectInViewport(page, assets[0].id);
});
test('Deep link to first bucket, drag scrubber to scroll down', async ({ page }) => {
await pageUtils.deepLinkPhotosPage(page, assets[0].id);
const firstScrubSegment = page.locator(`[data-segment-year-month="${yearMonths[0]}"]`);
const sourcebox = (await firstScrubSegment.boundingBox())!;
await firstScrubSegment.hover();
const currentY = sourcebox.y;
await page.mouse.move(sourcebox.x + sourcebox?.width / 2, currentY);
await page.mouse.down();
const height = page.viewportSize()?.height;
expect(height).toBeDefined();
await page.mouse.move(sourcebox.x + sourcebox?.width / 2, height! - 10, {
steps: 100,
});
await page.mouse.up();
await thumbnailUtils.expectInViewport(page, assets.at(-1)!.id);
});
test('Buckets cancel on scroll', async ({ page }) => {
await pageUtils.openPhotosPage(page);
testContext.slowBucket = true;
const failedUris: string[] = [];
page.on('requestfailed', (request) => {
failedUris.push(request.url());
});
const offscreenSegment = page.locator(`[data-segment-year-month="${yearMonths[12]}"]`);
await offscreenSegment.click({ force: true });
const lastSegment = page.locator(`[data-segment-year-month="${yearMonths.at(-1)!}"]`);
await lastSegment.click({ force: true });
const uris = await poll(page, async () => (failedUris.length > 0 ? failedUris : null));
expect(uris).toEqual(expect.arrayContaining([expect.stringContaining(padYearMonth(yearMonths[12]!))]));
});
});
test.describe('/albums', () => {
test('Open album', async ({ page }) => {
const album = timelineRestData.album;
await pageUtils.openAlbumPage(page, album.id);
await thumbnailUtils.expectInViewport(page, album.assetIds[0]);
});
test('Deep link to last photo', async ({ page }) => {
const album = timelineRestData.album;
const lastAsset = album.assetIds.at(-1);
await pageUtils.deepLinkAlbumPage(page, album.id, lastAsset!);
await thumbnailUtils.expectInViewport(page, album.assetIds.at(-1)!);
await thumbnailUtils.expectBottomIsTimelineBottom(page, album.assetIds.at(-1)!);
});
test('Add photos to album pre-selects existing', async ({ page }) => {
const album = timelineRestData.album;
await pageUtils.openAlbumPage(page, album.id);
await page.getByLabel('Add photos').click();
const asset = getAsset(timelineRestData, album.assetIds[0])!;
await pageUtils.goToAsset(page, asset.fileCreatedAt);
await thumbnailUtils.expectInViewport(page, asset.id);
await thumbnailUtils.expectSelectedReadonly(page, asset.id);
});
test('Add photos to album', async ({ page }) => {
const album = timelineRestData.album;
await pageUtils.openAlbumPage(page, album.id);
await page.locator('nav button[aria-label="Add photos"]').click();
const asset = getAsset(timelineRestData, album.assetIds[0])!;
await pageUtils.goToAsset(page, asset.fileCreatedAt);
await thumbnailUtils.expectInViewport(page, asset.id);
await thumbnailUtils.expectSelectedReadonly(page, asset.id);
await pageUtils.selectDay(page, 'Tue, Feb 27, 2024');
const put = pageRoutePromise(page, `**/api/albums/${album.id}/assets`, async (route, request) => {
const requestJson = request.postDataJSON();
await route.fulfill({
status: 200,
contentType: 'application/json',
json: requestJson.ids.map((id: string) => ({ id, success: true })),
});
changes.albumAdditions.push(...requestJson.ids);
});
await page.getByText('Done').click();
await expect(put).resolves.toEqual({
ids: [
'c077ea7b-cfa1-45e4-8554-f86c00ee5658',
'040fd762-dbbc-486d-a51a-2d84115e6229',
'86af0b5f-79d3-4f75-bab3-3b61f6c72b23',
],
});
const addedAsset = getAsset(timelineRestData, 'c077ea7b-cfa1-45e4-8554-f86c00ee5658')!;
await pageUtils.goToAsset(page, addedAsset.fileCreatedAt);
await thumbnailUtils.expectInViewport(page, 'c077ea7b-cfa1-45e4-8554-f86c00ee5658');
await thumbnailUtils.expectInViewport(page, '040fd762-dbbc-486d-a51a-2d84115e6229');
await thumbnailUtils.expectInViewport(page, '86af0b5f-79d3-4f75-bab3-3b61f6c72b23');
});
});
test.describe('/trash', () => {
test('open /photos, trash photo, open /trash, restore', async ({ page }) => {
await pageUtils.openPhotosPage(page);
const assetToTrash = assets[0];
await thumbnailUtils.withAssetId(page, assetToTrash.id).hover();
await thumbnailUtils.selectButton(page, assetToTrash.id).click();
await page.getByLabel('Menu').click();
const deleteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
changes.assetDeletions.push(...requestJson.ids);
await route.fulfill({
status: 200,
contentType: 'application/json',
json: requestJson.ids.map((id: string) => ({ id, success: true })),
});
});
await page.getByRole('menuitem').getByText('Delete').click();
await expect(deleteRequest).resolves.toEqual({
force: false,
ids: [assetToTrash.id],
});
await page.getByText('Trash', { exact: true }).click();
await thumbnailUtils.expectInViewport(page, assetToTrash.id);
await thumbnailUtils.withAssetId(page, assetToTrash.id).hover();
await thumbnailUtils.selectButton(page, assetToTrash.id).click();
const restoreRequest = pageRoutePromise(page, '**/api/trash/restore/assets', async (route, request) => {
const requestJson = request.postDataJSON();
changes.assetDeletions = changes.assetDeletions.filter((id) => !requestJson.ids.includes(id));
await route.fulfill({
status: 200,
contentType: 'application/json',
json: { count: requestJson.ids.length },
});
});
await page.getByText('Restore', { exact: true }).click();
await expect(restoreRequest).resolves.toEqual({
ids: [assetToTrash.id],
});
await expect(thumbnailUtils.withAssetId(page, assetToTrash.id)).toHaveCount(0);
await page.getByText('Photos', { exact: true }).click();
await thumbnailUtils.expectInViewport(page, assetToTrash.id);
});
test('open album, trash photo, open /trash, restore', async ({ page }) => {
const album = timelineRestData.album;
await pageUtils.openAlbumPage(page, album.id);
const assetToTrash = getAsset(timelineRestData, album.assetIds[0])!;
await thumbnailUtils.withAssetId(page, assetToTrash.id).hover();
await thumbnailUtils.selectButton(page, assetToTrash.id).click();
await page.getByLabel('Menu').click();
const deleteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
changes.assetDeletions.push(...requestJson.ids);
await route.fulfill({
status: 200,
contentType: 'application/json',
json: requestJson.ids.map((id: string) => ({ id, success: true })),
});
});
await page.getByRole('menuitem').getByText('Delete').click();
await expect(deleteRequest).resolves.toEqual({
force: false,
ids: [assetToTrash.id],
});
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
await page.getByText('Trash', { exact: true }).click();
await timelineUtils.waitForTimelineLoad(page);
await thumbnailUtils.expectInViewport(page, assetToTrash.id);
await thumbnailUtils.withAssetId(page, assetToTrash.id).hover();
await thumbnailUtils.selectButton(page, assetToTrash.id).click();
const restoreRequest = pageRoutePromise(page, '**/api/trash/restore/assets', async (route, request) => {
const requestJson = request.postDataJSON();
changes.assetDeletions = changes.assetDeletions.filter((id) => !requestJson.ids.includes(id));
await route.fulfill({
status: 200,
contentType: 'application/json',
json: { count: requestJson.ids.length },
});
});
await page.getByText('Restore', { exact: true }).click();
await expect(restoreRequest).resolves.toEqual({
ids: [assetToTrash.id],
});
await expect(thumbnailUtils.withAssetId(page, assetToTrash.id)).toHaveCount(0);
await pageUtils.openAlbumPage(page, album.id);
await thumbnailUtils.expectInViewport(page, assetToTrash.id);
});
});
test.describe('/archive', () => {
test('open /photos, archive photo, open /archive, unarchive', async ({ page }) => {
await pageUtils.openPhotosPage(page);
const assetToArchive = assets[0];
await thumbnailUtils.withAssetId(page, assetToArchive.id).hover();
await thumbnailUtils.selectButton(page, assetToArchive.id).click();
await page.getByLabel('Menu').click();
const archive = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.visibility !== 'archive') {
return await route.continue();
}
await route.fulfill({
status: 204,
});
changes.assetArchivals.push(...requestJson.ids);
});
await page.getByRole('menuitem').getByText('Archive').click();
await expect(archive).resolves.toEqual({
visibility: 'archive',
ids: [assetToArchive.id],
});
await expect(thumbnailUtils.withAssetId(page, assetToArchive.id)).toHaveCount(0);
await page.getByRole('link').getByText('Archive').click();
await thumbnailUtils.expectInViewport(page, assetToArchive.id);
await thumbnailUtils.withAssetId(page, assetToArchive.id).hover();
await thumbnailUtils.selectButton(page, assetToArchive.id).click();
const unarchiveRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.visibility !== 'timeline') {
return await route.continue();
}
changes.assetArchivals = changes.assetArchivals.filter((id) => !requestJson.ids.includes(id));
await route.fulfill({
status: 204,
});
});
await page.getByLabel('Unarchive').click();
await expect(unarchiveRequest).resolves.toEqual({
visibility: 'timeline',
ids: [assetToArchive.id],
});
await expect(thumbnailUtils.withAssetId(page, assetToArchive.id)).toHaveCount(0);
await page.getByText('Photos', { exact: true }).click();
await thumbnailUtils.expectInViewport(page, assetToArchive.id);
});
test('open album, archive photo, open album, unarchive', async ({ page }) => {
const album = timelineRestData.album;
await pageUtils.openAlbumPage(page, album.id);
const assetToArchive = getAsset(timelineRestData, album.assetIds[0])!;
await thumbnailUtils.withAssetId(page, assetToArchive.id).hover();
await thumbnailUtils.selectButton(page, assetToArchive.id).click();
await page.getByLabel('Menu').click();
const archive = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.visibility !== 'archive') {
return await route.continue();
}
changes.assetArchivals.push(...requestJson.ids);
await route.fulfill({
status: 204,
});
});
await page.getByRole('menuitem').getByText('Archive').click();
await expect(archive).resolves.toEqual({
visibility: 'archive',
ids: [assetToArchive.id],
});
console.log('Skipping assertion - TODO - fix that archiving in album doesnt add icon');
// await thumbnail.expectThumbnailIsArchive(page, assetToArchive.id);
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
await page.getByRole('link').getByText('Archive').click();
await timelineUtils.waitForTimelineLoad(page);
await thumbnailUtils.expectInViewport(page, assetToArchive.id);
await thumbnailUtils.withAssetId(page, assetToArchive.id).hover();
await thumbnailUtils.selectButton(page, assetToArchive.id).click();
const unarchiveRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.visibility !== 'timeline') {
return await route.continue();
}
changes.assetArchivals = changes.assetArchivals.filter((id) => !requestJson.ids.includes(id));
await route.fulfill({
status: 204,
});
});
await page.getByLabel('Unarchive').click();
await expect(unarchiveRequest).resolves.toEqual({
visibility: 'timeline',
ids: [assetToArchive.id],
});
console.log('Skipping assertion - TODO - fix bug with not removing asset from timeline-manager after unarchive');
// await expect(thumbnail.withAssetId(page, assetToArchive.id)).toHaveCount(0);
await pageUtils.openAlbumPage(page, album.id);
await thumbnailUtils.expectInViewport(page, assetToArchive.id);
});
});
test.describe('/favorite', () => {
test('open /photos, favorite photo, open /favorites, remove favorite, open /photos', async ({ page }) => {
await pageUtils.openPhotosPage(page);
const assetToFavorite = assets[0];
await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover();
await thumbnailUtils.selectButton(page, assetToFavorite.id).click();
const favorite = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.isFavorite === undefined) {
return await route.continue();
}
const isFavorite = requestJson.isFavorite;
if (isFavorite) {
changes.assetFavorites.push(...requestJson.ids);
}
await route.fulfill({
status: 204,
});
});
await page.getByLabel('Favorite').click();
await expect(favorite).resolves.toEqual({
isFavorite: true,
ids: [assetToFavorite.id],
});
// ensure thumbnail still exists and has favorite icon
await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id);
await page.getByRole('link').getByText('Favorites').click();
await thumbnailUtils.expectInViewport(page, assetToFavorite.id);
await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover();
await thumbnailUtils.selectButton(page, assetToFavorite.id).click();
const unFavoriteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.isFavorite === undefined) {
return await route.continue();
}
changes.assetFavorites = changes.assetFavorites.filter((id) => !requestJson.ids.includes(id));
await route.fulfill({
status: 204,
});
});
await page.getByLabel('Remove from favorites').click();
await expect(unFavoriteRequest).resolves.toEqual({
isFavorite: false,
ids: [assetToFavorite.id],
});
await expect(thumbnailUtils.withAssetId(page, assetToFavorite.id)).toHaveCount(0);
await page.getByText('Photos', { exact: true }).click();
await thumbnailUtils.expectInViewport(page, assetToFavorite.id);
});
test('Open album, favorite photo, open /favorites, remove favorite, Open album', async ({ page }) => {
const album = timelineRestData.album;
await pageUtils.openAlbumPage(page, album.id);
const assetToFavorite = getAsset(timelineRestData, album.assetIds[0])!;
await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover();
await thumbnailUtils.selectButton(page, assetToFavorite.id).click();
const favorite = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.isFavorite === undefined) {
return await route.continue();
}
const isFavorite = requestJson.isFavorite;
if (isFavorite) {
changes.assetFavorites.push(...requestJson.ids);
}
await route.fulfill({
status: 204,
});
});
await page.getByLabel('Favorite').click();
await expect(favorite).resolves.toEqual({
isFavorite: true,
ids: [assetToFavorite.id],
});
// ensure thumbnail still exists and has favorite icon
await thumbnailUtils.expectThumbnailIsFavorite(page, assetToFavorite.id);
await page.locator('#asset-selection-app-bar').getByLabel('Close').click();
await page.getByRole('link').getByText('Favorites').click();
await timelineUtils.waitForTimelineLoad(page);
await pageUtils.goToAsset(page, assetToFavorite.fileCreatedAt);
await thumbnailUtils.expectInViewport(page, assetToFavorite.id);
await thumbnailUtils.withAssetId(page, assetToFavorite.id).hover();
await thumbnailUtils.selectButton(page, assetToFavorite.id).click();
const unFavoriteRequest = pageRoutePromise(page, '**/api/assets', async (route, request) => {
const requestJson = request.postDataJSON();
if (requestJson.isFavorite === undefined) {
return await route.continue();
}
changes.assetFavorites = changes.assetFavorites.filter((id) => !requestJson.ids.includes(id));
await route.fulfill({
status: 204,
});
});
await page.getByLabel('Remove from favorites').click();
await expect(unFavoriteRequest).resolves.toEqual({
isFavorite: false,
ids: [assetToFavorite.id],
});
await expect(thumbnailUtils.withAssetId(page, assetToFavorite.id)).toHaveCount(0);
await pageUtils.openAlbumPage(page, album.id);
await thumbnailUtils.expectInViewport(page, assetToFavorite.id);
});
});
});
const getYearMonth = (assets: TimelineAssetConfig[], assetId: string) => {
const mockAsset = assets.find((mockAsset) => mockAsset.id === assetId)!;
const dateTime = DateTime.fromISO(mockAsset.fileCreatedAt!);
return dateTime.year + '-' + dateTime.month;
};

View File

@@ -0,0 +1,234 @@
import { BrowserContext, expect, Page } from '@playwright/test';
import { DateTime } from 'luxon';
import { TimelineAssetConfig } from 'src/generators/timeline';
export const sleep = (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
export const padYearMonth = (yearMonth: string) => {
const [year, month] = yearMonth.split('-');
return `${year}-${month.padStart(2, '0')}`;
};
export async function throttlePage(context: BrowserContext, page: Page) {
const session = await context.newCDPSession(page);
await session.send('Network.emulateNetworkConditions', {
offline: false,
downloadThroughput: (1.5 * 1024 * 1024) / 8,
uploadThroughput: (750 * 1024) / 8,
latency: 40,
connectionType: 'cellular3g',
});
await session.send('Emulation.setCPUThrottlingRate', { rate: 10 });
}
let activePollsAbortController = new AbortController();
export const cancelAllPollers = () => {
activePollsAbortController.abort();
activePollsAbortController = new AbortController();
};
export const poll = async <T>(
page: Page,
query: () => Promise<T>,
callback?: (result: Awaited<T> | undefined) => boolean,
) => {
let result;
const timeout = Date.now() + 10_000;
const signal = activePollsAbortController.signal;
const terminate = callback || ((result: Awaited<T> | undefined) => !!result);
while (!terminate(result) && Date.now() < timeout) {
if (signal.aborted) {
return;
}
try {
result = await query();
} catch {
// ignore
}
if (signal.aborted) {
return;
}
if (page.isClosed()) {
return;
}
try {
await page.waitForTimeout(50);
} catch {
return;
}
}
if (!result) {
// rerun to trigger error if any
result = await query();
}
return result;
};
export const thumbnailUtils = {
locator(page: Page) {
return page.locator('[data-thumbnail-focus-container]');
},
withAssetId(page: Page, assetId: string) {
return page.locator(`[data-thumbnail-focus-container][data-asset="${assetId}"]`);
},
selectButton(page: Page, assetId: string) {
return page.locator(`[data-thumbnail-focus-container][data-asset="${assetId}"] button`);
},
selectedAsset(page: Page) {
return page.locator('[data-thumbnail-focus-container]:has(button[aria-checked])');
},
async clickAssetId(page: Page, assetId: string) {
await thumbnailUtils.withAssetId(page, assetId).click();
},
async queryThumbnailInViewport(page: Page, collector: (assetId: string) => boolean) {
const assetIds: string[] = [];
for (const thumb of await this.locator(page).all()) {
const box = await thumb.boundingBox();
if (box) {
const assetId = await thumb.evaluate((e) => e.dataset.asset);
if (collector?.(assetId!)) {
return [assetId!];
}
assetIds.push(assetId!);
}
}
return assetIds;
},
async getFirstInViewport(page: Page) {
return await poll(page, () => thumbnailUtils.queryThumbnailInViewport(page, () => true));
},
async getAllInViewport(page: Page, collector: (assetId: string) => boolean) {
return await poll(page, () => thumbnailUtils.queryThumbnailInViewport(page, collector));
},
async expectThumbnailIsFavorite(page: Page, assetId: string) {
await expect(
thumbnailUtils
.withAssetId(page, assetId)
.locator(
'path[d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"]',
),
).toHaveCount(1);
},
async expectThumbnailIsArchive(page: Page, assetId: string) {
await expect(
thumbnailUtils
.withAssetId(page, assetId)
.locator('path[d="M20 21H4V10H6V19H18V10H20V21M3 3H21V9H3V3M5 5V7H19V5M10.5 11V14H8L12 18L16 14H13.5V11"]'),
).toHaveCount(1);
},
async expectSelectedReadonly(page: Page, assetId: string) {
// todo - need a data attribute for selected
await expect(
page.locator(
`[data-thumbnail-focus-container][data-asset="${assetId}"] > .group.cursor-not-allowed > .rounded-xl`,
),
).toBeVisible();
},
async expectTimelineHasOnScreenAssets(page: Page) {
const first = await thumbnailUtils.getFirstInViewport(page);
if (page.isClosed()) {
return;
}
expect(first).toBeTruthy();
},
async expectInViewport(page: Page, assetId: string) {
const box = await poll(page, () => thumbnailUtils.withAssetId(page, assetId).boundingBox());
if (page.isClosed()) {
return;
}
expect(box).toBeTruthy();
},
async expectBottomIsTimelineBottom(page: Page, assetId: string) {
const box = await thumbnailUtils.withAssetId(page, assetId).boundingBox();
const gridBox = await timelineUtils.locator(page).boundingBox();
if (page.isClosed()) {
return;
}
expect(box!.y + box!.height).toBeCloseTo(gridBox!.y + gridBox!.height, 0);
},
async expectTopIsTimelineTop(page: Page, assetId: string) {
const box = await thumbnailUtils.withAssetId(page, assetId).boundingBox();
const gridBox = await timelineUtils.locator(page).boundingBox();
if (page.isClosed()) {
return;
}
expect(box!.y).toBeCloseTo(gridBox!.y, 0);
},
};
export const timelineUtils = {
locator(page: Page) {
return page.locator('#asset-grid');
},
async waitForTimelineLoad(page: Page) {
await expect(timelineUtils.locator(page)).toBeInViewport();
await expect.poll(() => thumbnailUtils.locator(page).count()).toBeGreaterThan(0);
},
async getScrollTop(page: Page) {
const queryTop = () =>
page.evaluate(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return document.querySelector('#asset-grid').scrollTop;
});
await expect.poll(queryTop).toBeGreaterThan(0);
return await queryTop();
},
};
export const assetViewerUtils = {
locator(page: Page) {
return page.locator('#immich-asset-viewer');
},
async waitForViewerLoad(page: Page, asset: TimelineAssetConfig) {
await page
.locator(`img[draggable="false"][src="/api/assets/${asset.id}/thumbnail?size=preview&c=${asset.thumbhash}"]`)
.or(page.locator(`video[poster="/api/assets/${asset.id}/thumbnail?size=preview&c=${asset.thumbhash}"]`))
.waitFor();
},
async expectActiveAssetToBe(page: Page, assetId: string) {
const activeElement = () =>
page.evaluate(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return document.activeElement?.dataset?.asset;
});
await expect(poll(page, activeElement, (result) => result === assetId)).resolves.toBe(assetId);
},
};
export const pageUtils = {
async deepLinkPhotosPage(page: Page, assetId: string) {
await page.goto(`/photos?at=${assetId}`);
await timelineUtils.waitForTimelineLoad(page);
},
async openPhotosPage(page: Page) {
await page.goto(`/photos`);
await timelineUtils.waitForTimelineLoad(page);
},
async openAlbumPage(page: Page, albumId: string) {
await page.goto(`/albums/${albumId}`);
await timelineUtils.waitForTimelineLoad(page);
},
async deepLinkAlbumPage(page: Page, albumId: string, assetId: string) {
await page.goto(`/albums/${albumId}?at=${assetId}`);
await timelineUtils.waitForTimelineLoad(page);
},
async goToAsset(page: Page, assetDate: string) {
await timelineUtils.locator(page).hover();
const stringDate = DateTime.fromISO(assetDate).toFormat('MMddyyyy,hh:mm:ss.SSSa');
await page.keyboard.press('g');
await page.locator('#datetime').pressSequentially(stringDate);
await page.getByText('Confirm').click();
},
async selectDay(page: Page, day: string) {
await page.getByTitle(day).hover();
await page.locator('[data-group] .w-8').click();
},
async pauseTestDebug() {
console.log('NOTE: pausing test indefinately for debug');
await new Promise(() => void 0);
},
};

View File

@@ -52,14 +52,18 @@ test.describe('User Administration', () => {
await page.goto(`/admin/users/${user.userId}`);
await page.getByRole('button', { name: 'Edit user' }).click();
await page.getByRole('button', { name: 'Edit' }).click();
await expect(page.getByLabel('Admin User')).not.toBeChecked();
await page.getByText('Admin User').click();
await expect(page.getByLabel('Admin User')).toBeChecked();
await page.getByRole('button', { name: 'Confirm' }).click();
const updated = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) });
expect(updated.isAdmin).toBe(true);
await expect
.poll(async () => {
const userAdmin = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) });
return userAdmin.isAdmin;
})
.toBe(true);
});
test('revoke admin access', async ({ context, page }) => {
@@ -77,13 +81,17 @@ test.describe('User Administration', () => {
await page.goto(`/admin/users/${user.userId}`);
await page.getByRole('button', { name: 'Edit user' }).click();
await page.getByRole('button', { name: 'Edit' }).click();
await expect(page.getByLabel('Admin User')).toBeChecked();
await page.getByText('Admin User').click();
await expect(page.getByLabel('Admin User')).not.toBeChecked();
await page.getByRole('button', { name: 'Confirm' }).click();
const updated = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) });
expect(updated.isAdmin).toBe(false);
await expect
.poll(async () => {
const userAdmin = await getUserAdmin({ id: user.userId }, { headers: asBearerAuth(admin.accessToken) });
return userAdmin.isAdmin;
})
.toBe(false);
});
});

View File

@@ -17,7 +17,6 @@
"add_birthday": "Voeg 'n verjaarsdag by",
"add_endpoint": "Voeg Koppelvlakpunt by",
"add_exclusion_pattern": "Voeg uitsgluitingspatrone by",
"add_import_path": "Voeg invoerpad by",
"add_location": "Voeg ligging by",
"add_more_users": "Voeg meer gebruikers by",
"add_partner": "Voeg vennoot by",
@@ -101,7 +100,6 @@
"job_status": "Werkstatus",
"library_created": "Biblioteek geskep: {library}",
"library_deleted": "Biblioteek verwyder",
"library_import_path_description": "Spesifiseer 'n leer om in te neem. Hierdie leer, en al die sub leers, gaan deursoek word vir prente en videos.",
"library_scanning": "Periodieke Soek",
"library_scanning_description": "Stel periodieke deursoek van biblioteek in",
"library_scanning_enable_description": "Aktiveer periodieke biblioteekskandering",
@@ -170,7 +168,6 @@
"duplicates": "Duplikate",
"duration": "Duur",
"edit": "Wysig",
"edited": "Gewysigd",
"search_by_description": "Soek by beskrywing",
"search_by_description_example": "Stapdag in Sapa",
"version": "Weergawe",

View File

@@ -17,7 +17,6 @@
"add_birthday": "أضف تاريخ الميلاد",
"add_endpoint": "اضف نقطة نهاية",
"add_exclusion_pattern": "إضافة نمط إستثناء",
"add_import_path": "إضافة مسار الإستيراد",
"add_location": "إضافة موقع",
"add_more_users": "إضافة مستخدمين آخرين",
"add_partner": "أضف شريكًا",
@@ -112,19 +111,18 @@
"jobs_failed": "{jobCount, plural, other {# فشلت}}",
"library_created": "تم إنشاء المكتبة: {library}",
"library_deleted": "تم حذف المكتبة",
"library_import_path_description": "حدد مجلدًا للاستيراد. سيتم فحص هذا المجلد، بما في ذلك المجلدات الفرعية، بحثًا عن الصور ومقاطع الفيديو.",
"library_scanning": "المسح الدوري",
"library_scanning_description": "إعداد مسح المكتبة الدوري",
"library_scanning_enable_description": "تفعيل مسح المكتبة الدوري",
"library_settings": "المكتبة الخارجية",
"library_settings_description": "إدارة إعدادات المكتبة الخارجية",
"library_tasks_description": "مسح المكتبات الخارجية للعثور على الأصول الجديدة و/أو المتغيرة",
"library_watching_enable_description": "راقب المكتبات الخارجية لتغييرات الملفات",
"library_watching_settings": "مراقبة المكتبات (تجريبي)",
"library_watching_enable_description": "مراقبة المكتبات الخارجية لاكتشاف تغييرات الملفات",
"library_watching_settings": "مراقبة المكتبات [تجريبي]",
"library_watching_settings_description": "راقب تلقائيًا التغييرات في الملفات",
"logging_enable_description": "تفعيل تسجيل الأحداث",
"logging_level_description": "عند التفعيل، أي مستوى تسجيل سيستخدم.",
"logging_settings": "تسجيل الاحداث",
"logging_settings": "السجلات",
"machine_learning_availability_checks": "تحقق من التوفر",
"machine_learning_availability_checks_description": "تحديد خوادم التعلم الآلي المتاحة تلقائيًا وإعطاءها الأولوية",
"machine_learning_availability_checks_enabled": "تفعيل عمليات فحص التوفر",
@@ -154,6 +152,18 @@
"machine_learning_min_detection_score_description": "الحد الأدنى لنقطة الثقة لاكتشاف الوجه، تتراوح من 0 إلى 1. القيم الأقل ستكشف عن المزيد من الوجوه ولكن قد تؤدي إلى نتائج إيجابية خاطئة.",
"machine_learning_min_recognized_faces": "الحد الأدنى لعدد الوجوه المتعرف عليها",
"machine_learning_min_recognized_faces_description": "الحد الأدنى لعدد الوجوه المتعرف عليها لإنشاء شخص. زيادة هذا الرقم يجعل التعرف على الوجوه أكثر دقة على حساب زيادة احتمال عدم تعيين الوجه لشخص ما.",
"machine_learning_ocr": "التعرف البصري على الحروف",
"machine_learning_ocr_description": "استخدم التعلم الآلي للتعرف على النصوص في الصور",
"machine_learning_ocr_enabled": "تفعيل التعرف البصري على الحروف",
"machine_learning_ocr_enabled_description": "في حال تعطيل هذه الميزة، لن تخضع الصور لعملية التعرف على النصوص.",
"machine_learning_ocr_max_resolution": "أقصى دقة",
"machine_learning_ocr_max_resolution_description": "سيتم تغيير حجم المعاينات التي تتجاوز هذه الدقة مع الحفاظ على نسبة العرض إلى الارتفاع. القيم الأعلى توفر دقة أكبر، ولكنها تستغرق وقتًا أطول للمعالجة وتستهلك المزيد من الذاكرة.",
"machine_learning_ocr_min_detection_score": "الحد الأدنى لدرجة الكشف",
"machine_learning_ocr_min_detection_score_description": "لحد الأدنى لدرجة الثقة المطلوبة لاكتشاف النص، وتتراوح قيمتها من 0 إلى 1. ستؤدي القيم الأقل إلى اكتشاف المزيد من النصوص ولكنها قد تؤدي إلى نتائج إيجابية خاطئة.",
"machine_learning_ocr_min_recognition_score": "الحد الأدنى لدرجة التعرّف",
"machine_learning_ocr_min_score_recognition_description": "الحد الأدنى لدرجة الثقة المطلوبة للنصوص المكتشفة ليتم التعرف عليها، وتتراوح من 0 إلى 1. ستؤدي القيم الأقل إلى التعرف على المزيد من النصوص ولكنها قد تؤدي إلى نتائج إيجابية خاطئة.",
"machine_learning_ocr_model": "نموذج التعرف البصري على الحروف",
"machine_learning_ocr_model_description": "تتميز نماذج الخوادم بدقة أكبر من نماذج الأجهزة المحمولة، ولكنها تستغرق وقتًا أطول في المعالجة وتستهلك ذاكرة أكبر.",
"machine_learning_settings": "إعدادات التعلم الآلي",
"machine_learning_settings_description": "إدارة ميزات وإعدادات التعلم الآلي",
"machine_learning_smart_search": "البحث الذكي",
@@ -206,11 +216,13 @@
"note_cannot_be_changed_later": "ملاحظة: لا يمكن تغيير هذا لاحقًا!",
"notification_email_from_address": "عنوان المرسل",
"notification_email_from_address_description": "عنوان البريد الإلكتروني للمرسل، على سبيل المثال: \"Immich Photo Server noreply@example.com\". تاكد من استخدام عنوان بريد الكتروني يسمح لك بارسال البريد الالكتروني منه.",
"notification_email_host_description": "مضيف خادم البريد الإلكتروني (مثلًا: smtp.immich.app)",
"notification_email_host_description": "عنوان خادم البريد الإلكتروني (مثل smtp.immich.app)",
"notification_email_ignore_certificate_errors": "تجاهل أخطاء الشهادة",
"notification_email_ignore_certificate_errors_description": "تجاهل أخطاء التحقق من صحة شهادة TLS (غير مستحسن)",
"notification_email_password_description": "كلمة المرور المستخدمة للمصادقة مع خادم البريد الإلكتروني",
"notification_email_port_description": "منفذ خادم البريد الإلكتروني (مثلاً 25، 465، أو 587)",
"notification_email_secure": "بروتوكول نقل البريد البسيط الآمن SMTPS",
"notification_email_secure_description": "استخدم بروتوكول SMTPS (بروتوكول SMTP عبر TLS)",
"notification_email_sent_test_email_button": "إرسال بريد إلكتروني تجريبي وحفظ التعديلات",
"notification_email_setting_description": "إعدادات إرسال إشعارات البريد الإلكتروني",
"notification_email_test_email": "إرسال بريد تجريبي",
@@ -243,6 +255,7 @@
"oauth_storage_quota_default_description": "الحصة بالجيجابايت التي سيتم استخدامها عندما لا يتم توفير مطالبة.",
"oauth_timeout": "نفاذ وقت الطلب",
"oauth_timeout_description": "نفاذ وقت الطلب بالميلي ثانية",
"ocr_job_description": "استخدم التعلم الآلي للتعرف على النصوص في الصور",
"password_enable_description": "تسجيل الدخول باستخدام البريد الكتروني وكلمة المرور",
"password_settings": "تسجيل الدخول بكلمة المرور",
"password_settings_description": "إدارة تسجيل الدخول بكلمة المرور",
@@ -333,7 +346,7 @@
"transcoding_max_b_frames": "أقصى عدد من الإطارات B",
"transcoding_max_b_frames_description": "القيم الأعلى تعزز كفاءة الضغط، ولكنها تبطئ عملية الترميز. قد لا تكون متوافقة مع التسريع العتادي على الأجهزة القديمة. قيمة 0 تعطل إطارات B، بينما تضبط القيمة -1 هذا القيمة تلقائيًا.",
"transcoding_max_bitrate": "الحد الأقصى لمعدل البت",
"transcoding_max_bitrate_description": مكن أن يؤدي تعيين الحد الأقصى لمعدل البت إلى جعل أحجام الملفات أكثر قابلية للتنبؤ بها بتكلفة بسيطة بالنسبة للجودة. عند دقة 720 بكسل، تكون القيم النموذجية 2600 كيلو بت لـ VP9 أو HEVC، أو 4500 كيلو بت لـ H.264. معطل إذا تم ضبطه على 0.",
"transcoding_max_bitrate_description": تيح تعيين معدل البت الأقصى التحكم في حجم الملف مع تأثير طفيف على الجودة.عند دقة 720p، القيم المقترحة هي 2600 كيلوبت/ثانية لـ VP9 أو HEVC، و4500 كيلوبت/ثانية لـ H.264.يتم تعطيل الإعداد عند القيمة 0. إذا لم تُحدَّد وحدة، يُفترض k (كيلوبت/ثانية)؛ لذا فإن 5000، 5000k، و5M متكافئة.",
"transcoding_max_keyframe_interval": "الحد الأقصى للفاصل الزمني للإطار الرئيسي",
"transcoding_max_keyframe_interval_description": "يضبط الحد الأقصى لمسافة الإطار بين الإطارات الرئيسية. تؤدي القيم المنخفضة إلى زيادة سوء كفاءة الضغط، ولكنها تعمل على تحسين أوقات البحث وقد تعمل على تحسين الجودة في المشاهد ذات الحركة السريعة. 0 يضبط هذه القيمة تلقائيًا.",
"transcoding_optimal_description": "مقاطع الفيديو ذات الدقة الأعلى من الدقة المستهدفة أو بتنسيق غير مقبول",
@@ -351,7 +364,7 @@
"transcoding_target_resolution": "القرار المستهدف",
"transcoding_target_resolution_description": "يمكن أن تحافظ الدقة الأعلى على المزيد من التفاصيل ولكنها تستغرق وقتًا أطول للتشفير، ولها أحجام ملفات أكبر، ويمكن أن تقلل من استجابة التطبيق.",
"transcoding_temporal_aq": "التكميم التكيفي الزمني",
"transcoding_temporal_aq_description": "ينطبق فقط على NVENC. يزيد من جودة المشاهد عالية التفاصيل ومنخفضة الحركة. قد لا يكون متوافقًا مع الأجهزة القديمة.",
"transcoding_temporal_aq_description": "ينطبق فقط على NVENC. تعمل \"الكمّية التكيفية الزمنية\" على تحسين جودة المشاهد ذات التفاصيل الدقيقة والحركة البطيئة. قد لا يكون هذا الخيار متوافقًا مع الأجهزة القديمة.",
"transcoding_threads": "الخيوط",
"transcoding_threads_description": "تؤدي القيم الأعلى إلى تشفير أسرع، ولكنها تترك مساحة أقل للخادم لمعالجة المهام الأخرى أثناء النشاط. يجب ألا تزيد هذه القيمة عن عدد مراكز وحدة المعالجة المركزية. يزيد من الإستغلال إذا تم ضبطه على 0.",
"transcoding_tone_mapping": "رسم الخرائط النغمية",
@@ -402,11 +415,11 @@
"advanced_settings_prefer_remote_subtitle": "تكون بعض الأجهزة بطيئة للغاية في تحميل الصور المصغرة من الأصول المحلية. قم بتفعيل هذا الخيار لتحميل الصور البعيدة بدلاً من ذلك.",
"advanced_settings_prefer_remote_title": "تفضل الصور البعيدة",
"advanced_settings_proxy_headers_subtitle": "عرف عناوين الوكيل التي يستخدمها Immich لارسال كل طلب شبكي",
"advanced_settings_proxy_headers_title": "عناوين الوكيل",
"advanced_settings_proxy_headers_title": "عناوين الوكيل المخصصة [تجريبية]",
"advanced_settings_readonly_mode_subtitle": "تتيح هذه الميزة وضع العرض فقط، حيث يمكن للمستخدم معاينة الصور فقط، بينما يتم تعطيل جميع الخيارات الأخرى مثل تحديد عدة صور، أو مشاركتها، أو بثها، أو حذفها. يمكن تفعيل/تعطيل وضع العرض فقط من خلال صورة المستخدم في الشاشة الرئيسية",
"advanced_settings_readonly_mode_title": "وضع القراءة فقط",
"advanced_settings_self_signed_ssl_subtitle": "تخطي التحقق من شهادة SSL لخادم النقطة النهائي. مكلوب للشهادات الموقعة ذاتيا.",
"advanced_settings_self_signed_ssl_title": "السماح بشهادات SSL الموقعة ذاتيًا",
"advanced_settings_self_signed_ssl_title": "السماح بشهادات SSL الموقعة ذاتيًا [تجريبية]",
"advanced_settings_sync_remote_deletions_subtitle": "حذف او استعادة تلقائي للاصول على هذا الجهاز عند تنفيذ العملية على الويب",
"advanced_settings_sync_remote_deletions_title": "مزامنة عمليات الحذف عن بعد [تجريبي]",
"advanced_settings_tile_subtitle": "إعدادات المستخدم المتقدمة",
@@ -466,10 +479,14 @@
"api_key_description": "سيتم عرض هذه القيمة مرة واحدة فقط. يرجى التأكد من نسخها قبل إغلاق النافذة.",
"api_key_empty": "يجب ألا يكون اسم مفتاح API فارغًا",
"api_keys": "مفاتيح API",
"app_architecture_variant": "متغير (الهندسة المعمارية)",
"app_bar_signout_dialog_content": "هل أنت متأكد أنك تريد تسجيل الخروج؟",
"app_bar_signout_dialog_ok": "نعم",
"app_bar_signout_dialog_title": "خروج",
"app_download_links": "روابط تحميل التطبيق",
"app_settings": "إعدادات التطبيق",
"app_stores": "متاجر التطبيقات",
"app_update_available": "تحديث التطبيق متاح",
"appears_in": "يظهر في",
"apply_count": "تطبيق ({count, number})",
"archive": "الأرشيف",
@@ -553,6 +570,7 @@
"backup_albums_sync": "مزامنة ألبومات النسخ الاحتياطي",
"backup_all": "الجميع",
"backup_background_service_backup_failed_message": "فشل في النسخ الاحتياطي للأصول. جارٍ إعادة المحاولة…",
"backup_background_service_complete_notification": "تم الانتهاء من النسخ الاحتياطي للأصول",
"backup_background_service_connection_failed_message": "فشل في الاتصال بالخادم. جارٍ إعادة المحاولة…",
"backup_background_service_current_upload_notification": "تحميل {filename}",
"backup_background_service_default_notification": "التحقق من الأصول الجديدة…",
@@ -662,6 +680,8 @@
"change_password_description": "هذه إما هي المرة الأولى التي تقوم فيها بتسجيل الدخول إلى النظام أو أنه تم تقديم طلب لتغيير كلمة المرور الخاصة بك. الرجاء إدخال كلمة المرور الجديدة أدناه.",
"change_password_form_confirm_password": "تأكيد كلمة المرور",
"change_password_form_description": "مرحبًا {name}،\n\nاما ان تكون هذه هي المرة الأولى التي تقوم فيها بالتسجيل في النظام أو تم تقديم طلب لتغيير كلمة المرور الخاصة بك. الرجاء إدخال كلمة المرور الجديدة أدناه.",
"change_password_form_log_out": "تسجيل الخروج من جميع الأجهزة الأخرى",
"change_password_form_log_out_description": "يُنصح بتسجيل الخروج من جميع الأجهزة الأخرى",
"change_password_form_new_password": "كلمة المرور الجديدة",
"change_password_form_password_mismatch": "كلمة المرور غير مطابقة",
"change_password_form_reenter_new_password": "أعد إدخال كلمة مرور جديدة",
@@ -689,7 +709,7 @@
"client_cert_invalid_msg": "ملف شهادة عميل غير صالحة او كلمة سر غير صحيحة",
"client_cert_remove_msg": "تم ازالة شهادة العميل",
"client_cert_subtitle": "يدعم صيغ PKCS12 (.p12, .pfx)فقط. استيراد/ازالة الشهادات متاح فقط قبل تسجيل الدخول",
"client_cert_title": "شهادة مستخدم SSL",
"client_cert_title": "شهادة مستخدم SSL [تجريبية]",
"clockwise": "باتجاه عقارب الساعة",
"close": "إغلاق",
"collapse": "طي",
@@ -701,7 +721,6 @@
"comments_and_likes": "التعليقات والإعجابات",
"comments_are_disabled": "التعليقات معطلة",
"common_create_new_album": "إنشاء ألبوم جديد",
"common_server_error": "يرجى التحقق من اتصال الشبكة الخاص بك ، والتأكد من أن الجهاز قابل للوصول وإصدارات التطبيق/الجهاز متوافقة.",
"completed": "اكتمل",
"confirm": "تأكيد",
"confirm_admin_password": "تأكيد كلمة مرور المسؤول",
@@ -740,6 +759,7 @@
"create": "انشاء",
"create_album": "إنشاء ألبوم",
"create_album_page_untitled": "بدون اسم",
"create_api_key": "إنشاء مفتاح API",
"create_library": "إنشاء مكتبة",
"create_link": "إنشاء رابط",
"create_link_to_share": "إنشاء رابط للمشاركة",
@@ -769,6 +789,7 @@
"daily_title_text_date_year": "E ، MMM DD ، yyyy",
"dark": "معتم",
"dark_theme": "تبديل المظهر الداكن",
"date": "تاريخ",
"date_after": "التارخ بعد",
"date_and_time": "التاريخ و الوقت",
"date_before": "التاريخ قبل",
@@ -871,8 +892,6 @@
"edit_description_prompt": "الرجاء اختيار وصف جديد:",
"edit_exclusion_pattern": "تعديل نمط الاستبعاد",
"edit_faces": "تعديل الوجوه",
"edit_import_path": "تعديل مسار الاستيراد",
"edit_import_paths": "تعديل مسارات الاستيراد",
"edit_key": "تعديل المفتاح",
"edit_link": "تغيير الرابط",
"edit_location": "تعديل الموقع",
@@ -883,7 +902,6 @@
"edit_tag": "تعديل العلامة",
"edit_title": "تعديل العنوان",
"edit_user": "تعديل المستخدم",
"edited": "تم التعديل",
"editor": "محرر",
"editor_close_without_save_prompt": "لن يتم حفظ التغييرات",
"editor_close_without_save_title": "إغلاق المحرر؟",
@@ -945,7 +963,6 @@
"failed_to_stack_assets": "فشل في تكديس المحتويات",
"failed_to_unstack_assets": "فشل في فصل المحتويات",
"failed_to_update_notification_status": "فشل في تحديث حالة الإشعار",
"import_path_already_exists": "مسار الاستيراد هذا موجود مسبقًا.",
"incorrect_email_or_password": "بريد أو كلمة مرور غير صحيحة",
"paths_validation_failed": "فشل في التحقق من {paths, plural, one {# مسار} other {# مسارات}}",
"profile_picture_transparent_pixels": "لا يمكن أن تحتوي صور الملف الشخصي على أجزاء/بكسلات شفافة. يرجى التكبير و/أو تحريك الصورة.",
@@ -955,7 +972,6 @@
"unable_to_add_assets_to_shared_link": "تعذر إضافة المحتويات إلى الرابط المشترك",
"unable_to_add_comment": "تعذر إضافة التعليق",
"unable_to_add_exclusion_pattern": "تعذر إضافة نمط الإستبعاد",
"unable_to_add_import_path": "تعذر إضافة مسار الإستيراد",
"unable_to_add_partners": "تعذر إضافة الشركاء",
"unable_to_add_remove_archive": "تعذر {archived, select, true {إزالة المحتوى من} other {إضافة المحتوى إلى}} الأرشيف",
"unable_to_add_remove_favorites": "تعذر {favorite, select, true {إضافة المحتوى إلى} other {إزالة المحتوى من}} المفضلة",
@@ -978,12 +994,10 @@
"unable_to_delete_asset": "غير قادر على حذف المحتوى",
"unable_to_delete_assets": "حدث خطأ أثناء حذف المحتويات",
"unable_to_delete_exclusion_pattern": "غير قادر على حذف نمط الاستبعاد",
"unable_to_delete_import_path": "غير قادر على حذف مسار الاستيراد",
"unable_to_delete_shared_link": "غير قادر على حذف الرابط المشترك",
"unable_to_delete_user": "غير قادر على حذف المستخدم",
"unable_to_download_files": "غير قادر على تنزيل الملفات",
"unable_to_edit_exclusion_pattern": "غير قادر على تعديل نمط الاستبعاد",
"unable_to_edit_import_path": "غير قادر على تحرير مسار الاستيراد",
"unable_to_empty_trash": "غير قادر على إفراغ سلة المهملات",
"unable_to_enter_fullscreen": "غير قادر على الدخول إلى وضع ملء الشاشة",
"unable_to_exit_fullscreen": "غير قادر على الخروج من وضع ملء الشاشة",
@@ -1039,6 +1053,7 @@
"exif_bottom_sheet_description_error": "خطأ في تحديث الوصف",
"exif_bottom_sheet_details": "تفاصيل",
"exif_bottom_sheet_location": "موقع",
"exif_bottom_sheet_no_description": "لا يوجد وصف",
"exif_bottom_sheet_people": "الناس",
"exif_bottom_sheet_person_add_person": "اضف اسما",
"exit_slideshow": "خروج من العرض التقديمي",
@@ -1077,6 +1092,7 @@
"features_setting_description": "إدارة ميزات التطبيق",
"file_name": "إسم الملف",
"file_name_or_extension": "اسم الملف أو امتداده",
"file_size": "حجم الملف",
"filename": "اسم الملف",
"filetype": "نوع الملف",
"filter": "تصفية",
@@ -1116,11 +1132,10 @@
"hash_asset": "عمل Hash للأصل (للملف)",
"hashed_assets": "أصول (ملفات) تم عمل Hash لها",
"hashing": "يتم عمل Hash",
"header_settings_add_header_tip": "اضاف راس",
"header_settings_add_header_tip": "إضافة رأس الصفحة",
"header_settings_field_validator_msg": "القيمة لا يمكن ان تكون فارغة",
"header_settings_header_name_input": "اسم الرأس",
"header_settings_header_value_input": "قيمة الرأس",
"headers_settings_tile_subtitle": "قم بتعريف رؤوس الوكيل التي يجب أن يرسلها التطبيق مع كل طلب شبكة",
"headers_settings_tile_title": "رؤوس وكيل مخصصة",
"hi_user": "مرحبا {name} ({email})",
"hide_all_people": "إخفاء جميع الأشخاص",
@@ -1241,6 +1256,7 @@
"local_media_summary": "ملخص الملفات المحلية",
"local_network": "شبكة محلية",
"local_network_sheet_info": "سيتصل التطبيق بالخادم من خلال عنوان URL هذا عند استخدام شبكة Wi-Fi المحددة",
"location": "موقع",
"location_permission": "اذن الموقع",
"location_permission_content": "من أجل استخدام ميزة التبديل التلقائي، يحتاج Immich إلى إذن موقع دقيق حتى يتمكن من قراءة اسم شبكة Wi-Fi الحالية",
"location_picker_choose_on_map": "اختر على الخريطة",
@@ -1345,6 +1361,8 @@
"minute": "دقيقة",
"minutes": "دقائق",
"missing": "المفقودة",
"mobile_app": "تطبيق الجوال",
"mobile_app_download_onboarding_note": "قم بتنزيل التطبيق المصاحب للهاتف المحمول باستخدام الخيارات التالية",
"model": "نموذج",
"month": "شهر",
"monthly_title_text_date_format": "ط ط ط",
@@ -1363,6 +1381,8 @@
"my_albums": "ألبوماتي",
"name": "الاسم",
"name_or_nickname": "الاسم أو اللقب",
"navigate": "التنقل",
"navigate_to_time": "انتقل إلى الوقت",
"network_requirement_photos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية للصور",
"network_requirement_videos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية لمقاطع الفيديو",
"network_requirements": "متطلبات الشبكة",
@@ -1372,6 +1392,7 @@
"never": "أبداً",
"new_album": "البوم جديد",
"new_api_key": "مفتاح API جديد",
"new_date_range": "نطاق تاريخ جديد",
"new_password": "كلمة المرور الجديدة",
"new_person": "شخص جديد",
"new_pin_code": "رمز PIN الجديد",
@@ -1422,6 +1443,9 @@
"notifications": "إشعارات",
"notifications_setting_description": "إدارة الإشعارات",
"oauth": "OAuth",
"obtainium_configurator": "مُهيئ Obtainium",
"obtainium_configurator_instructions": "استخدم Obtainium لتثبيت تطبيق Android وتحديثه مباشرةً من صفحة إصدارات Immich على GitHub. أنشئ مفتاح API واختر الإصدار المناسب لإنشاء رابط تهيئة Obtainium الخاص بك",
"ocr": "التعرف البصري على الحروف",
"official_immich_resources": "الموارد الرسمية لشركة Immich",
"offline": "غير متصل",
"offset": "ازاحة",
@@ -1526,6 +1550,9 @@
"play_memories": "تشغيل الذكريات",
"play_motion_photo": "تشغيل الصور المتحركة",
"play_or_pause_video": "تشغيل الفيديو أو إيقافه مؤقتًا",
"play_original_video": "تشغيل الفيديو الأصلي",
"play_original_video_setting_description": "تفضيل تشغيل مقاطع الفيديو الأصلية بدلاً من مقاطع الفيديو المحولة. إذا لم يكن الملف الأصلي متوافقًا، فقد لا يتم تشغيله بشكل صحيح.",
"play_transcoded_video": "تشغيل الفيديو المُعاد ترميزه",
"please_auth_to_access": "الرجاء القيام بالمصادقة للوصول",
"port": "المنفذ",
"preferences_settings_subtitle": "ادارة تفضيلات التطبيق",
@@ -1543,13 +1570,9 @@
"privacy": "الخصوصية",
"profile": "حساب تعريفي",
"profile_drawer_app_logs": "السجلات",
"profile_drawer_client_out_of_date_major": "تطبيق الهاتف المحمول قديم.يرجى التحديث إلى أحدث إصدار رئيسي.",
"profile_drawer_client_out_of_date_minor": "تطبيق الهاتف المحمول قديم.يرجى التحديث إلى أحدث إصدار صغير.",
"profile_drawer_client_server_up_to_date": "العميل والخادم محدثان",
"profile_drawer_github": "Github",
"profile_drawer_readonly_mode": "تم تفعيل وضع القراءة فقط. اضغط مطولا على رمز صورة المستخدم للخروج.",
"profile_drawer_server_out_of_date_major": "الخادم قديم.يرجى التحديث إلى أحدث إصدار رئيسي.",
"profile_drawer_server_out_of_date_minor": "الخادم قديم.يرجى التحديث إلى أحدث إصدار صغير.",
"profile_image_of_user": "صورة الملف الشخصي لـ {user}",
"profile_picture_set": "مجموعة الصور الشخصية.",
"public_album": "الألبوم العام",
@@ -1666,6 +1689,7 @@
"reset_sqlite_confirmation": "هل أنت متأكد من رغبتك في إعادة ضبط قاعدة بيانات SQLite؟ ستحتاج إلى تسجيل الخروج ثم تسجيل الدخول مرة أخرى لإعادة مزامنة البيانات",
"reset_sqlite_success": "تم إعادة تعيين قاعدة بيانات SQLite بنجاح",
"reset_to_default": "إعادة التعيين إلى الافتراضي",
"resolution": "دقة",
"resolve_duplicates": "معالجة النسخ المكررة",
"resolved_all_duplicates": "تم حل جميع التكرارات",
"restore": "الاستعاده من سلة المهملات",
@@ -1684,6 +1708,7 @@
"running": "قيد التشغيل",
"save": "حفظ",
"save_to_gallery": "حفظ الى المعرض",
"saved": "تم الحفظ",
"saved_api_key": "تم حفظ مفتاح الـ API",
"saved_profile": "تم حفظ الملف",
"saved_settings": "تم حفظ الإعدادات",
@@ -1700,6 +1725,9 @@
"search_by_description_example": "يوم المشي لمسافات طويلة في سابا",
"search_by_filename": "البحث بإسم الملف أو نوعه",
"search_by_filename_example": "كـ IMG_1234.JPG أو PNG",
"search_by_ocr": "البحث عن طريق التعرف البصري على الحروف",
"search_by_ocr_example": "لاتيه",
"search_camera_lens_model": "بحث نموذج العدسة...",
"search_camera_make": "البحث حسب الشركة المصنعة للكاميرا...",
"search_camera_model": "البحث حسب موديل الكاميرا...",
"search_city": "البحث حسب المدينة...",
@@ -1716,6 +1744,7 @@
"search_filter_location_title": "اختر الموقع",
"search_filter_media_type": "نوع الوسائط",
"search_filter_media_type_title": "اختر نوع الوسائط",
"search_filter_ocr": "البحث عن طريق التعرف البصري على الحروف",
"search_filter_people_title": "اختر الاشخاص",
"search_for": "البحث عن",
"search_for_existing_person": "البحث عن شخص موجود",
@@ -1778,6 +1807,7 @@
"server_online": "الخادم متصل",
"server_privacy": "خصوصية الخادم",
"server_stats": "إحصائيات الخادم",
"server_update_available": "تحديث الخادم متاح",
"server_version": "إصدار الخادم",
"set": "‏تحديد",
"set_as_album_cover": "تحديد كغلاف للألبوم",
@@ -1806,6 +1836,8 @@
"setting_notifications_subtitle": "اضبط تفضيلات الإخطار",
"setting_notifications_total_progress_subtitle": "التقدم التحميل العام (تم القيام به/إجمالي الأصول)",
"setting_notifications_total_progress_title": "إظهار النسخ الاحتياطي الخلفية التقدم المحرز",
"setting_video_viewer_auto_play_subtitle": "بدء تشغيل مقاطع الفيديو تلقائيًا عند فتحها",
"setting_video_viewer_auto_play_title": "تشغيل الفيديوهات تلقائيًا",
"setting_video_viewer_looping_title": "تكرار مقطع فيديو تلقائيًا",
"setting_video_viewer_original_video_subtitle": "عند بث فيديو من الخادم، شغّل النسخة الأصلية حتى مع توفر ترميز بديل. قد يؤدي ذلك إلى تقطيع اثناء العرض . تُشغّل الفيديوهات المتوفرة محليًا بجودة أصلية بغض النظر عن هذا الإعداد.",
"setting_video_viewer_original_video_title": "اجبار عرض الفديو الاصلي",
@@ -1985,6 +2017,7 @@
"theme_setting_three_stage_loading_title": "تمكين تحميل ثلاث مراحل",
"they_will_be_merged_together": "سيتم دمجهم معًا",
"third_party_resources": "موارد الطرف الثالث",
"time": "وقت",
"time_based_memories": "ذكريات استنادًا للوقت",
"timeline": "الخط الزمني",
"timezone": "المنطقة الزمنية",
@@ -2017,6 +2050,7 @@
"troubleshoot": "استكشاف المشاكل",
"type": "النوع",
"unable_to_change_pin_code": "تفيير رمز PIN غير ممكن",
"unable_to_check_version": "تعذر التحقق من إصدار التطبيق أو الخادم",
"unable_to_setup_pin_code": "انشاء رمز PIN غير ممكن",
"unarchive": "أخرج من الأرشيف",
"unarchive_action_prompt": "{count} ازيل من الارشيف",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Doğum günü əlavə et",
"add_endpoint": "Son nöqtə əlavə et",
"add_exclusion_pattern": ıxarma nümunəsi əlavə et",
"add_import_path": "İdxal yolu əlavə et",
"add_location": "Məkan əlavə et",
"add_more_users": "Daha çox istifadəçi əlavə et",
"add_partner": "Partnyor əlavə et",
@@ -85,7 +84,6 @@
"jobs_failed": "{jobCount, plural, other {# uğursuz}}",
"library_created": "{library} kitabxanası yaradıldı",
"library_deleted": "Kitabxana silindi",
"library_import_path_description": "İdxal olunacaq qovluöu seçin. Bu qovluq, alt qovluqlar daxil olmaqla şəkil və videolar üçün skan ediləcəkdir.",
"library_scanning": "Periodik skan",
"library_scanning_description": "Periodik kitabxana skanını confiqurasiya et",
"library_scanning_enable_description": "Periodik kitabxana skanını aktivləşdir",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Дадаць дзень нараджэння",
"add_endpoint": "Дадаць кропку доступу",
"add_exclusion_pattern": "Дадаць шаблон выключэння",
"add_import_path": "Дадаць шлях імпарту",
"add_location": "Дадайце месца",
"add_more_users": "Дадаць больш карыстальнікаў",
"add_partner": "Дадаць партнёра",
@@ -318,8 +317,6 @@
"edit_description": "Рэдагаваць апісанне",
"edit_description_prompt": "Выберыце новае апісанне:",
"edit_faces": "Рэдагаваць твары",
"edit_import_path": "Рэдагаваць шлях імпарту",
"edit_import_paths": "Рэдагаваць шляхі імпарту",
"edit_key": "Рэдагаваць ключ",
"edit_link": "Рэдагаваць спасылку",
"edit_location": "Рэдагаваць месцазнаходжанне",
@@ -329,7 +326,6 @@
"edit_tag": "Рэдагаваць тэг",
"edit_title": "Рэдагаваць загаловак",
"edit_user": "Рэдагаваць карыстальніка",
"edited": "Адрэдагавана",
"editor": "Рэдактар",
"editor_close_without_save_prompt": "Змены не будуць захаваны",
"editor_close_without_save_title": "Закрыць рэдактар?",
@@ -399,6 +395,8 @@
"partner_list_user_photos": "Фота карыстальніка {user}",
"pause": "Прыпыніць",
"people": "Людзі",
"permanent_deletion_warning": "Папярэджанне аб канчатковым выдаленні",
"permanent_deletion_warning_setting_description": "Паказаць папярэджанне пры канчатковым выдаленні рэсурсаў",
"permission_onboarding_back": "Назад",
"permission_onboarding_continue_anyway": "Усё адно працягнуць",
"photos": "Фота",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Добави дата на раждане",
"add_endpoint": "Добави крайна точка",
"add_exclusion_pattern": "Добави модел за изключване",
"add_import_path": "Добави път за импортиране",
"add_location": "Дoбави местоположение",
"add_more_users": "Добави още потребители",
"add_partner": "Добави партньор",
@@ -32,7 +31,9 @@
"add_to_album_toggle": "Сменете избора за {album}",
"add_to_albums": "Добавяне в албуми",
"add_to_albums_count": "Добавяне в албуми ({count})",
"add_to_bottom_bar": "Добави към",
"add_to_shared_album": "Добави към споделен албум",
"add_upload_to_stack": "Добави качените в група",
"add_url": "Добави URL",
"added_to_archive": "Добавено към архива",
"added_to_favorites": "Добавени към любимите ви",
@@ -90,7 +91,7 @@
"image_prefer_embedded_preview_setting_description": "Използване на вградените миниатюри в RAW снимките като входни за обработка на изображенията, когато има такива. Това може да доведе до по-точни цветове за някои изображения, но качеството на прегледите зависи от камерата и изображението може да има повече компресионни артефакти.",
"image_prefer_wide_gamut": "Предпочитане на широка гама",
"image_prefer_wide_gamut_setting_description": "Използване на Display P3 за миниатюри. Това запазва по-добре жизнеността на изображенията с широки цветови пространства, но изображенията може да изглеждат по различен начин на стари устройства със стара версия на браузъра. sRGB изображенията се запазват като sRGB, за да се избегнат цветови промени.",
"image_preview_description": "Среден размер на изображението с премахнати метаданни, използвано при преглед на един актив и за машинно обучение",
"image_preview_description": "Среден размер на изображението с премахнати метаданни, използвано при преглед на един елемент и за машинно обучение",
"image_preview_quality_description": "Качество на предварителния преглед от 1 до 100. По-високата стойност е по-добра, но води до по-големи файлове и може да намали бързодействието на приложението. Задаването на ниска стойност може да повлияе на качеството на машинното обучение.",
"image_preview_title": "Настройки на прегледа",
"image_quality": "Качество",
@@ -111,15 +112,14 @@
"jobs_failed": "{jobCount, plural, other {# неуспешни}}",
"library_created": "Създадена библиотека: {library}",
"library_deleted": "Библиотека е изтрита",
"library_import_path_description": "Посочете папка за импортиране. Тази папка, включително подпапките, ще бъдат сканирани за изображения и видеоклипове.",
"library_scanning": "Периодично сканиране",
"library_scanning_description": "Конфигурирай периодично сканиране на библиотеката",
"library_scanning_enable_description": "Включване на периодичното сканиране на библиотеката",
"library_settings": "Външна библиотека",
"library_settings_description": "Управление на настройките за външна библиотека",
"library_tasks_description": "Сканирайте външни библиотеки за нови и/или променени активи",
"library_tasks_description": "Сканирайте външни библиотеки за нови и/или променени елементи",
"library_watching_enable_description": "Наблюдаване за промяна на файловете във външната библиотека",
"library_watching_settings": "Наблюдаване на библиотеката (ЕКСПЕРИМЕНТАЛНО)",
"library_watching_settings": "Наблюдаване на библиотеката [ЕКСПЕРИМЕНТАЛНО]",
"library_watching_settings_description": "Автоматично наблюдавай за променени файлове",
"logging_enable_description": "Включване на запис (логове)",
"logging_level_description": "Когато е включено, какво ниво на записване да се използва.",
@@ -150,9 +150,21 @@
"machine_learning_max_recognition_distance": "Максимално разстояние за разпознаване",
"machine_learning_max_recognition_distance_description": "Максимално разстояние между две лица, за да се считат за едно и също лице, в диапазона 0-2. Намаляването му може да предотврати определянето на две лица като едно и също лице, а увеличаването му може да предотврати определянето на едно и също лице като две различни лица. Имайте предвид, че е по-лесно да се слеят две лица, отколкото да се раздели едно лице на две, така че по възможност изберете по-ниска стойност.",
"machine_learning_min_detection_score": "Минимална оценка за откриване",
"machine_learning_min_detection_score_description": "Минимална оценка на доверието, за да бъде считано лице като открито - от 0 до 1. По-ниските стойности ще открият повече лица, но може да доведат до фалшиви положителни резултати.",
"machine_learning_min_detection_score_description": "Минимална оценка на доверие, за да бъде считано лице като открито - от 0 до 1. По-ниските стойности ще открият повече лица, но може да доведат до фалшиви положителни резултати.",
"machine_learning_min_recognized_faces": "Минимум разпознати лица",
"machine_learning_min_recognized_faces_description": "Минималният брой разпознати лица, необходими за създаването на лице. Увеличаването му прави разпознаването на лица по-прецизно за сметка на увеличаването на вероятността дадено лице да не бъде причислено към лице.",
"machine_learning_ocr": "Разпознаване на текст",
"machine_learning_ocr_description": "Използвайте машинно обучение за разпознаване на текст в изображенията",
"machine_learning_ocr_enabled": "Включи разпознаване на текст",
"machine_learning_ocr_enabled_description": "Ако е забранено, няма да се прави разпознаване на текст в изображенията.",
"machine_learning_ocr_max_resolution": "Максимална резолюция",
"machine_learning_ocr_max_resolution_description": "Изображения с резолюция над зададената ще бъдат преоразмерени при запазване на пропорцията. Голяма стойност позволява по-прецизно разпознаване, но обработката използва повече време и повече памет.",
"machine_learning_ocr_min_detection_score": "Минимална оценка за откриванe",
"machine_learning_ocr_min_detection_score_description": "Минималната оценка на доверие за откриване на текст може да бъде между 0 и 1. По-ниска стойност ще открива повече текст, но може да доведе до грешни резултати.",
"machine_learning_ocr_min_recognition_score": "Минимална оценкa за откриване",
"machine_learning_ocr_min_score_recognition_description": "Минимална оценка на доверие, за да бъде считан текст като открит - от 0 до 1. По-ниските стойности ще открият повече текст, но може да доведат до фалшиви положителни резултати.",
"machine_learning_ocr_model": "Модел за разпознаване на текст",
"machine_learning_ocr_model_description": "Сървърните модели са по-точни от мобилните модели, но изискват повече време и използват повече памет.",
"machine_learning_settings": "Настройки на машинното обучение",
"machine_learning_settings_description": "Управление на функциите и настройките за машинно обучение",
"machine_learning_smart_search": "Интелигентно Търсене",
@@ -178,7 +190,7 @@
"memory_cleanup_job": "Почистване на паметта",
"memory_generate_job": "Генериране на паметта",
"metadata_extraction_job": "Извличане на метаданни",
"metadata_extraction_job_description": "Извличане на метаданни от всеки от елемент, като GPS локация, лица и резолюция на файловете",
"metadata_extraction_job_description": "Извличане на метаданни от всеки елемент, като GPS локация, лица и резолюция на файловете",
"metadata_faces_import_setting": "Включи импорт на лице",
"metadata_faces_import_setting_description": "Импортирай лица от EXIF данни и помощни файлове",
"metadata_settings": "Опции за метаданни",
@@ -210,6 +222,8 @@
"notification_email_ignore_certificate_errors_description": "Игнорирай грешки свързани с валидация на TLS сертификат (не се препоръчва)",
"notification_email_password_description": "Парола използвана за удостоверяване пред сървъра за електронна поща",
"notification_email_port_description": "Порт на сървъра за електронна поща (например 25, 465 или 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Използвай SMTPS (SMTP по TLS)",
"notification_email_sent_test_email_button": "Изпрати тестов имейл и запази",
"notification_email_setting_description": "Настройки за изпращане на имейл известия",
"notification_email_test_email": "Изпрати тестов имейл",
@@ -242,6 +256,7 @@
"oauth_storage_quota_default_description": "Квота в GiB, която да се използва, когато не е посочено друго.",
"oauth_timeout": "Време на изчакване при заявка",
"oauth_timeout_description": "Време за изчакване на отговор на заявка, в милисекунди",
"ocr_job_description": "Използване на машинно обучение за разпознаване на текст в изображенията",
"password_enable_description": "Влизане с имейл и парола",
"password_settings": "Вписване с парола",
"password_settings_description": "Управление на настройките за влизане с парола",
@@ -332,7 +347,7 @@
"transcoding_max_b_frames": "Максимални B-фрейма",
"transcoding_max_b_frames_description": "По-високите стойности подобряват ефективността на компресията, но забавят разкодирането. Може да не е съвместим с хардуерното ускорение на по-стари устройства. 0 деактивира B-фрейма, докато -1 задава тази стойност автоматично.",
"transcoding_max_bitrate": "Максимален битрейт",
"transcoding_max_bitrate_description": "Задаването на максимален битрейт може да направи размерите на файловете по-предвидими при незначителни разлики за качеството. При 720p типичните стойности са 2600 kbit/s за VP9 или HEVC или 4500 kbit/s за H.264. Деактивирано, ако е зададено на 0.",
"transcoding_max_bitrate_description": "Задаването на максимален битрейт може да направи размерите на файловете по-предвидими при незначителни разлики за качеството. При 720p типичните стойности са 2600 kbit/s за VP9 или HEVC или 4500 kbit/s за H.264. Деактивирано, ако е зададено на 0. Когато не е зададена мерна единица, подразбира се k (kbit/s); така 5000, 5000k и 5M (Mbit/s) са еквивалентни.",
"transcoding_max_keyframe_interval": "Максимален интервал между ключовите кадри",
"transcoding_max_keyframe_interval_description": "Задава максималното разстояние между ключовите кадри. По-ниските стойности влошават ефективността на компресията, но подобряват времето за търсене и могат да подобрят качеството в сцени с бързо движение. 0 задава тази стойност автоматично.",
"transcoding_optimal_description": "Видеоклипове с по-висока от целевата разделителна способност или не в приетия формат",
@@ -350,7 +365,7 @@
"transcoding_target_resolution": "Целева резолюция",
"transcoding_target_resolution_description": "По-високите разделителни способности могат да представят повече детайли, но отнемат повече време за разкодиране, имат по-големи размери на файловете и могат да намалят отзивчивостта на приложението.",
"transcoding_temporal_aq": "Темпорален AQ",
"transcoding_temporal_aq_description": "Само за NVENC. Повишава качеството на сцени с висока детайлност и ниско ниво на движение. Може да не е съвместимо с по-стари устройства.",
"transcoding_temporal_aq_description": "Само за NVENC. Повишава качеството на сцени с висока детайлност и малко движение. Може да не е съвместимо с по-стари устройства.",
"transcoding_threads": "Нишки",
"transcoding_threads_description": "По-високите стойности водят до по-бързо разкодиране, но оставят по-малко място за сървъра да обработва други задачи, докато е активен. Тази стойност не трябва да надвишава броя на процесорните ядра. Увеличава максимално използването, ако е зададено на 0.",
"transcoding_tone_mapping": "Тонално картографиране",
@@ -401,11 +416,11 @@
"advanced_settings_prefer_remote_subtitle": "Някои устройства са твърде бавни за да генерират миниатюри. Активирай тази опция за да се зареждат винаги от сървъра.",
"advanced_settings_prefer_remote_title": "Предпочитай изображенията на сървъра",
"advanced_settings_proxy_headers_subtitle": "Дефиниране на прокси хедъри, които Immich трябва да изпраща с всяка мрежова заявка",
"advanced_settings_proxy_headers_title": "Прокси хедъри",
"advanced_settings_proxy_headers_title": "Прокси хедъри [ЕКСПЕРИМЕНТАЛНО]",
"advanced_settings_readonly_mode_subtitle": "Активира режима \"само за четене\", при който снимките могат да бъдат разглеждани, но неща като избор на няколко изображения, споделяне, изтриване са забранени. Активиране/деактивиране на режима само за четене става от картинката-аватар на потребителя от основния екран",
"advanced_settings_readonly_mode_title": "Режим само за четене",
"advanced_settings_self_signed_ssl_subtitle": "Пропуска проверката на SSL-сертификата на сървъра. Изисква се при самоподписани сертификати.",
"advanced_settings_self_signed_ssl_title": "Разреши самоподписани SSL сертификати",
"advanced_settings_self_signed_ssl_title": "Разреши самоподписани SSL сертификати [ЕКСПЕРИМЕНТАЛНО]",
"advanced_settings_sync_remote_deletions_subtitle": "Автоматично изтрии или възстанови обект на това устройство, когато действието е извършено през уеб-интерфейса",
"advanced_settings_sync_remote_deletions_title": "Синхронизация на дистанционни изтривания [ЕКСПЕРИМЕНТАЛНО]",
"advanced_settings_tile_subtitle": "Разширени потребителски настройки",
@@ -414,6 +429,7 @@
"age_months": "Възраст {months, plural, one {# месец} other {# месеци}}",
"age_year_months": "Възраст 1 година, {months, plural, one {# месец} other {# месеци}}",
"age_years": "{years, plural, other {Година #}}",
"album": "Албум",
"album_added": "Албумът е добавен",
"album_added_notification_setting_description": "Получавайте известие по имейл, когато бъдете добавени към споделен албум",
"album_cover_updated": "Обложката на албума е актуализирана",
@@ -459,16 +475,21 @@
"allow_edits": "Позволяване на редакции",
"allow_public_user_to_download": "Позволете на публичен потребител да може да изтегля",
"allow_public_user_to_upload": "Позволете на публичния потребител да може да качва",
"allowed": "Разрешено",
"alt_text_qr_code": "Изображение на QR код",
"anti_clockwise": "Обратно на часовниковата стрелка",
"api_key": "API ключ",
"api_key_description": "Тази стойност ще бъде показана само веднъж. Моля, не забравяйте да го копирате, преди да затворите прозореца.",
"api_key_empty": "Името на вашия API ключ не трябва да е празно",
"api_keys": "API ключове",
"app_architecture_variant": "Вариант (Ахитектура)",
"app_bar_signout_dialog_content": "Наистина ли искате да излезете?",
"app_bar_signout_dialog_ok": "Да",
"app_bar_signout_dialog_title": "Излез от профила",
"app_download_links": "Линкове за сваляне на приложението",
"app_settings": "Настройки ма приложението",
"app_stores": "Магазини за приложения",
"app_update_available": "Налична е нова версия",
"appears_in": "Излиза в",
"apply_count": "Приложи ({count, number})",
"archive": "Архив",
@@ -552,6 +573,7 @@
"backup_albums_sync": "Синхронизиране на архивите",
"backup_all": "Всичко",
"backup_background_service_backup_failed_message": "Неуспешно архивиране. Нов опит…",
"backup_background_service_complete_notification": "Завърши архивирането на обектите",
"backup_background_service_connection_failed_message": "Неуспешно свързване към сървъра. Нов опит…",
"backup_background_service_current_upload_notification": "Зареждам {filename}",
"backup_background_service_default_notification": "Търсене на нови обекти…",
@@ -661,6 +683,8 @@
"change_password_description": "Това е или първият път, когато влизате в системата, или е направена заявка за промяна на паролата ви. Моля, въведете новата парола по-долу.",
"change_password_form_confirm_password": "Потвърди паролата",
"change_password_form_description": "Здравейте {name},\n\nТова или е първото ви вписване в системата или има подадена заявка за смяна на паролата. Моля, въведете нова парола в полето по-долу.",
"change_password_form_log_out": "Излизане от профила на всички други устройства",
"change_password_form_log_out_description": "Препоръчваме да се излезе от профила на всички други устройства",
"change_password_form_new_password": "Нова парола",
"change_password_form_password_mismatch": "Паролите не съвпадат",
"change_password_form_reenter_new_password": "Повтори новата парола",
@@ -687,8 +711,8 @@
"client_cert_import_success_msg": "Клиентския сертификат е импортиран",
"client_cert_invalid_msg": "Невалиден сертификат или грешна парола",
"client_cert_remove_msg": "Клиентския сертификат е премахнат",
"client_cert_subtitle": "Поддържа се само формат PKCS12 (.p12, .pfx). Импорт и премахване на сертификат може само преди вписване в системата",
"client_cert_title": "Клиентски SSL сертификат",
"client_cert_subtitle": "Поддържа се само формат PKCS12 (.p12, .pfx). Импорт/премахване на сертификат може само преди вписване в системата",
"client_cert_title": "Клиентски SSL сертификат [ЕКСПЕРИМЕНТАЛНО]",
"clockwise": "По часовниковата стрелка",
"close": "Затвори",
"collapse": "Свиване",
@@ -700,7 +724,6 @@
"comments_and_likes": "Коментари и харесвания",
"comments_are_disabled": "Коментарите са деактивирани",
"common_create_new_album": "Създай нов албум",
"common_server_error": "Моля, проверете мрежовата връзка, убедете се, че сървъра е достъпен и версиите на сървъра и приложението са съвместими.",
"completed": "Завършено",
"confirm": "Потвърди",
"confirm_admin_password": "Потвърждаване на паролата на администратора",
@@ -739,6 +762,7 @@
"create": "Създай",
"create_album": "Създай албум",
"create_album_page_untitled": "Без заглавие",
"create_api_key": "Създайте API ключ",
"create_library": "Създай библиотека",
"create_link": "Създай линк",
"create_link_to_share": "Създаване на линк за споделяне",
@@ -768,6 +792,7 @@
"daily_title_text_date_year": "E, dd MMM yyyy",
"dark": "Тъмен",
"dark_theme": "Тъмна тема",
"date": "Дата",
"date_after": "Дата след",
"date_and_time": "Дата и час",
"date_before": "Дата преди",
@@ -870,8 +895,6 @@
"edit_description_prompt": "Моля, избери ново описание:",
"edit_exclusion_pattern": "Редактиране на шаблон за изключване",
"edit_faces": "Редактиране на лица",
"edit_import_path": "Редактиране на пътя за импортиране",
"edit_import_paths": "Редактиране на пътища за импортиране",
"edit_key": "Редактиране на ключ",
"edit_link": "Редактиране на линк",
"edit_location": "Редактиране на местоположението",
@@ -882,7 +905,6 @@
"edit_tag": "Редактирай таг",
"edit_title": "Редактиране на заглавието",
"edit_user": "Редактиране на потребител",
"edited": "Редактирано",
"editor": "Редактор",
"editor_close_without_save_prompt": "Промените няма да бъдат запазени",
"editor_close_without_save_title": "Затваряне на редактора?",
@@ -944,7 +966,6 @@
"failed_to_stack_assets": "Неуспешно подреждане на обекти",
"failed_to_unstack_assets": "Неуспешно премахване на подредбата на обекти",
"failed_to_update_notification_status": "Неуспешно обновяване на състоянието на известията",
"import_path_already_exists": "Този път за импортиране вече съществува.",
"incorrect_email_or_password": "Неправилен имейл или парола",
"paths_validation_failed": "{paths, plural, one {# път} other {# пътища}} не преминаха валидация",
"profile_picture_transparent_pixels": "Профилните снимки не могат да имат прозрачни пиксели. Моля, увеличете и/или преместете изображението.",
@@ -954,7 +975,6 @@
"unable_to_add_assets_to_shared_link": "Неуспешно добавяне на обекти в споделен линк",
"unable_to_add_comment": "Неуспешно добавяне на коментар",
"unable_to_add_exclusion_pattern": "Неуспешно добавяне на шаблон за изключение",
"unable_to_add_import_path": "Неуспешно добавяне на път за импортиране",
"unable_to_add_partners": "Неуспешно добавяне на партньори",
"unable_to_add_remove_archive": "Неуспешно {archived, select, true {премахване на обект от} other {добавяне на обект в}} архива",
"unable_to_add_remove_favorites": "Неуспешно {favorite, select, true {добавяне на обект в} other {премахване на обект от}} любими",
@@ -977,12 +997,10 @@
"unable_to_delete_asset": "Не може да изтрие файла",
"unable_to_delete_assets": "Грешка при изтриване на файлове",
"unable_to_delete_exclusion_pattern": "Не може да изтрие шаблон за изключване",
"unable_to_delete_import_path": "Пътят за импортиране не може да се изтрие",
"unable_to_delete_shared_link": "Споделената връзка не може да се изтрие",
"unable_to_delete_user": "Не може да изтрие потребител",
"unable_to_download_files": "Не могат да се изтеглят файловете",
"unable_to_edit_exclusion_pattern": "Не може да се редактира шаблон за изключване",
"unable_to_edit_import_path": "Пътят за импортиране не може да се редактира",
"unable_to_empty_trash": "Неуспешно изпразване на кошчето",
"unable_to_enter_fullscreen": "Не може да се отвори в цял екран",
"unable_to_exit_fullscreen": "Не може да излезе от цял екран",
@@ -1038,6 +1056,7 @@
"exif_bottom_sheet_description_error": "Неуспешно обновяване на описание",
"exif_bottom_sheet_details": "ПОДРОБНОСТИ",
"exif_bottom_sheet_location": "МЯСТО",
"exif_bottom_sheet_no_description": "Няма описание",
"exif_bottom_sheet_people": "ХОРА",
"exif_bottom_sheet_person_add_person": "Добави име",
"exit_slideshow": "Изход от слайдшоуто",
@@ -1076,6 +1095,7 @@
"features_setting_description": "Управление на функциите на приложението",
"file_name": "Име на файла",
"file_name_or_extension": "Име на файл или разширение",
"file_size": "Размер на файла",
"filename": "Име на файл",
"filetype": "Тип на файл",
"filter": "Филтър",
@@ -1119,7 +1139,6 @@
"header_settings_field_validator_msg": "Недопустимо е да няма стойност",
"header_settings_header_name_input": "Име на заглавието",
"header_settings_header_value_input": "Стойност на заглавието",
"headers_settings_tile_subtitle": "Дефиниране на прокси заглавия, които приложението трябва да изпраща с всяка мрежова заявка",
"headers_settings_tile_title": "Потребителски прокси заглавия",
"hi_user": "Здравей, {name} {email}",
"hide_all_people": "Скрий всички хора",
@@ -1172,6 +1191,8 @@
"import_path": "Път за импортиране",
"in_albums": "В {count, plural, one {# албум} other {# албума}}",
"in_archive": "В архив",
"in_year": "{year} г.",
"in_year_selector": "През",
"include_archived": "Включване на архивирани",
"include_shared_albums": "Включване на споделени албуми",
"include_shared_partner_assets": "Включване на споделените с партньор елементи",
@@ -1208,6 +1229,7 @@
"language_setting_description": "Изберете предпочитан език",
"large_files": "Големи файлове",
"last": "Последен",
"last_months": "{count, plural, one {Последния месец} other {Последните # месеца}}",
"last_seen": "Последно видяно",
"latest_version": "Последна версия",
"latitude": "Ширина",
@@ -1240,6 +1262,7 @@
"local_media_summary": "Обобщение на локалните файлове",
"local_network": "Локална мрежа",
"local_network_sheet_info": "Приложението ще се свърже със сървъра на този URL, когато устройството е свързано към зададената Wi-Fi мрежа",
"location": "Място",
"location_permission": "Разрешение за местоположение",
"location_permission_content": "За да работи функцията автоматично превключване, Immich се нуждае от разрешение за точно местоположение, за да може да чете името на текущата Wi-Fi мрежа",
"location_picker_choose_on_map": "Избери на карта",
@@ -1289,6 +1312,10 @@
"main_menu": "Главно меню",
"make": "Марка",
"manage_geolocation": "Управление на местоположенията",
"manage_media_access_rationale": "Това разрешение е необходимо за правилно преместване на обекти в кошчето и за възстановяване от там.",
"manage_media_access_settings": "Отвори Настройки",
"manage_media_access_subtitle": "Разрешете приложението Immich да управлява и мести медийни файлове.",
"manage_media_access_title": "Управление на медийни файлове",
"manage_shared_links": "Управление на споделени връзки",
"manage_sharing_with_partners": "Управление на споделянето с партньори",
"manage_the_app_settings": "Управление на настройките на приложението",
@@ -1344,12 +1371,15 @@
"minute": "Минута",
"minutes": "Минути",
"missing": "Липсващи",
"mobile_app": "Мобилно приложение",
"mobile_app_download_onboarding_note": "Свалете мобилното приложение Immich с някоя от следните опции",
"model": "Модел",
"month": "Месец",
"monthly_title_text_date_format": "MMMM г",
"more": "Още",
"move": "Премести",
"move_off_locked_folder": "Извади от заключената папка",
"move_to": "Премести към",
"move_to_lock_folder_action_prompt": "{count} са добавени в заключената папка",
"move_to_locked_folder": "Премести в заключена папка",
"move_to_locked_folder_confirmation": "Тези снимки и видеа ще бъдат изтрити от всички албуми и ще са достъпни само в заключената папка",
@@ -1362,6 +1392,8 @@
"my_albums": "Мои албуми",
"name": "Име",
"name_or_nickname": "Име или прякор",
"navigate": "Придвижване",
"navigate_to_time": "Придвижване до момент във времето",
"network_requirement_photos_upload": "Използвай мобилни данни за архивиране на снимки",
"network_requirement_videos_upload": "Използвай мобилни данни за архивиране на видео",
"network_requirements": "Изисквания към мрежата",
@@ -1371,11 +1403,13 @@
"never": "Никога",
"new_album": "Нов Албум",
"new_api_key": "Нов API ключ",
"new_date_range": "Нов период от време",
"new_password": "Нова парола",
"new_person": "Нов човек",
"new_pin_code": "Нов PIN код",
"new_pin_code_subtitle": "Това е първи достъп до заключена папка. Създайте PIN код за защитен достъп до тази страница",
"new_timeline": "Нова времева линия",
"new_update": "Ново обновление",
"new_user_created": "Създаден нов потребител",
"new_version_available": "НАЛИЧНА НОВА ВЕРСИЯ",
"newest_first": "Най-новите първи",
@@ -1391,6 +1425,7 @@
"no_cast_devices_found": "Няма намерени устройства за предаване",
"no_checksum_local": "Липсват контролни суми - не може да се получат локални обекти",
"no_checksum_remote": "Липсват контролни суми - не може да се получат обекти от сървъра",
"no_devices": "Няма оторизирани устройства",
"no_duplicates_found": "Не бяха открити дубликати.",
"no_exif_info_available": "Няма exif информация",
"no_explore_results_message": "Качете още снимки, за да разгледате колекцията си.",
@@ -1407,6 +1442,7 @@
"no_results_description": "Опитайте със синоним или по-обща ключова дума",
"no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си",
"no_uploads_in_progress": "Няма качване в момента",
"not_allowed": "Не е разрешено",
"not_available": "Неналично",
"not_in_any_album": "Не е в никой албум",
"not_selected": "Не е избрано",
@@ -1421,6 +1457,9 @@
"notifications": "Известия",
"notifications_setting_description": "Управление на известията",
"oauth": "OAuth",
"obtainium_configurator": "Конфигуратор за получаване",
"obtainium_configurator_instructions": "Използвайте Obtainium за инсталация и обновяване на приложението за Android директно от GitHub на Immich. Създайте API ключ и изберете вариант за да създадете Obtainium конфигурационен линк",
"ocr": "Оптично разпознаване на текст",
"official_immich_resources": "Официална информация за Immich",
"offline": "Офлайн",
"offset": "Отместване",
@@ -1514,6 +1553,8 @@
"photos_count": "{count, plural, one {{count, number} Снимка} other {{count, number} Снимки}}",
"photos_from_previous_years": "Снимки от предходни години",
"pick_a_location": "Избери локация",
"pick_custom_range": "Произволен период",
"pick_date_range": "Изберете период",
"pin_code_changed_successfully": "Успешно сменен PIN код",
"pin_code_reset_successfully": "Успешно нулиран PIN код",
"pin_code_setup_successfully": "Успешно зададен PIN код",
@@ -1525,6 +1566,9 @@
"play_memories": "Възпроизвеждане на спомени",
"play_motion_photo": "Възпроизведи Motion Photo",
"play_or_pause_video": "Възпроизвеждане или пауза на видео",
"play_original_video": "Пусни оригиналното видео",
"play_original_video_setting_description": "Предпочитане на показване на оригиналното видео, вместо транскодирани. Ако формата на оригиналния файл не се поддържа, възпроизвеждането може да бъде неправилно.",
"play_transcoded_video": "Покажи транскодирано видео",
"please_auth_to_access": "Моля, удостовери за достъп",
"port": "Порт",
"preferences_settings_subtitle": "Управление на предпочитанията на приложението",
@@ -1542,13 +1586,9 @@
"privacy": "Поверителност",
"profile": "Профил",
"profile_drawer_app_logs": "Дневник",
"profile_drawer_client_out_of_date_major": "Мобилното приложение е остаряло. Моля, актуализирайте до най-новата основна версия.",
"profile_drawer_client_out_of_date_minor": "Мобилното приложение е остаряло. Моля, актуализирайте до най-новата версия.",
"profile_drawer_client_server_up_to_date": "Клиента и сървъра са обновени",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Режима само за четене е активиран. С дълго натискане върху картиката-аватар на потребителя ще деактивирате само за четене.",
"profile_drawer_server_out_of_date_major": "Версията на сървъра е остаряла. Моля, актуализирайте поне до последната главна версия.",
"profile_drawer_server_out_of_date_minor": "Версията на сървъра е остаряла. Моля, актуализирайте до последната версия.",
"profile_image_of_user": "Профилна снимка на {user}",
"profile_picture_set": "Профилната снимка е сложена.",
"public_album": "Публичен албум",
@@ -1665,6 +1705,7 @@
"reset_sqlite_confirmation": "Наистина ли искате да нулирате базата данни SQLite? Ще трябва да излезете от системата и да се впишете отново за нова синхронизация на данните",
"reset_sqlite_success": "Успешно нулиране на базата данни SQLite",
"reset_to_default": "Връщане на фабрични настройки",
"resolution": "Резолюция",
"resolve_duplicates": "Реши дубликатите",
"resolved_all_duplicates": "Всички дубликати са решени",
"restore": "Възстановяване",
@@ -1683,6 +1724,7 @@
"running": "Изпълняване",
"save": "Запази",
"save_to_gallery": "Запази в галерията",
"saved": "Записано",
"saved_api_key": "Запазен API Key",
"saved_profile": "Запазен профил",
"saved_settings": "Запазени настройки",
@@ -1699,6 +1741,9 @@
"search_by_description_example": "Разходка в Сапа",
"search_by_filename": "Търси по име на файла или разширение",
"search_by_filename_example": "например IMG_1234.JPG или PNG",
"search_by_ocr": "Търсене на текст",
"search_by_ocr_example": "Lattе",
"search_camera_lens_model": "Търсене на модел на обектива...",
"search_camera_make": "Търси производител на камерата...",
"search_camera_model": "Търси модел на камерата...",
"search_city": "Търси град...",
@@ -1715,6 +1760,7 @@
"search_filter_location_title": "Избери място",
"search_filter_media_type": "Тип на файла",
"search_filter_media_type_title": "Избери тип на файла",
"search_filter_ocr": "Търсене нa текст",
"search_filter_people_title": "Избери хора",
"search_for": "Търси за",
"search_for_existing_person": "Търси съществуващ човек",
@@ -1777,6 +1823,7 @@
"server_online": "Сървър онлайн",
"server_privacy": "Поверителност на сървъра",
"server_stats": "Статус на сървъра",
"server_update_available": "Налична е нова версия за сървъра",
"server_version": "Версия на сървъра",
"set": "Задай",
"set_as_album_cover": "Задаване като обложка на албум",
@@ -1805,6 +1852,8 @@
"setting_notifications_subtitle": "Настройка на известията",
"setting_notifications_total_progress_subtitle": "Общ напредък на зареждане (готово/всички обекти)",
"setting_notifications_total_progress_title": "Показване на общия напредък на архивиране във фонов режим",
"setting_video_viewer_auto_play_subtitle": "Автоматично започни възпроизвеждане на видео при отваряне",
"setting_video_viewer_auto_play_title": "Автоматично възпроизвеждане на видео",
"setting_video_viewer_looping_title": "Циклично",
"setting_video_viewer_original_video_subtitle": "При показване на видео от сървъра показвай оригиналния файл, дори и да има транскодирана версия. Може да използва буфериране. Локално наличните видеа се показват винаги в оригинал, независимо от тази настройка.",
"setting_video_viewer_original_video_title": "Само оригинално видео",
@@ -1968,7 +2017,7 @@
"template": "Шаблон",
"theme": "Тема",
"theme_selection": "Избор на тема",
"theme_selection_description": "Автоматично задаване на светла или тъмна тема въз основа на системните предпочитания на вашия браузър",
"theme_selection_description": "Автоматично задаване на светла или тъмна тема спрямо системните предпочитания на браузъра ви",
"theme_setting_asset_list_storage_indicator_title": "Показвай индикатор за хранилището в заглавията на обектите",
"theme_setting_asset_list_tiles_per_row_title": "Брой обекти на ред ({count})",
"theme_setting_colorful_interface_subtitle": "Нанеси основен цвят върху фоновите повърхности.",
@@ -1984,7 +2033,9 @@
"theme_setting_three_stage_loading_title": "Включи три-степенно зареждане",
"they_will_be_merged_together": "Те ще бъдат обединени",
"third_party_resources": "Ресурси от трети страни",
"time": "Време",
"time_based_memories": "Спомени, базирани на времето",
"time_based_memories_duration": "Продължителност в секунди за показване на всяка картина.",
"timeline": "Хронология",
"timezone": "Часова зона",
"to_archive": "Архивирай",
@@ -2016,6 +2067,7 @@
"troubleshoot": "Отстраняване на проблеми",
"type": "Тип",
"unable_to_change_pin_code": "Невъзможна промяна на PIN кода",
"unable_to_check_version": "Невъзможна проверка на версията на приложението или сървъра",
"unable_to_setup_pin_code": "Неуспешно задаване на PIN кода",
"unarchive": "Разархивирай",
"unarchive_action_prompt": "{count} са премахнати от Архива",
@@ -2124,6 +2176,7 @@
"welcome": "Добре дошли",
"welcome_to_immich": "Добре дошли в Immich",
"wifi_name": "Wi-Fi мрежа",
"workflow": "Работен процес",
"wrong_pin_code": "Грешен PIN код",
"year": "Година",
"years_ago": "преди {years, plural, one {# година} other {# години}}",

View File

@@ -12,12 +12,28 @@
"add_a_name": "Putem nam blo hem",
"add_a_title": "Putem wan name blo hem",
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
"add_import_path": "Putem wan pat blo import",
"add_location": "Putem wan place blo hem",
"add_more_users": "Putem mor man",
"readonly_mode_enabled": "Mod blo yu no save janjem i on",
"reassigned_assets_to_new_person": "Janjem{count, plural, one {# asset} other {# assets}} blo nu man",
"reassing_hint": "janjem ol sumtin yu bin joos i go blo wan man",
"recent-albums": "album i no old tu mas",
"recent_searches": "lukabout wea i no old tu mas"
"recent_searches": "lukabout wea i no old tu mas",
"time_based_memories_duration": "hao mus second blo wan wan imij i stap lo scrin.",
"timezone": "taemzon",
"to_change_password": "janjem pasword",
"to_login": "Login",
"to_multi_select": "to jusem mani",
"to_parent": "go lo parent",
"to_select": "to selectem",
"to_trash": "toti",
"toggle_settings": "sho settings",
"total": "Total",
"trash": "Toti",
"trash_action_prompt": "{count} igo lo plaes lo toti",
"trash_all": "Putem ol i go lo toti",
"trash_count": "Toti {count, number}",
"trash_emptied": "basket blo toti i empti nomo",
"trash_no_results_message": "Foto mo video lo basket blo toti yu save lukem lo plaes ia.",
"trash_page_delete_all": "Delete oli ol"
}

View File

@@ -17,7 +17,6 @@
"add_birthday": "একটি জন্মদিন যোগ করুন",
"add_endpoint": "এন্ডপয়েন্ট যোগ করুন",
"add_exclusion_pattern": "বহির্ভূতকরণ নমুনা",
"add_import_path": "ইমপোর্ট করার পাথ যুক্ত করুন",
"add_location": "অবস্থান যুক্ত করুন",
"add_more_users": "আরো ব্যবহারকারী যুক্ত করুন",
"add_partner": "অংশীদার যোগ করুন",
@@ -111,7 +110,6 @@
"jobs_failed": "{jobCount, plural, other {# ব্যর্থ}}",
"library_created": "লাইব্রেরি তৈরি করা হয়েছেঃ {library}",
"library_deleted": "লাইব্রেরি মুছে ফেলা হয়েছে",
"library_import_path_description": "ইম্পোর্ট/যোগ করার জন্য একটি ফোল্ডার নির্দিষ্ট করুন। সাবফোল্ডার সহ এই ফোল্ডারটি ছবি এবং ভিডিওর জন্য স্ক্যান করা হবে।",
"library_scanning": "পর্যায়ক্রমিক স্ক্যানিং",
"library_scanning_description": "পর্যায়ক্রমিক লাইব্রেরি স্ক্যানিং কনফিগার করুন",
"library_scanning_enable_description": "পর্যায়ক্রমিক লাইব্রেরি স্ক্যানিং সক্ষম করুন",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Afegeix la data de naixement",
"add_endpoint": "afegir endpoint",
"add_exclusion_pattern": "Afegir un patró d'exclusió",
"add_import_path": "Afegir una ruta d'importació",
"add_location": "Afegir la ubicació",
"add_more_users": "Afegir més usuaris",
"add_partner": "Afegir company/a",
@@ -32,6 +31,7 @@
"add_to_album_toggle": "Commutar selecció de {album}",
"add_to_albums": "Afegir als àlbums",
"add_to_albums_count": "Afegir als àlbums ({count})",
"add_to_bottom_bar": "Afegir a",
"add_to_shared_album": "Afegir a un àlbum compartit",
"add_upload_to_stack": "Afegeix la càrrega a la pila",
"add_url": "Afegir URL",
@@ -64,7 +64,7 @@
"confirm_delete_library": "Esteu segurs que voleu eliminar la llibreria {library}?",
"confirm_delete_library_assets": "Esteu segurs que voleu esborrar aquesta llibreria? Això esborrarà {count, plural, one {# contained asset} other {all # contained assets}} d'Immich i no es podrà desfer. Els fitxers romandran al disc.",
"confirm_email_below": "Per a confirmar, escriviu \"{email}\" a sota",
"confirm_reprocess_all_faces": "Esteu segur que voleu reprocessar totes les cares? Això també esborrarà la gent que heu anomenat.",
"confirm_reprocess_all_faces": "Esteu segurs que voleu reprocessar totes les cares? Això també esborrarà la gent que heu anomenat.",
"confirm_user_password_reset": "Esteu segur que voleu reinicialitzar la contrasenya de l'usuari {user}?",
"confirm_user_pin_code_reset": "Esteu segur que voleu restablir el codi PIN de {user}?",
"create_job": "Crear tasca",
@@ -112,7 +112,6 @@
"jobs_failed": "{jobCount, plural, other {# fallides}}",
"library_created": "Bilbioteca creada: {library}",
"library_deleted": "Bilbioteca eliminada",
"library_import_path_description": "Especifiqueu una carpeta a importar. Aquesta carpeta, incloses les seves subcarpetes, serà escanejada per cercar-hi imatges i vídeos.",
"library_scanning": "Escaneig periòdic",
"library_scanning_description": "Configurar l'escaneig periòdic de bilbioteques",
"library_scanning_enable_description": "Habilita l'escaneig periòdic de biblioteques",
@@ -154,6 +153,18 @@
"machine_learning_min_detection_score_description": "La puntuació mínima de confiança per detectar una cara és de 0 a 1. Valors més baixos detectaran més cares, però poden donar lloc a falsos positius.",
"machine_learning_min_recognized_faces": "Nombre mínim de cares reconegudes",
"machine_learning_min_recognized_faces_description": "El nombre mínim de cares reconegudes per crear una persona. Augmentar aquest valor fa que el reconeixement facial sigui més precís, però augmenta la possibilitat que una cara no sigui assignada a una persona.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Fes servir machine learning per reconèixer text a imatges",
"machine_learning_ocr_enabled": "Activar OCR",
"machine_learning_ocr_enabled_description": "Si està desactivat, les imatges no seran objecte de reconeixement de text.",
"machine_learning_ocr_max_resolution": "Màxima resolució",
"machine_learning_ocr_max_resolution_description": "Vista prèvia per sobre d'aquesta resolució serà reescalada per preservar la relació d'aspecte. Resolucions altes són més precises, però triguen més i gasten més memòria.",
"machine_learning_ocr_min_detection_score": "Puntuació mínima de detecció",
"machine_learning_ocr_min_detection_score_description": "Puntuació de mínima confiança per la detecció del text entre 0-1. Valors baixos detectaran més text pero pot donar falsos positius.",
"machine_learning_ocr_min_recognition_score": "Puntuació mínima de reconeixement",
"machine_learning_ocr_min_score_recognition_description": "Puntuació de confiança mínima pel reconeixement del text entre 0-1. Valors baixos reconeixen més text però pot donar falsos positius.",
"machine_learning_ocr_model": "Model OCR",
"machine_learning_ocr_model_description": "Models de servidor són més precisos que els de móbil, pero triguen més a processar i usen més memòria.",
"machine_learning_settings": "Configuració d'aprenentatge automàtic",
"machine_learning_settings_description": "Gestiona funcions i configuració d'aprenentatge automàtic",
"machine_learning_smart_search": "Cerca intel·ligent",
@@ -211,6 +222,8 @@
"notification_email_ignore_certificate_errors_description": "Ignora els errors de validació de certificat TLS (no recomanat)",
"notification_email_password_description": "Contrasenya per a autenticar-se amb el servidor de correu electrònic",
"notification_email_port_description": "Port del servidor de correu electrònic (p.ex. 25, 465 o 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Fes servir SMTPS (SMTP sobre TLS)",
"notification_email_sent_test_email_button": "Envia correu de prova i desa",
"notification_email_setting_description": "Configuració per l'enviament de notificacions per correu electrònic",
"notification_email_test_email": "Envia correu de prova",
@@ -243,6 +256,7 @@
"oauth_storage_quota_default_description": "Quota disponible en GB quan no s'estableixi cap valor (Entreu 0 per a quota il·limitada).",
"oauth_timeout": "Solicitud caducada",
"oauth_timeout_description": "Timeout per a sol·licituds en mil·lisegons",
"ocr_job_description": "Fes servir machine learning per reconèixer text a les imatges",
"password_enable_description": "Inicia sessió amb correu electrònic i contrasenya",
"password_settings": "Inici de sessió amb contrasenya",
"password_settings_description": "Gestiona la configuració de l'inici de sessió amb contrasenya",
@@ -333,7 +347,7 @@
"transcoding_max_b_frames": "Nombre màxim de B-frames",
"transcoding_max_b_frames_description": "Els valors més alts milloren l'eficiència de la compressió, però alenteixen la codificació. És possible que no sigui compatible amb l'acceleració de maquinari en dispositius antics. 0 desactiva els B-frames, mentre que -1 estableix aquest valor automàticament.",
"transcoding_max_bitrate": "Taxa de bits màxima",
"transcoding_max_bitrate_description": "Establir una taxa de bits màxima pot fer que les mides dels fitxers siguin més previsibles amb un cost menor per a la qualitat. A 720p, els valors típics són 2600 kbit/s per a VP9 o HEVC, o 4500 kbit/s per a H.264. Desactivat si s'estableix a 0.",
"transcoding_max_bitrate_description": "Establir una taxa de bits màxima pot fer que les mides dels fitxers siguin més previsibles amb un cost menor per a la qualitat. A 720p, els valors típics són 2600 kbit/s per a VP9 o HEVC, o 4500 kbit/s per a H.264. Desactivat si s'estableix a 0. Quan no s'especifica, s'assumeix kbit/s; per tant 5000 i 5000k i 5M son equivalents.",
"transcoding_max_keyframe_interval": "Interval màxim de fotogrames clau",
"transcoding_max_keyframe_interval_description": "Estableix la distància màxima entre fotogrames clau. Els valors més baixos empitjoren l'eficiència de la compressió, però milloren els temps de cerca i poden millorar la qualitat en escenes amb moviment ràpid. 0 estableix aquest valor automàticament.",
"transcoding_optimal_description": "Vídeos superiors a la resolució objectiu o que no tenen un format acceptat",
@@ -351,7 +365,7 @@
"transcoding_target_resolution": "Resolució objectiu",
"transcoding_target_resolution_description": "Les resolucions més altes poden conservar més detalls, però triguen més temps a codificar-se, tenen mides de fitxer més grans i poden reduir la capacitat de resposta de l'aplicació.",
"transcoding_temporal_aq": "AQ temporal",
"transcoding_temporal_aq_description": "S'aplica només a NVENC. Augmenta la qualitat de les escenes de baix moviment i alt detall. És possible que no sigui compatible amb dispositius antics.",
"transcoding_temporal_aq_description": "S'aplica només a NVENC. Quantització adaptativa temporal augmenta la qualitat de les escenes de baix moviment i alt detall. És possible que no sigui compatible amb dispositius antics.",
"transcoding_threads": "Fils",
"transcoding_threads_description": "Els valors més alts condueixen a una codificació més ràpida, però deixen menys espai perquè el servidor processi altres tasques mentre està actiu. Aquest valor no hauria de ser superior al nombre de nuclis de CPU. Maximitza la utilització si s'estableix a 0.",
"transcoding_tone_mapping": "Mapeig de to",
@@ -402,11 +416,11 @@
"advanced_settings_prefer_remote_subtitle": "Alguns dispositius són molt lents en carregar miniatures dels elements locals. Activeu aquest paràmetre per carregar imatges remotes en el seu lloc.",
"advanced_settings_prefer_remote_title": "Prefereix imatges remotes",
"advanced_settings_proxy_headers_subtitle": "Definiu les capçaleres de proxy que Immich per enviar amb cada sol·licitud de xarxa",
"advanced_settings_proxy_headers_title": "Capçaleres de proxy",
"advanced_settings_proxy_headers_title": "Capçaleres de proxy particulars [EXPERIMENTAL]",
"advanced_settings_readonly_mode_subtitle": "Habilita el només de lectura mode on les fotos poden ser només vist, a coses els agrada seleccionant imatges múltiples, compartint, càsting, elimina és tot discapacitat. Habilita/Desactiva només de lectura via avatar d'usuari des de la pantalla major",
"advanced_settings_readonly_mode_title": "Mode de només lectura",
"advanced_settings_self_signed_ssl_subtitle": "Omet la verificació del certificat SSL del servidor. Requerit per a certificats autosignats.",
"advanced_settings_self_signed_ssl_title": "Permet certificats SSL autosignats",
"advanced_settings_self_signed_ssl_title": "Permet certificats SSL autosignats [EXPERIMENTAL]",
"advanced_settings_sync_remote_deletions_subtitle": "Suprimeix o restaura automàticament un actiu en aquest dispositiu quan es realitzi aquesta acció al web",
"advanced_settings_sync_remote_deletions_title": "Sincronitza les eliminacions remotes",
"advanced_settings_tile_subtitle": "Configuració avançada de l'usuari",
@@ -415,6 +429,7 @@
"age_months": "{months, plural, one {# mes} other {# mesos}}",
"age_year_months": "Un any i {months, plural, one {# mes} other {# mesos}}",
"age_years": "{years, plural, one {# any} other {# anys}}",
"album": "Àlbum",
"album_added": "Àlbum afegit",
"album_added_notification_setting_description": "Rep una notificació per correu quan siguis afegit a un àlbum compartit",
"album_cover_updated": "Portada de l'àlbum actualitzada",
@@ -460,16 +475,21 @@
"allow_edits": "Permet editar",
"allow_public_user_to_download": "Permet que l'usuari públic pugui descarregar",
"allow_public_user_to_upload": "Permet que l'usuari públic pugui carregar",
"allowed": "Permès",
"alt_text_qr_code": "Codi QR",
"anti_clockwise": "En sentit antihorari",
"api_key": "Clau API",
"api_key_description": "Aquest valor només es mostrarà una vegada. Assegureu-vos de copiar-lo abans de tancar la finestra.",
"api_key_empty": "El nom de la clau de l'API no pot estar buit",
"api_keys": "Claus API",
"app_architecture_variant": "Variant (Arquitectura)",
"app_bar_signout_dialog_content": "Estàs segur que vols tancar la sessió?",
"app_bar_signout_dialog_ok": "Sí",
"app_bar_signout_dialog_title": "Tanca la sessió",
"app_download_links": "App descarrega enllaços",
"app_settings": "Configuració de l'app",
"app_stores": "Botiga App",
"app_update_available": "Actualització App disponible",
"appears_in": "Apareix a",
"apply_count": "Aplicar ({count, number})",
"archive": "Arxiu",
@@ -553,6 +573,7 @@
"backup_albums_sync": "Sincronització d'àlbums de còpia de seguretat",
"backup_all": "Tots",
"backup_background_service_backup_failed_message": "No s'ha pogut copiar els elements. Tornant a intentar…",
"backup_background_service_complete_notification": "Backup completat d'actius",
"backup_background_service_connection_failed_message": "No s'ha pogut connectar al servidor. Tornant a intentar…",
"backup_background_service_current_upload_notification": "Pujant {filename}",
"backup_background_service_default_notification": "Cercant nous elements…",
@@ -621,7 +642,7 @@
"bugs_and_feature_requests": "Errors i sol·licituds de funcions",
"build": "Construeix",
"build_image": "Construeix la imatge",
"bulk_delete_duplicates_confirmation": "Esteu segur que voleu suprimir de manera massiva {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això mantindrà el recurs més gran de cada grup i esborrarà permanentment tots els altres duplicats. No podeu desfer aquesta acció!",
"bulk_delete_duplicates_confirmation": "Esteu segurs que voleu suprimir de manera massiva {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això mantindrà el recurs més gran de cada grup i esborrarà permanentment tots els altres duplicats. No podeu desfer aquesta acció!",
"bulk_keep_duplicates_confirmation": "Esteu segur que voleu mantenir {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això resoldrà tots els grups duplicats sense eliminar res.",
"bulk_trash_duplicates_confirmation": "Esteu segur que voleu enviar a les escombraries {count, plural, one {# recurs duplicat} other {# recursos duplicats}}? Això mantindrà el recurs més gran de cada grup i eliminarà la resta de duplicats.",
"buy": "Comprar Immich",
@@ -662,6 +683,8 @@
"change_password_description": "Aquesta és la primera vegada que inicieu la sessió al sistema o s'ha fet una sol·licitud per canviar la contrasenya. Introduïu la nova contrasenya a continuació.",
"change_password_form_confirm_password": "Confirma la contrasenya",
"change_password_form_description": "Hola {name},\n\nAquesta és la primera vegada que inicies sessió al sistema o bé s'ha sol·licitat canviar la teva contrasenya. Si us plau, introdueix la nova contrasenya a continuació.",
"change_password_form_log_out": "Fer fora de tots els altres dispositius",
"change_password_form_log_out_description": "Es recomana fer fora de tots els altres dispositius",
"change_password_form_new_password": "Nova contrasenya",
"change_password_form_password_mismatch": "Les contrasenyes no coincideixen",
"change_password_form_reenter_new_password": "Torna a introduir la nova contrasenya",
@@ -701,7 +724,6 @@
"comments_and_likes": "Comentaris i agradaments",
"comments_are_disabled": "Els comentaris estan desactivats",
"common_create_new_album": "Crea un àlbum nou",
"common_server_error": "Si us plau, comproveu la vostra connexió de xarxa, assegureu-vos que el servidor és accessible i que les versions de l'aplicació i del servidor són compatibles.",
"completed": "Completat",
"confirm": "Confirmar",
"confirm_admin_password": "Confirmeu la contrasenya d'administrador",
@@ -740,6 +762,7 @@
"create": "Crea",
"create_album": "Crear un àlbum",
"create_album_page_untitled": "Sense títol",
"create_api_key": "Crear clau API",
"create_library": "Crea una llibreria",
"create_link": "Crear enllaç",
"create_link_to_share": "Crear enllaç per compartir",
@@ -769,6 +792,7 @@
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Fosc",
"dark_theme": "Canviar a tema fosc",
"date": "Data",
"date_after": "Data posterior a",
"date_and_time": "Data i hora",
"date_before": "Data anterior a",
@@ -784,7 +808,7 @@
"deduplication_info_description": "Per preseleccionar recursos automàticament i eliminar els duplicats de manera massiva, ens fixem en:",
"default_locale": "Localització predeterminada",
"default_locale_description": "Format de dates i números segons la configuració del navegador",
"delete": "Esborra",
"delete": "Esborrar",
"delete_action_confirmation_message": "Segur que vols eliminar aquest recurs? Aquesta acció el mourà a la paperera del servidor, i et preguntarà si el vols eliminar localment",
"delete_action_prompt": "{count} eliminats",
"delete_album": "Esborra l'àlbum",
@@ -871,8 +895,6 @@
"edit_description_prompt": "Si us plau, selecciona una nova descripció:",
"edit_exclusion_pattern": "Edita patró d'exclusió",
"edit_faces": "Edita les cares",
"edit_import_path": "Edita la ruta d'importació",
"edit_import_paths": "Edita les rutes d'importació",
"edit_key": "Edita clau",
"edit_link": "Edita enllaç",
"edit_location": "Edita ubicació",
@@ -883,7 +905,6 @@
"edit_tag": "Editar etiqueta",
"edit_title": "Edita títol",
"edit_user": "Edita l'usuari",
"edited": "Editat",
"editor": "Editor",
"editor_close_without_save_prompt": "No es desaran els canvis",
"editor_close_without_save_title": "Tancar l'editor?",
@@ -945,7 +966,6 @@
"failed_to_stack_assets": "No s'han pogut apilar els elements",
"failed_to_unstack_assets": "No s'han pogut desapilar els elements",
"failed_to_update_notification_status": "Error en actualitzar l'estat de les notificacions",
"import_path_already_exists": "Aquesta ruta d'importació ja existeix.",
"incorrect_email_or_password": "Correu electrònic o contrasenya incorrectes",
"paths_validation_failed": "{paths, plural, one {# ruta} other {# rutes}} no ha pogut validar",
"profile_picture_transparent_pixels": "Les fotos de perfil no poden tenir píxels transparents. Per favor, feu zoom in, mogueu la imatge o ambdues.",
@@ -955,7 +975,6 @@
"unable_to_add_assets_to_shared_link": "No s'han pogut afegir els elements a l'enllaç compartit",
"unable_to_add_comment": "No es pot afegir el comentari",
"unable_to_add_exclusion_pattern": "No s'ha pogut afegir el patró dexclusió",
"unable_to_add_import_path": "No s'ha pogut afegir la ruta d'importació",
"unable_to_add_partners": "No es poden afegir companys",
"unable_to_add_remove_archive": "No s'ha pogut {archived, select, true {eliminar l'element de} other {afegir l'element a}} l'arxiu",
"unable_to_add_remove_favorites": "No s'ha pogut {favorite, select, true {afegir l'element als} other {eliminar l'element dels}} preferits",
@@ -978,12 +997,10 @@
"unable_to_delete_asset": "No es pot suprimir el recurs",
"unable_to_delete_assets": "S'ha produït un error en suprimir recursos",
"unable_to_delete_exclusion_pattern": "No es pot suprimir el patró d'exclusió",
"unable_to_delete_import_path": "No es pot suprimir la ruta d'importació",
"unable_to_delete_shared_link": "No es pot suprimir l'enllaç compartit",
"unable_to_delete_user": "No es pot eliminar l'usuari",
"unable_to_download_files": "No es poden descarregar fitxers",
"unable_to_edit_exclusion_pattern": "No es pot editar el patró d'exclusió",
"unable_to_edit_import_path": "No es pot editar la ruta d'importació",
"unable_to_empty_trash": "No es pot buidar la paperera",
"unable_to_enter_fullscreen": "No es pot entrar a la pantalla completa",
"unable_to_exit_fullscreen": "No es pot sortir de la pantalla completa",
@@ -1039,6 +1056,7 @@
"exif_bottom_sheet_description_error": "No s'ha pogut actualitzar la descripció",
"exif_bottom_sheet_details": "DETALLS",
"exif_bottom_sheet_location": "UBICACIÓ",
"exif_bottom_sheet_no_description": "Sense descrioció",
"exif_bottom_sheet_people": "PERSONES",
"exif_bottom_sheet_person_add_person": "Afegir nom",
"exit_slideshow": "Surt de la presentació de diapositives",
@@ -1077,6 +1095,7 @@
"features_setting_description": "Administrar les funcions de l'aplicació",
"file_name": "Nom de l'arxiu",
"file_name_or_extension": "Nom de l'arxiu o extensió",
"file_size": "Mida del fitxer",
"filename": "Nom del fitxer",
"filetype": "Tipus d'arxiu",
"filter": "Filtrar",
@@ -1120,7 +1139,6 @@
"header_settings_field_validator_msg": "El valor no pot estar buit",
"header_settings_header_name_input": "Nom de la capçalera",
"header_settings_header_value_input": "Valor de la capçalera",
"headers_settings_tile_subtitle": "Definiu les capçaleres de proxy que l'aplicació hauria d'enviar amb cada sol·licitud de xarxa",
"headers_settings_tile_title": "Capçaleres proxy personalitzades",
"hi_user": "Hola {name} ({email})",
"hide_all_people": "Amaga totes les persones",
@@ -1173,6 +1191,8 @@
"import_path": "Ruta d'importació",
"in_albums": "A {count, plural, one {# àlbum} other {# àlbums}}",
"in_archive": "En arxiu",
"in_year": "En {year}",
"in_year_selector": "En",
"include_archived": "Incloure arxivats",
"include_shared_albums": "Inclou àlbums compartits",
"include_shared_partner_assets": "Incloure elements dels companys",
@@ -1209,6 +1229,7 @@
"language_setting_description": "Seleccioneu el vostre idioma",
"large_files": "Fitxers Grans",
"last": "Últim",
"last_months": "{count, plural, one {Últim mes} other {Últims # mesos}}",
"last_seen": "Vist per últim cop",
"latest_version": "Última versió",
"latitude": "Latitud",
@@ -1241,6 +1262,7 @@
"local_media_summary": "Resum de Mitjans Locals",
"local_network": "Xarxa local",
"local_network_sheet_info": "L'aplicació es connectarà al servidor mitjançant aquest URL quan utilitzeu la xarxa Wi-Fi especificada",
"location": "Localització",
"location_permission": "Permís d'ubicació",
"location_permission_content": "Per utilitzar la funció de canvi automàtic, Immich necessita un permís d'ubicació precisa perquè pugui llegir el nom de la xarxa Wi-Fi actual",
"location_picker_choose_on_map": "Escollir en el mapa",
@@ -1290,6 +1312,10 @@
"main_menu": "Menú principal",
"make": "Fabricant",
"manage_geolocation": "Gestioneu la vostra ubicació",
"manage_media_access_rationale": "Aquest permís es necessari per a la correcta gestió dels actius que es mouen a la paperera i es restauren d'ella.",
"manage_media_access_settings": "Configuració oberta",
"manage_media_access_subtitle": "Permet a l'Immich gestionar i moure fitxers multimèdia.",
"manage_media_access_title": "Accés a la gestió de mitjans",
"manage_shared_links": "Administrar enllaços compartits",
"manage_sharing_with_partners": "Gestiona la compartició amb els companys",
"manage_the_app_settings": "Gestioneu la configuració de l'aplicació",
@@ -1345,12 +1371,15 @@
"minute": "Minut",
"minutes": "Minuts",
"missing": "Restants",
"mobile_app": "Aplicació mòbil",
"mobile_app_download_onboarding_note": "Descarregar la App de mòbil fent servir les seguents opcions",
"model": "Model",
"month": "Mes",
"monthly_title_text_date_format": "MMMM y",
"more": "Més",
"move": "Moure",
"move_off_locked_folder": "Moure fora de la carpeta bloquejada",
"move_to": "Moure a",
"move_to_lock_folder_action_prompt": "{count} afegides a la carpeta protegida",
"move_to_locked_folder": "Moure a la carpeta bloquejada",
"move_to_locked_folder_confirmation": "Aquestes fotos i vídeos seran eliminades de tots els àlbums, i només podran ser vistes des de la carpeta bloquejada",
@@ -1363,6 +1392,8 @@
"my_albums": "Els meus àlbums",
"name": "Nom",
"name_or_nickname": "Nom o sobrenom",
"navigate": "Navegar",
"navigate_to_time": "Navegar a un punt en el temps",
"network_requirement_photos_upload": "Fes servir dades mòbils per a còpies de seguretat de fotos",
"network_requirement_videos_upload": "Fes servir dades mòbils per a còpies de seguretat de videos",
"network_requirements": "Requeriments de Xarxa",
@@ -1372,11 +1403,13 @@
"never": "Mai",
"new_album": "Nou Àlbum",
"new_api_key": "Nova clau de l'API",
"new_date_range": "Navegar a un reng de dates",
"new_password": "Nova contrasenya",
"new_person": "Persona nova",
"new_pin_code": "Nou codi PIN",
"new_pin_code_subtitle": "Aquesta és la primera vegada que accedeixes a la carpeta bloquejada. Crea una codi PIN i accedeix de manera segura a aquesta pàgina",
"new_timeline": "Nova Línia de Temps",
"new_update": "Nova actualització",
"new_user_created": "Nou usuari creat",
"new_version_available": "NOVA VERSIÓ DISPONIBLE",
"newest_first": "El més nou primer",
@@ -1392,6 +1425,7 @@
"no_cast_devices_found": "No s'han trobat dispositius per transmetre",
"no_checksum_local": "Cap checksum disponible - no s'han pogut carregar els recursos locals",
"no_checksum_remote": "Cap checksum disponible - no s'ha pogut obtenir el recurs remot",
"no_devices": "No hi ha dispositius autoritzats",
"no_duplicates_found": "No s'han trobat duplicats.",
"no_exif_info_available": "No hi ha informació d'exif disponible",
"no_explore_results_message": "Penja més fotos per explorar la teva col·lecció.",
@@ -1408,6 +1442,7 @@
"no_results_description": "Proveu un sinònim o una paraula clau més general",
"no_shared_albums_message": "Creeu un àlbum per compartir fotos i vídeos amb persones a la vostra xarxa",
"no_uploads_in_progress": "Cap pujada en progrés",
"not_allowed": "No permès",
"not_available": "N/A",
"not_in_any_album": "En cap àlbum",
"not_selected": "No seleccionat",
@@ -1422,6 +1457,9 @@
"notifications": "Notificacions",
"notifications_setting_description": "Gestiona les notificacions",
"oauth": "OAuth",
"obtainium_configurator": "Configurador Obtainium",
"obtainium_configurator_instructions": "Utilitza Obtainium per instal·lar una actualització a la app directament des de Github-Immich. Crear una clau API i seleccionar una variant per crear un enllaç a la configuració Obtainium",
"ocr": "OCR",
"official_immich_resources": "Recursos oficials d'Immich",
"offline": "Fora de línia",
"offset": "Diferència",
@@ -1515,6 +1553,8 @@
"photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}",
"photos_from_previous_years": "Fotos d'anys anteriors",
"pick_a_location": "Triar una ubicació",
"pick_custom_range": "Rang personalitzat",
"pick_date_range": "Seleccioni un rang de dates",
"pin_code_changed_successfully": "Codi PIN canviat correctament",
"pin_code_reset_successfully": "S'ha restablert correctament el codi PIN",
"pin_code_setup_successfully": "S'ha configurat correctament un codi PIN",
@@ -1526,6 +1566,9 @@
"play_memories": "Reproduir records",
"play_motion_photo": "Reproduir Fotos en Moviment",
"play_or_pause_video": "Reproduir o posar en pausa el vídeo",
"play_original_video": "Veure el video original",
"play_original_video_setting_description": "Preferir la reproducció del video original sobre el video recodificat. Si el video original no es compatible potser no es reprodueixi correctament.",
"play_transcoded_video": "Veure el video recodificat",
"please_auth_to_access": "Per favor, autentica't per accedir",
"port": "Port",
"preferences_settings_subtitle": "Gestiona les preferències de l'aplicació",
@@ -1543,13 +1586,9 @@
"privacy": "Privacitat",
"profile": "Perfil",
"profile_drawer_app_logs": "Registres",
"profile_drawer_client_out_of_date_major": "L'aplicació mòbil està desactualitzada. Si us plau, actualitzeu a l'última versió major.",
"profile_drawer_client_out_of_date_minor": "L'aplicació mòbil està desactualitzada. Si us plau, actualitzeu a l'última versió menor.",
"profile_drawer_client_server_up_to_date": "El client i el servidor estan actualitzats",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Mode només lectura. Feu pulsació llarga a la icona de l'avatar d'usuari per sortir.",
"profile_drawer_server_out_of_date_major": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió major.",
"profile_drawer_server_out_of_date_minor": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió menor.",
"profile_image_of_user": "Imatge de perfil de {user}",
"profile_picture_set": "Imatge de perfil configurada.",
"public_album": "Àlbum públic",
@@ -1666,6 +1705,7 @@
"reset_sqlite_confirmation": "Segur que vols reiniciar la base de dades SQLite? Hauràs de tancar la sessió i tornar a accedir per a resincronitzar les dades",
"reset_sqlite_success": "S'ha reiniciat la base de dades correctament",
"reset_to_default": "Restableix els valors predeterminats",
"resolution": "Resolució",
"resolve_duplicates": "Resoldre duplicats",
"resolved_all_duplicates": "Tots els duplicats resolts",
"restore": "Recupera",
@@ -1684,6 +1724,7 @@
"running": "En execució",
"save": "Desa",
"save_to_gallery": "Desa a galeria",
"saved": "Guardat",
"saved_api_key": "Clau d'API guardada",
"saved_profile": "Perfil guardat",
"saved_settings": "Configuració guardada",
@@ -1700,6 +1741,9 @@
"search_by_description_example": "Jornada de senderisme a Sapa",
"search_by_filename": "Cerca per nom de fitxer o extensió",
"search_by_filename_example": "per exemple IMG_1234.JPG o PNG",
"search_by_ocr": "Buscar per OCR",
"search_by_ocr_example": "Després",
"search_camera_lens_model": "Buscar model de lents....",
"search_camera_make": "Buscar per fabricant de càmara...",
"search_camera_model": "Buscar per model de càmera...",
"search_city": "Buscar per ciutat...",
@@ -1716,6 +1760,7 @@
"search_filter_location_title": "Selecciona l'ubicació",
"search_filter_media_type": "Tipus de multimèdia",
"search_filter_media_type_title": "Selecciona tipus de multimèdia",
"search_filter_ocr": "Buscar per OCR",
"search_filter_people_title": "Selecciona persones",
"search_for": "Cercar",
"search_for_existing_person": "Busca una persona existent",
@@ -1778,6 +1823,7 @@
"server_online": "Servidor en línia",
"server_privacy": "Privadesa del servidor",
"server_stats": "Estadístiques del servidor",
"server_update_available": "Actualització del servidor disponible",
"server_version": "Versió del servidor",
"set": "Establir",
"set_as_album_cover": "Establir com a portada de l'àlbum",
@@ -1806,6 +1852,8 @@
"setting_notifications_subtitle": "Ajusta les preferències de notificació",
"setting_notifications_total_progress_subtitle": "Progrés general de la pujada (elements completats/total)",
"setting_notifications_total_progress_title": "Mostra el progrés total de la còpia de seguretat en segon pla",
"setting_video_viewer_auto_play_subtitle": "Comença a veure videos quan s'obrin",
"setting_video_viewer_auto_play_title": "Veure videos automàticament",
"setting_video_viewer_looping_title": "Bucle",
"setting_video_viewer_original_video_subtitle": "Quan reproduïu un vídeo des del servidor, reproduïu l'original encara que hi hagi una transcodificació disponible. Pot conduir a l'amortització. Els vídeos disponibles localment es reprodueixen en qualitat original independentment d'aquesta configuració.",
"setting_video_viewer_original_video_title": "Força el vídeo original",
@@ -1813,7 +1861,7 @@
"settings_require_restart": "Si us plau, reinicieu Immich per a aplicar aquest canvi",
"settings_saved": "Configuració desada",
"setup_pin_code": "Configurar un codi PIN",
"share": "Comparteix",
"share": "Compartir",
"share_action_prompt": "Compartits {count} recursos",
"share_add_photos": "Afegeix fotografies",
"share_assets_selected": "{count} seleccionats",
@@ -1985,7 +2033,9 @@
"theme_setting_three_stage_loading_title": "Activa la càrrega en tres etapes",
"they_will_be_merged_together": "Es combinaran",
"third_party_resources": "Recursos de tercers",
"time": "Temps",
"time_based_memories": "Records basats en el temps",
"time_based_memories_duration": "Quants segons es mostrarà cada imatge.",
"timeline": "Cronologia",
"timezone": "Fus horari",
"to_archive": "Arxivar",
@@ -2017,6 +2067,7 @@
"troubleshoot": "Solució de problemes",
"type": "Tipus",
"unable_to_change_pin_code": "No es pot canviar el codi PIN",
"unable_to_check_version": "No es pot comprovar la versió de l'aplicació ni del servidor",
"unable_to_setup_pin_code": "No s'ha pogut configurar el codi PIN",
"unarchive": "Desarxivar",
"unarchive_action_prompt": "{count} eliminades de l'arxiu",
@@ -2125,6 +2176,7 @@
"welcome": "Benvingut",
"welcome_to_immich": "Benvingut a immich",
"wifi_name": "Nom Wi-Fi",
"workflow": "Flux de treball",
"wrong_pin_code": "Codi PIN incorrecte",
"year": "Any",
"years_ago": "Fa {years, plural, one {# any} other {# anys}}",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Přidat datum narození",
"add_endpoint": "Přidat koncový bod",
"add_exclusion_pattern": "Přidat vzor vyloučení",
"add_import_path": "Přidat cestu importu",
"add_location": "Přidat polohu",
"add_more_users": "Přidat další uživatele",
"add_partner": "Přidat partnera",
@@ -32,6 +31,7 @@
"add_to_album_toggle": "Přepnout výběr pro {album}",
"add_to_albums": "Přidat do alb",
"add_to_albums_count": "Přidat do alb ({count})",
"add_to_bottom_bar": "Přidat do",
"add_to_shared_album": "Přidat do sdíleného alba",
"add_upload_to_stack": "Přidat nahrané do zásobníku",
"add_url": "Přidat URL",
@@ -112,15 +112,19 @@
"jobs_failed": "{jobCount, plural, one {# neúspěšný} few {# neúspěšné} other {# neúspěšných}}",
"library_created": "Vytvořena knihovna: {library}",
"library_deleted": "Knihovna smazána",
"library_import_path_description": "Zadejte složku, kterou chcete importovat. Tato složka bude prohledána včetně podsložek a budou v ní hledány obrázky a videa.",
"library_details": "Podrobnosti o knihovně",
"library_folder_description": "Zadejte složku, kterou chcete importovat. Tato složka, včetně podsložek, bude prohledána pro obrázky a videa.",
"library_remove_exclusion_pattern_prompt": "Opravdu chcete odstranit tento vzor vyloučení?",
"library_remove_folder_prompt": "Opravdu chcete odstranit tuto složku importu?",
"library_scanning": "Pravidelné prohledávání",
"library_scanning_description": "Nastavení pravidelného prohledávání knihovny",
"library_scanning_enable_description": "Povolit pravidelné prohledávání knihovny",
"library_settings": "Externí knihovna",
"library_settings_description": "Správa nastavení externí knihovny",
"library_tasks_description": "Vyhledávání nových nebo změněných položek v externích knihovnách",
"library_updated": "Knihovna aktualizována",
"library_watching_enable_description": "Sledovat změny souborů v externích knihovnách",
"library_watching_settings": "Sledování knihovny (EXPERIMENTÁLNÍ)",
"library_watching_settings": "Sledování knihovny [EXPERIMENTÁLNÍ]",
"library_watching_settings_description": "Automatické sledování změněných souborů",
"logging_enable_description": "Povolit protokolování",
"logging_level_description": "Když je povoleno, jakou úroveň protokolu použít.",
@@ -154,6 +158,18 @@
"machine_learning_min_detection_score_description": "Minimální skóre důvěryhodnosti pro detekci obličeje od 0 do 1. Nižší hodnoty odhalí více tváří, ale mohou vést k falešně pozitivním výsledkům.",
"machine_learning_min_recognized_faces": "Mininum rozpoznaných obličejů",
"machine_learning_min_recognized_faces_description": "Minimální počet rozpoznaných obličejů pro vytvoření osoby. Zvýšení tohoto počtu zpřesňuje rozpoznávání obličejů za cenu zvýšení pravděpodobnosti, že obličej nebude přiřazen k osobě.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Použijte strojové učení k rozpoznávání textu v obrázcích",
"machine_learning_ocr_enabled": "Povolit OCR",
"machine_learning_ocr_enabled_description": "Pokud je tato funkce vypnuta, obrázky nebudou podrobeny rozpoznávání textu.",
"machine_learning_ocr_max_resolution": "Maximální rozlišení",
"machine_learning_ocr_max_resolution_description": "Náhledy nad tímto rozlišením budou změněny tak, aby byl zachován poměr stran. Vyšší hodnoty jsou přesnější, ale jejich zpracování trvá déle a zabírají více paměti.",
"machine_learning_ocr_min_detection_score": "Minimální detekční skóre",
"machine_learning_ocr_min_detection_score_description": "Minimální skóre spolehlivosti pro detekci textu v rozmezí 01. Nižší hodnoty detekují více textu, ale mohou vést k falešným pozitivním výsledkům.",
"machine_learning_ocr_min_recognition_score": "Minimální počet bodů pro rozpoznání",
"machine_learning_ocr_min_score_recognition_description": "Minimální skóre spolehlivosti pro rozpoznání detekovaného textu v rozmezí 01. Nižší hodnoty rozpoznají více textu, ale mohou vést k falešným pozitivům.",
"machine_learning_ocr_model": "OCR model",
"machine_learning_ocr_model_description": "Serverové modely jsou přesnější než mobilní modely, ale jejich zpracování trvá déle a zabírají více paměti.",
"machine_learning_settings": "Strojové učení",
"machine_learning_settings_description": "Správa funkcí a nastavení strojového učení",
"machine_learning_smart_search": "Chytré vyhledávání",
@@ -161,6 +177,10 @@
"machine_learning_smart_search_enabled": "Povolit chytré vyhledávání",
"machine_learning_smart_search_enabled_description": "Pokud je vypnuto, obrázky nebudou kódovány pro inteligentní vyhledávání.",
"machine_learning_url_description": "URL serveru strojového učení. Pokud je zadáno více URL adres, budou jednotlivé servery zkoušeny postupně, dokud jeden z nich neodpoví úspěšně, a to v pořadí od prvního k poslednímu. Servery, které neodpoví, budou dočasně ignorovány, dokud nebudou opět online.",
"maintenance_settings": "Údržba",
"maintenance_settings_description": "Přepnout Immich do režimu údržby.",
"maintenance_start": "Zahájit režim údržby",
"maintenance_start_error": "Nepodařilo se zahájit režim údržby.",
"manage_concurrency": "Správa souběžnosti",
"manage_log_settings": "Správa nastavení protokolu",
"map_dark_style": "Tmavý motiv",
@@ -211,6 +231,8 @@
"notification_email_ignore_certificate_errors_description": "Ignorovat chyby ověření certifikátu TLS (nedoporučuje se)",
"notification_email_password_description": "Heslo pro ověření na e-mailovém serveru",
"notification_email_port_description": "Port e-mailového serveru (např. 25, 465 nebo 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Používat SMTPS (SMTP přes TLS)",
"notification_email_sent_test_email_button": "Odeslat testovací e-mail a uložit",
"notification_email_setting_description": "Nastavení pro zasílání e-mailových oznámení",
"notification_email_test_email": "Odeslat testovací e-mail",
@@ -243,6 +265,7 @@
"oauth_storage_quota_default_description": "Kvóta v GiB, která se použije, pokud není poskytnuta žádná deklarace.",
"oauth_timeout": "Časový limit požadavku",
"oauth_timeout_description": "Časový limit pro požadavky v milisekundách",
"ocr_job_description": "Použijte strojové učení k rozpoznávání textu v obrázcích",
"password_enable_description": "Přihlášení pomocí e-mailu a hesla",
"password_settings": "Přihlášení heslem",
"password_settings_description": "Správa nastavení přihlašování pomocí hesla",
@@ -333,7 +356,7 @@
"transcoding_max_b_frames": "Maximální počet B-snímků",
"transcoding_max_b_frames_description": "Vyšší hodnoty zvyšují účinnost komprese, ale zpomalují kódování. Nemusí být kompatibilní s hardwarovou akcelerací na starších zařízeních. Hodnota 0 zakáže B-snímky, zatímco -1 tuto hodnotu nastaví automaticky.",
"transcoding_max_bitrate": "Maximální datový tok",
"transcoding_max_bitrate_description": "Nastavení maximálního datového toku může zvýšit předvídatelnost velikosti souborů za cenu menší újmy na kvalitě. Při rozlišení 720p jsou typické hodnoty 2600 kbit/s pro VP9 nebo HEVC nebo 4500 kbit/s pro H.264. Je zakázáno, pokud je nastavena hodnota 0.",
"transcoding_max_bitrate_description": "Nastavení maximálního datového toku může zvýšit předvídatelnost velikosti souborů za cenu menší újmy na kvalitě. Při rozlišení 720p jsou typické hodnoty 2600 kbit/s pro VP9 nebo HEVC nebo 4500 kbit/s pro H.264. Pokud je nastaveno na 0, je zakázáno. Pokud není zadána žádná jednotka, předpokládá se k (pro kbit/s); proto jsou 5000, 5000k a 5M (pro Mbit/s) ekvivalentní.",
"transcoding_max_keyframe_interval": "Maximální interval klíčových snímků",
"transcoding_max_keyframe_interval_description": "Nastavuje maximální vzdálenost mezi klíčovými snímky. Nižší hodnoty zhoršují účinnost komprese, ale zlepšují rychlost při přeskakování a mohou zlepšit kvalitu ve scénách s rychlým pohybem. Hodnota 0 nastavuje tuto hodnotu automaticky.",
"transcoding_optimal_description": "Videa s vyšším než cílovým rozlišením nebo videa, která nejsou v akceptovaném formátu",
@@ -351,7 +374,7 @@
"transcoding_target_resolution": "Cílové rozlišení",
"transcoding_target_resolution_description": "Vyšší rozlišení mohou zachovat více detailů, ale jejich kódování trvá déle, mají větší velikost souboru a mohou snížit odezvu aplikace.",
"transcoding_temporal_aq": "Časové AQ",
"transcoding_temporal_aq_description": "Platí pouze pro NVENC. Zvyšuje kvalitu scén s vysokým počtem detailů a malým počtem pohybů. Nemusí být kompatibilní se staršími zařízeními.",
"transcoding_temporal_aq_description": "Platí pouze pro NVENC. Časová adaptivní kvantizace zvyšuje kvalitu scén s vysokým rozlišením a malým pohybem. Nemusí být kompatibilní se staršími zařízeními.",
"transcoding_threads": "Vlákna",
"transcoding_threads_description": "Vyšší hodnoty vedou k rychlejšímu kódování, ale ponechávají serveru méně prostoru pro zpracování jiných úloh. Tato hodnota by neměla být vyšší než počet jader procesoru. Maximalizuje využití, pokud je nastavena na 0.",
"transcoding_tone_mapping": "Mapování tónů",
@@ -402,11 +425,11 @@
"advanced_settings_prefer_remote_subtitle": "U některých zařízení je načítání miniatur z lokálních prostředků velmi pomalé. Aktivujte toto nastavení, aby se místo toho načítaly vzdálené obrázky.",
"advanced_settings_prefer_remote_title": "Preferovat vzdálené obrázky",
"advanced_settings_proxy_headers_subtitle": "Definice hlaviček proxy serveru, které by měl Immich odesílat s každým síťovým požadavkem",
"advanced_settings_proxy_headers_title": "Proxy hlavičky",
"advanced_settings_proxy_headers_title": "Vlastní proxy hlavičky [EXPERIMENTÁLNÍ]",
"advanced_settings_readonly_mode_subtitle": "Povoluje režim pouze pro čtení, ve kterém lze fotografie pouze prohlížet, ale funkce jako výběr více obrázků, sdílení, přenos, mazání jsou zakázány. Povolení/zakázání režimu pouze pro čtení pomocí avatara uživatele na hlavní obrazovce",
"advanced_settings_readonly_mode_title": "Režim pouze pro čtení",
"advanced_settings_self_signed_ssl_subtitle": "Vynechá ověření SSL certifikátu serveru. Vyžadováno pro self-signed certifikáty.",
"advanced_settings_self_signed_ssl_title": "Povolit self-signed SSL certifikáty",
"advanced_settings_self_signed_ssl_title": "Povolit self-signed SSL certifikáty [EXPERIMENTÁLNÍ]",
"advanced_settings_sync_remote_deletions_subtitle": "Automaticky odstranit nebo obnovit položku v tomto zařízení, když je tato akce provedena na webu",
"advanced_settings_sync_remote_deletions_title": "Synchronizace vzdáleného mazání [EXPERIMENTÁLNÍ]",
"advanced_settings_tile_subtitle": "Pokročilé uživatelské nastavení",
@@ -415,6 +438,7 @@
"age_months": "{months, plural, one {# měsíc} few {# měsíce} other {# měsíců}}",
"age_year_months": "1 rok a {months, plural, one {# měsíc} few {# měsíce} other {# měsíců}}",
"age_years": "{years, plural, one {# rok} few {# roky} other {# let}}",
"album": "Album",
"album_added": "Přidáno album",
"album_added_notification_setting_description": "Dostávat e-mailové oznámení, když jste přidáni do sdíleného alba",
"album_cover_updated": "Obal alba aktualizován",
@@ -460,16 +484,21 @@
"allow_edits": "Povolit úpravy",
"allow_public_user_to_download": "Povolit veřejnosti stahovat",
"allow_public_user_to_upload": "Povolit veřejnosti nahrávat",
"allowed": "Povoleno",
"alt_text_qr_code": "Obrázek QR kódu",
"anti_clockwise": "Proti směru hodinových ručiček",
"api_key": "API klíč",
"api_key_description": "Tato hodnota se zobrazí pouze jednou. Před zavřením okna ji nezapomeňte zkopírovat.",
"api_key_empty": "Název klíče API by neměl být prázdný",
"api_keys": "API klíče",
"app_architecture_variant": "Varianta (architektura)",
"app_bar_signout_dialog_content": "Určitě se chcete odhlásit?",
"app_bar_signout_dialog_ok": "Ano",
"app_bar_signout_dialog_title": "Odhlásit se",
"app_download_links": "Odkazy ke stažení aplikace",
"app_settings": "Aplikace",
"app_stores": "Obchody s aplikacemi",
"app_update_available": "K dispozici je aktualizace aplikace",
"appears_in": "Vyskytuje se v",
"apply_count": "Použít ({count, number})",
"archive": "Archiv",
@@ -553,6 +582,7 @@
"backup_albums_sync": "Synchronizace zálohovaných alb",
"backup_all": "Vše",
"backup_background_service_backup_failed_message": "Zálohování médií selhalo. Zkouším to znovu…",
"backup_background_service_complete_notification": "Zálohování položek dokončeno",
"backup_background_service_connection_failed_message": "Nepodařilo se připojit k serveru. Zkouším to znovu…",
"backup_background_service_current_upload_notification": "Nahrávání {filename}",
"backup_background_service_default_notification": "Kontrola nových médií…",
@@ -662,6 +692,8 @@
"change_password_description": "Buď se do systému přihlašujete poprvé, nebo jste byli požádáni o změnu hesla. Zadejte prosím nové heslo níže.",
"change_password_form_confirm_password": "Potvrďte heslo",
"change_password_form_description": "Dobrý den, {name}\n\nje to buď poprvé, co se přihlašujete do systému, nebo byl vytvořen požadavek na změnu hesla. Níže zadejte nové heslo.",
"change_password_form_log_out": "Odhlásit všechna ostatní zařízení",
"change_password_form_log_out_description": "Doporučujeme se odhlásit ze všech ostatních zařízení",
"change_password_form_new_password": "Nové heslo",
"change_password_form_password_mismatch": "Hesla se neshodují",
"change_password_form_reenter_new_password": "Znovu zadejte nové heslo",
@@ -688,8 +720,8 @@
"client_cert_import_success_msg": "Klientský certifikát je importován",
"client_cert_invalid_msg": "Neplatný soubor certifikátu nebo špatné heslo",
"client_cert_remove_msg": "Klientský certifikát je odstraněn",
"client_cert_subtitle": "Podpora pouze formátu PKCS12 (.p12, .pfx). Import/odstranění certifikátu je možné pouze před přihlášením",
"client_cert_title": "Klientský SSL certifikát",
"client_cert_subtitle": "Podporuje pouze formát PKCS12 (.p12, .pfx). Import/odstranění certifikátu je možné pouze před přihlášením",
"client_cert_title": "Klientský SSL certifikát [EXPERIMENTÁLNÍ]",
"clockwise": "Po směru hodinových ručiček",
"close": "Zavřít",
"collapse": "Sbalit",
@@ -701,7 +733,6 @@
"comments_and_likes": "Komentáře a lajky",
"comments_are_disabled": "Komentáře jsou vypnuty",
"common_create_new_album": "Vytvořit nové album",
"common_server_error": "Zkontrolujte připojení k internetu. Ujistěte se, že server je dostupný a aplikace/server jsou v kompatibilní verzi.",
"completed": "Dokončeno",
"confirm": "Potvrdit",
"confirm_admin_password": "Potvrzení hesla správce",
@@ -740,6 +771,7 @@
"create": "Vytvořit",
"create_album": "Vytvořit album",
"create_album_page_untitled": "Bez názvu",
"create_api_key": "Vytvořit API klíč",
"create_library": "Vytvořit knihovnu",
"create_link": "Vytvořit odkaz",
"create_link_to_share": "Vytvořit odkaz pro sdílení",
@@ -769,6 +801,7 @@
"daily_title_text_date_year": "EEEE, d. MMMM y",
"dark": "Tmavý",
"dark_theme": "Přepnout tmavý motiv",
"date": "Datum",
"date_after": "Datum po",
"date_and_time": "Datum a čas",
"date_before": "Datum před",
@@ -866,13 +899,11 @@
"edit_date_and_time": "Upravit datum a čas",
"edit_date_and_time_action_prompt": "{count} časových údajů upraveno",
"edit_date_and_time_by_offset": "Posunout datum",
"edit_date_and_time_by_offset_interval": "Nový rozsah dat: {from} {to}",
"edit_date_and_time_by_offset_interval": "Nový rozsah dat: {from} - {to}",
"edit_description": "Upravit popis",
"edit_description_prompt": "Vyberte nový popis:",
"edit_exclusion_pattern": "Upravit vzor vyloučení",
"edit_faces": "Upravit obličeje",
"edit_import_path": "Upravit cestu importu",
"edit_import_paths": "Úpravit importní cesty",
"edit_key": "Upravit klíč",
"edit_link": "Upravit odkaz",
"edit_location": "Upravit polohu",
@@ -883,7 +914,6 @@
"edit_tag": "Upravit značku",
"edit_title": "Upravit název",
"edit_user": "Upravit uživatele",
"edited": "Upraveno",
"editor": "Editor",
"editor_close_without_save_prompt": "Změny nebudou uloženy",
"editor_close_without_save_title": "Zavřít editor?",
@@ -945,8 +975,8 @@
"failed_to_stack_assets": "Nepodařilo se seskupit položky",
"failed_to_unstack_assets": "Nepodařilo se zrušit seskupení položek",
"failed_to_update_notification_status": "Nepodařilo se aktualizovat stav oznámení",
"import_path_already_exists": "Tato cesta importu již existuje.",
"incorrect_email_or_password": "Nesprávný e-mail nebo heslo",
"library_folder_already_exists": "Tato importní cesta již existuje.",
"paths_validation_failed": "{paths, plural, one {# cesta neprošla} few {# cesty neprošly} other {# cest neprošlo}} kontrolou",
"profile_picture_transparent_pixels": "Profilové obrázky nemohou mít průhledné pixely. Obrázek si prosím zvětšete nebo posuňte.",
"quota_higher_than_disk_size": "Nastavili jste kvótu vyšší, než je velikost disku",
@@ -955,7 +985,6 @@
"unable_to_add_assets_to_shared_link": "Nelze přidat položky do sdíleného odkazu",
"unable_to_add_comment": "Nelze přidat komentář",
"unable_to_add_exclusion_pattern": "Nelze přidat vzor vyloučení",
"unable_to_add_import_path": "Nelze přidat cestu importu",
"unable_to_add_partners": "Nelze přidat partnery",
"unable_to_add_remove_archive": "Nelze {archived, select, true {odstranit položku z} other {přidat položku do}} archivu",
"unable_to_add_remove_favorites": "Nelze {favorite, select, true {oblíbit položku} other {zrušit oblíbení položky}}",
@@ -978,12 +1007,10 @@
"unable_to_delete_asset": "Nelze odstranit položku",
"unable_to_delete_assets": "Chyba při odstraňování položek",
"unable_to_delete_exclusion_pattern": "Nelze odstranit vzor vyloučení",
"unable_to_delete_import_path": "Nelze odstranit cestu importu",
"unable_to_delete_shared_link": "Nepodařilo se odstranit sdílený odkaz",
"unable_to_delete_user": "Nelze odstranit uživatele",
"unable_to_download_files": "Nelze stáhnout soubory",
"unable_to_edit_exclusion_pattern": "Nelze upravit vzor vyloučení",
"unable_to_edit_import_path": "Nelze upravit cestu importu",
"unable_to_empty_trash": "Nelze vyprázdnit koš",
"unable_to_enter_fullscreen": "Nelze přejít do režimu celé obrazovky",
"unable_to_exit_fullscreen": "Nelze ukončit zobrazení na celou obrazovku",
@@ -1034,11 +1061,13 @@
"unable_to_update_user": "Nelze aktualizovat uživatele",
"unable_to_upload_file": "Nepodařilo se nahrát soubor"
},
"exclusion_pattern": "Vzor vyloučení",
"exif": "Exif",
"exif_bottom_sheet_description": "Přidat popis...",
"exif_bottom_sheet_description_error": "Chyba při aktualizaci popisu",
"exif_bottom_sheet_details": "PODROBNOSTI",
"exif_bottom_sheet_location": "POLOHA",
"exif_bottom_sheet_no_description": "Žádný popisek",
"exif_bottom_sheet_people": "LIDÉ",
"exif_bottom_sheet_person_add_person": "Přidat jméno",
"exit_slideshow": "Ukončit prezentaci",
@@ -1077,6 +1106,7 @@
"features_setting_description": "Správa funkcí aplikace",
"file_name": "Název souboru",
"file_name_or_extension": "Název nebo přípona souboru",
"file_size": "Velikost souboru",
"filename": "Název souboru",
"filetype": "Typ souboru",
"filter": "Filtr",
@@ -1091,6 +1121,7 @@
"folders_feature_description": "Procházení zobrazení složek s fotografiemi a videi v souborovém systému",
"forgot_pin_code_question": "Zapomněli jste PIN?",
"forward": "Dopředu",
"full_path": "Úplná cesta: {path}",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Tato funkce načítá externí zdroje z Googlu, aby mohla fungovat.",
"general": "Obecné",
@@ -1120,7 +1151,6 @@
"header_settings_field_validator_msg": "Hodnota nemůže být prázdná",
"header_settings_header_name_input": "Název hlavičky",
"header_settings_header_value_input": "Hodnota hlavičky",
"headers_settings_tile_subtitle": "Definice hlaviček proxy serveru, které má aplikace odesílat s každým síťovým požadavkem",
"headers_settings_tile_title": "Vlastní proxy hlavičky",
"hi_user": "Ahoj {name} ({email})",
"hide_all_people": "Skrýt všechny lidi",
@@ -1173,6 +1203,8 @@
"import_path": "Cesta importu",
"in_albums": "{count, plural, one {V # albu} few {Ve # albech} other {V # albech}}",
"in_archive": "V archivu",
"in_year": "V roce {year}",
"in_year_selector": "V roce",
"include_archived": "Včetně archivovaných",
"include_shared_albums": "Včetně sdílených alb",
"include_shared_partner_assets": "Včetně sdílených položek partnera",
@@ -1209,6 +1241,7 @@
"language_setting_description": "Vyberte upřednostňovaný jazyk",
"large_files": "Velké soubory",
"last": "Poslední",
"last_months": "{count, plural, one {Poslední měsíc} few {Poslední # měsíce} other {Posledních # měsíců}}",
"last_seen": "Naposledy viděno",
"latest_version": "Nejnovější verze",
"latitude": "Zeměpisná šířka",
@@ -1218,6 +1251,8 @@
"let_others_respond": "Nechte ostatní reagovat",
"level": "Úroveň",
"library": "Knihovna",
"library_add_folder": "Přidat složku",
"library_edit_folder": "Upravit složku",
"library_options": "Možnosti knihovny",
"library_page_device_albums": "Alba v zařízení",
"library_page_new_album": "Nové album",
@@ -1241,6 +1276,7 @@
"local_media_summary": "Souhrn místních médií",
"local_network": "Místní síť",
"local_network_sheet_info": "Aplikace se při použití zadané sítě Wi-Fi připojí k serveru prostřednictvím tohoto URL",
"location": "Poloha",
"location_permission": "Oprávnění polohy",
"location_permission_content": "Aby bylo možné používat funkci automatického přepínání, potřebuje Immich oprávnění k přesné poloze, aby mohl přečíst název aktuální sítě Wi-Fi",
"location_picker_choose_on_map": "Vybrat na mapě",
@@ -1288,8 +1324,17 @@
"loop_videos_description": "Povolit automatickou smyčku videa v prohlížeči.",
"main_branch_warning": "Používáte vývojovou verzi; důrazně doporučujeme používat verzi z vydání!",
"main_menu": "Hlavní nabídka",
"maintenance_description": "Immich byl přepnut do <link>režimu údržby</link>.",
"maintenance_end": "Ukončit režim údržby",
"maintenance_end_error": "Nepodařilo se ukončit režim údržby.",
"maintenance_logged_in_as": "Aktuálně přihlášen jako {user}",
"maintenance_title": "Dočasně nedostupné",
"make": "Výrobce",
"manage_geolocation": "Spravovat polohu",
"manage_media_access_rationale": "Toto oprávnění je vyžadováno pro správné zacházení s přesunem položek do koše a jejich obnovováním z něj.",
"manage_media_access_settings": "Otevřít nastavení",
"manage_media_access_subtitle": "Povolte aplikaci Immich spravovat a přesouvat soubory médií.",
"manage_media_access_title": "Přístup ke správě médií",
"manage_shared_links": "Spravovat sdílené odkazy",
"manage_sharing_with_partners": "Správa sdílení s partnery",
"manage_the_app_settings": "Správa nastavení aplikace",
@@ -1345,12 +1390,15 @@
"minute": "Minuta",
"minutes": "Minut",
"missing": "Chybějící",
"mobile_app": "Mobilní aplikace",
"mobile_app_download_onboarding_note": "Stáhněte si doprovodnou mobilní aplikaci pomocí následujících možností",
"model": "Model",
"month": "Měsíc",
"monthly_title_text_date_format": "LLLL y",
"more": "Více",
"move": "Přesunout",
"move_off_locked_folder": "Přesunout z uzamčené složky",
"move_to": "Přesunout do",
"move_to_lock_folder_action_prompt": "{count} přidaných do uzamčené složky",
"move_to_locked_folder": "Přesunout do uzamčené složky",
"move_to_locked_folder_confirmation": "Tyto fotky a videa budou odstraněny ze všech alb a bude je možné zobrazit pouze v uzamčené složce",
@@ -1363,6 +1411,8 @@
"my_albums": "Moje alba",
"name": "Jméno",
"name_or_nickname": "Jméno nebo přezdívka",
"navigate": "Navigovat",
"navigate_to_time": "Navigovat na čas",
"network_requirement_photos_upload": "Pro zálohování fotografií používat mobilní data",
"network_requirement_videos_upload": "Pro zálohování videí používat mobilní data",
"network_requirements": "Požadavky na síť",
@@ -1372,11 +1422,13 @@
"never": "Nikdy",
"new_album": "Nové album",
"new_api_key": "Nový API klíč",
"new_date_range": "Nový rozsah dat",
"new_password": "Nové heslo",
"new_person": "Nová osoba",
"new_pin_code": "Nový PIN kód",
"new_pin_code_subtitle": "Poprvé přistupujete k uzamčené složce. Vytvořte si kód PIN pro bezpečný přístup na tuto stránku",
"new_timeline": "Nová časová osa",
"new_update": "Nová aktualizace",
"new_user_created": "Vytvořen nový uživatel",
"new_version_available": "NOVÁ VERZE K DISPOZICI",
"newest_first": "Nejnovější první",
@@ -1392,12 +1444,14 @@
"no_cast_devices_found": "Nebyla nalezena žádná zařízení",
"no_checksum_local": "Není k dispozici kontrolní součet - nelze načíst místní položky",
"no_checksum_remote": "Není k dispozici kontrolní součet - nelze načíst vzdálenou položku",
"no_devices": "Žádná autorizovaná zařízení",
"no_duplicates_found": "Nebyly nalezeny žádné duplicity.",
"no_exif_info_available": "Exif není k dispozici",
"no_explore_results_message": "Nahrajte další fotografie a prozkoumejte svou sbírku.",
"no_favorites_message": "Přidejte si oblíbené položky a rychle najděte své nejlepší obrázky a videa",
"no_libraries_message": "Vytvořte si externí knihovnu pro zobrazení fotografií a videí",
"no_local_assets_found": "Nebyly nalezeny žádné místní položky s tímto kontrolním součtem",
"no_location_set": "Není nastavena poloha",
"no_locked_photos_message": "Fotky a videa v uzamčené složce jsou skryté a při procházení nebo vyhledávání v knihovně se nezobrazují.",
"no_name": "Bez jména",
"no_notifications": "Žádná oznámení",
@@ -1408,6 +1462,7 @@
"no_results_description": "Zkuste použít synonymum nebo obecnější klíčové slovo",
"no_shared_albums_message": "Vytvořte si album a sdílejte fotografie a videa s lidmi ve své síti",
"no_uploads_in_progress": "Neprobíhá žádné nahrávání",
"not_allowed": "Nepovoleno",
"not_available": "Není k dispozici",
"not_in_any_album": "Bez alba",
"not_selected": "Není vybráno",
@@ -1422,6 +1477,9 @@
"notifications": "Oznámení",
"notifications_setting_description": "Správa oznámení",
"oauth": "OAuth",
"obtainium_configurator": "Konfigurátor Obtainium",
"obtainium_configurator_instructions": "Pomocí aplikace Obtainium nainstalujte a aktualizujte aplikaci pro Android přímo z vydání na GitHubu Immich. Vytvořte API klíč a vyberte variantu pro vytvoření konfiguračního odkazu pro Obtainium",
"ocr": "OCR",
"official_immich_resources": "Oficiální zdroje Immich",
"offline": "Offline",
"offset": "Posun",
@@ -1515,6 +1573,8 @@
"photos_count": "{count, plural, one {{count, number} fotka} few {{count, number} fotky} other {{count, number} fotek}}",
"photos_from_previous_years": "Fotky z předchozích let",
"pick_a_location": "Vyberte polohu",
"pick_custom_range": "Vlastní rozsah",
"pick_date_range": "Vyberte rozsah dat",
"pin_code_changed_successfully": "PIN kód byl úspěšně změněn",
"pin_code_reset_successfully": "PIN kód úspěšně resetován",
"pin_code_setup_successfully": "PIN kód úspěšně nastaven",
@@ -1526,6 +1586,9 @@
"play_memories": "Přehrát vzpomníky",
"play_motion_photo": "Přehrát pohybovou fotografii",
"play_or_pause_video": "Přehrát nebo pozastavit video",
"play_original_video": "Přehrát původní video",
"play_original_video_setting_description": "Upřednostňujte přehrávání originálních videí před překódovanými videi. Pokud originální soubor není kompatibilní, nemusí se přehrávat správně.",
"play_transcoded_video": "Přehrát překódované video",
"please_auth_to_access": "Pro přístup se prosím ověřte",
"port": "Port",
"preferences_settings_subtitle": "Správa předvoleb aplikace",
@@ -1543,13 +1606,9 @@
"privacy": "Soukromí",
"profile": "Profil",
"profile_drawer_app_logs": "Logy",
"profile_drawer_client_out_of_date_major": "Mobilní aplikace je zastaralá. Aktualizujte ji na nejnovější hlavní verzi.",
"profile_drawer_client_out_of_date_minor": "Mobilní aplikace je zastaralá. Aktualizujte ji na nejnovější verzi.",
"profile_drawer_client_server_up_to_date": "Klient a server jsou aktuální",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Režim jen pro čtení. Ukončíte ho dlouhým podržením ikony avataru.",
"profile_drawer_server_out_of_date_major": "Server je zastaralý. Aktualizujte na nejnovější hlavní verzi.",
"profile_drawer_server_out_of_date_minor": "Server je zastaralý. Aktualizujte je na nejnovější verzi.",
"profile_image_of_user": "Profilový obrázek uživatele {user}",
"profile_picture_set": "Profilový obrázek nastaven.",
"public_album": "Veřejné album",
@@ -1626,7 +1685,7 @@
"remove_assets_album_confirmation": "Opravdu chcete z alba odstranit {count, plural, one {# položku} few {# položky} other {# položek}}?",
"remove_assets_shared_link_confirmation": "Opravdu chcete ze sdíleného odkazu odstranit {count, plural, one {# položku} few {# položky} other {# položek}}?",
"remove_assets_title": "Odstranit položky?",
"remove_custom_date_range": "Odstranit vlastní rozsah datumů",
"remove_custom_date_range": "Odstranit vlastní rozsah dat",
"remove_deleted_assets": "Odstranit offline soubory",
"remove_from_album": "Odstranit z alba",
"remove_from_album_action_prompt": "{count} odstraněných z alba",
@@ -1666,6 +1725,7 @@
"reset_sqlite_confirmation": "Jste si jisti, že chcete obnovit databázi SQLite? Pro opětovnou synchronizaci dat se budete muset odhlásit a znovu přihlásit",
"reset_sqlite_success": "Obnovení SQLite databáze proběhlo úspěšně",
"reset_to_default": "Obnovit výchozí nastavení",
"resolution": "Rozlišení",
"resolve_duplicates": "Vyřešit duplicity",
"resolved_all_duplicates": "Vyřešeny všechny duplicity",
"restore": "Obnovit",
@@ -1684,6 +1744,7 @@
"running": "Probíhá",
"save": "Uložit",
"save_to_gallery": "Uložit do galerie",
"saved": "Uloženo",
"saved_api_key": "API klíč uložen",
"saved_profile": "Profil uložen",
"saved_settings": "Nastavení uloženo",
@@ -1700,6 +1761,9 @@
"search_by_description_example": "Pěší turistika v Sapě",
"search_by_filename": "Vyhledávání podle názvu nebo přípony souboru",
"search_by_filename_example": "např. IMG_1234.JPG nebo PNG",
"search_by_ocr": "Hledat pomocí OCR",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Vyhledat model objektivu...",
"search_camera_make": "Vyhledat výrobce fotoaparátu...",
"search_camera_model": "Vyhledat model fotoaparátu...",
"search_city": "Vyhledat město...",
@@ -1708,7 +1772,7 @@
"search_filter_camera_title": "Výběr typu fotoaparátu",
"search_filter_date": "Datum",
"search_filter_date_interval": "{start} až {end}",
"search_filter_date_title": "Výběr rozmezí dat",
"search_filter_date_title": "Výběr rozsahu dat",
"search_filter_display_option_not_in_album": "Není v albu",
"search_filter_display_options": "Možnost zobrazení",
"search_filter_filename": "Vyhledávat podle názvu souboru",
@@ -1716,6 +1780,7 @@
"search_filter_location_title": "Výběr polohy",
"search_filter_media_type": "Typ média",
"search_filter_media_type_title": "Výběr typu média",
"search_filter_ocr": "Hledat pomocí OCR",
"search_filter_people_title": "Výběr lidí",
"search_for": "Vyhledat",
"search_for_existing_person": "Vyhledat existující osobu",
@@ -1777,7 +1842,10 @@
"server_offline": "Server offline",
"server_online": "Server online",
"server_privacy": "Ochrana soukromí serveru",
"server_restarting_description": "Tato stránka se za chvíli obnoví.",
"server_restarting_title": "Server se restartuje",
"server_stats": "Statistiky serveru",
"server_update_available": "K dispozici je aktualizace serveru",
"server_version": "Verze serveru",
"set": "Nastavit",
"set_as_album_cover": "Nastavit jako obal alba",
@@ -1806,6 +1874,8 @@
"setting_notifications_subtitle": "Přizpůsobení předvoleb oznámení",
"setting_notifications_total_progress_subtitle": "Celkový průběh nahrání (hotovo/celkově)",
"setting_notifications_total_progress_title": "Zobrazit celkový průběh zálohování na pozadí",
"setting_video_viewer_auto_play_subtitle": "Automaticky spustit přehrávání videí při jejich otevření",
"setting_video_viewer_auto_play_title": "Automatické přehrávání videí",
"setting_video_viewer_looping_title": "Smyčka",
"setting_video_viewer_original_video_subtitle": "Při streamování videa ze serveru přehrávat originál, i když je k dispozici překódovaná verze. Může vést k bufferování. Videa dostupná lokálně se přehrávají v původní kvalitě bez ohledu na toto nastavení.",
"setting_video_viewer_original_video_title": "Vynutit původní video",
@@ -1965,7 +2035,7 @@
"tag_updated": "Aktualizována značka: {tag}",
"tagged_assets": "Přiřazena značka {count, plural, one {# položce} other {# položkám}}",
"tags": "Značky",
"tap_to_run_job": "Klepnutím na spustíte úlohu",
"tap_to_run_job": "Klepnutím spustíte úlohu",
"template": "Šablona",
"theme": "Motiv",
"theme_selection": "Výběr motivu",
@@ -1985,7 +2055,9 @@
"theme_setting_three_stage_loading_title": "Povolení třístupňového načítání",
"they_will_be_merged_together": "Budou sloučeny dohromady",
"third_party_resources": "Zdroje třetích stran",
"time": "Čas",
"time_based_memories": "Časové vzpomínky",
"time_based_memories_duration": "Počet sekund k zobrazení každého obrázku.",
"timeline": "Časová osa",
"timezone": "Časové pásmo",
"to_archive": "Archivovat",
@@ -2017,6 +2089,7 @@
"troubleshoot": "Diagnostika",
"type": "Typ",
"unable_to_change_pin_code": "Nelze změnit PIN kód",
"unable_to_check_version": "Nepodařilo se zjistit verzi aplikace nebo serveru",
"unable_to_setup_pin_code": "Nelze nastavit PIN kód",
"unarchive": "Odebrat z archivu",
"unarchive_action_prompt": "{count} odstraněných z archivu",
@@ -2125,6 +2198,7 @@
"welcome": "Vítejte",
"welcome_to_immich": "Vítejte v Immichi",
"wifi_name": "Název Wi-Fi",
"workflow": "Pracovní postup",
"wrong_pin_code": "Chybný PIN kód",
"year": "Rok",
"years_ago": "Před {years, plural, one {rokem} other {# lety}}",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Ҫуралнӑ кун хушӑр",
"add_endpoint": "Вӗҫӗмлӗ пӑнчӑ хушар",
"add_exclusion_pattern": "Кӑларса пӑрахмалли йӗрке хуш",
"add_import_path": "Импорт ҫулне хуш",
"add_location": "Вырӑн хуш",
"add_more_users": "Усӑҫсем ытларах хуш",
"add_partner": "Мӑшӑр хуш",

View File

@@ -6,7 +6,7 @@
"action": "Handling",
"action_common_update": "Opdater",
"actions": "Handlinger",
"active": "Aktive",
"active": "Aktiv",
"activity": "Aktivitet",
"activity_changed": "Aktivitet er {enabled, select, true {aktiveret} other {deaktiveret}}",
"add": "Tilføj",
@@ -17,7 +17,6 @@
"add_birthday": "Tilføj en fødselsdag",
"add_endpoint": "Tilføj endepunkt",
"add_exclusion_pattern": "Tilføj udelukkelsesmønster",
"add_import_path": "Tilføj importsti",
"add_location": "Tilføj placering",
"add_more_users": "Tilføj flere brugere",
"add_partner": "Tilføj partner",
@@ -32,7 +31,9 @@
"add_to_album_toggle": "Skift selektion for {album}",
"add_to_albums": "Tilføj til albummer",
"add_to_albums_count": "Tilføj til albummer({count})",
"add_to_bottom_bar": "Tilføj til",
"add_to_shared_album": "Tilføj til delt album",
"add_upload_to_stack": "Tilføj upload til stack",
"add_url": "Tilføj URL",
"added_to_archive": "Tilføjet til arkiv",
"added_to_favorites": "Tilføjet til favoritter",
@@ -111,7 +112,6 @@
"jobs_failed": "{jobCount, plural, one {# fejlet} other {# fejlede}}",
"library_created": "Skabte bibliotek: {library}",
"library_deleted": "Bibliotek slettet",
"library_import_path_description": "Angiv en mappe, der skal importeres. Denne mappe, inklusive undermapper, vil blive scannet for billeder og videoer.",
"library_scanning": "Periodisk scanning",
"library_scanning_description": "Konfigurer periodisk biblioteksscanning",
"library_scanning_enable_description": "Aktiver periodisk biblioteksscanning",
@@ -119,7 +119,7 @@
"library_settings_description": "Administrer eksterne biblioteksindstillinger",
"library_tasks_description": "Scan eksterne biblioteker for nye og/eller ændrede mediefiler",
"library_watching_enable_description": "Overvåg eksterne biblioteker for filændringer",
"library_watching_settings": "Biblioteks overvågning (EKSPERIMENTEL)",
"library_watching_settings": "Biblioteks overvågning [EKSPERIMENTEL]",
"library_watching_settings_description": "Tjek automatisk for ændrede filer",
"logging_enable_description": "Aktiver logning",
"logging_level_description": "Når slået til, hvilket logniveau, der skal bruges.",
@@ -153,6 +153,18 @@
"machine_learning_min_detection_score_description": "Minimum tillidsscore for et ansigt, der kan registreres fra 0-1. Lavere værdier vil registrere flere ansigter, men kan resultere i falske positiver.",
"machine_learning_min_recognized_faces": "Minimum genkendte ansigter",
"machine_learning_min_recognized_faces_description": "Minimumsantallet af genkendte ansigter for en person, før denne person bliver oprettet. At øge dette gør ansigtsgenkendelse mere præcis på bekostning af at øge chancen for, at et ansigt ikke er tildelt en person.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Brug maskinlæring til at genkende tekst i billeder",
"machine_learning_ocr_enabled": "Aktiver OCR",
"machine_learning_ocr_enabled_description": "Hvis deaktiveret, vil tekstgenkendelse ikke blive udført på billederne.",
"machine_learning_ocr_max_resolution": "Maksimum opløsning",
"machine_learning_ocr_max_resolution_description": "Forhåndsvisninger over denne opløsning ændres i størrelse, mens billedformatet bevares. Højere værdier er mere nøjagtige, men tager længere tid at behandle og bruger mere hukommelse.",
"machine_learning_ocr_min_detection_score": "Minimum detektionsscore",
"machine_learning_ocr_min_detection_score_description": "Minimums konfidensscore for tekst, der skal detekteres, fra 0-1. Lavere værdier vil detektere mere tekst, men kan resultere i falsk positiver.",
"machine_learning_ocr_min_recognition_score": "Minimum genkendelsesscore",
"machine_learning_ocr_min_score_recognition_description": "Minimum konfidensscore for genkendelse af registreret tekst er fra 0-1. Lavere værdier vil genkende mere tekst, men kan resultere i falsk positiver.",
"machine_learning_ocr_model": "OCR model",
"machine_learning_ocr_model_description": "Server modeller er mere præcise end mobil modeller, men tager længer tid at processere og bruger mere hukommelse.",
"machine_learning_settings": "Maskinlæringsindstillinger",
"machine_learning_settings_description": "Administrer maskinlæringsfunktioner og indstillinger",
"machine_learning_smart_search": "Smart søgning",
@@ -160,6 +172,10 @@
"machine_learning_smart_search_enabled": "Aktiver smart søgning",
"machine_learning_smart_search_enabled_description": "Hvis deaktiveret, vil billeder ikke blive kodet til smart søgning.",
"machine_learning_url_description": "URLen for maskinlæringsserveren. Hvis mere end én URL angives, vil hver server blive forsøgt én ad gangen, indtil en svarer succesfuldt, i rækkefølge fra første til sidste. Servere, der ikke svarer, vil midlertidigt blive ignoreret, indtil de kommer online igen.",
"maintenance_settings": "Vedligeholdelse",
"maintenance_settings_description": "Sæt Immich i vedligeholdelsestilstand.",
"maintenance_start": "Start vedligeholdelsestilstand",
"maintenance_start_error": "Vedligeholdelsestilstand kunne ikke startes.",
"manage_concurrency": "Administrer antallet af samtidige opgaver",
"manage_log_settings": "Administrer logindstillinger",
"map_dark_style": "Mørk tema",
@@ -210,6 +226,8 @@
"notification_email_ignore_certificate_errors_description": "Ignorér TLS-certifikatgodkendelsesfejl (ikke anbefalet)",
"notification_email_password_description": "Adgangskode til brug ved autentificering med e-mailserveren",
"notification_email_port_description": "Emailserverens port (fx 25, 465 eller 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Brug SMTPS (SMTP over TLS)",
"notification_email_sent_test_email_button": "Send test-email og gem",
"notification_email_setting_description": "Indstillinger for sending af emailnotifikationer",
"notification_email_test_email": "Send test-email",
@@ -242,6 +260,7 @@
"oauth_storage_quota_default_description": "Kvote i GiB som bruges, når der ikke bliver oplyst en fordring.",
"oauth_timeout": "Forespørgslen udløb",
"oauth_timeout_description": "Udløbstid for forespørgsel i milisekunder",
"ocr_job_description": "Brug maskinlæring til at genkende tekst i billeder",
"password_enable_description": "Log ind med email og adgangskode",
"password_settings": "Adgangskodelogin",
"password_settings_description": "Administrer indstillinger for adgangskodelogin",
@@ -285,7 +304,7 @@
"storage_template_settings_description": "Administrer mappestrukturen og filnavnet for den uploadede mediefil",
"storage_template_user_label": "<code>{label}</code> er brugerens Lagringsmærkat",
"system_settings": "Systemindstillinger",
"tag_cleanup_job": "\"Tag\" cleanup",
"tag_cleanup_job": "\"Tag\"-oprydning",
"template_email_available_tags": "Du kan bruge følgende variabler i din skabelon: {tags}",
"template_email_if_empty": "Hvis skabelonen er tom, vil standard-e-mailen blive brugt.",
"template_email_invite_album": "Inviterings albumskabelon",
@@ -332,7 +351,7 @@
"transcoding_max_b_frames": "Maksimum B-frames",
"transcoding_max_b_frames_description": "Højere værdier forbedrer kompressionseffektivitet, men kan gøre indkodning langsommere. Er måske ikke kompatibelt med hardware-acceleration på ældre enheder. 0 slår B-frames fra, mens -1 sætter denne værdi automatisk.",
"transcoding_max_bitrate": "Maksimal bitrate",
"transcoding_max_bitrate_description": "At sætte en maksmimal bitrate kan gøre filstørrelserne mere forudsigelige med et lille tab i kvalitet. Ved 720p er almindelige værdier 2600 kbit/s for VP9 eller HEVC, eller 4500 kbit/s for H.264. Slået fra hvis sat til 0.",
"transcoding_max_bitrate_description": "Indstilling af en maksimal bitrate kan gøre filstørrelser mere forudsigelige, men med et mindre fald i kvaliteten. Ved 720p er typiske værdier 2600 kbit/s for VP9 eller HEVC eller 4500 kbit/s for H.264. Deaktiveret, hvis den er indstillet til 0. Når der ikke er angivet nogen enhed, antages k (for kbit/s); derfor er 5000, 5000k og 5M (for Mbit/s) ækvivalente.",
"transcoding_max_keyframe_interval": "Maksimal keyframe-interval",
"transcoding_max_keyframe_interval_description": "Sætter den maksimale frameafstand mellem keyframes. Lavere værdier forringer kompressionseffektiviteten, men forbedrer søgetider og kan forbedre kvaliteten i scener med hurtig bevægelse. 0 sætter denne værdi automatisk.",
"transcoding_optimal_description": "Videoer højere end målopløsningen eller ikke i et godkendt format",
@@ -361,11 +380,11 @@
"transcoding_two_pass_encoding_setting_description": "Transkoder af to omgange for at producere bedre indkodede videoer. Når den maksimale bitrate er slået til (som det kræver for at det fungerer med H.264 og HEVC), bruger denne tilstand en bitrateinterval baseret på den maksimale birate og ignorerer CRF. For VP9, kan CRF bruges hvis den maksimale bitrate er slået fra.",
"transcoding_video_codec": "Videocodec",
"transcoding_video_codec_description": "VP9 har en højere effektivitet og webkompatibilitet, men indkodningen tager længere tid. HEVC har lignende ydelse, men har lavere webkompatibilitet og er hurtig at transkode, men giver meget større filer. AV1 er det mest effektive codec, men mangler understøttelse på ældre enheder.",
"trash_enabled_description": "Aktivér skraldefunktioner",
"trash_enabled_description": "Aktivér \"Papirkurvs\"-funktioner",
"trash_number_of_days": "Antal dage",
"trash_number_of_days_description": "Antal dage aktiver i skraldespanden skal beholdes inden de fjernes permanent",
"trash_settings": "Skraldeindstillinger",
"trash_settings_description": "Administrér skraldeindstillinger",
"trash_number_of_days_description": "Antal dage elementer i papirkurven skal beholdes inden de fjernes permanent",
"trash_settings": "Papirkurvs-indstillinger",
"trash_settings_description": "Administrér papirkurvs-indstillinger",
"unlink_all_oauth_accounts": "Ophæv link til alle OAuth konti",
"unlink_all_oauth_accounts_description": "Husk at fjerne linket til alle OAuth konti før du migrerer til en ny udbyder.",
"unlink_all_oauth_accounts_prompt": "Er du sikker på, at du vil ophæve link til alle OAuth konti? Dette vil nulstille OAuth ID for hver bruger og kan ikke fortrydes.",
@@ -395,17 +414,17 @@
"admin_password": "Administratoradgangskode",
"administration": "Administration",
"advanced": "Avanceret",
"advanced_settings_enable_alternate_media_filter_subtitle": "Brug denne valgmulighed for at filtrere media under synkronisering baseret på alternative kriterier. Prøv kun denne hvis du har problemer med at appen ikke opdager alle albums.",
"advanced_settings_enable_alternate_media_filter_subtitle": "Brug denne valgmulighed for at filtrere media under synkronisering baseret på alternative kriterier. Prøv kun denne, hvis du har problemer med, at appen ikke opdager alle albums.",
"advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTEL] Brug alternativ enheds album synkroniserings filter",
"advanced_settings_log_level_title": "Logniveau: {level}",
"advanced_settings_prefer_remote_subtitle": "Nogle enheder er meget lang tid om at indlæse miniaturebilleder af lokale elementer. Aktiver denne indstilling for at indlæse elementer fra serveren i stedet.",
"advanced_settings_prefer_remote_title": "Foretræk elementer på serveren",
"advanced_settings_proxy_headers_subtitle": "Definer proxy headers Immich skal sende med hver netværks forespørgsel",
"advanced_settings_proxy_headers_title": "Proxy headere",
"advanced_settings_proxy_headers_title": "Tilpasset proxy headere [EKSPERIMENTALT]",
"advanced_settings_readonly_mode_subtitle": "Aktiverer skrivebeskyttet tilstand, hvor billederne alene kan vises. Ting som at vælge flere billeder, dele, caste og slette er alle deaktiveret. Aktiver skrivebeskyttet tilstand via en bruger avatar fra hovedskærmen",
"advanced_settings_readonly_mode_title": "Skrivebeskyttet tilstand",
"advanced_settings_self_signed_ssl_subtitle": "Spring verificering af SSL-certifikat over for serverens endelokation. Kræves for selvsignerede certifikater.",
"advanced_settings_self_signed_ssl_title": "Tillad selvsignerede certifikater",
"advanced_settings_self_signed_ssl_title": "Tillad selvsignerede SSL certifikater [EKSPERIMENTALT]",
"advanced_settings_sync_remote_deletions_subtitle": "Slet eller gendan automatisk en mediefil på denne enhed, når denne handling foretages på Immich webinterface",
"advanced_settings_sync_remote_deletions_title": "Synkroniser fjernsletninger [EKSPERIMENTELT]",
"advanced_settings_tile_subtitle": "Avancerede brugerindstillinger",
@@ -414,6 +433,7 @@
"age_months": "Alder {months, plural, one {# måned} other {# måneder}}",
"age_year_months": "Alder 1 år, {months, plural, one {# måned} other {# måneder}}",
"age_years": "{years, plural, other {Alder #}}",
"album": "Album",
"album_added": "Album tilføjet",
"album_added_notification_setting_description": "Modtag en emailnotifikation når du bliver tilføjet til en delt album",
"album_cover_updated": "Albumcover opdateret",
@@ -459,16 +479,21 @@
"allow_edits": "Tillad redigeringer",
"allow_public_user_to_download": "Tillad offentlige brugere til at hente",
"allow_public_user_to_upload": "Tillad offentlige brugere til at uploade",
"allowed": "Tilladt",
"alt_text_qr_code": "QR-kode billede",
"anti_clockwise": "Mod uret",
"api_key": "API-nøgle",
"api_key_description": "Denne værdi vises kun én gang. Venligst kopiér den før du lukker vinduet.",
"api_key_empty": "Din API-nøgle-navn burde ikke være tom",
"api_keys": "API-nøgler",
"app_architecture_variant": "Variant (Arkitektur)",
"app_bar_signout_dialog_content": "Er du sikker på, du vil logge ud?",
"app_bar_signout_dialog_ok": "Ja",
"app_bar_signout_dialog_title": "Log ud",
"app_download_links": "App Download Links",
"app_settings": "Appindstillinger",
"app_stores": "App Butikker",
"app_update_available": "App opdatering er tilgængelig",
"appears_in": "Optræder i",
"apply_count": "Brug ({count, number})",
"archive": "Arkiv",
@@ -502,7 +527,7 @@
"asset_offline_description": "Denne eksterne mediefil kan ikke længere findes på drevet. Kontakt venligst din Immich-administrator for hjælp.",
"asset_restored_successfully": "Elementet blev gendannet succesfuldt",
"asset_skipped": "Sprunget over",
"asset_skipped_in_trash": "I skraldespand",
"asset_skipped_in_trash": "I papirkurv",
"asset_trashed": "Objekt kasseret",
"asset_troubleshoot": "Fejlsøg på objekt",
"asset_uploaded": "Uploadet",
@@ -552,6 +577,7 @@
"backup_albums_sync": "Synkronisering af backupalbums",
"backup_all": "Alt",
"backup_background_service_backup_failed_message": "Sikkerhedskopiering af elementer fejlede. Forsøger igen…",
"backup_background_service_complete_notification": "Sikkerhedskopiering af aktiver fuldført",
"backup_background_service_connection_failed_message": "Forbindelsen til serveren blev tabt. Forsøger igen…",
"backup_background_service_current_upload_notification": "Uploader {filename}",
"backup_background_service_default_notification": "Søger efter nye elementer…",
@@ -661,6 +687,8 @@
"change_password_description": "Dette er enten første gang du tilmelder dig, eller en ændring af kodeordet blev bestilt. Indtast dit nye kodeord herunder.",
"change_password_form_confirm_password": "Bekræft kodeord",
"change_password_form_description": "Hej {name},\n\nDette er enten første gang du logger ind eller også er der lavet en anmodning om at ændre dit kodeord. Indtast venligst et nyt kodeord nedenfor.",
"change_password_form_log_out": "Log ud af alle andre enheder",
"change_password_form_log_out_description": "Det er anbefalet at logge ud af alle andre enheder",
"change_password_form_new_password": "Nyt kodeord",
"change_password_form_password_mismatch": "Kodeord er ikke ens",
"change_password_form_reenter_new_password": "Gentag nyt kodeord",
@@ -687,8 +715,8 @@
"client_cert_import_success_msg": "Klient certifikat er importeret",
"client_cert_invalid_msg": "Invalid certifikat fil eller forkert adgangskode",
"client_cert_remove_msg": "Klient certifikat er fjernet",
"client_cert_subtitle": "Supportere kin PKCS12 (.p12, .pfx) Certifikat importering/fjernelse er kun tilgængeligt før login",
"client_cert_title": "SSL Klient Certifikat",
"client_cert_subtitle": "Supportere kun PKCS12 (.p12, .pfx) format. Certifikat importering/fjernelse er kun tilgængeligt før login",
"client_cert_title": "SSL Klient Certifikat [EKSPERIMENTAL]",
"clockwise": "Med uret",
"close": "Luk",
"collapse": "Klap sammen",
@@ -700,7 +728,6 @@
"comments_and_likes": "Kommentarer og likes",
"comments_are_disabled": "Kommentarer er slået fra",
"common_create_new_album": "Opret et nyt album",
"common_server_error": "Tjek din internetforbindelse, sørg for at serveren er tilgængelig og at app- og serversioner er kompatible.",
"completed": "Fuldført",
"confirm": "Bekræft",
"confirm_admin_password": "Bekræft administratoradgangskode",
@@ -739,6 +766,7 @@
"create": "Opret",
"create_album": "Opret album",
"create_album_page_untitled": "Uden titel",
"create_api_key": "Opret API nøgle",
"create_library": "Opret bibliotek",
"create_link": "Opret link",
"create_link_to_share": "Opret link for at dele",
@@ -768,6 +796,7 @@
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Mørk",
"dark_theme": "Skift til mørkt tema",
"date": "Dato",
"date_after": "Dato efter",
"date_and_time": "Dato og klokkeslæt",
"date_before": "Dato før",
@@ -870,8 +899,6 @@
"edit_description_prompt": "Vælg venligst en ny beskrivelse:",
"edit_exclusion_pattern": "Redigér udelukkelsesmønster",
"edit_faces": "Redigér ansigter",
"edit_import_path": "Redigér import-sti",
"edit_import_paths": "Redigér import-stier",
"edit_key": "Redigér nøgle",
"edit_link": "Rediger link",
"edit_location": "Rediger placering",
@@ -882,7 +909,6 @@
"edit_tag": "Rediger tag",
"edit_title": "Redigér titel",
"edit_user": "Redigér bruger",
"edited": "Redigeret",
"editor": "Redaktør",
"editor_close_without_save_prompt": "Ændringerne vil ikke blive gemt",
"editor_close_without_save_title": "Luk editor?",
@@ -944,7 +970,6 @@
"failed_to_stack_assets": "Det lykkedes ikke at stable mediefiler",
"failed_to_unstack_assets": "Det lykkedes ikke at fjerne gruperingen af mediefiler",
"failed_to_update_notification_status": "Kunne ikke uploade notifikations status",
"import_path_already_exists": "Denne importsti findes allerede.",
"incorrect_email_or_password": "Forkert email eller kodeord",
"paths_validation_failed": "{paths, plural, one {# sti} other {# stier}} slog fejl ved validering",
"profile_picture_transparent_pixels": "Profilbilleder kan ikke have gennemsigtige pixels. Zoom venligst ind og/eller flyt billedet.",
@@ -954,7 +979,6 @@
"unable_to_add_assets_to_shared_link": "Kan ikke tilføje mediefiler til det delte link",
"unable_to_add_comment": "Ikke i stand til at tilføje kommentar",
"unable_to_add_exclusion_pattern": "Kunne ikke tilføje udelukkelsesmønster",
"unable_to_add_import_path": "Kunne ikke tilføje importsti",
"unable_to_add_partners": "Ikke i stand til at tilføje partnere",
"unable_to_add_remove_archive": "Kan Ikke {archived, select, true {fjerne aktiv fra} other {tilføje aktiv til}} Arkiv",
"unable_to_add_remove_favorites": "Kan ikke {favorite, select, true {tilføje aktiv til} other {fjerne aktiv fra}} favoritter",
@@ -977,13 +1001,11 @@
"unable_to_delete_asset": "Kan ikke slette mediefil",
"unable_to_delete_assets": "Fejl i sletning af mediefiler",
"unable_to_delete_exclusion_pattern": "Kunne ikke slette udelukkelsesmønster",
"unable_to_delete_import_path": "Kunne ikke slette importsti",
"unable_to_delete_shared_link": "Kunne ikke slette delt link",
"unable_to_delete_user": "Ikke i stand til at slette bruger",
"unable_to_download_files": "Kan ikke downloade filer",
"unable_to_edit_exclusion_pattern": "Kunne ikke redigere udelukkelsesmønster",
"unable_to_edit_import_path": "Kunne ikke redigere importsti",
"unable_to_empty_trash": "Ikke i stand til at tømme skraldespand",
"unable_to_empty_trash": "Ikke i stand til at tømme papirkurv",
"unable_to_enter_fullscreen": "Kan ikke aktivere fuldskærmstilstand",
"unable_to_exit_fullscreen": "Kan ikke forlade fuldskærmstilstand",
"unable_to_get_comments_number": "Kan ikke få antallet af kommentarer",
@@ -1008,7 +1030,7 @@
"unable_to_reset_pin_code": "Kunne ikke nulstille din PIN kode",
"unable_to_resolve_duplicate": "Kunne ikke opklare duplikat",
"unable_to_restore_assets": "Kunne ikke gendanne medierfil",
"unable_to_restore_trash": "Ikke i stand til at gendanne fra skraldespanden",
"unable_to_restore_trash": "Ikke i stand til at gendanne fra papirkurv",
"unable_to_restore_user": "Ikke i stand til at gendanne bruger",
"unable_to_save_album": "Ikke i stand til at gemme album",
"unable_to_save_api_key": "Kunne ikke gemme API-nøgle",
@@ -1038,6 +1060,7 @@
"exif_bottom_sheet_description_error": "Fejl ved opdatering af beskrivelsen",
"exif_bottom_sheet_details": "DETALJER",
"exif_bottom_sheet_location": "LOKATION",
"exif_bottom_sheet_no_description": "Ingen beskrivelse",
"exif_bottom_sheet_people": "PERSONER",
"exif_bottom_sheet_person_add_person": "Tilføj navn",
"exit_slideshow": "Afslut slideshow",
@@ -1076,6 +1099,7 @@
"features_setting_description": "Administrer app-funktioner",
"file_name": "Filnavn",
"file_name_or_extension": "Filnavn eller filtype",
"file_size": "Fil størrelse",
"filename": "Filnavn",
"filetype": "Filtype",
"filter": "Filter",
@@ -1115,11 +1139,10 @@
"hash_asset": "Hash objekter",
"hashed_assets": "Hashede objekter",
"hashing": "Hasher",
"header_settings_add_header_tip": "Tilføj Header",
"header_settings_add_header_tip": "Tilføj header",
"header_settings_field_validator_msg": "Værdi kan ikke være tom",
"header_settings_header_name_input": "Header navn",
"header_settings_header_value_input": "Header værdi",
"headers_settings_tile_subtitle": "Definer proxy headers appen skal sende med hver netværks forespørgsel",
"headers_settings_tile_title": "Brugerdefineret proxy headers",
"hi_user": "Hej {name} ({email})",
"hide_all_people": "Skjul alle personer",
@@ -1172,6 +1195,8 @@
"import_path": "Import-sti",
"in_albums": "I {count, plural, one {# album} other {# albummer}}",
"in_archive": "I arkiv",
"in_year": "I {year}",
"in_year_selector": "I",
"include_archived": "Inkluder arkiveret",
"include_shared_albums": "Inkludér delte albummer",
"include_shared_partner_assets": "Inkludér delte partnermedier",
@@ -1208,6 +1233,7 @@
"language_setting_description": "Vælg dit foretrukne sprog",
"large_files": "Store filer",
"last": "Sidste",
"last_months": "{count, plural, one {Sidste måned} other {Sidste # måneder}}",
"last_seen": "Sidst set",
"latest_version": "Seneste version",
"latitude": "Breddegrad",
@@ -1240,6 +1266,7 @@
"local_media_summary": "Opsummering af lokale media",
"local_network": "Lokalt netværk",
"local_network_sheet_info": "Appen vil oprette forbindelse til serveren via denne URL, når du bruger det angivne WiFi-netværk",
"location": "Lokation",
"location_permission": "Tilladelse til placering",
"location_permission_content": "For automatisk at skifte netværk, skal Immich *altid* have præcis placeringsadgang, så appen kan læse Wi-Fi netværkets navn",
"location_picker_choose_on_map": "Vælg på kort",
@@ -1287,8 +1314,17 @@
"loop_videos_description": "Aktivér for at genafspille videoer automatisk i detaljeret visning.",
"main_branch_warning": "Du bruger en udviklingsversion; vi anbefaler kraftigt at bruge en udgivelsesversion!",
"main_menu": "Hovedmenu",
"maintenance_description": "Immich er blevet sat i <link>vedligeholdelsestilstand</link>.",
"maintenance_end": "Afslut vedligeholdelsestilstand",
"maintenance_end_error": "Vedligeholdelsestilstand kunne ikke afsluttes.",
"maintenance_logged_in_as": "Aktuelt logget ind som {user}",
"maintenance_title": "Midlertidigt Utilgængelig",
"make": "Producent",
"manage_geolocation": "Administrer placering",
"manage_media_access_rationale": "Denne tilladelse er påkrævet for korrekt håndtering af flytning af elementer til papirkurven og gendannelse af dem fra den.",
"manage_media_access_settings": "Åben instillinger",
"manage_media_access_subtitle": "Tillad Immich appen at administrere og flytte mediefiler.",
"manage_media_access_title": "Mediestyringsadgang",
"manage_shared_links": "Håndter delte links",
"manage_sharing_with_partners": "Administrér deling med partnere",
"manage_the_app_settings": "Administrer appindstillinger",
@@ -1344,38 +1380,45 @@
"minute": "Minut",
"minutes": "Minutter",
"missing": "Mangler",
"mobile_app": "Mobil App",
"mobile_app_download_onboarding_note": "Hent den tilhørende mobilapp via en af følgende muligheder",
"model": "Model",
"month": "Måned",
"monthly_title_text_date_format": "MMMM y",
"monthly_title_text_date_format": "MMMM å",
"more": "Mere",
"move": "Flyt",
"move_off_locked_folder": "Flyt ud af låst mappe",
"move_to_lock_folder_action_prompt": "{count} føjet til i den låste mappe",
"move_to": "Flyt til",
"move_to_lock_folder_action_prompt": "{count} føjet til den låste mappe",
"move_to_locked_folder": "Flyt til låst mappe",
"move_to_locked_folder_confirmation": "Disse billeder og videoer vil blive fjernet fra alle albums, og vil kun være synlig fra den låste mappe",
"moved_to_archive": "Flyttede {count, plural, one {# mediefil} other {# mediefiler}} til arkivet",
"moved_to_library": "Flyttede {count, plural, one {# mediefil} other {# mediefiler}} til biblioteket",
"moved_to_trash": "Flyttet til skraldespand",
"multiselect_grid_edit_date_time_err_read_only": "Kan ikke redigere datoen på kun læselige elementer. Springer over",
"multiselect_grid_edit_gps_err_read_only": "Kan ikke redigere lokation af kun læselige elementer. Springer over",
"moved_to_trash": "Flyttet til papirkurv",
"multiselect_grid_edit_date_time_err_read_only": "Kan ikke redigere datoen på skrivebeskyttet elementer. Springer over",
"multiselect_grid_edit_gps_err_read_only": "Kan ikke redigere lokation af skrivebeskyttet elementer. Springer over",
"mute_memories": "Dæmp minder",
"my_albums": "Mine albummer",
"name": "Navn",
"name_or_nickname": "Navn eller kælenavn",
"name_or_nickname": "Navn eller kaldenavn",
"navigate": "Naviger",
"navigate_to_time": "Naviger til tid",
"network_requirement_photos_upload": "Benyt mobildatanettet for at sikkerhedskopiere dine fotos",
"network_requirement_videos_upload": "Benyt mobildatanettet for at sikkerhedskopiere dine videoer",
"network_requirements": "Netværkskrav",
"network_requirements_updated": "Netværkskravene er ændret, backup-køen nulstilles",
"networking_settings": "Netværk",
"networking_subtitle": "Administrer serverens endepunktindstillinger",
"never": "aldrig",
"never": "Aldrig",
"new_album": "Nyt album",
"new_api_key": "Ny API-nøgle",
"new_date_range": "Nyt datointerval",
"new_password": "Ny adgangskode",
"new_person": "Ny person",
"new_pin_code": "Ny PIN kode",
"new_pin_code_subtitle": "Dette er første gang du tilgår den låste mappe. Lav en PIN kode for sikkert at tilgå denne side",
"new_timeline": "Ny tidslinje",
"new_update": "Ny opdatering",
"new_user_created": "Ny bruger oprettet",
"new_version_available": "NY VERSION TILGÆNGELIG",
"newest_first": "Nyeste først",
@@ -1391,6 +1434,7 @@
"no_cast_devices_found": "Ingen Cast-enheder fundet",
"no_checksum_local": "Ingen checksum tilgængelig kan ikke hente lokale objekter",
"no_checksum_remote": "Ingen checksum tilgængelig kan ikke hente eksterne objekter",
"no_devices": "Ingen godkendte enheder",
"no_duplicates_found": "Ingen duplikater fundet.",
"no_exif_info_available": "Ingen tilgængelig exif information",
"no_explore_results_message": "Upload flere billeder for at udforske din samling.",
@@ -1407,6 +1451,7 @@
"no_results_description": "Prøv et synonym eller et mere generelt søgeord",
"no_shared_albums_message": "Opret et album for at dele billeder og videoer med personer i dit netværk",
"no_uploads_in_progress": "Ingen upload i gang",
"not_allowed": "Ikke tilladt",
"not_available": "ikke tilgængelig",
"not_in_any_album": "Ikke i noget album",
"not_selected": "Ikke valgt",
@@ -1421,6 +1466,9 @@
"notifications": "Notifikationer",
"notifications_setting_description": "Administrér notifikationer",
"oauth": "OAuth",
"obtainium_configurator": "Obtainium-konfigurator",
"obtainium_configurator_instructions": "Brug Obtainium til at installere og opdatere Android-appen direkte fra Immich-udgivelsen på GitHub. Opret en API-nøgle, og vælg en variant for at generere dit Obtainium-konfigurationslink",
"ocr": "OCR",
"official_immich_resources": "Officielle Immich-ressourcer",
"offline": "Offline",
"offset": "Forskydning",
@@ -1514,6 +1562,8 @@
"photos_count": "{count, plural, one {{count, number} Billede} other {{count, number} Billeder}}",
"photos_from_previous_years": "Billeder fra tidligere år",
"pick_a_location": "Vælg et sted",
"pick_custom_range": "Brugerdefineret periode",
"pick_date_range": "Vælg et datointerval",
"pin_code_changed_successfully": "Ændring af PIN kode vellykket",
"pin_code_reset_successfully": "Nulstilling af PIN kode vellykket",
"pin_code_setup_successfully": "Opsætning af PIN kode vellykket",
@@ -1525,6 +1575,9 @@
"play_memories": "Afspil minder",
"play_motion_photo": "Afspil bevægelsesbillede",
"play_or_pause_video": "Afspil eller pause video",
"play_original_video": "Afspil original video",
"play_original_video_setting_description": "Foretrækker afspilning af originale videoer frem for transkodede videoer. Hvis det originale element ikke er kompatibelt, afspilles det muligvis ikke korrekt.",
"play_transcoded_video": "Afspil transkodet video",
"please_auth_to_access": "Log venligst ind for at tilgå",
"port": "Port",
"preferences_settings_subtitle": "Administrer app-præferencer",
@@ -1542,13 +1595,9 @@
"privacy": "Privatliv",
"profile": "Profil",
"profile_drawer_app_logs": "Log",
"profile_drawer_client_out_of_date_major": "Mobilapp er forældet. Opdater venligst til den nyeste større version.",
"profile_drawer_client_out_of_date_minor": "Mobilapp er forældet. Opdater venligst til den nyeste mindre version.",
"profile_drawer_client_server_up_to_date": "Klient og server er ajour",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Skrivebeskyttet tilstand aktiveret. Lang tryk på bruger avatar ikonet for at afslutte.",
"profile_drawer_server_out_of_date_major": "Server er forældet. Opdater venligst til den nyeste større version.",
"profile_drawer_server_out_of_date_minor": "Server er forældet. Opdater venligst til den nyeste mindre version.",
"profile_image_of_user": "Profilbillede af {user}",
"profile_picture_set": "Profilbillede indstillet.",
"public_album": "Offentligt album",
@@ -1665,6 +1714,7 @@
"reset_sqlite_confirmation": "Er du sikker på, at du vil nulstille SQLite databasen? Du er nødt til at logge ud og ind igen for at gensynkronisere dine data",
"reset_sqlite_success": "Vellykket reset af SQLite databasen",
"reset_to_default": "Nulstil til standard",
"resolution": "Opløsning",
"resolve_duplicates": "Løs dubletter",
"resolved_all_duplicates": "Alle dubletter løst",
"restore": "Gendan",
@@ -1683,8 +1733,9 @@
"running": "Kører",
"save": "Gem",
"save_to_gallery": "Gem til galleri",
"saved": "Gemt",
"saved_api_key": "Gemt API-nøgle",
"saved_profile": "Gemte profil",
"saved_profile": "Gemt profil",
"saved_settings": "Gemte indstillinger",
"say_something": "Skriv noget",
"scaffold_body_error_occurred": "Der opstod en fejl",
@@ -1699,6 +1750,9 @@
"search_by_description_example": "Vandredag i Paris",
"search_by_filename": "Søg efter filnavn eller filtypenavn",
"search_by_filename_example": "dvs. IMG_1234.JPG eller PNG",
"search_by_ocr": "Søg via OCR",
"search_by_ocr_example": "Søg efter tekst i dine billeder",
"search_camera_lens_model": "Søg objektiv model...",
"search_camera_make": "Søg efter kameraproducent...",
"search_camera_model": "Søg efter kameramodel...",
"search_city": "Søg efter by...",
@@ -1715,6 +1769,7 @@
"search_filter_location_title": "Vælg lokation",
"search_filter_media_type": "Medietype",
"search_filter_media_type_title": "Vælg medietype",
"search_filter_ocr": "Søg via OCR",
"search_filter_people_title": "Vælg personer",
"search_for": "Søg efter",
"search_for_existing_person": "Søg efter eksisterende person",
@@ -1725,7 +1780,7 @@
"search_options": "Søgemuligheder",
"search_page_categories": "Kategorier",
"search_page_motion_photos": "Bevægelsesbilleder",
"search_page_no_objects": "Ingen elementer er tilgængelige",
"search_page_no_objects": "Ingen elementinfomation er tilgængelig",
"search_page_no_places": "Ingen placeringsinformation er tilgængelig",
"search_page_screenshots": "Skærmbilleder",
"search_page_search_photos_videos": "Søg i dine billeder og videoer",
@@ -1776,7 +1831,10 @@
"server_offline": "Server offline",
"server_online": "Server online",
"server_privacy": "Serverens privatliv",
"server_restarting_description": "Denne side opdateres om et øjeblik.",
"server_restarting_title": "Serveren genstarter",
"server_stats": "Serverstatus",
"server_update_available": "Serveropdatering er tilgængelig",
"server_version": "Server version",
"set": "Indstil",
"set_as_album_cover": "Indstil som albumcover",
@@ -1804,8 +1862,10 @@
"setting_notifications_single_progress_title": "Vis detaljeret baggrundsuploadstatus",
"setting_notifications_subtitle": "Tilpas dine notifikationspræferencer",
"setting_notifications_total_progress_subtitle": "Samlet uploadstatus (færdige/samlet antal elementer)",
"setting_notifications_total_progress_title": "Vis samlet baggrundsuploadstatus",
"setting_video_viewer_looping_title": "Looper",
"setting_notifications_total_progress_title": "Vis samlet baggrunds upload status",
"setting_video_viewer_auto_play_subtitle": "Begynd automatisk at afspille videoer, når de åbnes",
"setting_video_viewer_auto_play_title": "Automatisk afspilning af videoer",
"setting_video_viewer_looping_title": "Genafspilning",
"setting_video_viewer_original_video_subtitle": "Når der streames video fra serveren, afspil da den originale selv når en omkodet udgave er tilgængelig. Kan føre til buffering. Videoer, der er tilgængelige lokalt, afspilles i original kvalitet uanset denne indstilling.",
"setting_video_viewer_original_video_title": "Tving original video",
"settings": "Indstillinger",
@@ -1861,7 +1921,7 @@
"shared_link_info_chip_metadata": "EXIF",
"shared_link_manage_links": "Håndter delte links",
"shared_link_options": "Muligheder for delt link",
"shared_link_password_description": "Kræv et kodeord for at få adgang til dette delte link",
"shared_link_password_description": "Kodeord krævet for at få adgang til dette delte link",
"shared_links": "Delte links",
"shared_links_description": "Del billeder og videoer med et link",
"shared_photos_and_videos_count": "{assetCount, plural, other {# delte billeder & videoer.}}",
@@ -1894,8 +1954,8 @@
"show_search_options": "Vis søgeindstillinger",
"show_shared_links": "Vis delte links",
"show_slideshow_transition": "Vis overgang til diasshow",
"show_supporter_badge": "Supportermærke",
"show_supporter_badge_description": "Vis et supportermærke",
"show_supporter_badge": "Supporter skilt",
"show_supporter_badge_description": "Vis et supporter ikon",
"show_text_search_menu": "Vis tekstsøgningsmenu",
"shuffle": "Bland",
"sidebar": "Sidebjælke",
@@ -1930,7 +1990,7 @@
"start_date_before_end_date": "Startdato skal ligge før slutdato",
"state": "Stat",
"status": "Status",
"stop_casting": "Stop støbning",
"stop_casting": "Stop casting",
"stop_motion_photo": "Stopmotionbillede",
"stop_photo_sharing": "Stop med at dele dine billeder?",
"stop_photo_sharing_description": "{partner} vil ikke længere kunne tilgå dine billeder.",
@@ -1984,18 +2044,20 @@
"theme_setting_three_stage_loading_title": "Slå tre-trins indlæsning til",
"they_will_be_merged_together": "De vil blive slået sammen",
"third_party_resources": "Tredjepartsressourcer",
"time": "Tid",
"time_based_memories": "Tidsbaserede minder",
"time_based_memories_duration": "Antal sekunder, hvert billede skal vises.",
"timeline": "Tidslinje",
"timezone": "Tidszone",
"to_archive": "Arkivér",
"to_change_password": "Skift adgangskode",
"to_favorite": "Gør til favorit",
"to_login": "Login",
"to_multi_select": "For at vælge flere",
"to_parent": "Gå op",
"to_multi_select": "for at vælge flere",
"to_parent": "Gå et niveau op",
"to_select": "for at vælge",
"to_trash": "Papirkurv",
"toggle_settings": "S indstillinger til eller fra",
"toggle_settings": "Skift indstillinger",
"total": "Total",
"total_usage": "Samlet forbrug",
"trash": "Papirkurv",
@@ -2012,12 +2074,13 @@
"trash_page_restore_all": "Gendan alt",
"trash_page_select_assets_btn": "Vælg elementer",
"trash_page_title": "Papirkurv ({count})",
"trashed_items_will_be_permanently_deleted_after": "Mediefiler i skraldespanden vil blive slettet permanent efter {days, plural, one {# dag} other {# dage}}.",
"trashed_items_will_be_permanently_deleted_after": "Mediefiler i papirkurven vil blive slettet permanent efter {days, plural, one {# dag} other {# dage}}.",
"troubleshoot": "Fejlfinding",
"type": "Type",
"unable_to_change_pin_code": "Kunne ikke ændre PIN kode",
"unable_to_check_version": "Kan ikke tjekke app- eller serverversion",
"unable_to_setup_pin_code": "Kunne ikke sætte PIN kode",
"unarchive": "Afakivér",
"unarchive": "Af Akivér",
"unarchive_action_prompt": "{count} slettet fra Arkiv",
"unarchived_count": "{count, plural, other {Uarkiveret #}}",
"undo": "Fortryd",
@@ -2124,6 +2187,7 @@
"welcome": "Velkommen",
"welcome_to_immich": "Velkommen til Immich",
"wifi_name": "Wi-Fi navn",
"workflow": "Arbejdsproces",
"wrong_pin_code": "Forkert PIN kode",
"year": "År",
"years_ago": "{years, plural, one {# år} other {# år}} siden",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Geburtsdatum hinzufügen",
"add_endpoint": "Endpunkt hinzufügen",
"add_exclusion_pattern": "Ausschlussmuster hinzufügen",
"add_import_path": "Importpfad hinzufügen",
"add_location": "Standort hinzufügen",
"add_more_users": "Weitere Nutzer hinzufügen",
"add_partner": "Partner hinzufügen",
@@ -53,7 +52,7 @@
"backup_onboarding_1_description": "Offsite-Kopie in der Cloud oder an einem anderen physischen Ort.",
"backup_onboarding_2_description": "lokale Kopien auf verschiedenen Geräten. Dazu gehören die Hauptdateien und eine lokale Sicherung dieser Dateien.",
"backup_onboarding_3_description": "Kopien deiner Daten inklusive Originaldateien. Dies umfasst 1 Kopie an einem anderen Ort und 2 lokale Kopien.",
"backup_onboarding_description": "Eine <backblaze-link>3-2-1 Sicherungssrategie</backblaze-link> wird empfohlen, um deine Daten zu schützen. Du solltest sowohl Kopien deiner hochgeladenen Fotos/Videos als auch der Immich-Datenbank aufbewahren, um eine umfassende Sicherungslösung zu haben.",
"backup_onboarding_description": "Eine <backblaze-link>3-2-1 Sicherungsstrategie</backblaze-link> wird empfohlen, um deine Daten zu schützen. Du solltest sowohl Kopien deiner hochgeladenen Fotos/Videos als auch der Immich-Datenbank aufbewahren, um eine umfassende Sicherungslösung zu haben.",
"backup_onboarding_footer": "Weitere Informationen zum Sichern von Immich findest du in der <link>Dokumentation</link>.",
"backup_onboarding_parts_title": "Eine 3-2-1-Sicherung umfasst:",
"backup_onboarding_title": "Sicherungen",
@@ -66,7 +65,7 @@
"confirm_email_below": "Bestätige, indem du unten \"{email}\" eingibst",
"confirm_reprocess_all_faces": "Bist du sicher, dass du alle Gesichter erneut verarbeiten möchtest? Dies löscht auch alle bereits benannten Personen.",
"confirm_user_password_reset": "Bist du sicher, dass du das Passwort für {user} zurücksetzen möchtest?",
"confirm_user_pin_code_reset": "Bist du sicher, dass du den PIN Code von {user} zurücksetzen möchtest?",
"confirm_user_pin_code_reset": "Bist du sicher, dass du den PIN-Code von {user} zurücksetzen möchtest?",
"create_job": "Aufgabe erstellen",
"cron_expression": "Cron-Zeitangabe",
"cron_expression_description": "Setze das Scanintervall im Cron-Format. Hilfe mit dem Format bietet dir dabei z. B. der <link>Crontab Guru</link>",
@@ -112,7 +111,6 @@
"jobs_failed": "{jobCount, plural, other {# fehlgeschlagen}}",
"library_created": "Bibliothek erstellt: {library}",
"library_deleted": "Bibliothek gelöscht",
"library_import_path_description": "Gib einen Ordner für den Import an. Dieser Ordner, einschließlich der Unterordner, wird nach Bildern und Videos durchsucht.",
"library_scanning": "Periodisches Scannen",
"library_scanning_description": "Regelmäßiges Durchsuchen der Bibliothek einstellen",
"library_scanning_enable_description": "Regelmäßiges Scannen der Bibliothek aktivieren",
@@ -120,7 +118,7 @@
"library_settings_description": "Einstellungen externer Bibliotheken verwalten",
"library_tasks_description": "Überprüfe externe Bibliotheken auf neue und/oder veränderte Medien",
"library_watching_enable_description": "Überwache externe Bibliotheken auf Dateiänderungen",
"library_watching_settings": "Bibliotheksüberwachung (EXPERIMENTELL)",
"library_watching_settings": "Überwache Bibliothek [EXPERIMENTELL]",
"library_watching_settings_description": "Automatisch auf geänderte Dateien prüfen",
"logging_enable_description": "Aktiviere Logging",
"logging_level_description": "Wenn aktiviert, welches Log-Level genutzt wird.",
@@ -150,10 +148,22 @@
"machine_learning_max_detection_distance_description": "Maximaler Unterschied zwischen zwei Bildern, um sie als Duplikate zu betrachten, im Bereich von 0,001-0,1. Bei höheren Werten werden mehr Duplikate erkannt, aber es kann zu falsch-positiven Ergebnissen kommen.",
"machine_learning_max_recognition_distance": "Maximaler Erkennungsabstand",
"machine_learning_max_recognition_distance_description": "Maximaler Abstand zwischen zwei Gesichtern, die als dieselbe Person angesehen werden, von 0-2. Ein niedrigerer Wert kann verhindern, dass zwei Personen als dieselbe Person eingestuft werden, während ein höherer Wert verhindern kann, dass ein und dieselbe Person als zwei verschiedene Personen eingestuft wird. Bitte beachte dabei, dass es einfacher ist, zwei Personen zu verschmelzen, als eine Person in zwei zu teilen, also wähle nach Möglichkeit einen niedrigeren Schwellenwert.",
"machine_learning_min_detection_score": "Minimale Erkennungsrate",
"machine_learning_min_detection_score": "Mindest-Erkennungs Wert",
"machine_learning_min_detection_score_description": "Minimale Konfidenzrate für die Erkennung eines Gesichts von 0-1. Bei niedrigeren Werten werden mehr Gesichter erkannt, aber es kann zu falsch-positiven Ergebnissen kommen.",
"machine_learning_min_recognized_faces": "Mindestens erkannte Gesichter",
"machine_learning_min_recognized_faces_description": "Die Mindestanzahl von erkannten Gesichtern, damit eine Person erstellt werden kann. Eine Erhöhung dieses Wertes macht die Gesichtserkennung präziser, erhöht aber die Wahrscheinlichkeit, dass ein Gesicht nicht zu einer Person zugeordnet wird.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Maschinelles Lernen nutzen um Texte in Bildern zu erkennen",
"machine_learning_ocr_enabled": "OCR aktivieren",
"machine_learning_ocr_enabled_description": "Wenn deaktiviert, werden die Bilder nicht von der Texterkennung bearbeitet.",
"machine_learning_ocr_max_resolution": "Maximale Auflösung",
"machine_learning_ocr_max_resolution_description": "Vorschauen über dieser Auflösung werden unter Beibehaltung des Seitenverhältnisses verkleinert. Höhere Werte sind genauer, benötigen jedoch mehr Zeit für die Verarbeitung und verbrauchen mehr Speicher.",
"machine_learning_ocr_min_detection_score": "Minimaler Erkennungswert",
"machine_learning_ocr_min_detection_score_description": "Minimale Konfidenzrate für die Texterkennung von 01. Niedrigere Werte führen dazu, dass mehr Text erkannt wird, können jedoch zu falsch-positiven Ergebnissen führen.",
"machine_learning_ocr_min_recognition_score": "Mindest-Erkennungswert",
"machine_learning_ocr_min_score_recognition_description": "Minimale Konfidenzrate für die Erkennung von erkanntem Text von 01. Niedrigere Werte führen dazu, dass mehr Text erkannt wird, können jedoch zu falsch-positiven Ergebnissen führen.",
"machine_learning_ocr_model": "OCR Modell",
"machine_learning_ocr_model_description": "Server Modelle sind genauer als mobile Modelle, brauchen aber länger zur Verarbeitung und brauchen mehr Speicher.",
"machine_learning_settings": "Einstellungen für maschinelles Lernen",
"machine_learning_settings_description": "Funktionen und Einstellungen des maschinellen Lernens verwalten",
"machine_learning_smart_search": "Intelligente Suche",
@@ -211,6 +221,8 @@
"notification_email_ignore_certificate_errors_description": "TLS-Zertifikatsvalidierungsfehler ignorieren (nicht empfohlen)",
"notification_email_password_description": "Passwort für die Anmeldung am E-Mail-Server",
"notification_email_port_description": "Port des E-Mail-Servers (z.B. 25, 465, oder 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Benutze SMTPS (SMTP über TLS)",
"notification_email_sent_test_email_button": "Test-E-Mail versenden und speichern",
"notification_email_setting_description": "Einstellungen für E-Mail-Benachrichtigungen",
"notification_email_test_email": "Test-E-Mail senden",
@@ -243,6 +255,7 @@
"oauth_storage_quota_default_description": "Kontingent in GiB, das verwendet werden soll, wenn keines übermittelt wird.",
"oauth_timeout": "Zeitüberschreitung bei Anfrage",
"oauth_timeout_description": "Zeitüberschreitung für Anfragen in Millisekunden",
"ocr_job_description": "Verwende Machine Learning zur Erkennung von Text in Bildern",
"password_enable_description": "Mit E-Mail und Passwort anmelden",
"password_settings": "Passwort-Anmeldung",
"password_settings_description": "Passwort-Anmeldeeinstellungen verwalten",
@@ -333,7 +346,7 @@
"transcoding_max_b_frames": "Maximale B-Frames",
"transcoding_max_b_frames_description": "Höhere Werte verbessern die Komprimierungseffizienz, verlangsamen aber die Kodierung. Ist möglicherweise nicht mit der Hardware-Beschleunigung älterer Geräte kompatibel. 0 deaktiviert die B-Frames, während -1 diesen Wert automatisch setzt.",
"transcoding_max_bitrate": "Maximale Bitrate",
"transcoding_max_bitrate_description": "Die Festlegung einer maximalen Bitrate kann die Dateigrößen vorhersagbarer machen, ohne dass die Qualität darunter leidet. Bei 720p sind typische Werte 2600 kbit/s für VP9 oder HEVC oder 4500 kbit/s für H.264. Deaktiviert, wenn der Wert auf 0 gesetzt ist.",
"transcoding_max_bitrate_description": "Das Festlegen einer maximalen Bitrate kann die Dateigrößen vorhersagbarer machen, ohne dass die Qualität darunter leidet. Bei 720p sind typische Werte 2600 kbit/s für VP9 oder HEVC oder 4500 kbit/s für H.264. Deaktiviert, wenn der Wert auf 0 gesetzt ist. Wenn keine Einheit angegeben wird, wird von k (für kbit/s) ausgegangen; also sind 5000, 5000k und 5M (für Mbit/s) identisch.",
"transcoding_max_keyframe_interval": "Maximales Keyframe-Intervall",
"transcoding_max_keyframe_interval_description": "Legt den maximalen Frame-Abstand zwischen Keyframes fest. Niedrigere Werte verschlechtern die Komprimierungseffizienz, verbessern aber die Suchzeiten und können die Qualität in Szenen mit schnellen Bewegungen verbessern. Bei 0 wird dieser Wert automatisch eingestellt.",
"transcoding_optimal_description": "Videos mit einer höheren Auflösung als der Zielauflösung oder in einem nicht akzeptierten Format",
@@ -351,7 +364,7 @@
"transcoding_target_resolution": "Ziel-Auflösung",
"transcoding_target_resolution_description": "Höhere Auflösungen können mehr Details erhalten, benötigen aber mehr Zeit für die Codierung, haben größere Dateigrößen und können die Reaktionszeit der Anwendung beeinträchtigen.",
"transcoding_temporal_aq": "Temporäre AQ",
"transcoding_temporal_aq_description": "Gilt nur für NVENC. Verbessert die Qualität von Szenen mit hohem Detailreichtum und geringen Bewegungen. Dies ist möglicherweise nicht mit älteren Geräten kompatibel.",
"transcoding_temporal_aq_description": "Gilt nur für NVENC. Zeitlich adaptive Quantisierung verbessert die Qualität von Szenen mit hohem Detailreichtum und geringen Bewegungen. Dies ist möglicherweise nicht mit älteren Geräten kompatibel.",
"transcoding_threads": "Threads",
"transcoding_threads_description": "Höhere Werte führen zu einer schnelleren Kodierung, lassen dem Server jedoch weniger Spielraum für die Verarbeitung anderer Aufgaben im aktiven Zustand. Dieser Wert sollte nicht höher sein als die Anzahl der CPU-Kerne. Maximiert die Auslastung, wenn der Wert auf 0 gesetzt wird.",
"transcoding_tone_mapping": "Farbton-Mapping",
@@ -402,11 +415,11 @@
"advanced_settings_prefer_remote_subtitle": "Einige Geräte sind sehr langsam beim Laden von lokalen Vorschaubildern. Aktivieren Sie diese Einstellung, um stattdessen die Server-Bilder zu laden.",
"advanced_settings_prefer_remote_title": "Server-Bilder bevorzugen",
"advanced_settings_proxy_headers_subtitle": "Definiere einen Proxy-Header, den Immich bei jeder Netzwerkanfrage mitschicken soll",
"advanced_settings_proxy_headers_title": "Proxy-Headers",
"advanced_settings_proxy_headers_title": "Benutzerdefinierte Proxy-Header [Experimentell]",
"advanced_settings_readonly_mode_subtitle": "Aktiviert den schreibgeschützten Modus, in dem die Fotos nur angezeigt werden können. Funktionen wie das Auswählen mehrerer Bilder, das Teilen, das Übertragen und das Löschen sind deaktiviert. Aktivieren/Deaktiviere den schreibgeschützten Modus über den Benutzer-Avatar auf dem Hauptbildschirm",
"advanced_settings_readonly_mode_title": "Schreibgeschützter Modus",
"advanced_settings_self_signed_ssl_subtitle": "Verifizierung von SSL-Zertifikaten vom Server überspringen. Notwendig bei selbstsignierten Zertifikaten.",
"advanced_settings_self_signed_ssl_title": "Selbstsignierte SSL-Zertifikate erlauben",
"advanced_settings_self_signed_ssl_title": "Selbstsignierte SSL-Zertifikate erlauben [Experimentell]",
"advanced_settings_sync_remote_deletions_subtitle": "Automatisches Löschen oder Wiederherstellen einer Datei auf diesem Gerät, wenn diese Aktion im Web durchgeführt wird",
"advanced_settings_sync_remote_deletions_title": "Mit Server-Löschungen synchronisieren [Experimentell]",
"advanced_settings_tile_subtitle": "Erweiterte Benutzereinstellungen",
@@ -460,16 +473,21 @@
"allow_edits": "Bearbeiten erlauben",
"allow_public_user_to_download": "Erlaube öffentlichen Benutzern, herunterzuladen",
"allow_public_user_to_upload": "Erlaube öffentlichen Benutzern, hochzuladen",
"allowed": "Erlaubt",
"alt_text_qr_code": "QR-Code Bild",
"anti_clockwise": "Gegen den Uhrzeigersinn",
"api_key": "API-Schlüssel",
"api_key_description": "Dieser Wert wird nur einmal angezeigt. Bitte kopiere ihn, bevor du das Fenster schließt.",
"api_key_empty": "Dein API-Schlüssel-Name darf nicht leer sein",
"api_keys": "API-Schlüssel",
"app_architecture_variant": "Variante (Architektur)",
"app_bar_signout_dialog_content": "Bist du dir sicher, dass du dich abmelden möchtest?",
"app_bar_signout_dialog_ok": "Ja",
"app_bar_signout_dialog_title": "Abmelden",
"app_download_links": "App Download Links",
"app_settings": "App-Einstellungen",
"app_stores": "App Stores",
"app_update_available": "App Update verfügbar",
"appears_in": "Erscheint in",
"apply_count": "Anwenden ({count, number})",
"archive": "Archiv",
@@ -553,6 +571,7 @@
"backup_albums_sync": "Synchronisation der Sicherungsalben",
"backup_all": "Alle",
"backup_background_service_backup_failed_message": "Es trat ein Fehler bei der Sicherung auf. Erneuter Versuch…",
"backup_background_service_complete_notification": "Datei Backup abgeschlossen",
"backup_background_service_connection_failed_message": "Es konnte keine Verbindung zum Server hergestellt werden. Erneuter Versuch…",
"backup_background_service_current_upload_notification": "Lädt {filename} hoch",
"backup_background_service_default_notification": "Suche nach neuen Elementen…",
@@ -662,10 +681,12 @@
"change_password_description": "Dies ist entweder das erste Mal, dass du dich im System anmeldest, oder es wurde eine Anfrage zur Änderung deines Passworts gestellt. Bitte gib unten dein neues Passwort ein.",
"change_password_form_confirm_password": "Passwort bestätigen",
"change_password_form_description": "Hallo {name}\n\nDas ist entweder das erste Mal dass du dich einloggst oder es wurde eine Anfrage zur Änderung deines Passwortes gestellt. Bitte gib das neue Passwort ein.",
"change_password_form_log_out": "Von allen Geräte abmelden",
"change_password_form_log_out_description": "Es wird empfohlen, alle anderen Geräte abzumelden",
"change_password_form_new_password": "Neues Passwort",
"change_password_form_password_mismatch": "Passwörter stimmen nicht überein",
"change_password_form_reenter_new_password": "Passwort erneut eingeben",
"change_pin_code": "PIN Code ändern",
"change_pin_code": "PIN-Code ändern",
"change_your_password": "Ändere dein Passwort",
"changed_visibility_successfully": "Die Sichtbarkeit wurde erfolgreich geändert",
"charging": "Aufladen",
@@ -689,7 +710,7 @@
"client_cert_invalid_msg": "Ungültige Zertifikatsdatei oder falsches Passwort",
"client_cert_remove_msg": "Client Zertifikat wurde entfernt",
"client_cert_subtitle": "Unterstützt nur das PKCS12 (.p12, .pfx) Format. Zertifikatsimporte oder -entfernungen sind nur vor dem Login möglich",
"client_cert_title": "SSL-Client-Zertifikat",
"client_cert_title": "SSL-Client-Zertifikat [Experimentell]",
"clockwise": "Im Uhrzeigersinn",
"close": "Schließen",
"collapse": "Zusammenklappen",
@@ -701,14 +722,13 @@
"comments_and_likes": "Kommentare & Likes",
"comments_are_disabled": "Kommentare sind deaktiviert",
"common_create_new_album": "Neues Album erstellen",
"common_server_error": "Bitte überprüfe deine Netzwerkverbindung und stelle sicher, dass die App und Server Versionen kompatibel sind.",
"completed": "Abgeschlossen",
"confirm": "Bestätigen",
"confirm_admin_password": "Administrator Passwort bestätigen",
"confirm_delete_face": "Bist du sicher dass du das Gesicht von {name} aus der Datei entfernen willst?",
"confirm_delete_shared_link": "Bist du sicher, dass du diesen geteilten Link löschen willst?",
"confirm_keep_this_delete_others": "Alle anderen Dateien im Stapel bis auf diese werden gelöscht. Bist du sicher, dass du fortfahren möchten?",
"confirm_new_pin_code": "Neuen PIN Code bestätigen",
"confirm_new_pin_code": "Neuen PIN-Code bestätigen",
"confirm_password": "Passwort bestätigen",
"confirm_tag_face": "Wollen Sie dieses Gesicht mit {name} markieren?",
"confirm_tag_face_unnamed": "Möchten Sie dieses Gesicht markieren?",
@@ -740,6 +760,7 @@
"create": "Erstellen",
"create_album": "Album erstellen",
"create_album_page_untitled": "Unbenannt",
"create_api_key": "API Key erstellen",
"create_library": "Bibliothek erstellen",
"create_link": "Link erstellen",
"create_link_to_share": "Link zum Teilen erstellen",
@@ -760,7 +781,7 @@
"crop": "Zuschneiden",
"curated_object_page_title": "Dinge",
"current_device": "Aktuelles Gerät",
"current_pin_code": "Aktueller PIN Code",
"current_pin_code": "Aktueller PIN-Code",
"current_server_address": "Aktuelle Serveradresse",
"custom_locale": "Benutzerdefinierte Sprache",
"custom_locale_description": "Datumsangaben und Zahlen je nach Sprache und Land formatieren",
@@ -769,6 +790,7 @@
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Dunkel",
"dark_theme": "Dunkle Ansicht umschalten",
"date": "Datum",
"date_after": "Datum nach",
"date_and_time": "Datum und Zeit",
"date_before": "Datum vor",
@@ -871,8 +893,6 @@
"edit_description_prompt": "Bitte wähle eine neue Beschreibung:",
"edit_exclusion_pattern": "Ausschlussmuster bearbeiten",
"edit_faces": "Gesichter bearbeiten",
"edit_import_path": "Importpfad bearbeiten",
"edit_import_paths": "Importpfade bearbeiten",
"edit_key": "Schlüssel bearbeiten",
"edit_link": "Link bearbeiten",
"edit_location": "Standort bearbeiten",
@@ -883,7 +903,6 @@
"edit_tag": "Tag bearbeiten",
"edit_title": "Titel bearbeiten",
"edit_user": "Nutzer bearbeiten",
"edited": "Bearbeitet",
"editor": "Bearbeiter",
"editor_close_without_save_prompt": "Die Änderungen werden nicht gespeichert",
"editor_close_without_save_title": "Editor schließen?",
@@ -896,13 +915,13 @@
"empty_trash_confirmation": "Bist du sicher, dass du den Papierkorb leeren willst?\nDies entfernt alle Dateien im Papierkorb endgültig aus Immich und kann nicht rückgängig gemacht werden!",
"enable": "Aktivieren",
"enable_backup": "Sicherung aktivieren",
"enable_biometric_auth_description": "Gib deinen PIN Code ein, um die biometrische Authentifizierung zu aktivieren",
"enable_biometric_auth_description": "Gib deinen PIN-Code ein, um die biometrische Authentifizierung zu aktivieren",
"enabled": "Aktiviert",
"end_date": "Enddatum",
"enqueued": "Eingereiht",
"enter_wifi_name": "WLAN-Name eingeben",
"enter_your_pin_code": "PIN Code eingeben",
"enter_your_pin_code_subtitle": "Gib deinen PIN Code ein, um auf den gesperrten Ordner zuzugreifen",
"enter_your_pin_code": "PIN-Code eingeben",
"enter_your_pin_code_subtitle": "Gib deinen PIN-Code ein, um auf den gesperrten Ordner zuzugreifen",
"error": "Fehler",
"error_change_sort_album": "Ändern der Anzeigereihenfolge fehlgeschlagen",
"error_delete_face": "Fehler beim Löschen des Gesichts",
@@ -941,11 +960,10 @@
"failed_to_load_notifications": "Fehler beim Laden der Benachrichtigungen",
"failed_to_load_people": "Fehler beim Laden von Personen",
"failed_to_remove_product_key": "Fehler beim Entfernen des Produktschlüssels",
"failed_to_reset_pin_code": "Zurücksetzen des PIN Codes fehlgeschlagen",
"failed_to_reset_pin_code": "Zurücksetzen des PIN-Codes fehlgeschlagen",
"failed_to_stack_assets": "Dateien konnten nicht gestapelt werden",
"failed_to_unstack_assets": "Dateien konnten nicht entstapelt werden",
"failed_to_update_notification_status": "Benachrichtigungsstatus aktualisieren fehlgeschlagen",
"import_path_already_exists": "Dieser Importpfad existiert bereits.",
"incorrect_email_or_password": "Ungültige E-Mail oder Passwort",
"paths_validation_failed": "{paths, plural, one {# Pfad konnte} other {# Pfade konnten}} nicht validiert werden",
"profile_picture_transparent_pixels": "Profilbilder dürfen keine transparenten Pixel haben. Bitte zoome heran und/oder verschiebe das Bild.",
@@ -955,7 +973,6 @@
"unable_to_add_assets_to_shared_link": "Datei konnte nicht zum geteilten Link hinzugefügt werden",
"unable_to_add_comment": "Es kann kein Kommentar hinzufügt werden",
"unable_to_add_exclusion_pattern": "Ausschlussmuster konnte nicht hinzugefügt werden",
"unable_to_add_import_path": "Importpfad konnte nicht hinzugefügt werden",
"unable_to_add_partners": "Es können keine Partner hinzufügt werden",
"unable_to_add_remove_archive": "Datei konnte nicht {archived, select, true {aus dem Archiv entfernt} other {zum Archiv hinzugefügt}} werden",
"unable_to_add_remove_favorites": "Datei konnte nicht {favorite, select, true {von den Favoriten entfernt} other {zu den Favoriten hinzugefügt}} werden",
@@ -978,12 +995,10 @@
"unable_to_delete_asset": "Datei konnte nicht gelöscht werden",
"unable_to_delete_assets": "Fehler beim Löschen von Dateien",
"unable_to_delete_exclusion_pattern": "Ausschlussmuster konnte nicht gelöscht werden",
"unable_to_delete_import_path": "Importpfad konnte nicht gelöscht werden",
"unable_to_delete_shared_link": "Geteilter Link kann nicht gelöscht werden",
"unable_to_delete_user": "Nutzer konnte nicht gelöscht werden",
"unable_to_download_files": "Dateien konnten nicht heruntergeladen werden",
"unable_to_edit_exclusion_pattern": "Ausschlussmuster konnte nicht bearbeitet werden",
"unable_to_edit_import_path": "Importpfad konnte nicht bearbeitet werden",
"unable_to_empty_trash": "Papierkorb konnte nicht geleert werden",
"unable_to_enter_fullscreen": "Vollbildmodus kann nicht aktiviert werden",
"unable_to_exit_fullscreen": "Vollbildmodus kann nicht deaktiviert werden",
@@ -1006,7 +1021,7 @@
"unable_to_remove_partner": "Partner kann nicht entfernt werden",
"unable_to_remove_reaction": "Reaktion kann nicht entfernt werden",
"unable_to_reset_password": "Passwort kann nicht zurückgesetzt werden",
"unable_to_reset_pin_code": "Zurücksetzen des PIN Code nicht möglich",
"unable_to_reset_pin_code": "Zurücksetzen des PIN-Code nicht möglich",
"unable_to_resolve_duplicate": "Duplikate können nicht aufgelöst werden",
"unable_to_restore_assets": "Dateien konnten nicht wiederhergestellt werden",
"unable_to_restore_trash": "Papierkorb kann nicht wiederhergestellt werden",
@@ -1078,6 +1093,7 @@
"features_setting_description": "Funktionen der App verwalten",
"file_name": "Dateiname",
"file_name_or_extension": "Dateiname oder -erweiterung",
"file_size": "Dateigröße",
"filename": "Dateiname",
"filetype": "Dateityp",
"filter": "Filter",
@@ -1090,7 +1106,7 @@
"folder_not_found": "Ordner nicht gefunden",
"folders": "Ordner",
"folders_feature_description": "Durchsuchen der Ordneransicht für Fotos und Videos im Dateisystem",
"forgot_pin_code_question": "PIN Code vergessen?",
"forgot_pin_code_question": "PIN-Code vergessen?",
"forward": "Vorwärts",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Diese Funktion lädt externe Quellen von Google, um zu funktionieren.",
@@ -1121,7 +1137,6 @@
"header_settings_field_validator_msg": "Der Wert darf nicht leer sein",
"header_settings_header_name_input": "Header-Name",
"header_settings_header_value_input": "Header-Wert",
"headers_settings_tile_subtitle": "Definiere einen Proxy-Header, den die Anwendung bei jeder Netzwerkanfrage mitschicken soll",
"headers_settings_tile_title": "Benutzerdefinierte Proxy-Header",
"hi_user": "Hallo {name} ({email})",
"hide_all_people": "Alle Personen verbergen",
@@ -1174,6 +1189,8 @@
"import_path": "Importpfad",
"in_albums": "In {count, plural, one {# Album} other {# Alben}}",
"in_archive": "Im Archiv",
"in_year": "Im Jahr {year}",
"in_year_selector": "Im Jahr",
"include_archived": "Archivierte Dateien einbeziehen",
"include_shared_albums": "Freigegebene Alben einbeziehen",
"include_shared_partner_assets": "Geteilte Partner-Dateien mit einbeziehen",
@@ -1210,6 +1227,7 @@
"language_setting_description": "Wähle deine bevorzugte Sprache",
"large_files": "Große Dateien",
"last": "Letzte",
"last_months": "{count, plural, one {Letzter Monat} other {Letzte # Monate}}",
"last_seen": "Zuletzt gesehen",
"latest_version": "Aktuelle Version",
"latitude": "Breitengrad",
@@ -1242,6 +1260,7 @@
"local_media_summary": "Zusammenfassung der lokalen Medien",
"local_network": "Lokales Netzwerk",
"local_network_sheet_info": "Die App stellt über diese URL eine Verbindung zum Server her, wenn sie das angegebene WLAN-Netzwerk verwendet",
"location": "Standort",
"location_permission": "Standort Genehmigung",
"location_permission_content": "Um die automatische Umschaltfunktion nutzen zu können, benötigt Immich genaue Standortberechtigung, damit es den Namen des aktuellen WLAN-Netzwerks ermitteln kann",
"location_picker_choose_on_map": "Auf der Karte auswählen",
@@ -1278,7 +1297,7 @@
"login_form_server_empty": "Serveradresse eingeben.",
"login_form_server_error": "Es Konnte sich nicht mit dem Server verbunden werden.",
"login_has_been_disabled": "Die Anmeldung wurde deaktiviert.",
"login_password_changed_error": "Fehler beim Ändern deines Passwort",
"login_password_changed_error": "Fehler beim Ändern deines Passwortes",
"login_password_changed_success": "Passwort erfolgreich geändert",
"logout_all_device_confirmation": "Bist du sicher, dass du alle Geräte abmelden willst?",
"logout_this_device_confirmation": "Bist du sicher, dass du dieses Gerät abmelden willst?",
@@ -1291,6 +1310,10 @@
"main_menu": "Hauptmenü",
"make": "Marke",
"manage_geolocation": "Standort verwalten",
"manage_media_access_rationale": "Diese Berechtigung wird benötigt, um Dateien ordnungsgemäß in den Papierkorb schieben und daraus wiederherstellen zu können.",
"manage_media_access_settings": "Einstellungen öffnen",
"manage_media_access_subtitle": "Erlaube Immich, Mediendateien zu verwalten und zu verschieben.",
"manage_media_access_title": "Verwaltung von Mediendateien",
"manage_shared_links": "Freigegebene Links verwalten",
"manage_sharing_with_partners": "Gemeinsame Nutzung mit Partnern verwalten",
"manage_the_app_settings": "App-Einstellungen verwalten",
@@ -1332,13 +1355,13 @@
"memories_check_back_tomorrow": "Schau morgen wieder vorbei für weitere Erinnerungen",
"memories_setting_description": "Verwalte, was du in deinen Erinnerungen siehst",
"memories_start_over": "Erneut beginnen",
"memories_swipe_to_close": "Nach oben Wischen zum schließen",
"memories_swipe_to_close": "Nach oben Wischen zum Schließen",
"memory": "Erinnerung",
"memory_lane_title": "Foto-Erinnerungen {title}",
"menu": "Menü",
"merge": "Zusammenführen",
"merge_people": "Personen zusammenführen",
"merge_people_limit": "Du kannst nur bis zu 5 Gesichter auf einmal zusammenführen",
"merge_people_limit": "Du kannst maximal 5 Gesichter auf einmal zusammenführen",
"merge_people_prompt": "Willst du diese Personen zusammenführen? Diese Aktion kann nicht rückgängig gemacht werden.",
"merge_people_successfully": "Personen erfolgreich zusammengeführt",
"merged_people_count": "{count, plural, one {# Person} other {# Personen}} zusammengefügt",
@@ -1346,12 +1369,15 @@
"minute": "Minute",
"minutes": "Minuten",
"missing": "Fehlende",
"mobile_app": "Mobile App",
"mobile_app_download_onboarding_note": "Herunterladen der mobilen Begleiter-App über einen der folgenden Möglichkeiten",
"model": "Modell",
"month": "Monat",
"monthly_title_text_date_format": "MMMM y",
"more": "Mehr",
"move": "Verschieben",
"move_off_locked_folder": "Aus dem gesperrten Ordner verschieben",
"move_to": "Verschieben nach",
"move_to_lock_folder_action_prompt": "{count} zum gesperrten Ordner hinzugefügt",
"move_to_locked_folder": "In den gesperrten Ordner verschieben",
"move_to_locked_folder_confirmation": "Diese Fotos und Videos werden aus allen Alben entfernt und können nur noch im gesperrten Ordner angezeigt werden",
@@ -1364,6 +1390,8 @@
"my_albums": "Meine Alben",
"name": "Name",
"name_or_nickname": "Name oder Nickname",
"navigate": "Navigation",
"navigate_to_time": "Navigiere zu Zeit",
"network_requirement_photos_upload": "Mobile Daten verwenden, um Fotos zu sichern",
"network_requirement_videos_upload": "Mobile Daten verwenden, um Videos zu sichern",
"network_requirements": "Anforderungen ans Netzwerk",
@@ -1373,11 +1401,13 @@
"never": "Niemals",
"new_album": "Neues Album",
"new_api_key": "Neuer API-Schlüssel",
"new_date_range": "Neuer Datumsbereich",
"new_password": "Neues Passwort",
"new_person": "Neue Person",
"new_pin_code": "Neuer PIN Code",
"new_pin_code_subtitle": "Dies ist dein erster Zugriff auf den gesperrten Ordner. Erstelle einen PIN Code für den sicheren Zugriff auf diese Seite",
"new_pin_code": "Neuer PIN-Code",
"new_pin_code_subtitle": "Dies ist dein erster Zugriff auf den gesperrten Ordner. Erstelle einen PIN-Code für den sicheren Zugriff auf diese Seite",
"new_timeline": "Neue Zeitleiste",
"new_update": "Neues Update",
"new_user_created": "Neuer Benutzer wurde erstellt",
"new_version_available": "NEUE VERSION VERFÜGBAR",
"newest_first": "Neueste zuerst",
@@ -1393,6 +1423,7 @@
"no_cast_devices_found": "Keine Geräte zum Übertragen gefunden",
"no_checksum_local": "Prüfsumme nicht verfügbar - kann lokale Datei/en nicht laden",
"no_checksum_remote": "Prüfsumme nicht verfügbar - kann entfernte Datei/en nicht laden",
"no_devices": "Keine verwendeten Geräte",
"no_duplicates_found": "Es wurden keine Duplikate gefunden.",
"no_exif_info_available": "Keine EXIF-Informationen vorhanden",
"no_explore_results_message": "Lade weitere Fotos hoch, um deine Sammlung zu erkunden.",
@@ -1409,6 +1440,7 @@
"no_results_description": "Versuche es mit einem Synonym oder einem allgemeineren Stichwort",
"no_shared_albums_message": "Erstelle ein Album, um Fotos und Videos mit Personen in deinem Netzwerk zu teilen",
"no_uploads_in_progress": "Kein Upload in Bearbeitung",
"not_allowed": "Nicht erlaubt",
"not_available": "N/A",
"not_in_any_album": "In keinem Album",
"not_selected": "Nicht ausgewählt",
@@ -1423,6 +1455,9 @@
"notifications": "Benachrichtigungen",
"notifications_setting_description": "Benachrichtigungen verwalten",
"oauth": "OAuth",
"obtainium_configurator": "Obtainium Konfiguratior",
"obtainium_configurator_instructions": "Du kannst Obtainium benutzen, um die App direkt aus den Github Releases zu installieren oder zu aktualisieren. Bitte erstelle dazu einen API-Schlüssel und wähle eine Variante aus um einen Obtainium-Konfigurationslink zu erstellen",
"ocr": "OCR",
"official_immich_resources": "Offizielle Immich Quellen",
"offline": "Offline",
"offset": "Verschiebung",
@@ -1516,10 +1551,12 @@
"photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}",
"photos_from_previous_years": "Fotos von vorherigen Jahren",
"pick_a_location": "Wähle einen Ort",
"pin_code_changed_successfully": "PIN Code erfolgreich geändert",
"pin_code_reset_successfully": "PIN Code erfolgreich zurückgesetzt",
"pin_code_setup_successfully": "PIN Code erfolgreich festgelegt",
"pin_verification": "PIN Code Überprüfung",
"pick_custom_range": "Benutzerdefinierter Zeitraum",
"pick_date_range": "Wähle einen Zeitraum",
"pin_code_changed_successfully": "PIN-Code erfolgreich geändert",
"pin_code_reset_successfully": "PIN-Code erfolgreich zurückgesetzt",
"pin_code_setup_successfully": "PIN-Code erfolgreich festgelegt",
"pin_verification": "PIN-Code Überprüfung",
"place": "Ort",
"places": "Orte",
"places_count": "{count, plural, one {{count, number} Ort} other {{count, number} Orte}}",
@@ -1527,6 +1564,9 @@
"play_memories": "Erinnerungen abspielen",
"play_motion_photo": "Bewegte Bilder abspielen",
"play_or_pause_video": "Video abspielen oder pausieren",
"play_original_video": "Originales Video abspielen",
"play_original_video_setting_description": "Bevorzugen die Wiedergabe von Originalvideos gegenüber transkodierten Videos. Wenn das Original nicht kompatibel ist, wird es möglicherweise nicht korrekt wiedergegeben.",
"play_transcoded_video": "Transkodiertes Video abspielen",
"please_auth_to_access": "Für den Zugriff bitte Authentifizieren",
"port": "Port",
"preferences_settings_subtitle": "App-Einstellungen verwalten",
@@ -1544,13 +1584,9 @@
"privacy": "Privatsphäre",
"profile": "Profil",
"profile_drawer_app_logs": "Logs",
"profile_drawer_client_out_of_date_major": "Mobile-App ist veraltet. Bitte aktualisiere auf die neueste Major-Version.",
"profile_drawer_client_out_of_date_minor": "Mobile-App ist veraltet. Bitte aktualisiere auf die neueste Minor-Version.",
"profile_drawer_client_server_up_to_date": "Die App- und Server-Versionen sind aktuell",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Schreibgeschützter Modus aktiviert. Halte das Benutzer-Avatar-Symbol gedrückt, um den Modus zu verlassen.",
"profile_drawer_server_out_of_date_major": "Server-Version ist veraltet. Bitte aktualisiere auf die neueste Major-Version.",
"profile_drawer_server_out_of_date_minor": "Server-Version ist veraltet. Bitte aktualisiere auf die neueste Minor-Version.",
"profile_image_of_user": "Profilbild von {user}",
"profile_picture_set": "Profilbild gesetzt.",
"public_album": "Öffentliches Album",
@@ -1652,21 +1688,22 @@
"repair": "Reparatur",
"repair_no_results_message": "Nicht auffindbare und fehlende Dateien werden hier angezeigt",
"replace_with_upload": "Durch Upload ersetzen",
"repository": "Repository",
"repository": "Repositorium",
"require_password": "Passwort erforderlich",
"require_user_to_change_password_on_first_login": "Benutzer muss das Passwort beim ersten Login ändern",
"rescan": "Erneut scannen",
"reset": "Zurücksetzen",
"reset_password": "Passwort zurücksetzen",
"reset_people_visibility": "Sichtbarkeit von Personen zurücksetzen",
"reset_pin_code": "PIN Code zurücksetzen",
"reset_pin_code_description": "Falls du deinen PIN Code vergessen hast, wende dich an deinen Immich-Administrator um ihn zurücksetzen zu lassen",
"reset_pin_code_success": "PIN Code erfolgreich zurückgesetzt",
"reset_pin_code_with_password": "Mit deinem Passwort kannst du jederzeit deinen PIN Code zurücksetzen",
"reset_pin_code": "PIN-Code zurücksetzen",
"reset_pin_code_description": "Falls du deinen PIN-Code vergessen hast, kannst du dich an den Server-Administrator wenden, um ihn zurückzusetzen",
"reset_pin_code_success": "PIN-Code erfolgreich zurückgesetzt",
"reset_pin_code_with_password": "Mit deinem Passwort kannst du jederzeit deinen PIN-Code zurücksetzen",
"reset_sqlite": "SQLite Datenbank zurücksetzen",
"reset_sqlite_confirmation": "Bist du sicher, dass du die SQLite-Datenbank zurücksetzen willst? Du musst dich ab- und wieder anmelden, um die Daten neu zu synchronisieren",
"reset_sqlite_success": "SQLite Datenbank erfolgreich zurückgesetzt",
"reset_to_default": "Auf Standard zurücksetzen",
"resolution": "Auflösung",
"resolve_duplicates": "Duplikate entfernen",
"resolved_all_duplicates": "Alle Duplikate aufgelöst",
"restore": "Wiederherstellen",
@@ -1685,6 +1722,7 @@
"running": "Läuft",
"save": "Speichern",
"save_to_gallery": "In Galerie speichern",
"saved": "Gespeichert",
"saved_api_key": "API-Schlüssel wurde gespeichert",
"saved_profile": "Profil gespeichert",
"saved_settings": "Einstellungen gespeichert",
@@ -1701,6 +1739,9 @@
"search_by_description_example": "Wandern in Sapa",
"search_by_filename": "Suche nach Dateiname oder -erweiterung",
"search_by_filename_example": "z.B. IMG_1234.JPG oder PNG",
"search_by_ocr": "Suche per OCR",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Suche nach Kameralinse...",
"search_camera_make": "Suche nach Kameramarke...",
"search_camera_model": "Suche nach Kameramodell...",
"search_city": "Suche nach Stadt...",
@@ -1717,6 +1758,7 @@
"search_filter_location_title": "Ort auswählen",
"search_filter_media_type": "Medientyp",
"search_filter_media_type_title": "Medientyp auswählen",
"search_filter_ocr": "Suche per OCR",
"search_filter_people_title": "Personen auswählen",
"search_for": "Suche nach",
"search_for_existing_person": "Suche nach vorhandener Person",
@@ -1779,6 +1821,7 @@
"server_online": "Server online",
"server_privacy": "Privatsphäre auf dem Server",
"server_stats": "Server-Statistiken",
"server_update_available": "Server Update verfügbar",
"server_version": "Server-Version",
"set": "Speichern",
"set_as_album_cover": "Als Albumcover festlegen",
@@ -1807,13 +1850,15 @@
"setting_notifications_subtitle": "Benachrichtigungen anpassen",
"setting_notifications_total_progress_subtitle": "Gesamter Upload-Fortschritt (abgeschlossen/Anzahl Elemente)",
"setting_notifications_total_progress_title": "Zeige den Gesamtfortschritt der Hintergrundsicherung",
"setting_video_viewer_auto_play_subtitle": "Videos automatisch wiedergeben sobald sie geöffnet werden",
"setting_video_viewer_auto_play_title": "Videos automatisch wiedergeben",
"setting_video_viewer_looping_title": "Video-Wiederholung",
"setting_video_viewer_original_video_subtitle": "Beim Streaming eines Videos vom Server wird das Original abgespielt, auch wenn eine Transkodierung verfügbar ist. Kann zu Pufferung führen. Lokal verfügbare Videos werden unabhängig von dieser Einstellung in Originalqualität wiedergegeben.",
"setting_video_viewer_original_video_title": "Originalvideo erzwingen",
"settings": "Einstellungen",
"settings_require_restart": "Bitte starte Immich neu, um diese Einstellung anzuwenden",
"settings_saved": "Einstellungen gespeichert",
"setup_pin_code": "Einen PIN Code festlegen",
"setup_pin_code": "Einen PIN-Code festlegen",
"share": "Teilen",
"share_action_prompt": "{count} Dateien geteilt",
"share_add_photos": "Fotos hinzufügen",
@@ -1986,7 +2031,9 @@
"theme_setting_three_stage_loading_title": "Dreistufiges Laden aktivieren",
"they_will_be_merged_together": "Sie werden zusammengeführt",
"third_party_resources": "Drittanbieter-Quellen",
"time": "Zeit",
"time_based_memories": "Zeitbasierte Erinnerungen",
"time_based_memories_duration": "Anzahl der Sekunden, die jedes Bild angezeigt wird.",
"timeline": "Zeitleiste",
"timezone": "Zeitzone",
"to_archive": "Archivieren",
@@ -2014,11 +2061,12 @@
"trash_page_restore_all": "Alle wiederherstellen",
"trash_page_select_assets_btn": "Elemente auswählen",
"trash_page_title": "Papierkorb ({count})",
"trashed_items_will_be_permanently_deleted_after": "Gelöschte Objekte werden nach {days, plural, one {# Tag} other {# Tagen}} endgültig gelöscht.",
"trashed_items_will_be_permanently_deleted_after": "Objekte im Papierkorb werden nach {days, plural, one {# Tag} other {# Tagen}} endgültig gelöscht.",
"troubleshoot": "Fehler beheben",
"type": "Typ",
"unable_to_change_pin_code": "PIN Code konnte nicht geändert werden",
"unable_to_setup_pin_code": "PIN Code konnte nicht festgelegt werden",
"unable_to_change_pin_code": "PIN-Code konnte nicht geändert werden",
"unable_to_check_version": "App oder Server Versionscheck nicht möglich",
"unable_to_setup_pin_code": "PIN-Code konnte nicht festgelegt werden",
"unarchive": "Entarchivieren",
"unarchive_action_prompt": "{count} aus dem Archiv entfernt",
"unarchived_count": "{count, plural, other {# entarchiviert}}",
@@ -2075,8 +2123,8 @@
"user_has_been_deleted": "Dieser Benutzer wurde gelöscht.",
"user_id": "Nutzer-ID",
"user_liked": "{type, select, photo {Dieses Foto} video {Dieses Video} asset {Diese Datei} other {Dies}} gefällt {user}",
"user_pin_code_settings": "PIN Code",
"user_pin_code_settings_description": "Verwalte deinen PIN Code",
"user_pin_code_settings": "PIN-Code",
"user_pin_code_settings_description": "Verwalte deinen PIN-Code",
"user_privacy": "Datenschutzeinstellungen Nutzer",
"user_purchase_settings": "Kauf",
"user_purchase_settings_description": "Kauf verwalten",
@@ -2087,7 +2135,7 @@
"username": "Nutzername",
"users": "Benutzer",
"users_added_to_album_count": "{count, plural, one {# Benutzer} other {# Benutzer}} zum Album hinzugefügt",
"utilities": "Hilfsmittel",
"utilities": "Werkzeuge",
"validate": "Validieren",
"validate_endpoint_error": "Bitte gib eine gültige URL ein",
"variables": "Variablen",
@@ -2126,7 +2174,7 @@
"welcome": "Willkommen",
"welcome_to_immich": "Willkommen bei Immich",
"wifi_name": "WLAN-Name",
"wrong_pin_code": "PIN Code falsch",
"wrong_pin_code": "PIN-Code falsch",
"year": "Jahr",
"years_ago": "Vor {years, plural, one {einem Jahr} other {# Jahren}}",
"yes": "Ja",

View File

@@ -11,13 +11,12 @@
"activity_changed": "Η δραστηριότητα είναι {enabled, select, true {ενεργοποιημένη} other {απενεργοποιημένη}}",
"add": "Προσθήκη",
"add_a_description": "Προσθήκη περιγραφής",
"add_a_location": "Προσθήκη μίας τοποθεσίας",
"add_a_name": "Προσθέστε ένα όνομα",
"add_a_location": "Προσθήκη τοποθεσίας",
"add_a_name": "Προσθήκη ονόματος",
"add_a_title": "Προσθήκη τίτλου",
"add_birthday": "Προσθέστε την ημερομηνία γενεθλίων",
"add_birthday": "Προσθήκη γενεθλίων",
"add_endpoint": "Προσθήκη τελικού σημείου",
"add_exclusion_pattern": "Προσθήκη μοτίβου αποκλεισμού",
"add_import_path": "Προσθήκη μονοπατιού εισαγωγής",
"add_location": "Προσθήκη τοποθεσίας",
"add_more_users": "Προσθήκη επιπλέον χρηστών",
"add_partner": "Προσθήκη συνεργάτη",
@@ -28,7 +27,7 @@
"add_to_album": "Προσθήκη σε άλμπουμ",
"add_to_album_bottom_sheet_added": "Προστέθηκε στο {album}",
"add_to_album_bottom_sheet_already_exists": "Ήδη στο {album}",
"add_to_album_bottom_sheet_some_local_assets": "Ορισμένοι τοπικά στοιχεία δεν μπόρεσαν να προστεθούν στο άλμπουμ",
"add_to_album_bottom_sheet_some_local_assets": "Ορισμένα τοπικά στοιχεία δεν μπόρεσαν να προστεθούν στο άλμπουμ",
"add_to_album_toggle": "Εναλλαγή επιλογής για το {album}",
"add_to_albums": "Προσθήκη στα άλμπουμ",
"add_to_albums_count": "Προσθήκη στα άλμπουμ ({count})",
@@ -112,7 +111,6 @@
"jobs_failed": "{jobCount, plural, one {# απέτυχε} other {# απέτυχαν}}",
"library_created": "Δημιουργήθηκε η βιβλιοθήκη: {library}",
"library_deleted": "Η βιβλιοθήκη διαγράφηκε",
"library_import_path_description": "Καθορίστε έναν φάκελο για εισαγωγή. Αυτός ο φάκελος, συμπεριλαμβανομένων των υποφακέλων του, θα σαρωθεί για εικόνες και βίντεο.",
"library_scanning": "Περιοδική Σάρωση",
"library_scanning_description": "Ρύθμιση περιοδικής σάρωσης βιβλιοθήκης",
"library_scanning_enable_description": "Ενεργοποίηση περιοδικής σάρωσης βιβλιοθήκης",
@@ -211,6 +209,7 @@
"notification_email_ignore_certificate_errors_description": "Παράβλεψη σφαλμάτων επικύρωσης της πιστοποίησης TLS (δεν προτείνεται)",
"notification_email_password_description": "Κωδικός για την αυθεντικοποίηση με τον server του email",
"notification_email_port_description": "Θύρα του email server (πχ 25, 465, ή 587)",
"notification_email_secure_description": "Χρήση SMTPS (SMTP over TLS)",
"notification_email_sent_test_email_button": "Αποστολή test email και αποθήκευση",
"notification_email_setting_description": "Ρυθμίσεις για την αποστολή ειδοποιήσεων μέσω email",
"notification_email_test_email": "Αποστολή test email",
@@ -333,7 +332,7 @@
"transcoding_max_b_frames": "Μέγιστος αριθμός B-frames(Bidirectional Predictive Frames)",
"transcoding_max_b_frames_description": "Οι υψηλότερες τιμές βελτιώνουν την αποδοτικότητα της συμπίεσης, αλλά επιβραδύνουν την κωδικοποίηση. Ενδέχεται να μην είναι συμβατές με την επιτάχυνση υλικού σε παλαιότερες συσκευές. Η τιμή 0 απενεργοποιεί τα B-frames, ενώ η -1, τη ρυθμίζει αυτόματα.",
"transcoding_max_bitrate": "Μέγιστος ρυθμός μετάδοσης (bitrate)",
"transcoding_max_bitrate_description": "Η ρύθμιση ενός μέγιστου ρυθμού μετάδοσης(bitrate) μπορεί να κάνει το μέγεθος των αρχείων πιο προβλέψιμο, αλλά με ένα μικρό κόστος στην ποιότητα. Στην ανάλυση των 720p, οι τυπικές τιμές είναι 2600 kbit/s για VP9 ή HEVC, ή 4500 kbit/s για H.264. Απενεργοποιείται εάν οριστεί σε 0.",
"transcoding_max_bitrate_description": "Ο καθορισμός του μέγιστου bitrate μπορεί να κάνει το μέγεθος των αρχείων πιο προβλέψιμο, με ένα μικρό κόστος στην ποιότητα. Στα 720p, οι τυπικές τιμές είναι 2600 kbit/s για VP9 ή HEVC, ή 4500 kbit/s για H.264. Αν οριστεί σε 0, η ρύθμιση απενεργοποιείται. Όταν δεν καθορίζεται, θεωρείται το k (για kbit/s)· επομένως τα 5000, 5000k και 5M (για Mbit/s) είναι ισοδύναμα.",
"transcoding_max_keyframe_interval": "Μέγιστο χρονικό διάστημα μεταξύ των καρέ αναφοράς (keyframe)",
"transcoding_max_keyframe_interval_description": "Ορίζει το μέγιστο διάστημα μεταξύ των καρέ αναφοράς. Χαμηλότερες τιμές μειώνουν την αποδοτικότητα συμπίεσης, αλλά βελτιώνουν τον χρόνο αναζήτησης και μπορεί να βελτιώσουν την ποιότητα σε σκηνές με γρήγορη κίνηση. Η τιμή 0 ρυθμίζει αυτό το διάστημα αυτόματα.",
"transcoding_optimal_description": "Βίντεο με ανώτερη ανάλυση από την επιθυμητή ή σε μη αποδεκτή μορφή",
@@ -351,7 +350,7 @@
"transcoding_target_resolution": "Επιθυμητή ανάλυση",
"transcoding_target_resolution_description": "Οι υψηλότερες αναλύσεις μπορούν να διατηρήσουν περισσότερες λεπτομέρειες, αλλά απαιτούν περισσότερο χρόνο για κωδικοποίηση, παράγουν μεγαλύτερα αρχεία και μπορεί να μειώσουν την απόκριση της εφαρμογής.",
"transcoding_temporal_aq": "Χρονική Προσαρμοστική Ποιότητα AQ(Adaptive Quantization)",
"transcoding_temporal_aq_description": "Ισχύει μόνο για NVENC. Αυξάνει την ποιότητα σε σκηνές με υψηλή λεπτομέρεια και χαμηλή κίνηση. Ενδέχεται να μην είναι συμβατό με παλαιότερες συσκευές.",
"transcoding_temporal_aq_description": "Ισχύει μόνο για το NVENC. Η Χρονική προσαρμογή ποιότητας (Temporal Adaptive Quantization) βελτιώνει την ποιότητα σε σκηνές με υψηλή λεπτομέρεια και χαμηλή κίνηση. Ενδέχεται να μην είναι συμβατή με παλαιότερες συσκευές.",
"transcoding_threads": "Νήματα (παράλληλες διεργασίες)",
"transcoding_threads_description": "Οι υψηλότερες τιμές οδηγούν σε ταχύτερη κωδικοποίηση, αλλά αφήνουν λιγότερο χώρο στον διακομιστή για να επεξεργαστεί άλλες εργασίες όσο είναι ενεργή. Αυτή η τιμή δεν πρέπει να ξεπερνά τον αριθμό των πυρήνων του επεξεργαστή. Η μέγιστη αξιοποίηση επιτυγχάνεται αν οριστεί στο 0.",
"transcoding_tone_mapping": "Χαρτογράφηση χρωματικών τόνων",
@@ -466,9 +465,11 @@
"api_key_description": "Αυτή η τιμή θα εμφανιστεί μόνο μία φορά. Παρακαλώ βεβαιωθείτε ότι την έχετε αντιγράψει πριν κλείσετε το παράθυρο.",
"api_key_empty": "Το όνομα του κλειδιού API, δεν πρέπει να είναι κενό",
"api_keys": "Κλειδιά API",
"app_architecture_variant": "Παραλλαγή (Αρχιτεκτονική)",
"app_bar_signout_dialog_content": "Είστε βέβαιοι ότι θέλετε να αποσυνδεθείτε;",
"app_bar_signout_dialog_ok": "Ναι",
"app_bar_signout_dialog_title": "Αποσύνδεση",
"app_download_links": "Σύνδεσμοι Λήψης Εφαρμογής",
"app_settings": "Ρυθμίσεις εφαρμογής",
"appears_in": "Εμφανίζεται σε",
"apply_count": "Εφαρμογή ({count, number})",
@@ -701,7 +702,6 @@
"comments_and_likes": "Σχόλια & αντιδράσεις (likes)",
"comments_are_disabled": "Τα σχόλια είναι απενεργοποιημένα",
"common_create_new_album": "Δημιουργία νέου άλμπουμ",
"common_server_error": "Ελέγξτε τη σύνδεσή σας, βεβαιωθείτε ότι ο διακομιστής είναι προσβάσιμος και ότι οι εκδόσεις της εφαρμογής/διακομιστή είναι συμβατές.",
"completed": "Ολοκληρώθηκε",
"confirm": "Επιβεβαίωση",
"confirm_admin_password": "Επιβεβαίωση κωδικού Διαχειριστή",
@@ -871,8 +871,6 @@
"edit_description_prompt": "Παρακαλώ επιλέξτε νέα περιγραφή:",
"edit_exclusion_pattern": "Επεξεργασία μοτίβου αποκλεισμού",
"edit_faces": "Επεξεργασία προσώπων",
"edit_import_path": "Επεξεργασία διαδρομής εισαγωγής",
"edit_import_paths": "Επεξεργασία Διαδρομών Εισαγωγής",
"edit_key": "Επεξεργασία κλειδιού",
"edit_link": "Επεξεργασία συνδέσμου",
"edit_location": "Επεξεργασία τοποθεσίας",
@@ -883,7 +881,6 @@
"edit_tag": "Επεξεργασία ετικέτας",
"edit_title": "Επεξεργασία Τίτλου",
"edit_user": "Επεξεργασία χρήστη",
"edited": "Επεξεργάστηκε",
"editor": "Επεξεργαστής",
"editor_close_without_save_prompt": "Αυτές οι αλλαγές δεν θα αποθηκευτούν",
"editor_close_without_save_title": "Κλείσιμο επεξεργαστή;",
@@ -945,7 +942,6 @@
"failed_to_stack_assets": "Αποτυχία στην συμπίεση των στοιχείων",
"failed_to_unstack_assets": "Αποτυχία στην αποσυμπίεση των στοιχείων",
"failed_to_update_notification_status": "Αποτυχία ενημέρωσης της κατάστασης ειδοποίησης",
"import_path_already_exists": "Αυτή η διαδρομή εισαγωγής υπάρχει ήδη.",
"incorrect_email_or_password": "Λανθασμένο email ή κωδικός πρόσβασης",
"paths_validation_failed": "{paths, plural, one {# διαδρομή} other {# διαδρομές}} απέτυχαν κατά την επικύρωση",
"profile_picture_transparent_pixels": "Οι εικόνες προφίλ δεν μπορούν να έχουν διαφανή εικονοστοιχεία. Παρακαλώ μεγεθύνετε ή/και μετακινήστε την εικόνα.",
@@ -955,7 +951,6 @@
"unable_to_add_assets_to_shared_link": "Αδυναμία προσθήκης στοιχείου στον κοινόχρηστο σύνδεσμο",
"unable_to_add_comment": "Αδυναμία προσθήκης σχολίου",
"unable_to_add_exclusion_pattern": "Αδυναμία προσθήκης μοτίβου αποκλεισμού",
"unable_to_add_import_path": "Αδυναμία προσθήκης διαδρομής εισαγωγής",
"unable_to_add_partners": "Αδυναμία προσθήκης συνεργατών",
"unable_to_add_remove_archive": "Αδυναμία {archived, select, true {αφαίρεσης του στοιχείου από το} other {προσθήκης του στοιχείου στο}} αρχείο",
"unable_to_add_remove_favorites": "Αδυναμία {favorite, select, true {προσθήκης του στοιχείου στα} other {αφαίρεσης του στοιχείου από τα}} αγαπημένα",
@@ -978,12 +973,10 @@
"unable_to_delete_asset": "Αδυναμία διαγραφής στοιχείου",
"unable_to_delete_assets": "Σφάλμα κατα τη διαγραφή στοιχείων",
"unable_to_delete_exclusion_pattern": "Αδυναμία διαγραφής μοτίβου αποκλεισμού",
"unable_to_delete_import_path": "Αδυναμία διαγραφής διαδρομής εισαγωγής",
"unable_to_delete_shared_link": "Αδυναμία διαγραφής κοινόχρηστου συνδέσμου",
"unable_to_delete_user": "Αδυναμία διαγραφής χρήστη",
"unable_to_download_files": "Αδυναμία λήψης αρχείων",
"unable_to_edit_exclusion_pattern": "Αδυναμία επεξεργασίας μοτίβου αποκλεισμού",
"unable_to_edit_import_path": "Αδυναμία επεξεργασίας διαδρομής εισαγωγής",
"unable_to_empty_trash": "Αδυναμία αδειάσματος του κάδου απορριμμάτων",
"unable_to_enter_fullscreen": "Αδυναμία μετάβασης σε πλήρη οθόνη",
"unable_to_exit_fullscreen": "Αδυναμία εξόδου από πλήρη οθόνη",
@@ -1039,6 +1032,7 @@
"exif_bottom_sheet_description_error": "Σφάλμα κατά την ενημέρωση της περιγραφής",
"exif_bottom_sheet_details": "ΛΕΠΤΟΜΕΡΕΙΕΣ",
"exif_bottom_sheet_location": "ΤΟΠΟΘΕΣΙΑ",
"exif_bottom_sheet_no_description": "Καμία περιγραφή",
"exif_bottom_sheet_people": "ΑΤΟΜΑ",
"exif_bottom_sheet_person_add_person": "Προσθήκη ονόματος",
"exit_slideshow": "Έξοδος από την παρουσίαση",
@@ -1120,7 +1114,6 @@
"header_settings_field_validator_msg": "Η τιμή δεν μπορεί να είναι κενή",
"header_settings_header_name_input": "Όνομα κεφαλίδας",
"header_settings_header_value_input": "Τιμή κεφαλίδας",
"headers_settings_tile_subtitle": "Καθορίστε τις κεφαλίδες διακομιστή μεσολάβησης που θα πρέπει να στέλνει η εφαρμογή με κάθε αίτημα δικτύου",
"headers_settings_tile_title": "Προσαρμοσμένες κεφαλίδες διακομιστή μεσολάβησης",
"hi_user": "Γειά σου {name} {email}",
"hide_all_people": "Απόκρυψη όλων των ατόμων",
@@ -1345,6 +1338,8 @@
"minute": "Λεπτό",
"minutes": "Λεπτά",
"missing": "Όσα Λείπουν",
"mobile_app": "Εφαρμογή για κινητά",
"mobile_app_download_onboarding_note": "Μπορείτε να αποκτήσετε ξανά πρόσβαση σε αυτές τις επιλογές από τη σελίδα Βοηθήματα.",
"model": "Μοντέλο",
"month": "Μήνας",
"monthly_title_text_date_format": "ΜΜΜΜ y",
@@ -1363,6 +1358,8 @@
"my_albums": "Τα άλμπουμ μου",
"name": "Όνομα",
"name_or_nickname": "Όνομα ή ψευδώνυμο",
"navigate": "Πλοηγηθείτε",
"navigate_to_time": "Πλοηγηθείτε στο Χρόνο",
"network_requirement_photos_upload": "Χρήση δεδομένων κινητής τηλεφωνίας για τη δημιουργία αντιγράφων ασφαλείας των φωτογραφιών",
"network_requirement_videos_upload": "Χρήση δεδομένων κινητής τηλεφωνίας για τη δημιουργία αντιγράφων ασφαλείας των βίντεο",
"network_requirements": "Απαιτήσεις Δυκτίου",
@@ -1372,6 +1369,7 @@
"never": "Ποτέ",
"new_album": "Νέο Άλμπουμ",
"new_api_key": "Νέο API Key",
"new_date_range": "Εύρος νέας ημερομηνίας",
"new_password": "Νέος κωδικός πρόσβασης",
"new_person": "Νέο άτομο",
"new_pin_code": "Νέος κωδικός PIN",
@@ -1422,6 +1420,8 @@
"notifications": "Ειδοποιήσεις",
"notifications_setting_description": "Διαχείριση ειδοποιήσεων",
"oauth": "OAuth",
"obtainium_configurator": "Ρυθμιστής Obtainium",
"obtainium_configurator_instructions": "Δημιουργήστε ένα κλειδί API και επιλέξτε μια παραλλαγή για να δημιουργήσετε τον σύνδεσμο σας ρύθμισης Obtainium.",
"official_immich_resources": "Επίσημοι Πόροι του Immich",
"offline": "Εκτός σύνδεσης",
"offset": "Μετατόπιση",
@@ -1543,13 +1543,9 @@
"privacy": "Ιδιωτικότητα",
"profile": "Προφίλ",
"profile_drawer_app_logs": "Καταγραφές",
"profile_drawer_client_out_of_date_major": "Παρακαλώ ενημερώστε την εφαρμογή στην πιο πρόσφατη κύρια έκδοση.",
"profile_drawer_client_out_of_date_minor": "Παρακαλώ ενημερώστε την εφαρμογή στην πιο πρόσφατη δευτερεύουσα έκδοση.",
"profile_drawer_client_server_up_to_date": "Ο πελάτης και ο διακομιστής είναι ενημερωμένοι",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Η λειτουργία μόνο-για-ανάγνωση ενεργοποιήθηκε. Κρατήστε πατημένο το εικονίδιο του χρήστη για απενεργοποίηση.",
"profile_drawer_server_out_of_date_major": "Παρακαλώ ενημερώστε τον διακομιστή στην πιο πρόσφατη κύρια έκδοση.",
"profile_drawer_server_out_of_date_minor": "Παρακαλώ ενημερώστε τον διακομιστή στην πιο πρόσφατη δευτερεύουσα έκδοση.",
"profile_image_of_user": "Εικόνα προφίλ του χρήστη {user}",
"profile_picture_set": "Ορισμός εικόνας προφίλ.",
"public_album": "Δημόσιο άλμπουμ",
@@ -1806,6 +1802,8 @@
"setting_notifications_subtitle": "Προσαρμόστε τις προτιμήσεις ειδοποίησης",
"setting_notifications_total_progress_subtitle": "Συνολική πρόοδος μεταφόρτωσης (ολοκληρώθηκε/σύνολο στοιχείων)",
"setting_notifications_total_progress_title": "Εμφάνιση συνολικής προόδου δημιουργίας αντιγράφων ασφαλείας παρασκηνίου",
"setting_video_viewer_auto_play_subtitle": "Αυτόματη αναπαραγωγή βίντεο κατά το άνοιγμά τους",
"setting_video_viewer_auto_play_title": "Αυτόματη αναπαραγωγή βίντεο",
"setting_video_viewer_looping_title": "Συνεχής Επανάληψη",
"setting_video_viewer_original_video_subtitle": "Όταν μεταδίδετε ένα βίντεο από τον διακομιστή, αναπαράγετε το αυθεντικό ακόμη και όταν υπάρχει διαθέσιμο με διαφορετική κωδικοποίηση. Μπορεί να προκαλέσει καθυστέρηση φόρτωσης. Τα βίντεο που είναι διαθέσιμα τοπικά, αναπαράγονται στην αυθεντική ποιότητα, ανεξαρτήτως αυτής της ρύθμισης.",
"setting_video_viewer_original_video_title": "Αναγκαστική αναπαραγωγή αυθεντικού βίντεο",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Add a birthday",
"add_endpoint": "Add endpoint",
"add_exclusion_pattern": "Add exclusion pattern",
"add_import_path": "Add import path",
"add_location": "Add location",
"add_more_users": "Add more users",
"add_partner": "Add partner",
@@ -32,6 +31,7 @@
"add_to_album_toggle": "Toggle selection for {album}",
"add_to_albums": "Add to albums",
"add_to_albums_count": "Add to albums ({count})",
"add_to_bottom_bar": "Add to",
"add_to_shared_album": "Add to shared album",
"add_upload_to_stack": "Add upload to stack",
"add_url": "Add URL",
@@ -112,13 +112,17 @@
"jobs_failed": "{jobCount, plural, other {# failed}}",
"library_created": "Created library: {library}",
"library_deleted": "Library deleted",
"library_import_path_description": "Specify a folder to import. This folder, including subfolders, will be scanned for images and videos.",
"library_details": "Library details",
"library_folder_description": "Specify a folder to import. This folder, including subfolders, will be scanned for images and videos.",
"library_remove_exclusion_pattern_prompt": "Are you sure you want to remove this exclusion pattern?",
"library_remove_folder_prompt": "Are you sure you want to remove this import folder?",
"library_scanning": "Periodic Scanning",
"library_scanning_description": "Configure periodic library scanning",
"library_scanning_enable_description": "Enable periodic library scanning",
"library_settings": "External Library",
"library_settings_description": "Manage external library settings",
"library_tasks_description": "Scan external libraries for new and/or changed assets",
"library_updated": "Updated library",
"library_watching_enable_description": "Watch external libraries for file changes",
"library_watching_settings": "Library watching [EXPERIMENTAL]",
"library_watching_settings_description": "Automatically watch for changed files",
@@ -173,6 +177,10 @@
"machine_learning_smart_search_enabled": "Enable smart search",
"machine_learning_smart_search_enabled_description": "If disabled, images will not be encoded for smart search.",
"machine_learning_url_description": "The URL of the machine learning server. If more than one URL is provided, each server will be attempted one-at-a-time until one responds successfully, in order from first to last. Servers that don't respond will be temporarily ignored until they come back online.",
"maintenance_settings": "Maintenance",
"maintenance_settings_description": "Put Immich into maintenance mode.",
"maintenance_start": "Start maintenance mode",
"maintenance_start_error": "Failed to start maintenance mode.",
"manage_concurrency": "Manage Concurrency",
"manage_log_settings": "Manage log settings",
"map_dark_style": "Dark style",
@@ -430,6 +438,7 @@
"age_months": "Age {months, plural, one {# month} other {# months}}",
"age_year_months": "Age 1 year, {months, plural, one {# month} other {# months}}",
"age_years": "{years, plural, other {Age #}}",
"album": "Album",
"album_added": "Album added",
"album_added_notification_setting_description": "Receive an email notification when you are added to a shared album",
"album_cover_updated": "Album cover updated",
@@ -475,6 +484,7 @@
"allow_edits": "Allow edits",
"allow_public_user_to_download": "Allow public user to download",
"allow_public_user_to_upload": "Allow public user to upload",
"allowed": "Allowed",
"alt_text_qr_code": "QR code image",
"anti_clockwise": "Anti-clockwise",
"api_key": "API Key",
@@ -894,8 +904,6 @@
"edit_description_prompt": "Please select a new description:",
"edit_exclusion_pattern": "Edit exclusion pattern",
"edit_faces": "Edit faces",
"edit_import_path": "Edit import path",
"edit_import_paths": "Edit Import Paths",
"edit_key": "Edit key",
"edit_link": "Edit link",
"edit_location": "Edit location",
@@ -967,8 +975,8 @@
"failed_to_stack_assets": "Failed to stack assets",
"failed_to_unstack_assets": "Failed to un-stack assets",
"failed_to_update_notification_status": "Failed to update notification status",
"import_path_already_exists": "This import path already exists.",
"incorrect_email_or_password": "Incorrect email or password",
"library_folder_already_exists": "This import path already exists.",
"paths_validation_failed": "{paths, plural, one {# path} other {# paths}} failed validation",
"profile_picture_transparent_pixels": "Profile pictures cannot have transparent pixels. Please zoom in and/or move the image.",
"quota_higher_than_disk_size": "You set a quota higher than the disk size",
@@ -977,7 +985,6 @@
"unable_to_add_assets_to_shared_link": "Unable to add assets to shared link",
"unable_to_add_comment": "Unable to add comment",
"unable_to_add_exclusion_pattern": "Unable to add exclusion pattern",
"unable_to_add_import_path": "Unable to add import path",
"unable_to_add_partners": "Unable to add partners",
"unable_to_add_remove_archive": "Unable to {archived, select, true {remove asset from} other {add asset to}} archive",
"unable_to_add_remove_favorites": "Unable to {favorite, select, true {add asset to} other {remove asset from}} favorites",
@@ -1000,12 +1007,10 @@
"unable_to_delete_asset": "Unable to delete asset",
"unable_to_delete_assets": "Error deleting assets",
"unable_to_delete_exclusion_pattern": "Unable to delete exclusion pattern",
"unable_to_delete_import_path": "Unable to delete import path",
"unable_to_delete_shared_link": "Unable to delete shared link",
"unable_to_delete_user": "Unable to delete user",
"unable_to_download_files": "Unable to download files",
"unable_to_edit_exclusion_pattern": "Unable to edit exclusion pattern",
"unable_to_edit_import_path": "Unable to edit import path",
"unable_to_empty_trash": "Unable to empty trash",
"unable_to_enter_fullscreen": "Unable to enter fullscreen",
"unable_to_exit_fullscreen": "Unable to exit fullscreen",
@@ -1056,6 +1061,7 @@
"unable_to_update_user": "Unable to update user",
"unable_to_upload_file": "Unable to upload file"
},
"exclusion_pattern": "Exclusion pattern",
"exif": "Exif",
"exif_bottom_sheet_description": "Add Description...",
"exif_bottom_sheet_description_error": "Error updating description",
@@ -1115,6 +1121,7 @@
"folders_feature_description": "Browsing the folder view for the photos and videos on the file system",
"forgot_pin_code_question": "Forgot your PIN?",
"forward": "Forward",
"full_path": "Full path: {path}",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "This feature loads external resources from Google in order to work.",
"general": "General",
@@ -1151,6 +1158,7 @@
"hide_named_person": "Hide person {name}",
"hide_password": "Hide password",
"hide_person": "Hide person",
"hide_text_recognition": "Hide text recognition",
"hide_unnamed_people": "Hide unnamed people",
"home_page_add_to_album_conflicts": "Added {added} assets to album {album}. {failed} assets are already in the album.",
"home_page_add_to_album_err_local": "Can not add local assets to albums yet, skipping",
@@ -1196,6 +1204,8 @@
"import_path": "Import path",
"in_albums": "In {count, plural, one {# album} other {# albums}}",
"in_archive": "In archive",
"in_year": "In {year}",
"in_year_selector": "In",
"include_archived": "Include archived",
"include_shared_albums": "Include shared albums",
"include_shared_partner_assets": "Include shared partner assets",
@@ -1232,6 +1242,7 @@
"language_setting_description": "Select your preferred language",
"large_files": "Large Files",
"last": "Last",
"last_months": "{count, plural, one {Last month} other {Last # months}}",
"last_seen": "Last seen",
"latest_version": "Latest Version",
"latitude": "Latitude",
@@ -1241,6 +1252,8 @@
"let_others_respond": "Let others respond",
"level": "Level",
"library": "Library",
"library_add_folder": "Add folder",
"library_edit_folder": "Edit folder",
"library_options": "Library options",
"library_page_device_albums": "Albums on Device",
"library_page_new_album": "New album",
@@ -1312,8 +1325,17 @@
"loop_videos_description": "Enable to automatically loop a video in the detail viewer.",
"main_branch_warning": "You're using a development version; we strongly recommend using a release version!",
"main_menu": "Main menu",
"maintenance_description": "Immich has been put into <link>maintenance mode</link>.",
"maintenance_end": "End maintenance mode",
"maintenance_end_error": "Failed to end maintenance mode.",
"maintenance_logged_in_as": "Currently logged in as {user}",
"maintenance_title": "Temporarily Unavailable",
"make": "Make",
"manage_geolocation": "Manage location",
"manage_media_access_rationale": "This permission is required for proper handling of moving assets to the trash and restoring them from it.",
"manage_media_access_settings": "Open settings",
"manage_media_access_subtitle": "Allow the Immich app to manage and move media files.",
"manage_media_access_title": "Media Management Access",
"manage_shared_links": "Manage shared links",
"manage_sharing_with_partners": "Manage sharing with partners",
"manage_the_app_settings": "Manage the app settings",
@@ -1377,6 +1399,7 @@
"more": "More",
"move": "Move",
"move_off_locked_folder": "Move out of locked folder",
"move_to": "Move to",
"move_to_lock_folder_action_prompt": "{count} added to the locked folder",
"move_to_locked_folder": "Move to locked folder",
"move_to_locked_folder_confirmation": "These photos and video will be removed from all albums, and only viewable from the locked folder",
@@ -1406,6 +1429,7 @@
"new_pin_code": "New PIN code",
"new_pin_code_subtitle": "This is your first time accessing the locked folder. Create a PIN code to securely access this page",
"new_timeline": "New Timeline",
"new_update": "New update",
"new_user_created": "New user created",
"new_version_available": "NEW VERSION AVAILABLE",
"newest_first": "Newest first",
@@ -1421,12 +1445,14 @@
"no_cast_devices_found": "No cast devices found",
"no_checksum_local": "No checksum available - cannot fetch local assets",
"no_checksum_remote": "No checksum available - cannot fetch remote asset",
"no_devices": "No authorized devices",
"no_duplicates_found": "No duplicates were found.",
"no_exif_info_available": "No exif info available",
"no_explore_results_message": "Upload more photos to explore your collection.",
"no_favorites_message": "Add favorites to quickly find your best pictures and videos",
"no_libraries_message": "Create an external library to view your photos and videos",
"no_local_assets_found": "No local assets found with this checksum",
"no_location_set": "No location set",
"no_locked_photos_message": "Photos and videos in the locked folder are hidden and won't show up as you browse or search your library.",
"no_name": "No Name",
"no_notifications": "No notifications",
@@ -1437,6 +1463,7 @@
"no_results_description": "Try a synonym or more general keyword",
"no_shared_albums_message": "Create an album to share photos and videos with people in your network",
"no_uploads_in_progress": "No uploads in progress",
"not_allowed": "Not allowed",
"not_available": "N/A",
"not_in_any_album": "Not in any album",
"not_selected": "Not selected",
@@ -1547,6 +1574,8 @@
"photos_count": "{count, plural, one {{count, number} Photo} other {{count, number} Photos}}",
"photos_from_previous_years": "Photos from previous years",
"pick_a_location": "Pick a location",
"pick_custom_range": "Custom range",
"pick_date_range": "Select a date range",
"pin_code_changed_successfully": "Successfully changed PIN code",
"pin_code_reset_successfully": "Successfully reset PIN code",
"pin_code_setup_successfully": "Successfully setup a PIN code",
@@ -1814,6 +1843,8 @@
"server_offline": "Server Offline",
"server_online": "Server Online",
"server_privacy": "Server Privacy",
"server_restarting_description": "This page will refresh momentarily.",
"server_restarting_title": "Server is restarting",
"server_stats": "Server Stats",
"server_update_available": "Server update is available",
"server_version": "Server Version",
@@ -1937,6 +1968,7 @@
"show_slideshow_transition": "Show slideshow transition",
"show_supporter_badge": "Supporter badge",
"show_supporter_badge_description": "Show a supporter badge",
"show_text_recognition": "Show text recognition",
"show_text_search_menu": "Show text search menu",
"shuffle": "Shuffle",
"sidebar": "Sidebar",
@@ -2007,6 +2039,7 @@
"tags": "Tags",
"tap_to_run_job": "Tap to run job",
"template": "Template",
"text_recognition": "Text recognition",
"theme": "Theme",
"theme_selection": "Theme selection",
"theme_selection_description": "Automatically set the theme to light or dark based on your browser's system preference",
@@ -2027,6 +2060,7 @@
"third_party_resources": "Third-Party Resources",
"time": "Time",
"time_based_memories": "Time-based memories",
"time_based_memories_duration": "Number of seconds to display each image.",
"timeline": "Timeline",
"timezone": "Timezone",
"to_archive": "Archive",
@@ -2167,6 +2201,7 @@
"welcome": "Welcome",
"welcome_to_immich": "Welcome to Immich",
"wifi_name": "Wi-Fi Name",
"workflow": "Workflow",
"wrong_pin_code": "Wrong PIN code",
"year": "Year",
"years_ago": "{years, plural, one {# year} other {# years}} ago",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Agregar un cumpleaños",
"add_endpoint": "Agregar endpoint",
"add_exclusion_pattern": "Agregar patrón de exclusión",
"add_import_path": "Agregar ruta de importación",
"add_location": "Agregar ubicación",
"add_more_users": "Agregar más usuarios",
"add_partner": "Agregar compañero",
@@ -32,6 +31,7 @@
"add_to_album_toggle": "Alternar selección para el {album}",
"add_to_albums": "Incluir en álbumes",
"add_to_albums_count": "Incluir en {count} álbumes",
"add_to_bottom_bar": "Añadir a",
"add_to_shared_album": "Incluir en álbum compartido",
"add_upload_to_stack": "Añadir archivo y apilar",
"add_url": "Agregar URL",
@@ -112,15 +112,19 @@
"jobs_failed": "{jobCount, plural, one {# fallido} other {# fallidos}}",
"library_created": "La biblioteca ha sido creada: {library}",
"library_deleted": "Biblioteca eliminada",
"library_import_path_description": "Indica una carpeta para importar. Esta carpeta y sus subcarpetas serán escaneadas en busca de elementos multimedia.",
"library_details": "Detalles de la biblioteca",
"library_folder_description": "Especifica una carpeta para importar. Esta carpeta, incluidas sus subcarpetas, se analizará en busca de imágenes y vídeos.",
"library_remove_exclusion_pattern_prompt": "¿Estás seguro de que quieres eliminar este patrón de exclusión?",
"library_remove_folder_prompt": "¿Estás seguro de que quieres eliminar esta carpeta de importación?",
"library_scanning": "Escaneo periódico",
"library_scanning_description": "Configurar el escaneo periódico de la biblioteca",
"library_scanning_enable_description": "Activar el escaneo periódico de la biblioteca",
"library_settings": "Biblioteca externa",
"library_settings_description": "Administrar configuración biblioteca externa",
"library_tasks_description": "Buscar elementos nuevos o modificados en bibliotecas externas",
"library_updated": "Biblioteca actualizada",
"library_watching_enable_description": "Vigilar las bibliotecas externas para detectar cambios en los archivos",
"library_watching_settings": "Vigilancia de la biblioteca (EXPERIMENTAL)",
"library_watching_settings": "Vigilancia de la biblioteca [EXPERIMENTAL]",
"library_watching_settings_description": "Vigilar automaticamente en busca de archivos modificados",
"logging_enable_description": "Habilitar registro",
"logging_level_description": "Indica el nivel de registro a utilizar cuando está habilitado.",
@@ -154,6 +158,18 @@
"machine_learning_min_detection_score_description": "Puntuación de confianza mínima para que se detecte una cara de 0 a 1. Los valores más bajos detectarán más rostros pero pueden generar falsos positivos.",
"machine_learning_min_recognized_faces": "Rostros mínimos reconocidos",
"machine_learning_min_recognized_faces_description": "El número mínimo de rostros reconocidos para que se cree una persona. Aumentar esto permite que el reconocimiento facial sea más preciso a costa de aumentar la posibilidad de que no se asigne una cara a una persona.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Usa el aprendizaje automático para reconocer texto en imágenes",
"machine_learning_ocr_enabled": "Activar OCR",
"machine_learning_ocr_enabled_description": "Si está desactivado, las imágenes no se someterán al reconocimiento de texto.",
"machine_learning_ocr_max_resolution": "Resolución máxima",
"machine_learning_ocr_max_resolution_description": "Las vistas previas por encima de esta resolución se redimensionarán manteniendo la relación de aspecto. Los valores más altos son más precisos, pero tardan más en procesarse y consumen más memoria.",
"machine_learning_ocr_min_detection_score": "Puntuación mínima de detección",
"machine_learning_ocr_min_detection_score_description": "Puntuación mínima de confianza para que el texto sea detectado de 0 a 1. Los valores más bajos detectarán más texto, pero pueden producir falsos positivos.",
"machine_learning_ocr_min_recognition_score": "Puntuación mínima de reconocimiento",
"machine_learning_ocr_min_score_recognition_description": "Puntuación mínima de confianza para que el texto detectado sea reconocido de 0 a 1. Los valores más bajos reconocerán más texto, pero pueden producir falsos positivos.",
"machine_learning_ocr_model": "Modelo de OCR",
"machine_learning_ocr_model_description": "Los modelos del servidor son más precisos que los modelos para móviles móviles, pero tardan más en procesar y consumen más memoria.",
"machine_learning_settings": "Configuración de aprendizaje automático",
"machine_learning_settings_description": "Administrar funciones y configuraciones de aprendizaje automático",
"machine_learning_smart_search": "Busqueda inteligente",
@@ -161,6 +177,10 @@
"machine_learning_smart_search_enabled": "Habilitar búsqueda inteligente",
"machine_learning_smart_search_enabled_description": "Al desactivarlo las imágenes no se procesarán para usar la búsqueda inteligente.",
"machine_learning_url_description": "La URL del servidor de aprendizaje automático. Si se proporciona más de una URL se intentará acceder a cada servidor sucesivamente hasta que uno responda correctamente en el orden especificado. Los servidores que no respondan serán ignorados temporalmente hasta que vuelvan a estar en línea.",
"maintenance_settings": "Mantenimiento",
"maintenance_settings_description": "Poner Immich en modo de mantenimiento.",
"maintenance_start": "Iniciar el modo de mantenimiento",
"maintenance_start_error": "Error al iniciar el modo de mantenimiento.",
"manage_concurrency": "Ajustes de concurrencia",
"manage_log_settings": "Administrar la configuración de los registros",
"map_dark_style": "Estilo oscuro",
@@ -202,7 +222,7 @@
"nightly_tasks_sync_quota_usage_setting_description": "Actualizar la cuota de almacenamiento del usuario, según el uso actual",
"no_paths_added": "No se han agregado rutas",
"no_pattern_added": "No se han agregado patrones",
"note_apply_storage_label_previous_assets": "Nota: Para aplicar la etiqueta de almacenamiento a los elementos que ya se subieron, ejecuta la",
"note_apply_storage_label_previous_assets": "Nota: Para aplicar la Etiqueta de Almacenamiento a los elementos previamente subidos, ejecuta la",
"note_cannot_be_changed_later": "NOTA: ¡No se puede cambiar posteriormente!",
"notification_email_from_address": "Desde",
"notification_email_from_address_description": "Dirección de correo electrónico del remitente, por ejemplo: \"Immich Photo Server <noreply@example.com>\". Asegúrate de utilizar una dirección desde la que puedas enviar correos electrónicos.",
@@ -211,6 +231,8 @@
"notification_email_ignore_certificate_errors_description": "Ignorar los errores de validación del certificado TLS (no recomendado)",
"notification_email_password_description": "Contraseña a utilizar al autenticarse con el servidor de correo electrónico",
"notification_email_port_description": "Puerto del servidor de correo electrónico (por ejemplo: 25, 465 o 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Usar SMTPS (SMTP sobre TLS)",
"notification_email_sent_test_email_button": "Enviar correo electrónico de prueba y guardar",
"notification_email_setting_description": "Configuraciones para enviar notificaciones por correo electrónico",
"notification_email_test_email": "Enviar email de prueba",
@@ -241,8 +263,9 @@
"oauth_storage_quota_claim_description": "Fijar la cuota de almacenamiento del usuario automáticamente al valor solicitado.",
"oauth_storage_quota_default": "Cuota de almacenamiento predeterminada (GiB)",
"oauth_storage_quota_default_description": "Cuota (en GiB) que se usará cuando no se solicite un valor específico.",
"oauth_timeout": "Tiempo de espera agotado para la solicitud",
"oauth_timeout": "Tiempo de espera de la solicitud agotado",
"oauth_timeout_description": "Tiempo de espera de solicitudes en milisegundos",
"ocr_job_description": "Usar aprendizaje automático para reconocer texto en imágenes",
"password_enable_description": "Iniciar sesión con correo electrónico y contraseña",
"password_settings": "Contraseña de Acceso",
"password_settings_description": "Administrar la configuración de inicio de sesión con contraseña",
@@ -333,7 +356,7 @@
"transcoding_max_b_frames": "Maximos B-frames",
"transcoding_max_b_frames_description": "Los valores más altos mejoran la eficiencia de la compresión, pero ralentizan la codificación. Puede que no sea compatible con la aceleración de hardware en dispositivos más antiguos. 0 desactiva los fotogramas B, mientras que -1 establece este valor automáticamente.",
"transcoding_max_bitrate": "Máxima tasa de bits",
"transcoding_max_bitrate_description": "Establecer una tasa de bits máxima puede hacer que los tamaños de archivos sean más predecibles con un costo menor para la calidad. A 720p, los valores típicos son 2600 kbit/s para VP9 o HEVC, o 4500 kbit/s para H.264. Deshabilitado si se establece en 0.",
"transcoding_max_bitrate_description": "Establecer una tasa de bits máxima puede hacer que los tamaños de archivo sean más predecibles a un coste menor en la calidad. A 720p, los valores típicos son 2600 kbit/s para VP9 o HEVC, o 4500 kbit/s para H.264. Se desactiva si se establece en 0. Cuando no se especifica una unidad, se asume k (para kbit/s); por lo tanto, 5000, 5000k y 5M (para Mbit/s) son equivalentes.",
"transcoding_max_keyframe_interval": "Intervalo máximo de fotogramas clave",
"transcoding_max_keyframe_interval_description": "Establece la distancia máxima de fotograma entre fotogramas clave. Los valores más bajos empeoran la eficiencia de la compresión, pero mejoran los tiempos de búsqueda y pueden mejorar la calidad en escenas con movimientos rápidos. 0 establece este valor automáticamente.",
"transcoding_optimal_description": "Vídeos con una resolución superior a la fijada o que no están en un formato aceptado",
@@ -351,7 +374,7 @@
"transcoding_target_resolution": "Resolución deseada",
"transcoding_target_resolution_description": "Las resoluciones más altas pueden conservar más detalles, pero la codificación tarda más, tienen tamaños de archivo más grandes y pueden reducir la capacidad de respuesta de la aplicación.",
"transcoding_temporal_aq": "AQ temporal",
"transcoding_temporal_aq_description": "Se aplica únicamente a NVENC. Aumenta la calidad de escenas con mucho detalle y poco movimiento. Puede que no sea compatible con dispositivos más antiguos.",
"transcoding_temporal_aq_description": "Solo se aplica a NVENC. La Cuantificación Adaptativa Temporal aumenta la calidad de las escenas con mucho detalle y poco movimiento. Podría no ser compatible con dispositivos más antiguos.",
"transcoding_threads": "Hilos",
"transcoding_threads_description": "Los valores más altos conducen a una codificación más rápida, pero dejan menos espacio para que el servidor procese otras tareas mientras está activo. Este valor no debe ser mayor que la cantidad de núcleos de CPU. Maximiza la utilización si se establece en 0.",
"transcoding_tone_mapping": "Mapeo de tonos",
@@ -402,11 +425,11 @@
"advanced_settings_prefer_remote_subtitle": "Algunos dispositivos tardan mucho en cargar las miniaturas desde los archivos locales. Activa esta opción para cargar imágenes remotas en su lugar.",
"advanced_settings_prefer_remote_title": "Preferir imágenes remotas",
"advanced_settings_proxy_headers_subtitle": "Configura headers HTTP que Immich incluirá en cada petición de red",
"advanced_settings_proxy_headers_title": "Cabeceras Proxy",
"advanced_settings_proxy_headers_title": "Cabeceras proxy personalizadas [EXPERIMENTAL]",
"advanced_settings_readonly_mode_subtitle": "Habilita el modo de solo lectura donde las fotografías sólo pueden ser vistas, funciones como seleccionar múltiples imágenes, compartir, transmitir, eliminar son deshabilitadas. Habilita/Deshabilita solo lectura vía el avatar del usuario en la pantalla principal",
"advanced_settings_readonly_mode_title": "Modo Solo lectura",
"advanced_settings_readonly_mode_title": "Modo solo lectura",
"advanced_settings_self_signed_ssl_subtitle": "Omitir verificación del certificado SSL del servidor. Requerido para certificados autofirmados.",
"advanced_settings_self_signed_ssl_title": "Permitir certificados autofirmados",
"advanced_settings_self_signed_ssl_title": "Permitir certificados SSL autofirmados [EXPERIMENTAL]",
"advanced_settings_sync_remote_deletions_subtitle": "Eliminar o restaurar automáticamente un recurso en este dispositivo cuando se realice esa acción en la web",
"advanced_settings_sync_remote_deletions_title": "Sincronizar eliminaciones remotas [EXPERIMENTAL]",
"advanced_settings_tile_subtitle": "Configuraciones avanzadas del usuario",
@@ -415,6 +438,7 @@
"age_months": "Tiempo {months, plural, one {# mes} other {# meses}}",
"age_year_months": "1 año, {months, plural, one {# mes} other {# meses}}",
"age_years": "Edad {years, plural, one {# año} other {# años}}",
"album": "Álbum",
"album_added": "Álbum agregado",
"album_added_notification_setting_description": "Reciba una notificación por correo electrónico cuando lo agreguen a un álbum compartido",
"album_cover_updated": "Portada del álbum actualizada",
@@ -445,7 +469,7 @@
"album_viewer_appbar_share_leave": "Abandonar álbum",
"album_viewer_appbar_share_to": "Compartir Con",
"album_viewer_page_share_add_users": "Agregar usuarios",
"album_with_link_access": "Permite que cualquiera que tenga este enlace vea las fotos y las personas del álbum.",
"album_with_link_access": "Permitir que cualquiera que tenga el enlace vea las fotos y las personas del álbum.",
"albums": "Álbumes",
"albums_count": "{count, plural, one {{count, number} álbum} other {{count, number} álbumes}}",
"albums_default_sort_order": "Ordenación por defecto de los álbumes",
@@ -459,17 +483,22 @@
"allow_dark_mode": "Permitir modo oscuro",
"allow_edits": "Permitir edición",
"allow_public_user_to_download": "Permitir descargas a los usuarios públicos",
"allow_public_user_to_upload": "Permitir subir fotos a los usuarios públicos",
"allow_public_user_to_upload": "Permitir a los usuarios públicos subir fotos",
"allowed": "Permitido",
"alt_text_qr_code": "Código QR",
"anti_clockwise": "En sentido antihorario",
"api_key": "Clave API",
"api_key_description": "Este valor sólo se mostrará una vez. Asegúrese de copiarlo antes de cerrar la ventana.",
"api_key_empty": "El nombre de su clave API no debe estar vacío",
"api_keys": "Claves API",
"app_architecture_variant": "Variante (Arquitectura)",
"app_bar_signout_dialog_content": "¿Estás seguro que quieres cerrar sesión?",
"app_bar_signout_dialog_ok": "Sí",
"app_bar_signout_dialog_title": "Cerrar sesión",
"app_download_links": "Enlaces de Descarga de la Aplicación",
"app_settings": "Ajustes de la aplicacion",
"app_stores": "Tiendas de Aplicaciones",
"app_update_available": "Actualización de aplicación está disponible",
"appears_in": "Aparece en",
"apply_count": "Aplicar ({count, number})",
"archive": "Archivo",
@@ -477,14 +506,14 @@
"archive_or_unarchive_photo": "Archivar o restaurar foto",
"archive_page_no_archived_assets": "No se encontraron elementos archivados",
"archive_page_title": "Archivo ({count})",
"archive_size": "Tamaño del archivo",
"archive_size": "Tamaño de archivo comprimido",
"archive_size_description": "Configure el tamaño del archivo para descargas (en GB)",
"archived": "Archivado",
"archived_count": "{count, plural, one {# archivado} other {# archivados}}",
"are_these_the_same_person": "¿Son la misma persona?",
"are_you_sure_to_do_this": "¿Estas seguro de que quieres hacer esto?",
"asset_action_delete_err_read_only": "No se pueden borrar el archivo(s) de solo lectura, omitiendo",
"asset_action_share_err_offline": "No se pudo obtener el archivo(s) sin conexión, omitiendo",
"are_you_sure_to_do_this": "¿Estás seguro de que quieres hacer esto?",
"asset_action_delete_err_read_only": "No se puede borrar archivo(s) de solo lectura, omitiendo",
"asset_action_share_err_offline": "No se pudo obtener archivo(s) sin conexión, omitiendo",
"asset_added_to_album": "Agregado al álbum",
"asset_adding_to_album": "Agregando al álbum…",
"asset_description_updated": "La descripción del elemento ha sido actualizada",
@@ -553,6 +582,7 @@
"backup_albums_sync": "Sincronización de álbumes de respaldo",
"backup_all": "Todos",
"backup_background_service_backup_failed_message": "Error al copiar elementos. Reintentando…",
"backup_background_service_complete_notification": "Copia de seguridad de activos completada",
"backup_background_service_connection_failed_message": "Error al conectar con el servidor. Reintentando…",
"backup_background_service_current_upload_notification": "Subiendo {filename}",
"backup_background_service_default_notification": "Comprobando nuevos elementos…",
@@ -649,7 +679,7 @@
"cannot_merge_people": "No se pueden fusionar personas",
"cannot_undo_this_action": "¡No puedes deshacer esta acción!",
"cannot_update_the_description": "No se puede actualizar la descripción",
"cast": "Convertir",
"cast": "Transmitir",
"cast_description": "Configura los posibles destinos de retransmisión",
"change_date": "Cambiar fecha",
"change_description": "Cambiar descripción",
@@ -662,6 +692,8 @@
"change_password_description": "Esta es la primera vez que inicia sesión en el sistema o se ha realizado una solicitud para cambiar su contraseña. Por favor ingrese la nueva contraseña a continuación.",
"change_password_form_confirm_password": "Confirmar contraseña",
"change_password_form_description": "Hola {name},\n\nEsta es la primera vez que inicias sesión en el sistema o se ha solicitado cambiar tu contraseña. Por favor, introduce la nueva contraseña a continuación.",
"change_password_form_log_out": "Cerrar sesión los demás dispositivos",
"change_password_form_log_out_description": "Se recomienda cerrar sesión en todos los demás dispositivos",
"change_password_form_new_password": "Nueva contraseña",
"change_password_form_password_mismatch": "Las contraseñas no coinciden",
"change_password_form_reenter_new_password": "Vuelve a ingresar la nueva contraseña",
@@ -689,7 +721,7 @@
"client_cert_invalid_msg": "Archivo de certificado no válido o contraseña incorrecta",
"client_cert_remove_msg": "El certificado de cliente se ha eliminado",
"client_cert_subtitle": "Solo se admite el formato PKCS12 (.p12, .pfx). La importación/eliminación de certificados solo está disponible antes de iniciar sesión",
"client_cert_title": "Certificado de cliente SSL",
"client_cert_title": "Certificado de cliente SSL [EXPERIMENTAL]",
"clockwise": "En el sentido de las agujas del reloj",
"close": "Cerrar",
"collapse": "Agrupar",
@@ -701,7 +733,6 @@
"comments_and_likes": "Comentarios y me gusta",
"comments_are_disabled": "Los comentarios están deshabilitados",
"common_create_new_album": "Crear nuevo álbum",
"common_server_error": "Por favor, comprueba tu conexión de red, asegúrate de que el servidor esté accesible y las versiones de la aplicación y del servidor sean compatibles.",
"completed": "Completado",
"confirm": "Confirmar",
"confirm_admin_password": "Confirmar contraseña del administrador",
@@ -723,7 +754,7 @@
"control_bottom_app_bar_edit_location": "Editar ubicación",
"control_bottom_app_bar_edit_time": "Editar fecha y hora",
"control_bottom_app_bar_share_link": "Enlace para compartir",
"control_bottom_app_bar_share_to": "Enviar",
"control_bottom_app_bar_share_to": "Compartir a",
"control_bottom_app_bar_trash_from_immich": "Mover a la papelera",
"copied_image_to_clipboard": "Imagen copiada al portapapeles.",
"copied_to_clipboard": "¡Copiado al portapapeles!",
@@ -740,6 +771,7 @@
"create": "Crear",
"create_album": "Crear álbum",
"create_album_page_untitled": "Sin título",
"create_api_key": "Crear clave API",
"create_library": "Crear biblioteca",
"create_link": "Crear enlace",
"create_link_to_share": "Crear enlace compartido",
@@ -769,6 +801,7 @@
"daily_title_text_date_year": "E dd de MMM, yyyy",
"dark": "Oscuro",
"dark_theme": "Alternar tema oscuro",
"date": "Fecha",
"date_after": "Fecha posterior",
"date_and_time": "Fecha y Hora",
"date_before": "Fecha anterior",
@@ -871,8 +904,6 @@
"edit_description_prompt": "Por favor selecciona una nueva descripción:",
"edit_exclusion_pattern": "Editar patrón de exclusión",
"edit_faces": "Editar rostros",
"edit_import_path": "Editar ruta de importación",
"edit_import_paths": "Editar ruta de importación",
"edit_key": "Editar clave",
"edit_link": "Editar enlace",
"edit_location": "Editar ubicación",
@@ -883,7 +914,6 @@
"edit_tag": "Editar etiqueta",
"edit_title": "Editar Titulo",
"edit_user": "Editar usuario",
"edited": "Editado",
"editor": "Editor",
"editor_close_without_save_prompt": "No se guardarán los cambios",
"editor_close_without_save_title": "¿Cerrar el editor?",
@@ -945,8 +975,8 @@
"failed_to_stack_assets": "No se pudieron agrupar los archivos",
"failed_to_unstack_assets": "Error al desagrupar los archivos",
"failed_to_update_notification_status": "Error al actualizar el estado de la notificación",
"import_path_already_exists": "Esta ruta de importación ya existe.",
"incorrect_email_or_password": "Contraseña o email incorrecto",
"library_folder_already_exists": "Esta ruta de importación ya existe.",
"paths_validation_failed": "Falló la validación en {paths, plural, one {# carpeta} other {# carpetas}}",
"profile_picture_transparent_pixels": "Las imágenes de perfil no pueden tener píxeles transparentes. Por favor amplíe y/o mueva la imagen.",
"quota_higher_than_disk_size": "Se ha establecido una cuota superior al tamaño del disco",
@@ -955,7 +985,6 @@
"unable_to_add_assets_to_shared_link": "No se pueden agregar archivos al enlace compartido",
"unable_to_add_comment": "No se puede agregar comentario",
"unable_to_add_exclusion_pattern": "No se puede agregar el patrón de exclusión",
"unable_to_add_import_path": "No se puede agregar la ruta de importación",
"unable_to_add_partners": "No se pueden agregar compañeros",
"unable_to_add_remove_archive": "No se puede archivar {archived, select, true {remove asset from} other {add asset to}}",
"unable_to_add_remove_favorites": "{favorite, select, true {No se pudo agregar el elemento a los favoritos} other {No se pudo eliminar el elemento de los favoritos}}",
@@ -978,12 +1007,10 @@
"unable_to_delete_asset": "No se puede eliminar el archivo",
"unable_to_delete_assets": "Error al eliminar archivos",
"unable_to_delete_exclusion_pattern": "No se puede eliminar el patrón de exclusión",
"unable_to_delete_import_path": "No se puede eliminar la ruta de importación",
"unable_to_delete_shared_link": "No se puede eliminar el enlace compartido",
"unable_to_delete_user": "No se puede eliminar el usuario",
"unable_to_download_files": "No se pueden descargar archivos",
"unable_to_edit_exclusion_pattern": "No se puede editar el patrón de exclusión",
"unable_to_edit_import_path": "No se puede editar la ruta de importación",
"unable_to_empty_trash": "No se puede vaciar la papelera",
"unable_to_enter_fullscreen": "No se puede acceder al modo pantalla completa",
"unable_to_exit_fullscreen": "No se puede salir del modo pantalla completa",
@@ -1034,11 +1061,13 @@
"unable_to_update_user": "No se puede actualizar el usuario",
"unable_to_upload_file": "Error al subir el archivo"
},
"exclusion_pattern": "Patrón de exclusión",
"exif": "EXIF",
"exif_bottom_sheet_description": "Agregar descripción…",
"exif_bottom_sheet_description_error": "Error al actualizar la descripción",
"exif_bottom_sheet_details": "DETALLES",
"exif_bottom_sheet_location": "UBICACIÓN",
"exif_bottom_sheet_no_description": "Sin descripción",
"exif_bottom_sheet_people": "PERSONAS",
"exif_bottom_sheet_person_add_person": "Agregar nombre",
"exit_slideshow": "Salir de la presentación",
@@ -1077,9 +1106,10 @@
"features_setting_description": "Administrar las funciones de la aplicación",
"file_name": "Nombre de archivo",
"file_name_or_extension": "Nombre del archivo o extensión",
"file_size": "Tamaño del archivo",
"filename": "Nombre del archivo",
"filetype": "Tipo de archivo",
"filter": "Filtrar",
"filter": "Filtros",
"filter_people": "Filtrar personas",
"filter_places": "Filtrar lugares",
"find_them_fast": "Encuéntrelos rápidamente por nombre con la búsqueda",
@@ -1091,6 +1121,7 @@
"folders_feature_description": "Explorar la vista de carpetas para las fotos y los videos en el sistema de archivos",
"forgot_pin_code_question": "¿Olvidaste tu código PIN?",
"forward": "Avanzar",
"full_path": "Ruta completa: {path}",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Esta funcionalidad carga recursos externos desde Google para poder funcionar.",
"general": "General",
@@ -1120,7 +1151,6 @@
"header_settings_field_validator_msg": "El valor no puede estar vacío",
"header_settings_header_name_input": "Nombre de la cabecera",
"header_settings_header_value_input": "Valor de la cabecera",
"headers_settings_tile_subtitle": "Configura headers HTTP que la aplicación incluirá en cada petición de red",
"headers_settings_tile_title": "Cabeceras de proxy personalizadas",
"hi_user": "Hola {name} ({email})",
"hide_all_people": "Ocultar a todas las personas",
@@ -1173,6 +1203,8 @@
"import_path": "Importar ruta",
"in_albums": "En {count, plural, one {# álbum} other {# álbumes}}",
"in_archive": "En archivo",
"in_year": "En {year}",
"in_year_selector": "En",
"include_archived": "Incluir archivados",
"include_shared_albums": "Incluir álbumes compartidos",
"include_shared_partner_assets": "Incluir elementos compartidos por compañeros",
@@ -1209,6 +1241,7 @@
"language_setting_description": "Selecciona tu idioma preferido",
"large_files": "Archivos Grandes",
"last": "Último",
"last_months": "{count, plural, one {Último mes} other {Últimos # meses}}",
"last_seen": "Ultima vez visto",
"latest_version": "Última versión",
"latitude": "Latitud",
@@ -1218,6 +1251,8 @@
"let_others_respond": "Permitir que otros respondan",
"level": "Nivel",
"library": "Biblioteca",
"library_add_folder": "Añadir carpeta",
"library_edit_folder": "Editar carpeta",
"library_options": "Opciones de biblioteca",
"library_page_device_albums": "Álbumes en el dispositivo",
"library_page_new_album": "Nuevo álbum",
@@ -1241,6 +1276,7 @@
"local_media_summary": "Resumen de Medios Locales",
"local_network": "Red local",
"local_network_sheet_info": "La aplicación se conectará al servidor a través de esta URL cuando utilice la red Wi-Fi especificada",
"location": "Ubicación",
"location_permission": "Permiso de ubicación",
"location_permission_content": "Para usar la función de cambio automático, Immich necesita permiso de ubicación precisa para poder leer el nombre de la red Wi-Fi actual",
"location_picker_choose_on_map": "Elegir en el mapa",
@@ -1288,8 +1324,17 @@
"loop_videos_description": "Habilite la reproducción automática de un video en el visor de detalles.",
"main_branch_warning": "Está utilizando una versión de desarrollo; ¡le recomendamos encarecidamente que utilice una versión de lanzamiento!",
"main_menu": "Menú principal",
"maintenance_description": "Immich se ha puesto en <link>modo de mantenimiento</link>.",
"maintenance_end": "Finalizar el modo de mantenimiento",
"maintenance_end_error": "Error al finalizar el modo de mantenimiento.",
"maintenance_logged_in_as": "Sesión iniciada actualmente como {user}",
"maintenance_title": "No disponible temporalmente",
"make": "Marca",
"manage_geolocation": "Administrar ubicación",
"manage_media_access_rationale": "Este permiso se requiere para mover recursos a la papelera correctamente, así como para restaurarlos desde la misma.",
"manage_media_access_settings": "Abrir configuración",
"manage_media_access_subtitle": "Permitir a la app Immich gestionar y mover archivos multimedia.",
"manage_media_access_title": "Acceso a gestión de archivos multimedia",
"manage_shared_links": "Administrar enlaces compartidos",
"manage_sharing_with_partners": "Gestionar el uso compartido con compañeros",
"manage_the_app_settings": "Administrar la configuración de la aplicación",
@@ -1345,12 +1390,15 @@
"minute": "Minuto",
"minutes": "Minutos",
"missing": "Faltante",
"mobile_app": "Aplicación Móvil",
"mobile_app_download_onboarding_note": "Descarga la aplicación móvil utilizando las siguientes opciones",
"model": "Modelo",
"month": "Mes",
"monthly_title_text_date_format": "MMMM a",
"more": "Mas",
"move": "Mover",
"move_off_locked_folder": "Sacar de la carpeta protegida",
"move_to": "Mover a",
"move_to_lock_folder_action_prompt": "{count} agregado(s) a la carpeta protegida",
"move_to_locked_folder": "Mover a la carpeta protegida",
"move_to_locked_folder_confirmation": "Estas fotos y vídeos se eliminarán de todos los álbumes; solo se podrán ver en la carpeta protegida",
@@ -1363,6 +1411,8 @@
"my_albums": "Mis álbumes",
"name": "Nombre",
"name_or_nickname": "Nombre o apodo",
"navigate": "Navegar",
"navigate_to_time": "Navegar a Hora",
"network_requirement_photos_upload": "Usar datos móviles para crear una copia de seguridad de las fotos",
"network_requirement_videos_upload": "Usar datos móviles para crear una copia de seguridad de los videos",
"network_requirements": "Requisitos de red",
@@ -1372,11 +1422,13 @@
"never": "Nunca",
"new_album": "Nuevo álbum",
"new_api_key": "Nueva clave API",
"new_date_range": "Nuevo rango de fechas",
"new_password": "Nueva contraseña",
"new_person": "Nueva persona",
"new_pin_code": "Nuevo PIN",
"new_pin_code_subtitle": "Esta es la primera vez que accedes a la carpeta protegida. Crea un código PIN seguro para acceder a esta página",
"new_timeline": "Nueva Línea de tiempo",
"new_update": "Nueva actualización",
"new_user_created": "Nuevo usuario creado",
"new_version_available": "NUEVA VERSIÓN DISPONIBLE",
"newest_first": "El más reciente primero",
@@ -1392,12 +1444,14 @@
"no_cast_devices_found": "No se encontraron dispositivos de transmisión",
"no_checksum_local": "Suma de verificación no disponible. No se pueden obtener los elementos locales",
"no_checksum_remote": "Suma de verificación no disponible. No se puede obtener el elemento remoto",
"no_devices": "Dispositivos no autorizados",
"no_duplicates_found": "No se encontraron duplicados.",
"no_exif_info_available": "No hay información exif disponible",
"no_explore_results_message": "Sube más fotos para explorar tu colección.",
"no_favorites_message": "Agregue favoritos para encontrar rápidamente sus mejores fotos y videos",
"no_libraries_message": "Crea una biblioteca externa para ver tus fotos y vídeos",
"no_local_assets_found": "No se encontraron elementos locales con esta suma de comprobación",
"no_location_set": "No se ha establecido ninguna ubicación",
"no_locked_photos_message": "Las fotos y los vídeos de la carpeta protegida se mantienen ocultos; no aparecerán cuando veas o busques elementos en tu biblioteca.",
"no_name": "Sin nombre",
"no_notifications": "Ninguna notificación",
@@ -1408,6 +1462,7 @@
"no_results_description": "Pruebe con un sinónimo o una palabra clave más general",
"no_shared_albums_message": "Crea un álbum para compartir fotos y vídeos con personas de tu red",
"no_uploads_in_progress": "No hay cargas en progreso",
"not_allowed": "No permitido",
"not_available": "N/D",
"not_in_any_album": "Sin álbum",
"not_selected": "No seleccionado",
@@ -1422,6 +1477,9 @@
"notifications": "Notificaciones",
"notifications_setting_description": "Administrar notificaciones",
"oauth": "OAuth",
"obtainium_configurator": "Configurador de Obtainium",
"obtainium_configurator_instructions": "Usa Obtainium para instalar y actualizar la aplicación de Android directamente desde las versiones publicadas en el GitHub de Immich. Crea una clave API y selecciona una variante para generar tu enlace de configuración de Obtainium",
"ocr": "OCR",
"official_immich_resources": "Recursos oficiales de Immich",
"offline": "Desconectado",
"offset": "Desviación",
@@ -1515,6 +1573,8 @@
"photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}",
"photos_from_previous_years": "Fotos de años anteriores",
"pick_a_location": "Elige una ubicación",
"pick_custom_range": "Rango personalizado",
"pick_date_range": "Seleccione un rango de fechas",
"pin_code_changed_successfully": "PIN cambiado exitosamente",
"pin_code_reset_successfully": "PIN restablecido exitosamente",
"pin_code_setup_successfully": "PIN establecido exitosamente",
@@ -1526,6 +1586,9 @@
"play_memories": "Reproducir recuerdos",
"play_motion_photo": "Reproducir foto en movimiento",
"play_or_pause_video": "Reproducir o pausar vídeo",
"play_original_video": "Reproducir video original",
"play_original_video_setting_description": "Preferir la reproducción de videos originales en lugar de videos transcodificados. Si el recurso original no es compatible, es posible que no se reproduzca correctamente.",
"play_transcoded_video": "Reproducir video transcodificado",
"please_auth_to_access": "Por favor, autentícate para acceder",
"port": "Puerto",
"preferences_settings_subtitle": "Configuraciones de la aplicación",
@@ -1543,13 +1606,9 @@
"privacy": "Privacidad",
"profile": "Perfil",
"profile_drawer_app_logs": "Registros",
"profile_drawer_client_out_of_date_major": "La app está desactualizada. Por favor actualiza a la última versión principal.",
"profile_drawer_client_out_of_date_minor": "La app está desactualizada. Por favor actualiza a la última versión menor.",
"profile_drawer_client_server_up_to_date": "Cliente y Servidor están actualizados",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Modo Solo lectura habilitado. Mantén pulsado el icono del avatar del usuario para salir.",
"profile_drawer_server_out_of_date_major": "El servidor está desactualizado. Por favor actualiza a la última versión principal.",
"profile_drawer_server_out_of_date_minor": "El servidor está desactualizado. Por favor actualiza a la última versión menor.",
"profile_image_of_user": "Foto de perfil de {user}",
"profile_picture_set": "Conjunto de imágenes de perfil.",
"public_album": "Álbum público",
@@ -1606,8 +1665,8 @@
"recent_searches": "Búsquedas recientes",
"recently_added": "Añadidos recientemente",
"recently_added_page_title": "Recién Agregadas",
"recently_taken": "Recientemente tomado",
"recently_taken_page_title": "Recientemente Tomado",
"recently_taken": "Tomadas recientemente",
"recently_taken_page_title": "Tomadas Recientemente",
"refresh": "Actualizar",
"refresh_encoded_videos": "Recargar los vídeos codificados",
"refresh_faces": "Actualizar caras",
@@ -1666,6 +1725,7 @@
"reset_sqlite_confirmation": "¿Estás seguro que deseas restablecer la base de datos SQLite? Deberás cerrar sesión y volver a iniciarla para resincronizar los datos",
"reset_sqlite_success": "Restablecer exitosamente la base de datos SQLite",
"reset_to_default": "Restablecer los valores predeterminados",
"resolution": "Resolución",
"resolve_duplicates": "Resolver duplicados",
"resolved_all_duplicates": "Todos los duplicados resueltos",
"restore": "Restaurar",
@@ -1684,6 +1744,7 @@
"running": "En ejecución",
"save": "Guardar",
"save_to_gallery": "Guardado en la galería",
"saved": "Guardado",
"saved_api_key": "Clave API guardada",
"saved_profile": "Perfil guardado",
"saved_settings": "Configuraciones guardadas",
@@ -1700,6 +1761,9 @@
"search_by_description_example": "Día de senderismo en Sapa",
"search_by_filename": "Buscar por nombre de archivo o extensión",
"search_by_filename_example": "es decir IMG_1234.JPG o PNG",
"search_by_ocr": "Buscar por OCR",
"search_by_ocr_example": "Café con leche",
"search_camera_lens_model": "Buscar modelo de lente...",
"search_camera_make": "Buscar fabricante de cámara...",
"search_camera_model": "Buscar modelo de cámara...",
"search_city": "Buscar ciudad...",
@@ -1716,6 +1780,7 @@
"search_filter_location_title": "Seleccionar una ubicación",
"search_filter_media_type": "Tipo de archivo",
"search_filter_media_type_title": "Seleccionar el tipo de archivo",
"search_filter_ocr": "Buscar por OCR",
"search_filter_people_title": "Seleccionar personas",
"search_for": "Buscar",
"search_for_existing_person": "Buscar persona existente",
@@ -1772,12 +1837,15 @@
"send_message": "Enviar mensaje",
"send_welcome_email": "Enviar correo de bienvenida",
"server_endpoint": "Punto final del servidor",
"server_info_box_app_version": "Versión de la Aplicación",
"server_info_box_app_version": "Versión de la aplicación",
"server_info_box_server_url": "Enlace del servidor",
"server_offline": "Servidor desconectado",
"server_online": "Servidor en línea",
"server_privacy": "Privacidad del Servidor",
"server_restarting_description": "Esta página se actualizará en breve.",
"server_restarting_title": "El servidor se está reiniciando",
"server_stats": "Estadísticas del servidor",
"server_update_available": "Actualización de servidor disponible",
"server_version": "Versión del servidor",
"set": "Establecer",
"set_as_album_cover": "Establecer portada del álbum",
@@ -1806,6 +1874,8 @@
"setting_notifications_subtitle": "Ajusta tus preferencias de notificación",
"setting_notifications_total_progress_subtitle": "Progreso general de subida (elementos completados/total)",
"setting_notifications_total_progress_title": "Mostrar progreso total de copia de seguridad en segundo plano",
"setting_video_viewer_auto_play_subtitle": "Reproducir vídeos automáticamente al abrirlos",
"setting_video_viewer_auto_play_title": "Reproducir vídeos automáticamente",
"setting_video_viewer_looping_title": "Bucle",
"setting_video_viewer_original_video_subtitle": "Al reproducir un video en streaming desde el servidor, reproducir el original incluso cuando haya una transcodificación disponible. Puede causar buffering. Los videos disponibles localmente se reproducen en calidad original independientemente de esta configuración.",
"setting_video_viewer_original_video_title": "Forzar vídeo original",
@@ -1985,7 +2055,9 @@
"theme_setting_three_stage_loading_title": "Activar carga en tres etapas",
"they_will_be_merged_together": "Se fusionarán entre sí",
"third_party_resources": "Recursos de terceros",
"time": "Tiempo",
"time_based_memories": "Recuerdos basados en tiempo",
"time_based_memories_duration": "Número de segundos que se mostrará cada imagen.",
"timeline": "Cronología",
"timezone": "Zona horaria",
"to_archive": "Archivar",
@@ -2017,6 +2089,7 @@
"troubleshoot": "Solucionar problemas",
"type": "Tipo",
"unable_to_change_pin_code": "No se ha podido cambiar el PIN",
"unable_to_check_version": "No se puede comprobar la versión de la aplicación o del servidor",
"unable_to_setup_pin_code": "No se ha podido establecer el PIN",
"unarchive": "Desarchivar",
"unarchive_action_prompt": "{count} eliminados del archivo",
@@ -2125,6 +2198,7 @@
"welcome": "Bienvenido",
"welcome_to_immich": "Bienvenido a Immich",
"wifi_name": "Nombre Wi-Fi",
"workflow": "Flujo de trabajo",
"wrong_pin_code": "Código PIN incorrecto",
"year": "Año",
"years_ago": "Hace {years, plural, one {# año} other {# años}}",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Lisa sünnipäev",
"add_endpoint": "Lisa lõpp-punkt",
"add_exclusion_pattern": "Lisa välistamismuster",
"add_import_path": "Lisa imporditee",
"add_location": "Lisa asukoht",
"add_more_users": "Lisa rohkem kasutajaid",
"add_partner": "Lisa partner",
@@ -32,6 +31,7 @@
"add_to_album_toggle": "Muuda albumi {album} valikut",
"add_to_albums": "Lisa albumitesse",
"add_to_albums_count": "Lisa albumitesse ({count})",
"add_to_bottom_bar": "Lisa",
"add_to_shared_album": "Lisa jagatud albumisse",
"add_upload_to_stack": "Virnasta üleslaaditud üksus",
"add_url": "Lisa URL",
@@ -112,15 +112,19 @@
"jobs_failed": "{jobCount, plural, other {# ebaõnnestus}}",
"library_created": "Lisatud kogu: {library}",
"library_deleted": "Kogu kustutatud",
"library_import_path_description": "Määra kaust, mida importida. Sellest kaustast ning alamkaustadest otsitakse pilte ja videosid.",
"library_details": "Kogu detailid",
"library_folder_description": "Vali kaust, mida importida. Sellest kaustast ja alamkaustadest otsitakse pilte ja videosid.",
"library_remove_exclusion_pattern_prompt": "Kas oled kindel, et soovid selle välistamismustri eemaldada?",
"library_remove_folder_prompt": "Kas oled kindel, et soovid selle impordikausta eemaldada?",
"library_scanning": "Perioodiline skaneerimine",
"library_scanning_description": "Seadista kogu perioodiline skaneerimine",
"library_scanning_enable_description": "Luba kogu perioodiline skaneerimine",
"library_settings": "Väline kogu",
"library_settings_description": "Halda välise kogu seadeid",
"library_tasks_description": "Otsi välistest kogudest uusi ja muutunud üksuseid",
"library_updated": "Kogu uuendatud",
"library_watching_enable_description": "Jälgi välises kogus failide muudatusi",
"library_watching_settings": "Kogu jälgimine (EKSPERIMENTAALNE)",
"library_watching_settings": "Kogu jälgimine [EKSPERIMENTAALNE]",
"library_watching_settings_description": "Jälgi automaatselt muutunud faile",
"logging_enable_description": "Luba logimine",
"logging_level_description": "Kui lubatud, millist logimistaset kasutada.",
@@ -154,6 +158,18 @@
"machine_learning_min_detection_score_description": "Minimaalne usaldusskoor näo avastamiseks, vahemikus 0-1. Madalamad väärtused leiavad rohkem nägusid, kuid võib esineda valepositiivseid.",
"machine_learning_min_recognized_faces": "Minimaalne tuvastatud nägude arv",
"machine_learning_min_recognized_faces_description": "Minimaalne tuvastatud nägude arv, mida saab isikuks grupeerida. Selle suurendamine teeb näotuvastuse täpsemaks, kuid suureneb tõenäosus, et nägu ei seostata ühegi isikuga.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Kasuta piltidelt teksti tuvastamiseks masinõpet",
"machine_learning_ocr_enabled": "Luba OCR",
"machine_learning_ocr_enabled_description": "Kui keelatud, ei rakendata piltidele tekstituvastust.",
"machine_learning_ocr_max_resolution": "Maksimaalne resolutsioon",
"machine_learning_ocr_max_resolution_description": "Eelvaated üle selle resolutsiooni vähendatakse, säilitades külgede suhte. Suuremad väärtused on täpsemad, aga töötlemine võtab kauem aega ja kasutab rohkem mälu.",
"machine_learning_ocr_min_detection_score": "Minimaalne avastusskoor",
"machine_learning_ocr_min_detection_score_description": "Minimaalne usaldusskoor teksti avastamiseks, vahemikus 0-1. Madalamad väärtused leiavad rohkem teksti, kuid võib esineda valepositiivseid.",
"machine_learning_ocr_min_recognition_score": "Minimaalne tuvastusskoor",
"machine_learning_ocr_min_score_recognition_description": "Minimaalne usaldusskoor avastatud teksti tuvastamiseks, vahemikus 0-1. Madalamad väärtused tuvastavad rohkem teksti, kuid võib esineda valepositiivseid.",
"machine_learning_ocr_model": "OCR mudel",
"machine_learning_ocr_model_description": "Serverimudelid on täpsemad kui mobiilsed mudelid, aga töötlemine võtab rohkem aega ja kasutab rohkem mälu.",
"machine_learning_settings": "Masinõppe seaded",
"machine_learning_settings_description": "Halda masinõppe funktsioone ja seadeid",
"machine_learning_smart_search": "Nutiotsing",
@@ -161,6 +177,10 @@
"machine_learning_smart_search_enabled": "Luba nutiotsing",
"machine_learning_smart_search_enabled_description": "Kui keelatud, siis ei kodeerita pilte nutiotsingu jaoks.",
"machine_learning_url_description": "Masinõppe serveri URL. Kui ette on antud rohkem kui üks URL, proovitakse neid järjest ükshaaval, kuni üks edukalt vastab. Servereid, mis ei vasta, ignoreeritakse ajutiselt, kuni ühendus taastub.",
"maintenance_settings": "Hooldus",
"maintenance_settings_description": "Pane Immich hooldusrežiimi.",
"maintenance_start": "Käivita hooldusrežiim",
"maintenance_start_error": "Hooldusrežiimi käivitamine ebaõnnestus.",
"manage_concurrency": "Halda samaaegsust",
"manage_log_settings": "Halda logi seadeid",
"map_dark_style": "Tume stiil",
@@ -211,6 +231,8 @@
"notification_email_ignore_certificate_errors_description": "Ignoreeri TLS sertifikaadi valideerimise vigu (mittesoovituslik)",
"notification_email_password_description": "Parool e-posti serveriga autentimiseks",
"notification_email_port_description": "E-posti serveri port (nt. 25, 465 või 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Kasuta SMTPS-i (SMTP üle TLS-i)",
"notification_email_sent_test_email_button": "Saada test e-kiri ja salvesta",
"notification_email_setting_description": "E-posti teel teavituste saatmise seaded",
"notification_email_test_email": "Saada test e-kiri",
@@ -243,6 +265,7 @@
"oauth_storage_quota_default_description": "Kvoot (GiB), mida kasutada, kui ühtegi väidet pole esitatud.",
"oauth_timeout": "Päringu ajalõpp",
"oauth_timeout_description": "Päringute ajalõpp millisekundites",
"ocr_job_description": "Kasuta piltidelt teksti tuvastamiseks masinõpet",
"password_enable_description": "Logi sisse e-posti aadressi ja parooliga",
"password_settings": "Parooliga sisselogimine",
"password_settings_description": "Halda parooliga sisselogimise seadeid",
@@ -333,7 +356,7 @@
"transcoding_max_b_frames": "Maksimaalne B-kaadrite arv",
"transcoding_max_b_frames_description": "Kõrgemad väärtused parandavad pakkimise efektiivsust, aga aeglustavad kodeerimist. See valik ei pruugi olla ühilduv riistvaralise kiirendusega vanematel seadmetel. 0 lülitab B-kaadrid välja, -1 määrab väärtuse automaatselt.",
"transcoding_max_bitrate": "Maksimaalne bitisagedus",
"transcoding_max_bitrate_description": "Maksimaalse bitisageduse määramine teeb failisuurused ennustatavamaks, väikese kvaliteedikao hinnaga. 720p resolutsiooni puhul on tüüpilised väärtused 2600 kbit/s (VP9 ja HEVC) või 4500 kbit/s (H.264). Väärtus 0 eemaldab piirangu.",
"transcoding_max_bitrate_description": "Maksimaalse bitisageduse määramine teeb failisuurused ennustatavamaks, väikese kvaliteedikao hinnaga. 720p resolutsiooni puhul on tüüpilised väärtused 2600 kbit/s (VP9 ja HEVC) või 4500 kbit/s (H.264). Väärtus 0 eemaldab piirangu. Kui ühikut pole määratud, eeldatakse k (kbit/s); seega 5000, 5000k ja 5M (Mbit/s) on samaväärsed.",
"transcoding_max_keyframe_interval": "Maksimaalne võtmekaadri intervall",
"transcoding_max_keyframe_interval_description": "Määrab maksimaalse kauguse võtmekaadrite vahel. Madalamad väärtused vähendavad pakkimise efektiivsust, aga parandavad otsimiskiirust ning võivad tõsta kiire liikumisega stseenide kvaliteeti. 0 määrab väärtuse automaatselt.",
"transcoding_optimal_description": "Kõrgema kui lubatud resolutsiooniga või mittelubatud formaadis videod",
@@ -351,7 +374,7 @@
"transcoding_target_resolution": "Sihtresolutsioon",
"transcoding_target_resolution_description": "Kõrgemad resolutsioonid säilitavad rohkem detaile, aga kodeerimine võtab kauem aega, tekitab suuremaid faile ning võib mõjutada rakenduse töökiirust.",
"transcoding_temporal_aq": "Temporal AQ",
"transcoding_temporal_aq_description": "Rakendub NVENC puhul. Parandab paljude detailide, aga vähese liikumisega stseenide kvaliteeti. Ei pruugi ühilduda vanemate seadmetega.",
"transcoding_temporal_aq_description": "Rakendub NVENC puhul. Temporal Adaptive Quantization parandab paljude detailide, aga vähese liikumisega stseenide kvaliteeti. Ei pruugi ühilduda vanemate seadmetega.",
"transcoding_threads": "Lõimed",
"transcoding_threads_description": "Kõrgem väärtus tähendab kiiremat kodeerimist, aga jätab serverile muude tegevuste jaoks vähem ressursse. See väärtus ei tohiks olla suurem kui protsessori tuumade arv. Väärtus 0 tähendab maksimaalset kasutust.",
"transcoding_tone_mapping": "Toonivastendus",
@@ -402,11 +425,11 @@
"advanced_settings_prefer_remote_subtitle": "Mõned seadmed laadivad lokaalsete üksuste pisipilte piinavalt aeglaselt. Aktiveeri see seadistus, et laadida selle asemel kaugpilte.",
"advanced_settings_prefer_remote_title": "Eelista kaugpilte",
"advanced_settings_proxy_headers_subtitle": "Määra vaheserveri päised, mida Immich peaks iga päringuga saatma",
"advanced_settings_proxy_headers_title": "Vaheserveri päised",
"advanced_settings_proxy_headers_title": "Kohandatud vaheserveri päised [EKSPERIMENTAALNE]",
"advanced_settings_readonly_mode_subtitle": "Lülitab sisse kirjutuskaitserežiimi, milles saab fotosid ainult vaadata ning toimingud nagu mitme pildi valimine, jagamine, edastamine ja kustutamine on keelatud. Lülita kirjutuskaitserežiim sisse/välja põhiekraanil oleva avatari kaudu",
"advanced_settings_readonly_mode_title": "Kirjutuskaitserežiim",
"advanced_settings_self_signed_ssl_subtitle": "Jätab serveri lõpp-punkti SSL-sertifikaadi kontrolli vahele. Nõutud endasigneeritud sertifikaatide jaoks.",
"advanced_settings_self_signed_ssl_title": "Luba endasigneeritud SSL-sertifikaadid",
"advanced_settings_self_signed_ssl_title": "Luba endasigneeritud SSL-sertifikaadid [EKSPERIMENTAALNE]",
"advanced_settings_sync_remote_deletions_subtitle": "Kustuta või taasta üksus selles seadmes automaatself, kui sama tegevus toimub veebis",
"advanced_settings_sync_remote_deletions_title": "Sünkrooni kaugkustutamised [EKSPERIMENTAALNE]",
"advanced_settings_tile_subtitle": "Edasijõudnud kasutajate seaded",
@@ -415,6 +438,7 @@
"age_months": "Vanus {months, plural, one {# kuu} other {# kuud}}",
"age_year_months": "Vanus 1 aasta, {months, plural, one {# kuu} other {# kuud}}",
"age_years": "{years, plural, other {Vanus #}}",
"album": "Album",
"album_added": "Album lisatud",
"album_added_notification_setting_description": "Saa teavitus e-posti teel, kui sind lisatakse jagatud albumisse",
"album_cover_updated": "Albumi kaanepilt muudetud",
@@ -460,16 +484,21 @@
"allow_edits": "Luba muutmine",
"allow_public_user_to_download": "Luba avalikul kasutajal alla laadida",
"allow_public_user_to_upload": "Luba avalikul kasutajal üles laadida",
"allowed": "Lubatud",
"alt_text_qr_code": "QR kood",
"anti_clockwise": "Vastupäeva",
"api_key": "API võti",
"api_key_description": "Seda väärtust kuvatakse ainult üks kord. Kopeeri see enne akna sulgemist.",
"api_key_empty": "Su API võtme nimi ei tohiks olla tühi",
"api_keys": "API võtmed",
"app_architecture_variant": "Variant (arhitektuur)",
"app_bar_signout_dialog_content": "Kas oled kindel, et soovid välja logida?",
"app_bar_signout_dialog_ok": "Jah",
"app_bar_signout_dialog_title": "Logi välja",
"app_download_links": "Rakenduse allalaadimise lingid",
"app_settings": "Rakenduse seaded",
"app_stores": "Rakendusepoed",
"app_update_available": "Rakenduse uuendus on saadaval",
"appears_in": "Albumid",
"apply_count": "Rakenda ({count, number})",
"archive": "Arhiiv",
@@ -553,6 +582,7 @@
"backup_albums_sync": "Varundusalbumite sünkroniseerimine",
"backup_all": "Kõik",
"backup_background_service_backup_failed_message": "Üksuste varundamine ebaõnnestus. Uuesti proovimine…",
"backup_background_service_complete_notification": "Üksuste varundamine lõppenud",
"backup_background_service_connection_failed_message": "Serveriga ühendumine ebaõnnestus. Uuesti proovimine…",
"backup_background_service_current_upload_notification": "{filename} üleslaadimine",
"backup_background_service_default_notification": "Uute üksuste kontrollimine…",
@@ -662,6 +692,8 @@
"change_password_description": "See on su esimene kord süsteemi siseneda, või on tehtud taotlus parooli muutmiseks. Palun sisesta allpool uus parool.",
"change_password_form_confirm_password": "Kinnita parool",
"change_password_form_description": "Hei {name},\n\nSa kas logid süsteemi esimest korda sisse, või on esitatud taotlus sinu parooli muutmiseks. Palun sisesta allpool uus parool.",
"change_password_form_log_out": "Logi muudest seadmetest välja",
"change_password_form_log_out_description": "Soovituslik on kõigist muudest seadmetest välja logida",
"change_password_form_new_password": "Uus parool",
"change_password_form_password_mismatch": "Paroolid ei klapi",
"change_password_form_reenter_new_password": "Korda uut parooli",
@@ -689,7 +721,7 @@
"client_cert_invalid_msg": "Vigane sertifikaadi fail või vale parool",
"client_cert_remove_msg": "Klientsertifikaat on eemaldatud",
"client_cert_subtitle": "Toetab ainult PKCS12 (.p12, .pfx) formaati. Sertifikaadi importimine/eemaldamine on saadaval ainult enne sisselogimist",
"client_cert_title": "SSL klientsertifikaat",
"client_cert_title": "SSL klientsertifikaat [EKSPERIMENTAALNE]",
"clockwise": "Päripäeva",
"close": "Sulge",
"collapse": "Peida",
@@ -701,7 +733,6 @@
"comments_and_likes": "Kommentaarid ja meeldimised",
"comments_are_disabled": "Kommentaarid on keelatud",
"common_create_new_album": "Lisa uus album",
"common_server_error": "Kontrolli oma võrguühendust ja veendu, et server on kättesaadav ning rakenduse ja serveri versioonid on ühilduvad.",
"completed": "Lõpetatud",
"confirm": "Kinnita",
"confirm_admin_password": "Kinnita administraatori parool",
@@ -740,6 +771,7 @@
"create": "Lisa",
"create_album": "Lisa album",
"create_album_page_untitled": "Pealkirjata",
"create_api_key": "Lisa API võti",
"create_library": "Lisa kogu",
"create_link": "Lisa link",
"create_link_to_share": "Lisa jagamiseks link",
@@ -769,6 +801,7 @@
"daily_title_text_date_year": "d. MMMM yyyy",
"dark": "Tume",
"dark_theme": "Lülita tume teema",
"date": "Kuupäev",
"date_after": "Kuupäev pärast",
"date_and_time": "Kuupäev ja kellaaeg",
"date_before": "Kuupäev enne",
@@ -871,8 +904,6 @@
"edit_description_prompt": "Palun vali uus kirjeldus:",
"edit_exclusion_pattern": "Muuda välistamismustrit",
"edit_faces": "Muuda nägusid",
"edit_import_path": "Muuda imporditeed",
"edit_import_paths": "Muuda imporditeid",
"edit_key": "Muuda võtit",
"edit_link": "Muuda linki",
"edit_location": "Muuda asukohta",
@@ -883,7 +914,6 @@
"edit_tag": "Muuda silti",
"edit_title": "Muuda pealkirja",
"edit_user": "Muuda kasutajat",
"edited": "Muudetud",
"editor": "Muutja",
"editor_close_without_save_prompt": "Muudatusi ei salvestata",
"editor_close_without_save_title": "Sulge muutja?",
@@ -945,8 +975,8 @@
"failed_to_stack_assets": "Üksuste virnastamine ebaõnnestus",
"failed_to_unstack_assets": "Üksuste eraldamine ebaõnnestus",
"failed_to_update_notification_status": "Teavituste seisundi uuendamine ebaõnnestus",
"import_path_already_exists": "See imporditee on juba olemas.",
"incorrect_email_or_password": "Vale e-posti aadress või parool",
"library_folder_already_exists": "See imporditee on juba olemas.",
"paths_validation_failed": "{paths, plural, one {# tee} other {# teed}} ei valideerunud",
"profile_picture_transparent_pixels": "Profiilipildis ei tohi olla läbipaistvaid piksleid. Palun suumi sisse ja/või liiguta pilti.",
"quota_higher_than_disk_size": "Määratud kvoot on suurem kui kettamaht",
@@ -955,7 +985,6 @@
"unable_to_add_assets_to_shared_link": "Üksuste jagatud lingile lisamine ebaõnnestus",
"unable_to_add_comment": "Kommentaari lisamine ebaõnnestus",
"unable_to_add_exclusion_pattern": "Välistamismustri lisamine ebaõnnestus",
"unable_to_add_import_path": "Imporditee lisamine ebaõnnestus",
"unable_to_add_partners": "Partnerite lisamine ebaõnnestus",
"unable_to_add_remove_archive": "{archived, select, true {Üksuse arhiivist taastamine} other {Üksuse arhiveerimine}} ebaõnnestus",
"unable_to_add_remove_favorites": "Üksuse {favorite, select, true {lemmikuks lisamine} other {lemmikutest eemaldamine}} ebaõnnestus",
@@ -978,12 +1007,10 @@
"unable_to_delete_asset": "Üksuse kustutamine ebaõnnestus",
"unable_to_delete_assets": "Viga üksuste kustutamisel",
"unable_to_delete_exclusion_pattern": "Välistamismustri kustutamine ebaõnnestus",
"unable_to_delete_import_path": "Imporditee kustutamine ebaõnnestus",
"unable_to_delete_shared_link": "Jagatud lingi kustutamine ebaõnnestus",
"unable_to_delete_user": "Kasutaja kustutamine ebaõnnestus",
"unable_to_download_files": "Failide allalaadimine ebaõnnestus",
"unable_to_edit_exclusion_pattern": "Välistamismustri muutmine ebaõnnestus",
"unable_to_edit_import_path": "Imporditee muutmine ebaõnnestus",
"unable_to_empty_trash": "Prügikasti tühjendamine ebaõnnestus",
"unable_to_enter_fullscreen": "Täisekraanile lülitamine ebaõnnestus",
"unable_to_exit_fullscreen": "Täisekraanilt väljumine ebaõnnestus",
@@ -1034,6 +1061,7 @@
"unable_to_update_user": "Kasutaja muutmine ebaõnnestus",
"unable_to_upload_file": "Faili üleslaadimine ebaõnnestus"
},
"exclusion_pattern": "Välistamismuster",
"exif": "Exif",
"exif_bottom_sheet_description": "Lisa kirjeldus...",
"exif_bottom_sheet_description_error": "Viga kirjelduse muutmisel",
@@ -1078,6 +1106,7 @@
"features_setting_description": "Halda rakenduse funktsioone",
"file_name": "Failinimi",
"file_name_or_extension": "Failinimi või -laiend",
"file_size": "Failisuurus",
"filename": "Failinimi",
"filetype": "Failitüüp",
"filter": "Filter",
@@ -1092,6 +1121,7 @@
"folders_feature_description": "Kaustavaate abil failisüsteemis olevate fotode ja videote sirvimine",
"forgot_pin_code_question": "Unustasid oma PIN-koodi?",
"forward": "Edasi",
"full_path": "Täielik tee: {path}",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "See funktsionaalsus laadib töötamiseks Google'st väliseid ressursse.",
"general": "Üldine",
@@ -1121,7 +1151,6 @@
"header_settings_field_validator_msg": "Väärtus ei saa olla tühi",
"header_settings_header_name_input": "Päise nimi",
"header_settings_header_value_input": "Päise väärtus",
"headers_settings_tile_subtitle": "Määra vaheserveri päised, mida rakendus peaks iga päringuga saatma",
"headers_settings_tile_title": "Kohandatud vaheserveri päised",
"hi_user": "Tere {name} ({email})",
"hide_all_people": "Peida kõik isikud",
@@ -1129,6 +1158,7 @@
"hide_named_person": "Peida isik {name}",
"hide_password": "Peida parool",
"hide_person": "Peida isik",
"hide_text_recognition": "Peida tekstituvastus",
"hide_unnamed_people": "Peida nimetud isikud",
"home_page_add_to_album_conflicts": "{added} üksust lisati albumisse {album}. {failed} üksust oli juba albumis.",
"home_page_add_to_album_err_local": "Lokaalseid üksuseid ei saa veel albumisse lisada, jäetakse vahele",
@@ -1174,6 +1204,8 @@
"import_path": "Imporditee",
"in_albums": "{count, plural, one {# albumis} other {# albumis}}",
"in_archive": "Arhiivis",
"in_year": "Aastal {year}",
"in_year_selector": "Aastal",
"include_archived": "Kaasa arhiveeritud",
"include_shared_albums": "Kaasa jagatud albumid",
"include_shared_partner_assets": "Kaasa partneri jagatud üksused",
@@ -1210,6 +1242,7 @@
"language_setting_description": "Vali oma eelistatud keel",
"large_files": "Suured failid",
"last": "Viimane",
"last_months": "{count, plural, one {Eelmine kuu} other {Eelmised # kuud}}",
"last_seen": "Viimati nähtud",
"latest_version": "Uusim versioon",
"latitude": "Laiuskraad",
@@ -1219,6 +1252,8 @@
"let_others_respond": "Luba teistel vastata",
"level": "Tase",
"library": "Kogu",
"library_add_folder": "Lisa kaust",
"library_edit_folder": "Muuda kausta",
"library_options": "Kogu seaded",
"library_page_device_albums": "Albumid seadmes",
"library_page_new_album": "Uus album",
@@ -1242,6 +1277,7 @@
"local_media_summary": "Lokaalsete üksuste kokkuvõte",
"local_network": "Kohalik võrk",
"local_network_sheet_info": "Rakendus ühendub valitud Wi-Fi võrgus olles serveriga selle URL-i kaudu",
"location": "Asukoht",
"location_permission": "Asukoha luba",
"location_permission_content": "Automaatseks ümberlülitumiseks vajab Immich täpse asukoha luba, et saaks lugeda aktiivse WiFi-võrgu nime",
"location_picker_choose_on_map": "Vali kaardil",
@@ -1289,8 +1325,17 @@
"loop_videos_description": "Lülita sisse, et detailvaates videot automaatselt taasesitada.",
"main_branch_warning": "Sa kasutad arendusversiooni; soovitame tungivalt kasutada väljalaskeversiooni!",
"main_menu": "Peamenüü",
"maintenance_description": "Immich on <link>hooldusrežiimis</link>.",
"maintenance_end": "Lõpeta hooldusrežiim",
"maintenance_end_error": "Hooldusrežiimi lõpetamine ebaõnnestus.",
"maintenance_logged_in_as": "Logitud sisse kasutajana {user}",
"maintenance_title": "Ajutiselt mittesaadaval",
"make": "Mark",
"manage_geolocation": "Halda asukohta",
"manage_media_access_rationale": "Seda luba on vaja üksuste prügikasti liigutamiseks ja sealt taastamiseks.",
"manage_media_access_settings": "Ava seaded",
"manage_media_access_subtitle": "Luba Immich'i rakendusel multimeediafaile hallata ja liigutada.",
"manage_media_access_title": "Üksuste haldamise ligipääs",
"manage_shared_links": "Halda jagatud linke",
"manage_sharing_with_partners": "Halda partneritega jagamist",
"manage_the_app_settings": "Halda rakenduse seadeid",
@@ -1346,12 +1391,15 @@
"minute": "Minut",
"minutes": "Minutit",
"missing": "Puuduvad",
"mobile_app": "Mobiilirakendus",
"mobile_app_download_onboarding_note": "Mobiilirakenduse allalaadimiseks kasuta järgnevaid valikuid",
"model": "Mudel",
"month": "Kuu",
"monthly_title_text_date_format": "MMMM y",
"more": "Rohkem",
"move": "Liiguta",
"move_off_locked_folder": "Liiguta lukustatud kaustast välja",
"move_to": "Liiguta",
"move_to_lock_folder_action_prompt": "{count} lisatud lukustatud kausta",
"move_to_locked_folder": "Liiguta lukustatud kausta",
"move_to_locked_folder_confirmation": "Need fotod ja videod eemaldatakse kõigist albumitest ning nad on nähtavad ainult lukustatud kaustas",
@@ -1364,6 +1412,8 @@
"my_albums": "Minu albumid",
"name": "Nimi",
"name_or_nickname": "Nimi või hüüdnimi",
"navigate": "Navigeeri",
"navigate_to_time": "Navigeeri aega",
"network_requirement_photos_upload": "Kasuta fotode varundamiseks mobiilset andmesidet",
"network_requirement_videos_upload": "Kasuta videote varundamiseks mobiilset andmesidet",
"network_requirements": "Võrgu nõuded",
@@ -1373,11 +1423,13 @@
"never": "Mitte kunagi",
"new_album": "Uus album",
"new_api_key": "Uus API võti",
"new_date_range": "Uus kuupäevavahemik",
"new_password": "Uus parool",
"new_person": "Uus isik",
"new_pin_code": "Uus PIN-kood",
"new_pin_code_subtitle": "See on sul esimene kord lukustatud kausta kasutada. Turvaliseks ligipääsuks loo PIN-kood",
"new_timeline": "Uus ajajoon",
"new_update": "Uus uuendus",
"new_user_created": "Uus kasutaja lisatud",
"new_version_available": "UUS VERSIOON SAADAVAL",
"newest_first": "Uuemad eespool",
@@ -1393,12 +1445,14 @@
"no_cast_devices_found": "Edastamise seadmeid ei leitud",
"no_checksum_local": "Kontrollsumma pole saadaval - lokaalse üksuse pärimine ebaõnnestus",
"no_checksum_remote": "Kontrollsumma pole saadaval - kaugüksuse pärimine ebaõnnestus",
"no_devices": "Autoriseeritud seadmeid pole",
"no_duplicates_found": "Ühtegi duplikaati ei leitud.",
"no_exif_info_available": "Exif info pole saadaval",
"no_explore_results_message": "Oma kogu avastamiseks laadi üles rohkem fotosid.",
"no_favorites_message": "Lisa lemmikud, et oma parimaid fotosid ja videosid kiiresti leida",
"no_libraries_message": "Lisa väline kogu oma fotode ja videote vaatamiseks",
"no_local_assets_found": "Selle kontrollsummaga lokaalseid üksuseid ei leitud",
"no_location_set": "Asukoht pole määratud",
"no_locked_photos_message": "Lukustatud kaustas olevad fotod ja videod on peidetud ning need pole kogu sirvimisel ja otsimisel nähtavad.",
"no_name": "Nimetu",
"no_notifications": "Teavitusi pole",
@@ -1409,6 +1463,7 @@
"no_results_description": "Proovi sünonüümi või üldisemat märksõna",
"no_shared_albums_message": "Lisa album, et fotosid ja videosid teistega jagada",
"no_uploads_in_progress": "Üleslaadimisi käimas ei ole",
"not_allowed": "Keelatud",
"not_available": "Pole saadaval",
"not_in_any_album": "Pole üheski albumis",
"not_selected": "Ei ole valitud",
@@ -1423,6 +1478,9 @@
"notifications": "Teavitused",
"notifications_setting_description": "Halda teavitusi",
"oauth": "OAuth",
"obtainium_configurator": "Obtainiumi seadistamine",
"obtainium_configurator_instructions": "Androidi rakenduse otse GitHub'ist paigaldamiseks ja uuendamiseks kasuta Obtainiumit. Seadistamise lingi loomiseks lisa API võti ja vali rakenduse variant",
"ocr": "OCR",
"official_immich_resources": "Ametlikud Immich'i ressursid",
"offline": "Ühendus puudub",
"offset": "Nihe",
@@ -1516,6 +1574,8 @@
"photos_count": "{count, plural, one {{count, number} foto} other {{count, number} fotot}}",
"photos_from_previous_years": "Fotod varasematest aastatest",
"pick_a_location": "Vali asukoht",
"pick_custom_range": "Kohandatud vahemik",
"pick_date_range": "Vali kuupäevavahemik",
"pin_code_changed_successfully": "PIN-kood edukalt muudetud",
"pin_code_reset_successfully": "PIN-kood edukalt lähtestatud",
"pin_code_setup_successfully": "PIN-kood edukalt seadistatud",
@@ -1527,6 +1587,9 @@
"play_memories": "Esita mälestused",
"play_motion_photo": "Esita liikuv foto",
"play_or_pause_video": "Esita või peata video",
"play_original_video": "Taasesita algne video",
"play_original_video_setting_description": "Eelista transkodeeritud video asemel algse video taasesitamist. Kui algne üksus ei ole ühilduv, võib taasesitamine ebaõnnestuda.",
"play_transcoded_video": "Taasesita transkodeeritud video",
"please_auth_to_access": "Ligipääsemiseks palun autendi",
"port": "Port",
"preferences_settings_subtitle": "Halda rakenduse eelistusi",
@@ -1544,13 +1607,9 @@
"privacy": "Privaatsus",
"profile": "Profiil",
"profile_drawer_app_logs": "Logid",
"profile_drawer_client_out_of_date_major": "Mobiilirakendus on aegunud. Palun uuenda uusimale suurele versioonile.",
"profile_drawer_client_out_of_date_minor": "Mobiilirakendus on aegunud. Palun uuenda uusimale väikesele versioonile.",
"profile_drawer_client_server_up_to_date": "Klient ja server on uuendatud",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Kirjutuskaitserežiim sisse lülitatud. Väljumiseks puuduta pikalt avatari ikooni.",
"profile_drawer_server_out_of_date_major": "Server on aegunud. Palun uuenda uusimale suurele versioonile.",
"profile_drawer_server_out_of_date_minor": "Server on aegunud. Palun uuenda uusimale väikesele versioonile.",
"profile_image_of_user": "Kasutaja {user} profiilipilt",
"profile_picture_set": "Profiilipilt määratud.",
"public_album": "Avalik album",
@@ -1667,6 +1726,7 @@
"reset_sqlite_confirmation": "Kas oled kindel, et soovid SQLite andmebaasi lähtestada? Andmete uuesti sünkroonimiseks pead välja ja jälle sisse logima",
"reset_sqlite_success": "SQLite andmebaas edukalt lähtestatud",
"reset_to_default": "Lähtesta",
"resolution": "Resolutsioon",
"resolve_duplicates": "Lahenda duplikaadid",
"resolved_all_duplicates": "Kõik duplikaadid lahendatud",
"restore": "Taasta",
@@ -1685,6 +1745,7 @@
"running": "Käimas",
"save": "Salvesta",
"save_to_gallery": "Salvesta galeriisse",
"saved": "Salvestatud",
"saved_api_key": "API võti salvestatud",
"saved_profile": "Profiil salvestatud",
"saved_settings": "Seaded salvestatud",
@@ -1701,6 +1762,9 @@
"search_by_description_example": "Matkapäev Sapas",
"search_by_filename": "Otsi failinime või -laiendi järgi",
"search_by_filename_example": "st. IMG_1234.JPG või PNG",
"search_by_ocr": "Otsi OCR-i abil",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Otsi läätse mudelit...",
"search_camera_make": "Otsi kaamera marki...",
"search_camera_model": "Otsi kaamera mudelit...",
"search_city": "Otsi linna...",
@@ -1717,6 +1781,7 @@
"search_filter_location_title": "Vali asukoht",
"search_filter_media_type": "Üksuse tüüp",
"search_filter_media_type_title": "Vali üksuse tüüp",
"search_filter_ocr": "Otsi OCR-i abil",
"search_filter_people_title": "Vali isikud",
"search_for": "Otsi",
"search_for_existing_person": "Otsi olemasolevat isikut",
@@ -1778,7 +1843,10 @@
"server_offline": "Serveriga ühendus puudub",
"server_online": "Server ühendatud",
"server_privacy": "Serveri privaatsus",
"server_restarting_description": "Leht värskendatakse hetkeliselt.",
"server_restarting_title": "Server taaskäivitub",
"server_stats": "Serveri statistika",
"server_update_available": "Serveri uuendus on saadaval",
"server_version": "Serveri versioon",
"set": "Määra",
"set_as_album_cover": "Sea albumi kaanepildiks",
@@ -1807,6 +1875,8 @@
"setting_notifications_subtitle": "Halda oma teavituste eelistusi",
"setting_notifications_total_progress_subtitle": "Üldine üleslaadimise edenemine (üksuseid tehtud/kokku)",
"setting_notifications_total_progress_title": "Kuva taustal varundamise üldist edenemist",
"setting_video_viewer_auto_play_subtitle": "Alusta videote avamisel automaatselt taasesitust",
"setting_video_viewer_auto_play_title": "Esita videod automaatselt",
"setting_video_viewer_looping_title": "Taasesitus",
"setting_video_viewer_original_video_subtitle": "Esita serverist video voogedastamisel originaal, isegi kui transkodeeritud video on saadaval. Võib põhjustada puhverdamist. Lokaalselt saadaolevad videod mängitakse originaalkvaliteediga sõltumata sellest seadest.",
"setting_video_viewer_original_video_title": "Sunni originaalvideo",
@@ -1898,6 +1968,7 @@
"show_slideshow_transition": "Kuva slaidiesitluse üleminekud",
"show_supporter_badge": "Toetaja märk",
"show_supporter_badge_description": "Kuva toetaja märki",
"show_text_recognition": "Kuva tekstituvastust",
"show_text_search_menu": "Kuva tekstiotsingu menüüd",
"shuffle": "Juhuslik",
"sidebar": "Külgmenüü",
@@ -1968,6 +2039,7 @@
"tags": "Sildid",
"tap_to_run_job": "Puuduta tööte käivitamiseks",
"template": "Mall",
"text_recognition": "Tekstituvastus",
"theme": "Teema",
"theme_selection": "Teema valik",
"theme_selection_description": "Sea automaatselt hele või tume teema vastavalt veebilehitseja eelistustele",
@@ -1986,7 +2058,9 @@
"theme_setting_three_stage_loading_title": "Luba kolmeastmeline laadimine",
"they_will_be_merged_together": "Nad ühendatakse kokku",
"third_party_resources": "Kolmanda osapoole ressursid",
"time": "Aeg",
"time_based_memories": "Ajapõhised mälestused",
"time_based_memories_duration": "Aeg sekundites, kui kaua igat pilti kuvada.",
"timeline": "Ajajoon",
"timezone": "Ajavöönd",
"to_archive": "Arhiivi",
@@ -2018,6 +2092,7 @@
"troubleshoot": "Tõrkeotsing",
"type": "Tüüp",
"unable_to_change_pin_code": "PIN-koodi muutmine ebaõnnestus",
"unable_to_check_version": "Rakenduse või serveri versiooni kontrollimine ebaõnnestus",
"unable_to_setup_pin_code": "PIN-koodi seadistamine ebaõnnestus",
"unarchive": "Taasta arhiivist",
"unarchive_action_prompt": "{count} eemaldatud arhiivist",
@@ -2101,7 +2176,7 @@
"video_hover_setting_description": "Esita video eelvaade, kui hiirt selle kohal hõljutada. Isegi kui keelatud, saab taasesituse alustada taasesitusnupu kohal hõljutades.",
"videos": "Videod",
"videos_count": "{count, plural, one {# video} other {# videot}}",
"view": "Vaade",
"view": "Vaata",
"view_album": "Vaata albumit",
"view_all": "Vaata kõiki",
"view_all_users": "Vaata kõiki kasutajaid",
@@ -2126,6 +2201,7 @@
"welcome": "Tere tulemast",
"welcome_to_immich": "Tere tulemast Immich'isse",
"wifi_name": "WiFi-võrgu nimi",
"workflow": "Töövoog",
"wrong_pin_code": "Vale PIN-kood",
"year": "Aasta",
"years_ago": "{years, plural, one {# aasta} other {# aastat}} tagasi",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Urtebetetzea gehitu",
"add_endpoint": "Endpoint-a gehitu",
"add_exclusion_pattern": "Bazterketa eredua gehitu",
"add_import_path": "Inportazio bidea gehitu",
"add_location": "Kokapena gehitu",
"add_more_users": "Erabiltzaile gehiago gehitu",
"add_partner": "Kidea gehitu",
@@ -58,6 +57,7 @@
"image_format_description": "WebP ereduak JPEG baino fitxategi txikiagoak sortzen ditu, baina motelagoa da kodifikatzen.",
"image_preview_title": "Aurreikusiaen Konfigurazioa",
"image_quality": "Kalitatea",
"image_resolution": "Erresoluzioa",
"image_settings": "Argazkien Konfigurazioa",
"image_thumbnail_title": "Argazki Txikien Konfigurazioa",
"job_created": "Zeregina sortuta",
@@ -81,8 +81,11 @@
"metadata_faces_import_setting": "Gaitu aurpegien inportazioa",
"metadata_settings": "Metadata Konfigurazioa",
"metadata_settings_description": "Kudeatu metadaten konfigurazioa",
"migration_job": "Migrazio"
"migration_job": "Migrazio",
"oauth_settings": "OAuth",
"transcoding_acceleration_vaapi": "VAAPI"
},
"advanced": "Aurreratua",
"advanced_settings_readonly_mode_title": "Irakurri-bakarrik Modua",
"apply_count": "Ezarri ({count, number})",
"assets_added_to_albums_count": "Gehituta {assetTotal, plural, one {# asset} other {# assets}} to {albumTotal, plural, one {# album} other {# albums}}",

View File

@@ -15,23 +15,28 @@
"add_a_title": "افزودن عنوان",
"add_birthday": "افزودن تاریخ تولد",
"add_exclusion_pattern": "افزودن الگوی استثنا",
"add_import_path": "افزودن مسیر ورودی",
"add_location": "افزودن مکان",
"add_more_users": "افزودن کاربرهای بیشتر",
"add_partner": "افزودن شریک",
"add_path": "افزودن مسیر",
"add_photos": "افزودن عکس ها",
"add_tag": "افزودن تگ",
"add_to": "افزودن به …",
"add_to_album": "افزودن به آلبوم",
"add_to_album_bottom_sheet_added": "به آلبوم {album} اضافه شد",
"add_to_album_bottom_sheet_already_exists": "قبلا در آلبوم {album} موجود است",
"add_to_album_bottom_sheet_some_local_assets": "برخی از محتواهای محلی را نشد به آلبوم اضافه کرد",
"add_to_albums": "افزودن به آلبوم",
"add_to_albums_count": "افزودن به آلبوم ها {count}",
"add_to_shared_album": "افزودن به آلبوم اشتراکی",
"add_upload_to_stack": "افزودن فایل ارسالی به مجموعه",
"add_url": "افزودن آدرس URL",
"added_to_archive": "به آرشیو اضافه شد",
"added_to_favorites": "به علاقه مندی ها اضافه شد",
"added_to_favorites_count": "{count, number} تا به علاقه مندی ها اضافه شد",
"admin": {
"add_exclusion_pattern_description": "الگوهای استثنا را اضافه کنید. پشتیبانی از گلابینگ با استفاده از *, ** و ? وجود دارد. برای نادیده گرفتن تمام فایل‌ها در هر دایرکتوری با نام \"Raw\"، از \"**/Raw/**\" استفاده کنید. برای نادیده گرفتن تمام فایل‌هایی که با \".tif\" پایان می‌یابند، از \"**/*.tif\" استفاده کنید. برای نادیده گرفتن یک مسیر مطلق، از \"/path/to/ignore/**\" استفاده کنید.",
"admin_user": "ادمین",
"authentication_settings": "تنظیمات احراز هویت",
"authentication_settings_description": "مدیریت رمز عبور، OAuth، و سایر تنظیمات احراز هویت",
"authentication_settings_disable_all": "آیا مطمئن هستید که می‌خواهید تمام روش‌های ورود را غیرفعال کنید؟ ورود به طور کامل غیرفعال خواهد شد.",
@@ -44,6 +49,7 @@
"confirm_email_below": "برای تأیید، \"{email}\" را در زیر تایپ کنید",
"confirm_reprocess_all_faces": "آیا مطمئن هستید که می‌خواهید تمام چهره‌ها را مجددا پردازش کنید؟ این عمل باعث پاک شدن افراد مشخص شده نیز خواهد شد.",
"confirm_user_password_reset": "آیا مطمئن هستید که می‌خواهید رمز عبور {user} را بازنشانی کنید؟",
"confirm_user_pin_code_reset": "آیا مطمئن هستید که می‌خواهید کد PIN {user} را بازنشانی کنید؟",
"disable_login": "غیرفعال کردن ورود",
"duplicate_detection_job_description": "اجرای یادگیری ماشین بر روی فایل‌ها برای شناسایی تصاویر مشابه. این وابسته به جستجوی هوشمند است",
"exclusion_pattern_description": "الگوهای استثنا به شما امکان می‌دهد هنگام اسکن کتابخانه خود فایل‌ها و پوشه‌ها را نادیده بگیرید . این مفید است اگر پوشه‌هایی دارید که فایل‌هایی را شامل می‌شوند که نمی‌خواهید وارد کنید، مانند فایل‌های RAW.",
@@ -54,11 +60,21 @@
"failed_job_command": "دستور {command} برای کار: {job} ناموفق بود",
"force_delete_user_warning": "هشدار: این عمل باعث حذف فوری کاربر و تمام فایل‌ها می‌شود. این عمل قابل بازگشت نیست و فایل‌ها قابل بازیابی نیستند.",
"image_format_description": "فرمت WebP فایل‌های کوچکتری نسبت به JPEG ایجاد می‌کند، اما زمان کدگذاری آن کندتر است.",
"image_fullsize_description": "تصویر با اندازه کامل و بدون فراداده، مورد استفاده هنگام بزرگ‌نمایی",
"image_fullsize_enabled": "فعال‌سازی تولید تصویر با اندازه کامل",
"image_fullsize_enabled_description": "تولید تصویر با اندازه کامل برای فرمت‌های غیرسازگار با وب. هنگامی که گزینه «استفاده از پیش‌نمایش تعبیه‌شده» فعال باشد، پیش‌نمایش‌های تعبیه‌شده مستقیماً بدون تبدیل استفاده می‌شوند. این تنظیم بر فرمت‌های سازگار با وب مانند JPEG تأثیری ندارد.",
"image_fullsize_quality_description": "کیفیت تصویر با اندازه کامل از ۱ تا ۱۰۰. هرچه بالاتر باشد، کیفیت بهتر است، اما فایل‌های بزرگ‌تری ایجاد می‌کند.",
"image_fullsize_title": "تنظیمات تصویر با اندازه کامل",
"image_prefer_embedded_preview": "ترجیحات پیش‌نمایش تعبیه‌شده",
"image_prefer_embedded_preview_setting_description": "استفاده از پیش‌نمایش داخلی در عکس‌های RAW به عنوان ورودی پردازش تصویر هنگامی که در دسترس باشد. این می‌تواند رنگ‌های دقیق‌تری را برای برخی تصاویر تولید کند، اما کیفیت پیش‌نمایش به دوربین بستگی دارد و ممکن است تصویر آثار فشرده‌سازی بیشتری داشته باشد.",
"image_prefer_embedded_preview_setting_description": "استفاده از پیش‌نمایش‌های تعبیه‌شده در عکس‌های RAW بهعنوان ورودی برای پردازش تصویر، در صورت موجود بودن. این می‌تواند رنگ‌های دقیق‌تری برای برخی تصاویر ایجاد کند، اما کیفیت پیش‌نمایش به دوربین بستگی دارد و ممکن است تصویر دارای نویزهای فشرده‌سازی بیشتری باشد.",
"image_prefer_wide_gamut": "ترجیحات گستره رنگی وسیع",
"image_prefer_wide_gamut_setting_description": "برای تصاویر کوچک از فضای رنگی Display P3 استفاده کنید. این کار باعث حفظ زنده بودن رنگ‌ها در تصاویر با گستره رنگی وسیع می‌شود، اما ممکن است تصاویر در دستگاه‌های قدیمی با نسخه‌های قدیمی مرورگر به شکل متفاوتی نمایش داده شوند. تصاویر با فضای رنگی sRGB به همان حالت sRGB نگه داشته می‌شوند تا از تغییرات رنگی جلوگیری شود.",
"image_preview_description": "تصویر با اندازه متوسط و بدون فراداده، مورد استفاده هنگام مشاهده یک دارایی و برای یادگیری ماشین",
"image_preview_quality_description": "کیفیت پیش‌نمایش از ۱ تا ۱۰۰. هرچه بالاتر باشد، کیفیت بهتر است، اما فایل‌های بزرگ‌تری ایجاد می‌کند و ممکن است پاسخ‌گویی برنامه کاهش یابد. تنظیم مقدار پایین می‌تواند بر کیفیت یادگیری ماشین تأثیر بگذارد.",
"image_preview_title": "تنظیمات پیش‌نمایش",
"image_quality": "کیفیت",
"image_resolution": "وضوح تصویر",
"image_resolution_description": "وضوح بالاتر می‌تواند جزئیات بیشتری را حفظ کند، اما تبدیل آن زمان بیشتری می‌برد، حجم فایل‌ها را افزایش می‌دهد و ممکن است پاسخ‌گویی برنامه را کاهش دهد.",
"image_settings": "تنظیمات عکس",
"image_settings_description": "مدیریت کیفیت و وضوح تصاویر تولید شده",
"job_concurrency": "همزمانی {job}",
@@ -68,7 +84,6 @@
"job_status": "وضعیت کار",
"library_created": "کتابخانه ایجاد شده: {library}",
"library_deleted": "کتابخانه حذف شد",
"library_import_path_description": "یک پوشه برای وارد کردن مشخص کنید. این پوشه، به همراه زیرپوشه‌ها، برای یافتن تصاویر و ویدیوها اسکن خواهد شد.",
"library_scanning": "اسکن دوره ای",
"library_scanning_description": "تنظیم اسکن دوره‌ای کتابخانه",
"library_scanning_enable_description": "فعال کردن اسکن دوره‌ای کتابخانه",
@@ -412,7 +427,6 @@
"edit_people": "ویرایش افراد",
"edit_title": "ویرایش عنوان",
"edit_user": "ویرایش کاربر",
"edited": "ویرایش شد",
"editor": "ویرایشگر",
"email": "ایمیل",
"empty_trash": "خالی کردن سطل زباله",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Lisää syntymäpäivä",
"add_endpoint": "Lisää päätepiste",
"add_exclusion_pattern": "Lisää poissulkemismalli",
"add_import_path": "Lisää tuontipolku",
"add_location": "Lisää sijainti",
"add_more_users": "Lisää käyttäjiä",
"add_partner": "Lisää kumppani",
@@ -28,11 +27,13 @@
"add_to_album": "Lisää albumiin",
"add_to_album_bottom_sheet_added": "Lisätty albumiin {album}",
"add_to_album_bottom_sheet_already_exists": "Kohde on jo albumissa {album}",
"add_to_album_bottom_sheet_some_local_assets": "Joitakin osia paikallisesta sisällöstä ei pystytty lisämään albumiin",
"add_to_album_bottom_sheet_some_local_assets": "Joitakin osia paikallisesta sisällöstä ei pystytty lisäämään albumiin",
"add_to_album_toggle": "Vaihda albumin {album} valintaa",
"add_to_albums": "Lisää albumeihin",
"add_to_albums_count": "Lisää albumeihin ({count})",
"add_to_bottom_bar": "Lisää",
"add_to_shared_album": "Lisää jaettuun albumiin",
"add_upload_to_stack": "Lisää kuvapinoon",
"add_url": "Lisää URL",
"added_to_archive": "Lisätty arkistoon",
"added_to_favorites": "Lisätty suosikkeihin",
@@ -111,7 +112,6 @@
"jobs_failed": "{jobCount, plural, other {# epäonnistunutta}}",
"library_created": "Kirjasto {library} luotu",
"library_deleted": "Kirjasto poistettu",
"library_import_path_description": "Määritä kansio joka tuodaan. Kuvat ja videot skannataan tästä kansiosta, sekä alikansioista.",
"library_scanning": "Ajoittainen skannaus",
"library_scanning_description": "Määritä ajoittaiset kirjastojen skannaukset",
"library_scanning_enable_description": "Ota käyttöön ajoittaiset kirjastojen skannaukset",
@@ -153,6 +153,18 @@
"machine_learning_min_detection_score_description": "Pienin kasvojen tunnistamisessa saatu vahvuusarvo välillä 0-1. Matalammalla arvolla havaitaan enemmän kasvoja, mutta voi lisätä virhearvioiden määrää.",
"machine_learning_min_recognized_faces": "Tunnistettujen kasvojen vähimmäismäärä",
"machine_learning_min_recognized_faces_description": "Luotavan käyttäjän kasvojen vähimmäismäärä. Arvoa nostamalla kasvojentunnistuksen tarkkuus paranee, mutta todennäköisyys sille, että kasvoja ei osata yhdistää henkilöön kasvaa.",
"machine_learning_ocr": "Tekstintunnistus (OCR)",
"machine_learning_ocr_description": "Käytä koneoppimista tekstin tunnistamiseen kuvista",
"machine_learning_ocr_enabled": "Aktivoi OCR",
"machine_learning_ocr_enabled_description": "Jos asetus on pois päältä, kuvia ei prosessoida tekstin tunnistamiseksi.",
"machine_learning_ocr_max_resolution": "Maksimiresoluutio",
"machine_learning_ocr_max_resolution_description": "Tätä suuremmat esikatselukuvat tullaan pienentämään samassa kuvasuhteessa. Suuremmat arvot ovat tarkempia, mutta kestävät pidempään prosessoida ja käyttävät enemmän muistia.",
"machine_learning_ocr_min_detection_score": "Tunnistuksen vähimmäispistemäärä",
"machine_learning_ocr_min_detection_score_description": "Tekstin tunnistuksen vähimmäisluottamusarvo (01). Pienemmät arvot tunnistavat enemmän tekstiä, mutta voivat johtaa virheellisiin osumiin.",
"machine_learning_ocr_min_recognition_score": "Pienin tunnistuksen pistemäärä",
"machine_learning_ocr_min_score_recognition_description": "Pienin arvo tekstin tunnistuksen varmuudelle välillä 0-1. Pienemmät arvot tunnistavat enemmän tekstiä, mutta saattavat johtaa useampaan väärään positiiviseen.",
"machine_learning_ocr_model": "OCR-malli",
"machine_learning_ocr_model_description": "Palvelinmallit ovat tarkempia kuin mobiilimallit, mutta prosessointi kestää pidempään ja käyttää enemmän muistia.",
"machine_learning_settings": "Koneoppimisen asetukset",
"machine_learning_settings_description": "Koneoppimisen ominaisuudet ja asetukset",
"machine_learning_smart_search": "Älykäs etsintä",
@@ -210,6 +222,8 @@
"notification_email_ignore_certificate_errors_description": "Älä huomioi TLS-varmenteiden validointivirheitä (ei suositeltu)",
"notification_email_password_description": "Sähköpostipalvelimen salasana",
"notification_email_port_description": "Sähköpostipalvelimen portti (esim. 25, 465, tai 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Käytä SMTPS:ää (SMTP over TLS)",
"notification_email_sent_test_email_button": "Lähetä testaussähköposti ja tallenna",
"notification_email_setting_description": "Sähköposti-ilmoitusten asetukset",
"notification_email_test_email": "Lähetä testisähköposti",
@@ -242,6 +256,7 @@
"oauth_storage_quota_default_description": "Käytettävä kiintiön määrä gigatavuissa, kun väittämää ei ole annettu.",
"oauth_timeout": "Pyynnön aikakatkaisu",
"oauth_timeout_description": "Pyyntöjen aikakatkaisu millisekunteina",
"ocr_job_description": "Käytä koneoppimista tunnistamaan tekstiä kuvista",
"password_enable_description": "Kirjaudu käyttäen sähköpostiosoitetta ja salasanaa",
"password_settings": "Kirjaudu salasanalla",
"password_settings_description": "Hallitse salasanakirjautumisen asetuksia",
@@ -332,7 +347,7 @@
"transcoding_max_b_frames": "B-kehysten enimmäismäärä",
"transcoding_max_b_frames_description": "Korkeampi arvo parantaa pakkausta, mutta hidastaa enkoodausta. Ei välttämättä ole yhteensopiva vanhempien laitteiden kanssa. 0 poistaa B-kehykset käytöstä, -1 määrittää arvon automaattisesti.",
"transcoding_max_bitrate": "Suurin bittinopeus",
"transcoding_max_bitrate_description": "Suurimman sallitun bittinopeuden asettaminen tekee tiedostojen koosta ennustettavampaa vaikka laatu voi hieman heiketä. 720p videossa tyypilliset arvot ovat 2600 kbit/s VP9:lle ja HEVC:lle, tai 4500 kbit/s H.254:lle. Jos 0, ei käytössä.",
"transcoding_max_bitrate_description": "Suurimman sallitun bittinopeuden asettaminen tekee tiedostojen koosta ennustettavampaa vaikka laatu voi hieman heiketä. 720p videossa tyypilliset arvot ovat 2600 kbit/s VP9:lle ja HEVC:lle, tai 4500 kbit/s H.254:lle. Jos 0, ei käytössä. Jos yksikköä ei ole annettu, oletus on k (kbit/s). Eli 5000, 5000k ja 5M ovat yhtä suuria.",
"transcoding_max_keyframe_interval": "Suurin avainkehysten väli",
"transcoding_max_keyframe_interval_description": "Asettaa avainkehysten välin maksimiarvon. Alempi arvo huonontaa pakkauksen tehoa, mutta parantaa hakuaikoja ja voi parantaa laatua nopealiikkeisissä kohtauksissa. 0 asettaa arvon automaattisesti.",
"transcoding_optimal_description": "Videot, joiden resoluutio on korkeampi kuin kohteen, tai ei hyväksytyssä formaatissa",
@@ -350,7 +365,7 @@
"transcoding_target_resolution": "Kohderesoluutio",
"transcoding_target_resolution_description": "Korkeampi resoluutio on tarkempi, mutta kestää kauemmin enkoodata, vie enemmän tilaa ja voi hidastaa sovelluksen responsiivisuutta.",
"transcoding_temporal_aq": "Väliaikainen AQ",
"transcoding_temporal_aq_description": "Vaikuttaa vain NVENC:lle. Parantaa laatua kohtauksissa, joissa on paljon yksityiskohtia ja vähän liikettä. Ei välttämättä ole yhteensopiva vanhempien laitteiden kanssa.",
"transcoding_temporal_aq_description": "Vaikuttaa vain NVENC:lle. Aikaperusteinen adaptiivinen kvantisointi parantaa laatua kohtauksissa, joissa on paljon yksityiskohtia ja vähän liikettä. Ei välttämättä ole yhteensopiva vanhempien laitteiden kanssa.",
"transcoding_threads": "Säikeet",
"transcoding_threads_description": "Korkeampi arvo nopeuttaa enkoodausta, mutta vie tilaa palvelimen muilta tehtäviltä. Tämä arvo ei tulisi olla suurempi mitä suorittimen ytimien määrä. Suurin mahdollinen käyttö, mikäli arvo on 0.",
"transcoding_tone_mapping": "Sävykartoitus",
@@ -401,11 +416,11 @@
"advanced_settings_prefer_remote_subtitle": "Jotkut laitteet ovat erittäin hitaita lataamaan esikatselukuvia paikallisista kohteista. Aktivoi tämä asetus käyttääksesi etäkuvia.",
"advanced_settings_prefer_remote_title": "Suosi etäkuvia",
"advanced_settings_proxy_headers_subtitle": "Määritä välityspalvelimen otsikot(proxy headers), jotka Immichin tulisi lähettää jokaisen verkkopyynnön mukana",
"advanced_settings_proxy_headers_title": "Välityspalvelimen otsikot",
"advanced_settings_proxy_headers_title": "Mukautetut välityspalvelimen otsikot [KOKEELLINEN]",
"advanced_settings_readonly_mode_subtitle": "Aktivoi vain luku -tilan, jolloin valokuvia voi ainoastaan selata. Toiminnot kuten useiden kuvien valitseminen, jakaminen, siirtäminen toistolaitteelle ja poistaminen ovat pois käytöstä. Laita vain luku -tila päälle tai pois päältä päävalikon käyttäjäkuvakkeesta",
"advanced_settings_readonly_mode_title": "Vain luku -tila",
"advanced_settings_self_signed_ssl_subtitle": "Ohita SSL sertifikaattivarmennus palvelimen päätepisteellä. Vaaditaan self-signed -sertifikaateissa.",
"advanced_settings_self_signed_ssl_title": "Salli self-signed SSL -sertifikaatit",
"advanced_settings_self_signed_ssl_title": "Salli self-signed SSL -sertifikaatit [KOKEELLINEN]",
"advanced_settings_sync_remote_deletions_subtitle": "Poista tai palauta kohde automaattisesti tällä laitteella, kun kyseinen toiminto suoritetaan verkossa",
"advanced_settings_sync_remote_deletions_title": "Synkronoi etäpoistot [KOKEELLINEN]",
"advanced_settings_tile_subtitle": "Edistyneen käyttäjän asetukset",
@@ -414,6 +429,7 @@
"age_months": "Ikä {months, plural, one {# kuukausi} other {# kuukautta}}",
"age_year_months": "Ikä 1 vuosi, {months, plural, one {# kuukausi} other {# kuukautta}}",
"age_years": "{years, plural, other {Ikä #v}}",
"album": "Albumi",
"album_added": "Albumi lisätty",
"album_added_notification_setting_description": "Saa sähköpostia kun sinut lisätään jaettuun albumiin",
"album_cover_updated": "Albumin kansikuva päivitetty",
@@ -459,16 +475,21 @@
"allow_edits": "Salli muutokset",
"allow_public_user_to_download": "Salli julkisten käyttäjien ladata tiedostoja",
"allow_public_user_to_upload": "Salli julkisten käyttäjien lähettää tiedostoja",
"allowed": "Sallittu",
"alt_text_qr_code": "QR-koodi",
"anti_clockwise": "Vastapäivään",
"api_key": "API-avain",
"api_key_description": "Tämä arvo näytetään vain kerran. Varmista, että olet kopioinut sen ennen kuin suljet ikkunan.",
"api_key_empty": "API-avaimesi ei pitäisi olla tyhjä",
"api_keys": "API-avaimet",
"app_architecture_variant": "Variantti (Arkkitehtuuri)",
"app_bar_signout_dialog_content": "Haluatko varmasti kirjautua ulos?",
"app_bar_signout_dialog_ok": "Kyllä",
"app_bar_signout_dialog_title": "Kirjaudu ulos",
"app_download_links": "Sovelluksen latauslinkit",
"app_settings": "Sovellusasetukset",
"app_stores": "Sovelluskaupat",
"app_update_available": "Sovellukseen on saatavilla päivitys",
"appears_in": "Esiintyy albumeissa",
"apply_count": "Aseta {count, number}",
"archive": "Arkisto",
@@ -552,6 +573,7 @@
"backup_albums_sync": "Varmuuskopioitujen albumeiden synkronointi",
"backup_all": "Kaikki",
"backup_background_service_backup_failed_message": "Kohteiden varmuuskopiointi epäonnistui. Yritetään uudelleen…",
"backup_background_service_complete_notification": "Kohteiden varmuuskopiointi valmis",
"backup_background_service_connection_failed_message": "Palvelimeen ei saatu yhteyttä. Yritetään uudelleen…",
"backup_background_service_current_upload_notification": "Lähetetään {filename}",
"backup_background_service_default_notification": "Tarkistetaan uusia kohteita…",
@@ -661,6 +683,8 @@
"change_password_description": "Tämä on joko ensimmäinen kertasi kun kirjaudut järjestelmään, tai salasanasi on pyydetty vaihtamaan. Määritä uusi salasana alle.",
"change_password_form_confirm_password": "Vahvista salasana",
"change_password_form_description": "Hei {name},\n\nTämä on joko ensimmäinen kerta, kun kirjaudut järjestelmään, tai sinulta on pyydetty salasanan vaihtoa. Ole hyvä ja syötä uusi salasana alle.",
"change_password_form_log_out": "Kirjaudu ulos kaikilta muilta laitteilta",
"change_password_form_log_out_description": "On suositeltavaa kirjautua ulos kaikilta laitteilta",
"change_password_form_new_password": "Uusi salasana",
"change_password_form_password_mismatch": "Salasanat eivät täsmää",
"change_password_form_reenter_new_password": "Uusi salasana uudelleen",
@@ -688,7 +712,7 @@
"client_cert_invalid_msg": "Virheellinen varmennetiedosto tai väärä salasana",
"client_cert_remove_msg": "Asiakassertifikaatti on poistettu",
"client_cert_subtitle": "Vain PKCS12 (.p12, .pfx) -muotoa tuetaan. Varmenteen tuonti/poisto on käytettävissä vain ennen sisäänkirjautumista",
"client_cert_title": "SSL-asiakassertifikaatti",
"client_cert_title": "SSL-asiakassertifikaatti [KOKEELLINEN]",
"clockwise": "Myötäpäivään",
"close": "Sulje",
"collapse": "Supista",
@@ -700,7 +724,6 @@
"comments_and_likes": "Kommentit ja tykkäykset",
"comments_are_disabled": "Kommentointi ei käytössä",
"common_create_new_album": "Luo uusi albumi",
"common_server_error": "Tarkista internet-yhteytesi. Varmista että palvelin on saavutettavissa ja sovellus-/palvelinversiot ovat yhteensopivia.",
"completed": "Valmis",
"confirm": "Vahvista",
"confirm_admin_password": "Vahvista ylläpitäjän salasana",
@@ -739,6 +762,7 @@
"create": "Luo",
"create_album": "Luo albumi",
"create_album_page_untitled": "Nimetön",
"create_api_key": "Luo API-avain",
"create_library": "Luo uusi kirjasto",
"create_link": "Luo linkki",
"create_link_to_share": "Luo linkki jaettavaksi",
@@ -768,6 +792,7 @@
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Tumma",
"dark_theme": "Vaihda tumma teema",
"date": "Päivämäärä",
"date_after": "Päivämäärän jälkeen",
"date_and_time": "Päivämäärä ja aika",
"date_before": "Päivä ennen",
@@ -870,8 +895,6 @@
"edit_description_prompt": "Valitse uusi kuvaus:",
"edit_exclusion_pattern": "Muokkaa poissulkemismallia",
"edit_faces": "Muokkaa kasvoja",
"edit_import_path": "Muokkaa tuontipolkua",
"edit_import_paths": "Muokkaa tuontipolkuja",
"edit_key": "Muokkaa avainta",
"edit_link": "Muokkaa linkkiä",
"edit_location": "Muokkaa sijaintia",
@@ -882,7 +905,6 @@
"edit_tag": "Muokkaa tunnistetta",
"edit_title": "Muokkaa otsikkoa",
"edit_user": "Muokkaa käyttäjää",
"edited": "Muokattu",
"editor": "Muokkaaja",
"editor_close_without_save_prompt": "Muutoksia ei tallenneta",
"editor_close_without_save_title": "Suljetaanko editori?",
@@ -944,7 +966,6 @@
"failed_to_stack_assets": "Medioiden pinoaminen epäonnistui",
"failed_to_unstack_assets": "Medioiden pinoamisen purku epäonnistui",
"failed_to_update_notification_status": "Ilmoituksen tilan päivittäminen epäonnistui",
"import_path_already_exists": "Tämä tuontipolku on jo olemassa.",
"incorrect_email_or_password": "Väärä sähköpostiosoite tai salasana",
"paths_validation_failed": "{paths, plural, one {# polun} other {# polun}} validointi epäonnistui",
"profile_picture_transparent_pixels": "Profiilikuvassa ei voi olla läpinäkyviä pikseleitä. Zoomaa lähemmäs ja/tai siirrä kuvaa.",
@@ -954,7 +975,6 @@
"unable_to_add_assets_to_shared_link": "Medioiden lisääminen jaettuun linkkiin epäonnistui",
"unable_to_add_comment": "Kommentin lisääminen epäonnistui",
"unable_to_add_exclusion_pattern": "Ei voida lisätä poissulkemismallia",
"unable_to_add_import_path": "Tuontipolkua ei voitu lisätä",
"unable_to_add_partners": "Kumppaneita ei voitu lisätä",
"unable_to_add_remove_archive": "Ei voida {archived, select, true {poistaa kohdetta arkistosta} other {lisätä kohdetta arkistoon}}",
"unable_to_add_remove_favorites": "Ei voida {favorite, select, true {lisätä kohdetta suosikkeihin} other {poistaa kohdetta suosikeista}}",
@@ -977,12 +997,10 @@
"unable_to_delete_asset": "Kohteen poistaminen epäonnistui",
"unable_to_delete_assets": "Virhe kohteen poistamisessa",
"unable_to_delete_exclusion_pattern": "Ei voida poistaa poissulkemismallia",
"unable_to_delete_import_path": "Tuontipolkua ei voitu poistaa",
"unable_to_delete_shared_link": "Jaetun linkin poistaminen epäonnistui",
"unable_to_delete_user": "Käyttäjän poistaminen epäonnistui",
"unable_to_download_files": "Tiedostojen lataaminen epäonnistui",
"unable_to_edit_exclusion_pattern": "Ei voida muokata poissulkemismallia",
"unable_to_edit_import_path": "Tuontipolkua ei voitu muokata",
"unable_to_empty_trash": "Roskakorin tyhjentäminen epäonnistui",
"unable_to_enter_fullscreen": "Koko ruudun tilaan siirtyminen epäonnistui",
"unable_to_exit_fullscreen": "Koko ruudun tilasta poistuminen epäonnistui",
@@ -1038,6 +1056,7 @@
"exif_bottom_sheet_description_error": "Kuvauksen muuttaminen epäonnistui",
"exif_bottom_sheet_details": "TIEDOT",
"exif_bottom_sheet_location": "SIJAINTI",
"exif_bottom_sheet_no_description": "Ei kuvausta",
"exif_bottom_sheet_people": "IHMISET",
"exif_bottom_sheet_person_add_person": "Lisää nimi",
"exit_slideshow": "Poistu diaesityksestä",
@@ -1076,6 +1095,7 @@
"features_setting_description": "Hallitse sovelluksen ominaisuuksia",
"file_name": "Tiedoston nimi",
"file_name_or_extension": "Tiedostonimi tai tiedostopääte",
"file_size": "Tiedostokoko",
"filename": "Tiedostonimi",
"filetype": "Tiedostotyyppi",
"filter": "Suodatin",
@@ -1119,7 +1139,6 @@
"header_settings_field_validator_msg": "Arvo ei voi olla tyhjä",
"header_settings_header_name_input": "Otsikon nimi",
"header_settings_header_value_input": "Otsikon arvo",
"headers_settings_tile_subtitle": "Määritä välityspalvelimen otsikot, jotka sovelluksen tulisi lähettää jokaisen verkkopyynnön mukana",
"headers_settings_tile_title": "Mukautettu proxy headers",
"hi_user": "Hei {name} ({email})",
"hide_all_people": "Piilota kaikki henkilöt",
@@ -1240,6 +1259,7 @@
"local_media_summary": "Paikallisen median yhteenveto",
"local_network": "Lähiverkko",
"local_network_sheet_info": "Sovellus muodostaa yhteyden palvelimeen tämän URL-osoitteen kautta, kun käytetään määritettyä Wi-Fi-verkkoa",
"location": "Sijainti",
"location_permission": "Sijainnin käyttöoikeus",
"location_permission_content": "Automaattisen vaihtotoiminnon käyttämiseksi Immich tarvitsee tarkan sijainnin käyttöoikeuden, jotta se voi lukea nykyisen Wi-Fi-verkon nimen",
"location_picker_choose_on_map": "Valitse kartalta",
@@ -1340,10 +1360,12 @@
"merge_people_prompt": "Haluatko yhdistää nämä henkilöt? Tätä valintaa ei voi peruuttaa.",
"merge_people_successfully": "Henkilöt yhdistetty",
"merged_people_count": "{count, plural, one {# Henkilö} other {# henkilöä}} yhdistetty",
"minimize": "PIenennä",
"minimize": "Pienennä",
"minute": "Minuutti",
"minutes": "Minuutit",
"missing": "Puuttuvat",
"mobile_app": "Mobiilisovellus",
"mobile_app_download_onboarding_note": "Lataa mobiilisovellus käyttämällä seuraavia vaihtoehtoja",
"model": "Malli",
"month": "Kuukauden mukaan",
"monthly_title_text_date_format": "MMMM y",
@@ -1362,6 +1384,8 @@
"my_albums": "Omat albumit",
"name": "Nimi",
"name_or_nickname": "Nimi tai lempinimi",
"navigate": "Navigoi",
"navigate_to_time": "Navigoi aikaan",
"network_requirement_photos_upload": "Käytä mobiiliverkkoa kuvien varmuuskopioimiseksi",
"network_requirement_videos_upload": "Käytä mobiiliverkkoa videoiden varmuuskopioimiseksi",
"network_requirements": "Verkkovaatimukset",
@@ -1371,6 +1395,7 @@
"never": "ei koskaan",
"new_album": "Uusi Albumi",
"new_api_key": "Uusi API-avain",
"new_date_range": "Uusi aikaväli",
"new_password": "Uusi salasana",
"new_person": "Uusi henkilö",
"new_pin_code": "Uusi PIN-koodi",
@@ -1421,6 +1446,9 @@
"notifications": "Ilmoitukset",
"notifications_setting_description": "Hallitse ilmoituksia",
"oauth": "OAuth",
"obtainium_configurator": "Obtainium-määritystyökalu",
"obtainium_configurator_instructions": "Käytä Obtainiumia asentaaksesi ja päivittääksesi Android-sovelluksen suoraan Immichin GitHubin julkaisukanavasta. Luo API-avain ja valitse variantti luodaksesi Obtainium-määrityslinkin",
"ocr": "OCR (Tekstintunnistus)",
"official_immich_resources": "Viralliset Immich-resurssit",
"offline": "Offline",
"offset": "Ero",
@@ -1518,13 +1546,16 @@
"pin_code_reset_successfully": "PIN-koodin nollaus onnistui",
"pin_code_setup_successfully": "PIN-koodin asettaminen onnistui",
"pin_verification": "PIN-koodin vahvistus",
"place": "Sijainti",
"place": "Paikka",
"places": "Paikat",
"places_count": "{count, plural, one {{count, number} Paikka} other {{count, number} Paikkaa}}",
"play": "Toista",
"play_memories": "Toista muistot",
"play_motion_photo": "Toista Liikekuva",
"play_or_pause_video": "Toista tai keskeytä video",
"play_original_video": "Toista alkuperäinen video",
"play_original_video_setting_description": "Suosi alkuperäisten videoiden toistoa transkoodattujen videoiden sijaan. Jos alkuperäinen tiedosto ei ole yhteensopiva, se ei välttämättä toistu oikein.",
"play_transcoded_video": "Toista transkoodattu video",
"please_auth_to_access": "Ole hyvä ja kirjaudu sisään",
"port": "Portti",
"preferences_settings_subtitle": "Hallitse sovelluksen asetuksia",
@@ -1542,13 +1573,9 @@
"privacy": "Tietosuoja",
"profile": "Profiili",
"profile_drawer_app_logs": "Lokit",
"profile_drawer_client_out_of_date_major": "Sovelluksen mobiiliversio on vanhentunut. Päivitä viimeisimpään merkittävään versioon.",
"profile_drawer_client_out_of_date_minor": "Sovelluksen mobiiliversio on vanhentunut. Päivitä viimeisimpään versioon.",
"profile_drawer_client_server_up_to_date": "Asiakasohjelma ja palvelin ovat ajan tasalla",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Muokkaus on estetty. Paina käyttäjäkuvaketta pitkään palataksesi muokkaustilaan.",
"profile_drawer_server_out_of_date_major": "Palvelimen ohjelmistoversio on vanhentunut. Päivitä viimeisimpään merkittävään versioon.",
"profile_drawer_server_out_of_date_minor": "Palvelimen ohjelmistoversio on vanhentunut. Päivitä viimeisimpään versioon.",
"profile_image_of_user": "Käyttäjän {user} profiilikuva",
"profile_picture_set": "Profiilikuva asetettu.",
"public_album": "Julkinen albumi",
@@ -1665,6 +1692,7 @@
"reset_sqlite_confirmation": "Haluatko varmasti nollata SQLite tietokannan? Sinun tulee kirjautua sovelluksesta ulos ja takaisin sisään uudelleensynkronoidaksesi datan",
"reset_sqlite_success": "SQLite Tietokanta nollattu onnistuneesti",
"reset_to_default": "Palauta oletusasetukset",
"resolution": "Resoluutio",
"resolve_duplicates": "Ratkaise kaksoiskappaleet",
"resolved_all_duplicates": "Kaikki kaksoiskappaleet selvitetty",
"restore": "Palauta",
@@ -1683,6 +1711,7 @@
"running": "Käynnissä",
"save": "Tallenna",
"save_to_gallery": "Tallenna galleriaan",
"saved": "Tallennettu",
"saved_api_key": "API-avain tallennettu",
"saved_profile": "Profiili tallennettu",
"saved_settings": "Asetukset tallennettu",
@@ -1699,6 +1728,9 @@
"search_by_description_example": "Vaelluspäivä Sapassa",
"search_by_filename": "Hae tiedostonimen tai -päätteen mukaan",
"search_by_filename_example": "esim. IMG_1234.JPG tai PNG",
"search_by_ocr": "Etsi tekstintunnistuksella (OCR)",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Etsi linssin mallia...",
"search_camera_make": "Etsi kameramerkkiä...",
"search_camera_model": "Etsi kameramallia...",
"search_city": "Etsi kaupunkia...",
@@ -1715,6 +1747,7 @@
"search_filter_location_title": "Valitse sijainti",
"search_filter_media_type": "Mediatyyppi",
"search_filter_media_type_title": "Valitse mediatyyppi",
"search_filter_ocr": "Hae tekstintunnistuksella (OCR)",
"search_filter_people_title": "Valitse ihmiset",
"search_for": "Hae",
"search_for_existing_person": "Etsi olemassa olevaa henkilöä",
@@ -1777,6 +1810,7 @@
"server_online": "Palvelin Online-tilassa",
"server_privacy": "Palvelimen tietosuoja",
"server_stats": "Palvelimen tilastot",
"server_update_available": "Palvelimeen on saatavilla päivitys",
"server_version": "Palvelimen versio",
"set": "Aseta",
"set_as_album_cover": "Aseta albumin kanneksi",
@@ -1805,6 +1839,8 @@
"setting_notifications_subtitle": "Ilmoitusasetusten määrittely",
"setting_notifications_total_progress_subtitle": "Lähetyksen yleinen edistyminen (kohteita lähetetty/yhteensä)",
"setting_notifications_total_progress_title": "Näytä taustavarmuuskopioinnin kokonaisedistyminen",
"setting_video_viewer_auto_play_subtitle": "Aloita videoiden toistaminen automaattisesti kun ne avataan",
"setting_video_viewer_auto_play_title": "Toista videoita automaattisesti",
"setting_video_viewer_looping_title": "Silmukkatoisto",
"setting_video_viewer_original_video_subtitle": "Kun toistat videota palvelimelta, toista alkuperäinen, vaikka transkoodattu versio olisi saatavilla. Tämä voi johtaa puskurointiin. Paikalliset videot toistetaan aina alkuperäislaadulla.",
"setting_video_viewer_original_video_title": "Pakota alkuperäinen video",
@@ -1984,7 +2020,9 @@
"theme_setting_three_stage_loading_title": "Ota kolmivaiheinen lataus käyttöön",
"they_will_be_merged_together": "Nämä tullaan yhdistämään",
"third_party_resources": "Kolmannen osapuolen resurssit",
"time": "Aika",
"time_based_memories": "Aikaan perustuvat muistot",
"time_based_memories_duration": "Kuvien näyttöaika sekunteina.",
"timeline": "Aikajana",
"timezone": "Aikavyöhyke",
"to_archive": "Arkistoi",
@@ -2016,6 +2054,7 @@
"troubleshoot": "Vianetsintä",
"type": "Tyyppi",
"unable_to_change_pin_code": "PIN-koodin vaihtaminen epäonnistui",
"unable_to_check_version": "Sovelluksen tai palvelimen versiota ei voitu tarkistaa",
"unable_to_setup_pin_code": "PIN-koodin määrittäminen epäonnistui",
"unarchive": "Palauta arkistosta",
"unarchive_action_prompt": "{count} poistettu arkistosta",

View File

@@ -25,6 +25,8 @@
"add_to_album": "Idagdag sa album",
"add_to_album_bottom_sheet_added": "Naidagdag sa {album}",
"add_to_album_bottom_sheet_already_exists": "Nasa {album} na",
"add_to_albums": "Idagdag sa mga album",
"add_to_albums_count": "Idagdag sa mga album ({count})",
"add_to_shared_album": "Idagdag sa shared album",
"add_url": "Magdagdag ng URL",
"added_to_archive": "Naidagdag sa archive",
@@ -60,23 +62,24 @@
"exclusion_pattern_description": "Maaaring gamitin ang mga pattern na pangbukod para hindi pansinin ang ilang file o folder habang binabasa ang iyong library. Mainam itong solusyon para sa mga folder na may file na ayaw niyong ma-import, tulad ng mga RAW na file.",
"force_delete_user_warning": "BABALA: Tatanggalin itong user at lahat ng asset nila, Hindi ito mababawi at ang kanilang files ay hindi na mababalik",
"image_format": "Format",
"library_import_path_description": "Tukuyin ang folder na i-import. Ang folder na ito, kasama ang subfolders, ay mag sa-scan para sa mga imahe at mga videos.",
"note_cannot_be_changed_later": "TANDAAN: Hindi na ito pwede baguhin sa susunod!",
"server_welcome_message_description": "Mensahe na ipapakita sa login page.",
"user_restore_description": "Ang account ni <b>{user}</b> ay maibabalik."
},
"album_user_left": "Umalis sa {album}",
"all_albums": "Lahat ng albums",
"all_people": "Lahat ng tao",
"all_videos": "Lahat ng video",
"api_key_description": "Isang beses lamang na ipapakita itong value. Siguraduhin na ikopya itong value bago iclose ang window na ito.",
"are_these_the_same_person": "Itong tao na ito ay parehas?",
"asset_adding_to_album": "Dinadagdag sa album...",
"asset_filename_is_offline": "Offline ang asset {filename}",
"asset_uploading": "Ina-upload...",
"create_album_page_untitled": "Walang pamagat",
"documentation": "Dokumentasyion",
"done": "Tapos na",
"download": "I-download",
"edit": "I-edit",
"edited": "Inedit",
"editor_close_without_save_title": "Isara ang editor?",
"explore": "I-explore",
"export": "I-export",

View File

@@ -4,7 +4,7 @@
"account_settings": "Paramètres du compte",
"acknowledge": "Compris",
"action": "Action",
"action_common_update": "Mise à jour",
"action_common_update": "Mettre à jour",
"actions": "Actions",
"active": "En cours",
"activity": "Activité",
@@ -17,7 +17,6 @@
"add_birthday": "Ajouter un anniversaire",
"add_endpoint": "Ajouter une adresse",
"add_exclusion_pattern": "Ajouter un schéma d'exclusion",
"add_import_path": "Ajouter un chemin à importer",
"add_location": "Ajouter une localisation",
"add_more_users": "Ajouter plus d'utilisateurs",
"add_partner": "Ajouter un partenaire",
@@ -32,6 +31,7 @@
"add_to_album_toggle": "Basculer la sélection pour {album}",
"add_to_albums": "Ajouter aux albums",
"add_to_albums_count": "Ajouter aux albums ({count})",
"add_to_bottom_bar": "Ajouter à",
"add_to_shared_album": "Ajouter à l'album partagé",
"add_upload_to_stack": "Ajouter les éléments téléversés à la pile",
"add_url": "Ajouter l'URL",
@@ -112,15 +112,19 @@
"jobs_failed": "{jobCount, plural, other {# en échec}}",
"library_created": "Bibliothèque créée: {library}",
"library_deleted": "Bibliothèque supprimée",
"library_import_path_description": "Spécifier un dossier à importer. Ce dossier, y compris ses sous-dossiers, sera analysé à la recherche d'images et de vidéos.",
"library_details": "Détails de la bibliothèque",
"library_folder_description": "Renseignez un dossier à importer. Ce dossier et ses sous-dossiers seront scannés pour leurs images et vidéos.",
"library_remove_exclusion_pattern_prompt": "Êtes-vous sûr de vouloir supprimer ce schéma d'exclusion?",
"library_remove_folder_prompt": "Êtes-vous sûr de vouloir supprimer ce dossier d'import?",
"library_scanning": "Analyse périodique",
"library_scanning_description": "Configurer l'analyse périodique de la bibliothèque",
"library_scanning_enable_description": "Activer l'analyse périodique de la bibliothèque",
"library_settings": "Bibliothèque externe",
"library_settings_description": "Gestion des paramètres des bibliothèques externes",
"library_tasks_description": "Scanner les bibliothèques externes pour les nouveaux et/ou les éléments modifiés",
"library_updated": "Bibliothèque mise à jour",
"library_watching_enable_description": "Surveiller les modifications de fichiers dans les bibliothèques externes",
"library_watching_settings": "Surveillance de bibliothèque (EXPÉRIMENTAL)",
"library_watching_settings": "Surveillance de bibliothèque [EXPÉRIMENTAL]",
"library_watching_settings_description": "Surveiller automatiquement les fichiers modifiés",
"logging_enable_description": "Activer la journalisation",
"logging_level_description": "Niveau de journalisation lorsque cette option est activée.",
@@ -154,6 +158,18 @@
"machine_learning_min_detection_score_description": "Score de confiance minimal pour qu'un visage soit détecté, allant de 0 à 1. Des valeurs plus basses détecteront plus de visages mais peuvent entraîner des faux positifs.",
"machine_learning_min_recognized_faces": "Nombre minimal de visages reconnus",
"machine_learning_min_recognized_faces_description": "Nombre minimal de visages reconnus pour qu'une personne soit créée. Augmenter cette valeur rend la reconnaissance faciale plus précise au détriment d'augmenter la chance qu'un visage ne soit pas attribué à une personne.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Utiliser l'apprentissage automatique pour reconnaître le texte dans les images",
"machine_learning_ocr_enabled": "Activer la reconnaissance de caractères",
"machine_learning_ocr_enabled_description": "Si désactivé, la reconnaissance de texte ne s'appliquera pas aux images.",
"machine_learning_ocr_max_resolution": "Résolution maximale",
"machine_learning_ocr_max_resolution_description": "Les prévisualisations au-dessus de cette résolution seront retaillées en conservant leur ratio. Des valeurs plus grandes sont plus précises, mais sont plus lentes et utilisent plus de mémoire.",
"machine_learning_ocr_min_detection_score": "Score minimum de détection",
"machine_learning_ocr_min_detection_score_description": "Score de confiance minimum pour la détection du textew entre 0 et 1. Des valeurs faibles permettront de reconnaître davantage de texte mais peuvent entraîner des faux positifs.",
"machine_learning_ocr_min_recognition_score": "Score de reconnaissance minimum",
"machine_learning_ocr_min_score_recognition_description": "Score de confiance minimum pour la reconnaissance du texte, entre 0 et 1. Des valeurs faible permettront de reconnaître davantage de texte, mais peuvent entraîner des faux positifs.",
"machine_learning_ocr_model": "Modèle de Reconnaissance Optique de Caractères",
"machine_learning_ocr_model_description": "Les modèles du serveur sont plus précis que les modèles mobiles, mais ils sont plus lents et utilisent plus de mémoire.",
"machine_learning_settings": "Paramètres d'apprentissage automatique",
"machine_learning_settings_description": "Gérer les fonctionnalités et les paramètres d'apprentissage automatique",
"machine_learning_smart_search": "Recherche intelligente",
@@ -161,6 +177,10 @@
"machine_learning_smart_search_enabled": "Activer la recherche intelligente",
"machine_learning_smart_search_enabled_description": "Si cette option est désactivée, les images ne seront pas encodées pour la recherche intelligente.",
"machine_learning_url_description": "LURL du serveur d'apprentissage automatique. Si plusieurs URL sont fournies, chaque serveur sera essayé un par un jusquà ce que lun deux réponde avec succès, dans lordre de la première à la dernière. Les serveurs ne répondant pas seront temporairement ignorés jusqu'à ce qu'ils soient de nouveau opérationnels.",
"maintenance_settings": "Maintenance",
"maintenance_settings_description": "Mettre Immich en mode maintenance.",
"maintenance_start": "Démarrer le mode maintenance",
"maintenance_start_error": "Échec du démarrage du mode maintenance.",
"manage_concurrency": "Gérer du multitâche",
"manage_log_settings": "Gérer les paramètres de journalisation",
"map_dark_style": "Thème sombre",
@@ -211,6 +231,8 @@
"notification_email_ignore_certificate_errors_description": "Ignorer les erreurs de validation du certificat TLS (non recommandé)",
"notification_email_password_description": "Mot de passe à utiliser lors de l'authentification avec le serveur de messagerie",
"notification_email_port_description": "Port du serveur de messagerie (par exemple 25, 465 ou 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Utilise SMTPS (SMTP via TLS)",
"notification_email_sent_test_email_button": "Envoyer un courriel de test et enregistrer",
"notification_email_setting_description": "Paramètres pour l'envoi de notifications par courriel",
"notification_email_test_email": "Envoyer un courriel de test",
@@ -243,6 +265,7 @@
"oauth_storage_quota_default_description": "Quota en Gio à utiliser lorsqu'aucune valeur n'est précisée.",
"oauth_timeout": "Expiration de la durée de la requête",
"oauth_timeout_description": "Délai d'expiration des requêtes en millisecondes",
"ocr_job_description": "Utiliser un modèle d'apprentissage automatique pour reconnaitre le texte dans les images",
"password_enable_description": "Connexion avec courriel et mot de passe",
"password_settings": "Connexion par mot de passe",
"password_settings_description": "Gérer les paramètres de connexion par mot de passe",
@@ -305,7 +328,7 @@
"transcoding_acceleration_api": "API d'accélération",
"transcoding_acceleration_api_description": "Il s'agit de l'API qui interagira avec votre appareil pour accélérer le transcodage. Ce paramètre fait au mieux: il basculera vers le transcodage logiciel en cas d'échec. Le codec vidéo VP9 peut fonctionner ou non selon votre matériel.",
"transcoding_acceleration_nvenc": "NVENC (nécessite un GPU NVIDIA)",
"transcoding_acceleration_qsv": "Quick Sync (nécessite un processeur Intel de 7ème génération ou plus)",
"transcoding_acceleration_qsv": "Quick Sync (nécessite un processeur Intel de 7ème génération ou supérieur)",
"transcoding_acceleration_rkmpp": "RKMPP (uniquement sur les SOCs Rockchip)",
"transcoding_acceleration_vaapi": "VAAPI",
"transcoding_accepted_audio_codecs": "Codecs audio acceptés",
@@ -333,7 +356,7 @@
"transcoding_max_b_frames": "Nombre maximum de trames B",
"transcoding_max_b_frames_description": "Des valeurs plus élevées améliorent l'efficacité de la compression, mais ralentissent l'encodage. Elles peuvent ne pas être compatibles avec l'accélération matérielle sur les anciens appareils. Une valeur de 0 désactive les trames B, tandis qu'une valeur de -1 définit automatiquement ce paramètre.",
"transcoding_max_bitrate": "Débit binaire maximal",
"transcoding_max_bitrate_description": "Définir un débit binaire maximal peut résulter en des fichiers de taille plus prédictible, au prix d'une légère perte en qualité. En 720p, les valeurs sont 2600 kbit/s pour du VP9 ou du HEVC ou 4500 kbit/s pour du H.264. Désactivé si le débit binaire est à 0.",
"transcoding_max_bitrate_description": "Définir un débit binaire maximal peut rendre la taille des fichiers plus prévisible, au prix dune légère perte de qualité. En 720p, les valeurs typiques sont de 2600 kbit/s pour du VP9 ou du HEVC, ou de 4500 kbit/s pour du H.264. Désactivé si le débit binaire est fixé à 0. Lorsquaucune unité nest spécifiée, k (pour kbit/s) est supposée; ainsi, 5000, 5000k et 5M (pour Mbit/s) sont équivalents.",
"transcoding_max_keyframe_interval": "Intervalle maximal entre les images clés",
"transcoding_max_keyframe_interval_description": "Définit la distance maximale de trames entre les images clés. Les valeurs plus basses diminuent l'efficacité de la compression, mais améliorent les temps de recherche et peuvent améliorer la qualité dans les scènes avec des mouvements rapides. Une valeur de 0 définit automatiquement ce paramètre.",
"transcoding_optimal_description": "Les vidéos dont la résolution est supérieure à celle attendue ou celles qui ne sont pas dans un format accepté",
@@ -351,7 +374,7 @@
"transcoding_target_resolution": "Résolution cible",
"transcoding_target_resolution_description": "Des résolutions plus élevées peuvent préserver plus de détails, mais prennent plus de temps à encoder, ont de plus grandes tailles de fichiers, et peuvent réduire la réactivité de l'application.",
"transcoding_temporal_aq": "Quantification adaptative temporelle (temporal AQ)",
"transcoding_temporal_aq_description": "S'applique uniquement à NVENC. Améliore la qualité des scènes riches en détails et à faible mouvement. Peut ne pas être compatible avec les anciens appareils.",
"transcoding_temporal_aq_description": "S'applique uniquement à NVENC. La quantification adaptative temporelle améliore la qualité des scènes riches en détails et à faible mouvement. Peut ne pas être compatible avec les anciens appareils.",
"transcoding_threads": "Processus",
"transcoding_threads_description": "Une valeur plus élevée entraîne un encodage plus rapide, mais laisse moins de place au serveur pour traiter d'autres tâches pendant son activité. Cette valeur ne doit pas être supérieure au nombre de cœurs de CPU. Une valeur égale à 0 maximise l'utilisation.",
"transcoding_tone_mapping": "Mappage tonal",
@@ -402,11 +425,11 @@
"advanced_settings_prefer_remote_subtitle": "Certains appareils sont très lents à charger des miniatures à partir de ressources locales. Activez ce paramètre pour charger des images externes à la place.",
"advanced_settings_prefer_remote_title": "Préférer les images externes",
"advanced_settings_proxy_headers_subtitle": "Ajoutez des en-têtes personnalisés à chaque requête réseau",
"advanced_settings_proxy_headers_title": "En-têtes de proxy",
"advanced_settings_proxy_headers_title": "En-têtes de proxy personnalisés [EXPÉRIMENTAL]",
"advanced_settings_readonly_mode_subtitle": "Active le mode lecture seule, où les photos peuvent seulement être visualisées, et les actions comme les sélections multiples, le partage, la diffusion, la suppression sont désactivées. Activer/désactiver la lecture seule via l'image de l'utilisateur depuis l'écran d'accueil",
"advanced_settings_readonly_mode_title": "Mode lecture seule",
"advanced_settings_self_signed_ssl_subtitle": "Permet d'ignorer la vérification du certificat SSL pour le point d'accès du serveur. Requis pour les certificats auto-signés.",
"advanced_settings_self_signed_ssl_title": "Autoriser les certificats SSL auto-signés",
"advanced_settings_self_signed_ssl_title": "Autoriser les certificats SSL auto-signés [EXPÉRIMENTAL]",
"advanced_settings_sync_remote_deletions_subtitle": "Supprimer ou restaurer automatiquement un média sur cet appareil lorsqu'une action a été faite sur le web",
"advanced_settings_sync_remote_deletions_title": "Synchroniser les suppressions depuis le serveur [EXPÉRIMENTAL]",
"advanced_settings_tile_subtitle": "Paramètres d'utilisateur avancés",
@@ -415,6 +438,7 @@
"age_months": "Âge {months, plural, one {# mois} other {# mois}}",
"age_year_months": "Âge 1 an, {months, plural, one {# mois} other {# mois}}",
"age_years": "Âge {years, plural, one {# an} other {# ans}}",
"album": "Album",
"album_added": "Album ajouté",
"album_added_notification_setting_description": "Recevoir une notification par courriel lorsque vous êtes ajouté(e) à un album partagé",
"album_cover_updated": "Couverture de l'album mise à jour",
@@ -460,16 +484,21 @@
"allow_edits": "Autoriser les modifications",
"allow_public_user_to_download": "Permettre le téléchargement par des utilisateurs non connectés",
"allow_public_user_to_upload": "Permettre l'envoi par des utilisateurs non connectés",
"allowed": "Autorisé",
"alt_text_qr_code": "Image du code QR",
"anti_clockwise": "Sens anti-horaire",
"api_key": "Clé API",
"api_key_description": "Cette valeur ne sera affichée qu'une seule fois. Assurez-vous de la copier avant de fermer la fenêtre.",
"api_key_empty": "Le nom de votre clé API ne doit pas être vide",
"api_keys": "Clés d'API",
"app_architecture_variant": "Variante (Architecture)",
"app_bar_signout_dialog_content": "Êtes-vous sûr(e) de vouloir vous déconnecter?",
"app_bar_signout_dialog_ok": "Oui",
"app_bar_signout_dialog_title": "Se déconnecter",
"app_download_links": "Liens de téléchargement de l'appli",
"app_settings": "Paramètres de l'application",
"app_stores": "Magasins d'applications",
"app_update_available": "Une mise à jour est disponible",
"appears_in": "Apparaît dans",
"apply_count": "Appliquer ({count, number})",
"archive": "Archive",
@@ -553,6 +582,7 @@
"backup_albums_sync": "Sauvegarde de la synchronisation des albums",
"backup_all": "Tout",
"backup_background_service_backup_failed_message": "Échec de la sauvegarde des médias. Nouvelle tentative…",
"backup_background_service_complete_notification": "Sauvegarde du média terminée",
"backup_background_service_connection_failed_message": "Impossible de se connecter au serveur. Nouvelle tentative…",
"backup_background_service_current_upload_notification": "Envoi de {filename}",
"backup_background_service_default_notification": "Recherche de nouveaux médias…",
@@ -600,7 +630,7 @@
"backup_controller_page_turn_on": "Activer la sauvegarde au premier plan",
"backup_controller_page_uploading_file_info": "Envoi des informations du fichier",
"backup_err_only_album": "Impossible de retirer le seul album",
"backup_error_sync_failed": "Échec de la synchronisation. Impossible d'exécuter la sauvegarde.",
"backup_error_sync_failed": "Échec de synchronisation.",
"backup_info_card_assets": "médias",
"backup_manual_cancelled": "Annulé",
"backup_manual_in_progress": "Envoi déjà en cours. Réessayez plus tard",
@@ -662,6 +692,8 @@
"change_password_description": "C'est la première fois que vous vous connectez ou une demande a été faite pour changer votre mot de passe. Veuillez entrer le nouveau mot de passe ci-dessous.",
"change_password_form_confirm_password": "Confirmez le mot de passe",
"change_password_form_description": "Bonjour {name},\n\nC'est la première fois que vous vous connectez au système ou vous avez demandé de changer votre mot de passe. Veuillez saisir le nouveau mot de passe ci-dessous.",
"change_password_form_log_out": "Déconnecter tous les autres appareils",
"change_password_form_log_out_description": "Il est recommandé de déconnecter tous les autres appareils",
"change_password_form_new_password": "Nouveau mot de passe",
"change_password_form_password_mismatch": "Les mots de passe ne correspondent pas",
"change_password_form_reenter_new_password": "Saisissez à nouveau le nouveau mot de passe",
@@ -689,7 +721,7 @@
"client_cert_invalid_msg": "Fichier de certificat invalide ou mot de passe incorrect",
"client_cert_remove_msg": "Certificat supprimé",
"client_cert_subtitle": "Prend en charge uniquement le format PKCS12 (.p12, .pfx). L'importation/suppression de certificats n'est possible qu'avant la connexion",
"client_cert_title": "Certificat SSL",
"client_cert_title": "Certificat SSL [EXPÉRIMENTAL]",
"clockwise": "Sens horaire",
"close": "Fermer",
"collapse": "Réduire",
@@ -701,9 +733,8 @@
"comments_and_likes": "Commentaires et \"J'aime\"",
"comments_are_disabled": "Les commentaires sont désactivés",
"common_create_new_album": "Créer un nouvel album",
"common_server_error": "Veuillez vérifier votre connexion réseau, vous assurer que le serveur est accessible et que les versions de l'application et du serveur sont compatibles.",
"completed": "Complété",
"confirm": "Confirmez",
"confirm": "Confirmer",
"confirm_admin_password": "Confirmez le mot de passe Admin",
"confirm_delete_face": "Êtes-vous sûr de vouloir supprimer le visage de {name} du média?",
"confirm_delete_shared_link": "Voulez-vous vraiment supprimer ce lien partagé?",
@@ -740,6 +771,7 @@
"create": "Créer",
"create_album": "Créer un album",
"create_album_page_untitled": "Sans titre",
"create_api_key": "Créer une clé d'API",
"create_library": "Créer une bibliothèque",
"create_link": "Créer le lien",
"create_link_to_share": "Créer un lien pour partager",
@@ -769,6 +801,7 @@
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Sombre",
"dark_theme": "Activer le thème sombre",
"date": "Date",
"date_after": "Date après",
"date_and_time": "Date et heure",
"date_before": "Date avant",
@@ -871,8 +904,6 @@
"edit_description_prompt": "Choisir une nouvelle description :",
"edit_exclusion_pattern": "Modifier le schéma d'exclusion",
"edit_faces": "Modifier les visages",
"edit_import_path": "Modifier le chemin d'importation",
"edit_import_paths": "Modifier les chemins d'importation",
"edit_key": "Modifier la clé",
"edit_link": "Modifier le lien",
"edit_location": "Modifier la localisation",
@@ -883,7 +914,6 @@
"edit_tag": "Modifier l'étiquette",
"edit_title": "Modifier le titre",
"edit_user": "Modifier l'utilisateur",
"edited": "Modifié",
"editor": "Editeur",
"editor_close_without_save_prompt": "Les changements ne seront pas enregistrés",
"editor_close_without_save_title": "Fermer l'éditeur?",
@@ -895,7 +925,7 @@
"empty_trash": "Vider la corbeille",
"empty_trash_confirmation": "Êtes-vous sûr de vouloir vider la corbeille? Cela supprimera définitivement de Immich tous les médias qu'elle contient.\nVous ne pouvez pas annuler cette action!",
"enable": "Active",
"enable_backup": "Activer la sauvegarde",
"enable_backup": "Sauvegarde",
"enable_biometric_auth_description": "Entrez votre code PIN pour activer l'authentification biométrique",
"enabled": "Activé",
"end_date": "Date de fin",
@@ -945,8 +975,8 @@
"failed_to_stack_assets": "Impossible d'empiler les médias",
"failed_to_unstack_assets": "Impossible de dépiler les médias",
"failed_to_update_notification_status": "Erreur de mise à jour du statut des notifications",
"import_path_already_exists": "Ce chemin d'importation existe déjà.",
"incorrect_email_or_password": "Courriel ou mot de passe incorrect",
"library_folder_already_exists": "Ce chemin d'import existe déjà.",
"paths_validation_failed": "Validation échouée pour {paths, plural, one {# un chemin} other {# plusieurs chemins}}",
"profile_picture_transparent_pixels": "Les images de profil ne peuvent pas avoir de pixels transparents. Veuillez agrandir et/ou déplacer l'image.",
"quota_higher_than_disk_size": "Le quota saisi est supérieur à l'espace disponible",
@@ -955,7 +985,6 @@
"unable_to_add_assets_to_shared_link": "Impossible d'ajouter des médias au lien partagé",
"unable_to_add_comment": "Impossible d'ajouter un commentaire",
"unable_to_add_exclusion_pattern": "Impossible d'ajouter un schéma d'exclusion",
"unable_to_add_import_path": "Impossible d'ajouter le chemin d'importation",
"unable_to_add_partners": "Impossible d'ajouter des partenaires",
"unable_to_add_remove_archive": "Impossible {archived, select, true {de supprimer des médias de} other {d'ajouter des médias à}} l'archive",
"unable_to_add_remove_favorites": "Impossible {favorite, select, true {d'ajouter des médias aux} other {de supprimer des médias des}} favoris",
@@ -978,12 +1007,10 @@
"unable_to_delete_asset": "Impossible de supprimer le média",
"unable_to_delete_assets": "Erreur lors de la suppression des médias",
"unable_to_delete_exclusion_pattern": "Impossible de supprimer le modèle d'exclusion",
"unable_to_delete_import_path": "Impossible de supprimer le chemin d'importation",
"unable_to_delete_shared_link": "Impossible de supprimer le lien de partage",
"unable_to_delete_user": "Impossible de supprimer l'utilisateur",
"unable_to_download_files": "Impossible de télécharger les fichiers",
"unable_to_edit_exclusion_pattern": "Impossible de modifier le modèle d'exclusion",
"unable_to_edit_import_path": "Impossible de modifier le chemin d'importation",
"unable_to_empty_trash": "Impossible de vider la corbeille",
"unable_to_enter_fullscreen": "Mode plein écran indisponible",
"unable_to_exit_fullscreen": "Impossible de sortir du mode plein écran",
@@ -1034,11 +1061,13 @@
"unable_to_update_user": "Impossible de mettre à jour l'utilisateur",
"unable_to_upload_file": "Impossible d'envoyer le fichier"
},
"exclusion_pattern": "Schéma d'exclusion",
"exif": "Exif",
"exif_bottom_sheet_description": "Ajouter une description...",
"exif_bottom_sheet_description_error": "Erreur de mise à jour de la description",
"exif_bottom_sheet_details": "DÉTAILS",
"exif_bottom_sheet_location": "LOCALISATION",
"exif_bottom_sheet_no_description": "Aucune description",
"exif_bottom_sheet_people": "PERSONNES",
"exif_bottom_sheet_person_add_person": "Ajouter un nom",
"exit_slideshow": "Quitter le diaporama",
@@ -1077,6 +1106,7 @@
"features_setting_description": "Gérer les fonctionnalités de l'application",
"file_name": "Nom du fichier",
"file_name_or_extension": "Nom du fichier ou extension",
"file_size": "Taille du fichier",
"filename": "Nom du fichier",
"filetype": "Type de fichier",
"filter": "Filtres",
@@ -1091,6 +1121,7 @@
"folders_feature_description": "Parcourir l'affichage par dossiers pour les photos et les vidéos sur le système de fichiers",
"forgot_pin_code_question": "Code PIN oublié?",
"forward": "Avant",
"full_path": "Chemin complet : {path}",
"gcast_enabled": "Diffusion Google Cast",
"gcast_enabled_description": "Cette fonctionnalité charge des ressources externes depuis Google pour fonctionner.",
"general": "Général",
@@ -1120,7 +1151,6 @@
"header_settings_field_validator_msg": "Cette valeur ne peut pas être vide",
"header_settings_header_name_input": "Nom de l'en-tête",
"header_settings_header_value_input": "Valeur de l'en-tête",
"headers_settings_tile_subtitle": "Définir les en-têtes de proxy que l'application doit envoyer avec chaque requête réseau",
"headers_settings_tile_title": "En-têtes de proxy personnalisés",
"hi_user": "Bonjour {name} ({email})",
"hide_all_people": "Cacher toutes les personnes",
@@ -1173,6 +1203,8 @@
"import_path": "Chemin d'importation",
"in_albums": "Dans {count, plural, one {# album} other {# albums}}",
"in_archive": "Dans les archives",
"in_year": "Dans {year}",
"in_year_selector": "Dans",
"include_archived": "Inclure les archives",
"include_shared_albums": "Inclure les albums partagés",
"include_shared_partner_assets": "Inclure les médias partagés du partenaire",
@@ -1209,6 +1241,7 @@
"language_setting_description": "Sélectionnez votre langue préférée",
"large_files": "Fichiers volumineux",
"last": "Dernier",
"last_months": "{count, plural, one {Dernier mois} other {Derniers # mois}}",
"last_seen": "Dernièrement utilisé",
"latest_version": "Dernière version",
"latitude": "Latitude",
@@ -1218,6 +1251,8 @@
"let_others_respond": "Laisser les autres réagir",
"level": "Niveau",
"library": "Bibliothèque",
"library_add_folder": "Ajouter un dossier",
"library_edit_folder": "Modifier un dossier",
"library_options": "Options de bibliothèque",
"library_page_device_albums": "Albums sur l'appareil",
"library_page_new_album": "Nouvel album",
@@ -1241,6 +1276,7 @@
"local_media_summary": "Résumé du média local",
"local_network": "Réseau local",
"local_network_sheet_info": "L'application va se connecter au serveur via cette URL quand l'appareil est connecté à ce réseau Wi-Fi",
"location": "Localisation",
"location_permission": "Autorisation de localisation",
"location_permission_content": "Afin de pouvoir changer d'adresse automatiquement, Immich doit avoir accès à la localisation précise, afin d'accéder au nom du réseau wifi utilisé",
"location_picker_choose_on_map": "Sélectionner sur la carte",
@@ -1288,8 +1324,17 @@
"loop_videos_description": "Activer pour voir la vidéo en boucle dans le lecteur détaillé.",
"main_branch_warning": "Vous utilisez une version de développement. Nous vous recommandons fortement d'utiliser une version stable!",
"main_menu": "Menu principal",
"maintenance_description": "Immich a été mis en <link>mode maintenance</link>.",
"maintenance_end": "Arrêter le mode maintenance",
"maintenance_end_error": "Échec de l'arrêt du mode maintenance.",
"maintenance_logged_in_as": "Actuellement connecté en tant que {user}",
"maintenance_title": "Temporairement non disponible",
"make": "Marque",
"manage_geolocation": "Gérer la localisation",
"manage_media_access_rationale": "Cette autorisation est nécessaire pour gérer correctement le déplacement de médias vers la corbeille et la restauration depuis celle-ci.",
"manage_media_access_settings": "Ouvrir les paramètres",
"manage_media_access_subtitle": "Autoriser l'application Immich à gérer et déplacer des fichiers de média.",
"manage_media_access_title": "Accès à la gestion de médias",
"manage_shared_links": "Gérer les liens partagés",
"manage_sharing_with_partners": "Gérer le partage avec les partenaires",
"manage_the_app_settings": "Gérer les paramètres de l'application",
@@ -1345,12 +1390,15 @@
"minute": "Minute",
"minutes": "Minutes",
"missing": "Manquant",
"mobile_app": "Appli mobile",
"mobile_app_download_onboarding_note": "Téléchargez l'application mobile compagnon via les options suivantes",
"model": "Modèle",
"month": "Mois",
"monthly_title_text_date_format": "MMMM y",
"more": "Plus",
"move": "Déplacer",
"move_off_locked_folder": "Déplacer en dehors du dossier verrouillé",
"move_to": "Déplacer vers",
"move_to_lock_folder_action_prompt": "{count} ajouté(s) au dossier verrouillé",
"move_to_locked_folder": "Déplacer dans le dossier verrouillé",
"move_to_locked_folder_confirmation": "Ces photos et vidéos seront retirées de tous les albums et ne seront visibles que dans le dossier verrouillé",
@@ -1363,6 +1411,8 @@
"my_albums": "Mes albums",
"name": "Nom",
"name_or_nickname": "Nom ou surnom",
"navigate": "Naviguer vers",
"navigate_to_time": "Naviguer vers Date/Heure",
"network_requirement_photos_upload": "Utiliser les données mobile pour sauvegarder les photos",
"network_requirement_videos_upload": "Utiliser les données mobile pour sauvegarder les vidéos",
"network_requirements": "Prérequis réseau",
@@ -1372,11 +1422,13 @@
"never": "Jamais",
"new_album": "Nouvel Album",
"new_api_key": "Nouvelle clé API",
"new_date_range": "Nouvelle plage de date",
"new_password": "Nouveau mot de passe",
"new_person": "Nouvelle personne",
"new_pin_code": "Nouveau code PIN",
"new_pin_code_subtitle": "C'est votre premier accès au dossier verrouillé. Créez un code PIN pour sécuriser l'accès à cette page",
"new_timeline": "Nouvelle vue chronologique",
"new_update": "Nouvelle mise à jour",
"new_user_created": "Nouvel utilisateur créé",
"new_version_available": "NOUVELLE VERSION DISPONIBLE",
"newest_first": "Récents en premier",
@@ -1392,12 +1444,14 @@
"no_cast_devices_found": "Aucun appareil de diffusion trouvé",
"no_checksum_local": "Aucune empreinte numerique disponible - impossible de récupérer les médias locaux",
"no_checksum_remote": "Aucune empreinte numérique disponible - impossible de récupérer les médias distants",
"no_devices": "Aucun appareil autorisé",
"no_duplicates_found": "Aucun doublon n'a été trouvé.",
"no_exif_info_available": "Aucune information exif disponible",
"no_explore_results_message": "Envoyez plus de photos pour explorer votre bibliothèque.",
"no_favorites_message": "Ajouter des photos et vidéos à vos favoris pour les retrouver plus rapidement",
"no_libraries_message": "Créer une bibliothèque externe pour voir vos photos et vidéos dans un autre espace de stockage",
"no_local_assets_found": "Aucun média local trouvé avec cette empreinte numerique",
"no_location_set": "Aucune localisation definie",
"no_locked_photos_message": "Les photos et vidéos du dossier verrouillé sont masqués et ne s'afficheront pas dans votre galerie ou la recherche.",
"no_name": "Pas de nom",
"no_notifications": "Pas de notification",
@@ -1408,6 +1462,7 @@
"no_results_description": "Essayez un synonyme ou un mot-clé plus général",
"no_shared_albums_message": "Créer un album pour partager vos photos et vidéos avec les personnes de votre réseau",
"no_uploads_in_progress": "Pas d'envoi en cours",
"not_allowed": "Non autorisé",
"not_available": "N/A",
"not_in_any_album": "Dans aucun album",
"not_selected": "Non sélectionné",
@@ -1422,6 +1477,9 @@
"notifications": "Notifications",
"notifications_setting_description": "Gérer les notifications",
"oauth": "OAuth",
"obtainium_configurator": "Configuration pour Obtainium",
"obtainium_configurator_instructions": "Utilisez Obtainium pour installer et mettre à jour l'application Android directement depuis la version d'Immich sur Github. Créer une clé d'API et sélectionner une variante pour créer votre lien de configuration pour Obtainium",
"ocr": "Reconnaissance Optique de Caractères",
"official_immich_resources": "Ressources Immich officielles",
"offline": "Hors ligne",
"offset": "Décalage",
@@ -1515,6 +1573,8 @@
"photos_count": "{count, plural, one {{count, number} Photo} other {{count, number} Photos}}",
"photos_from_previous_years": "Photos des années précédentes",
"pick_a_location": "Choisissez une localisation",
"pick_custom_range": "Période personnalisée",
"pick_date_range": "Sélectionner une période de dates",
"pin_code_changed_successfully": "Code PIN changé avec succès",
"pin_code_reset_successfully": "Réinitialisation du code PIN réussie",
"pin_code_setup_successfully": "Définition du code PIN réussie",
@@ -1526,6 +1586,9 @@
"play_memories": "Lancer les souvenirs",
"play_motion_photo": "Jouer la photo animée",
"play_or_pause_video": "Lancer ou mettre en pause la vidéo",
"play_original_video": "Lire la vidéo originale",
"play_original_video_setting_description": "Préférer la lecture des vidéos originales plutôt que les vidéos transcodées. Si le média original n'est pas compatible, il pourrait ne pas être lu correctement.",
"play_transcoded_video": "Lire la vidéo transcodée",
"please_auth_to_access": "Merci de vous authentifier pour accéder",
"port": "Port",
"preferences_settings_subtitle": "Gérer les préférences de l'application",
@@ -1543,13 +1606,9 @@
"privacy": "Vie privée",
"profile": "Profil",
"profile_drawer_app_logs": "Journaux",
"profile_drawer_client_out_of_date_major": "L'application mobile est obsolète. Veuillez effectuer la mise à jour vers la dernière version majeure.",
"profile_drawer_client_out_of_date_minor": "L'application mobile est obsolète. Veuillez effectuer la mise à jour vers la dernière version mineure.",
"profile_drawer_client_server_up_to_date": "Le client et le serveur sont à jour",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Mode lecture seule activé. Faites un appui long sur l'image de l'utilisateur pour quitter.",
"profile_drawer_server_out_of_date_major": "Le serveur est obsolète. Veuillez mettre à jour vers la dernière version majeure.",
"profile_drawer_server_out_of_date_minor": "Le serveur est obsolète. Veuillez mettre à jour vers la dernière version mineure.",
"profile_image_of_user": "Image de profil de {user}",
"profile_picture_set": "Photo de profil définie.",
"public_album": "Album public",
@@ -1666,6 +1725,7 @@
"reset_sqlite_confirmation": "Êtes-vous certain de vouloir réinitialiser la base de données SQLite? Vous devrez vous déconnecter puis vous reconnecter à nouveau pour resynchroniser les données",
"reset_sqlite_success": "La base de données SQLite à été réinitialisé avec succès",
"reset_to_default": "Rétablir les valeurs par défaut",
"resolution": "Résolution",
"resolve_duplicates": "Résoudre les doublons",
"resolved_all_duplicates": "Résolution de tous les doublons",
"restore": "Restaurer",
@@ -1684,6 +1744,7 @@
"running": "En cours",
"save": "Sauvegarder",
"save_to_gallery": "Enregistrer",
"saved": "Sauvegardé",
"saved_api_key": "Clé API sauvegardée",
"saved_profile": "Profil enregistré",
"saved_settings": "Paramètres enregistrés",
@@ -1700,6 +1761,9 @@
"search_by_description_example": "Randonnée à Sapa",
"search_by_filename": "Rechercher par nom du fichier ou extension",
"search_by_filename_example": "Exemple: IMG_1234.JPG ou PNG",
"search_by_ocr": "Recherche par OCR",
"search_by_ocr_example": "café latte",
"search_camera_lens_model": "Chercher par modèle d'objectif...",
"search_camera_make": "Rechercher par marque d'appareil photo...",
"search_camera_model": "Rechercher par modèle d'appareil photo...",
"search_city": "Rechercher par ville...",
@@ -1716,6 +1780,7 @@
"search_filter_location_title": "Sélectionner une localisation",
"search_filter_media_type": "Type de média",
"search_filter_media_type_title": "Sélectionner type de média",
"search_filter_ocr": "Recherche par OCR",
"search_filter_people_title": "Sélectionner une personne",
"search_for": "Chercher",
"search_for_existing_person": "Rechercher une personne existante",
@@ -1773,11 +1838,14 @@
"send_welcome_email": "Envoyer un courriel de bienvenue",
"server_endpoint": "Adresse du serveur",
"server_info_box_app_version": "Version de l'application",
"server_info_box_server_url": "URL du serveur",
"server_info_box_server_url": "Server URL",
"server_offline": "Serveur hors ligne",
"server_online": "Serveur en ligne",
"server_privacy": "Vie privée pour le serveur",
"server_restarting_description": "Cette page va se rafraîchir dans quelques instants.",
"server_restarting_title": "Le serveur redémarre",
"server_stats": "Statistiques du serveur",
"server_update_available": "Une mise à jour du serveur est disponible",
"server_version": "Version du serveur",
"set": "Définir",
"set_as_album_cover": "Définir comme couverture d'album",
@@ -1806,6 +1874,8 @@
"setting_notifications_subtitle": "Ajustez vos préférences de notification",
"setting_notifications_total_progress_subtitle": "Progression globale de l'envoi (effectué/total des médias)",
"setting_notifications_total_progress_title": "Afficher la progression totale de la sauvegarde en arrière-plan",
"setting_video_viewer_auto_play_subtitle": "Lancer automatiquement la lecture des vidéos lorsquelles sont ouvertes",
"setting_video_viewer_auto_play_title": "Lecture automatique des vidéos",
"setting_video_viewer_looping_title": "Boucle",
"setting_video_viewer_original_video_subtitle": "Lors de la diffusion d'une vidéo depuis le serveur, lisez l'original même si un transcodage est disponible. Cela peut entraîner de la mise en mémoire tampon. Les vidéos disponibles localement sont lues en qualité d'origine, quel que soit ce paramètre.",
"setting_video_viewer_original_video_title": "Forcer la vidéo originale",
@@ -1898,7 +1968,7 @@
"show_supporter_badge": "Badge de contributeur",
"show_supporter_badge_description": "Afficher le badge de contributeur",
"show_text_search_menu": "Afficher le menu de recherche de texte",
"shuffle": "Mélanger",
"shuffle": "Aléatoire",
"sidebar": "Barre latérale",
"sidebar_display_description": "Afficher un lien vers la vue dans la barre latérale",
"sign_out": "Déconnexion",
@@ -1985,7 +2055,9 @@
"theme_setting_three_stage_loading_title": "Activer le chargement en trois étapes",
"they_will_be_merged_together": "Elles seront fusionnées ensemble",
"third_party_resources": "Ressources tierces",
"time": "Horaire",
"time_based_memories": "Souvenirs basés sur la date",
"time_based_memories_duration": "Durée en secondes d'affichage de chaque image.",
"timeline": "Vue chronologique",
"timezone": "Fuseau horaire",
"to_archive": "Archiver",
@@ -2017,6 +2089,7 @@
"troubleshoot": "Dépannage",
"type": "Type",
"unable_to_change_pin_code": "Impossible de changer le code PIN",
"unable_to_check_version": "Impossible de vérifier la version de l'application ou du serveur",
"unable_to_setup_pin_code": "Impossible de définir le code PIN",
"unarchive": "Désarchiver",
"unarchive_action_prompt": "{count} supprimé(s) de l'archive",
@@ -2125,6 +2198,7 @@
"welcome": "Bienvenue",
"welcome_to_immich": "Bienvenue sur Immich",
"wifi_name": "Nom du réseau wifi",
"workflow": "Flux de travail",
"wrong_pin_code": "Code PIN erroné",
"year": "Année",
"years_ago": "Il y a {years, plural, one {# an} other {# ans}}",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Engadir cumpreanos",
"add_endpoint": "Engadir punto final",
"add_exclusion_pattern": "Engadir patrón de exclusión",
"add_import_path": "Engadir ruta de importación",
"add_location": "Engadir localización",
"add_more_users": "Engadir máis usuarios",
"add_partner": "Engadir compañeiro/a",
@@ -32,7 +31,9 @@
"add_to_album_toggle": "Alternar selección para {album}",
"add_to_albums": "Engadir a álbums",
"add_to_albums_count": "Engadir a {count} álbums",
"add_to_bottom_bar": "Engadir a",
"add_to_shared_album": "Engadir ao álbum compartido",
"add_upload_to_stack": "Engade cargar á pila",
"add_url": "Engadir URL",
"added_to_archive": "Engadido ao arquivo",
"added_to_favorites": "Engadido a favoritos",
@@ -57,7 +58,7 @@
"backup_onboarding_parts_title": "Unha copia de seguridade 3-2-1 inclúe:",
"backup_onboarding_title": "Copia de seguridade",
"backup_settings": "Configuración da copia da base de datos",
"backup_settings_description": "Xestionar a configuración da copia da base de datos",
"backup_settings_description": "Xestionar a configuración da copia da base de datos.",
"cleared_jobs": "Traballos borrados para: {job}",
"config_set_by_file": "A configuración establécese actualmente mediante un ficheiro de configuración",
"confirm_delete_library": "Está seguro de que quere eliminar a biblioteca {library}?",
@@ -111,7 +112,6 @@
"jobs_failed": "{jobCount, plural, other {# fallados}}",
"library_created": "Biblioteca creada: {library}",
"library_deleted": "Biblioteca eliminada",
"library_import_path_description": "Especifique un cartafol para importar. Este cartafol, incluídos os subcartafoles, escanearase en busca de imaxes e vídeos.",
"library_scanning": "Escaneo periódico",
"library_scanning_description": "Configurar o escaneo periódico da biblioteca",
"library_scanning_enable_description": "Activar o escaneo periódico da biblioteca",
@@ -119,7 +119,7 @@
"library_settings_description": "Xestionar a configuración da biblioteca externa",
"library_tasks_description": "Escanear bibliotecas externas en busca de activos novos e/ou modificados",
"library_watching_enable_description": "Vixiar bibliotecas externas para detectar cambios nos ficheiros",
"library_watching_settings": "Vixilancia da biblioteca (EXPERIMENTAL)",
"library_watching_settings": "Vixilancia da biblioteca [EXPERIMENTAL]",
"library_watching_settings_description": "Vixiar automaticamente os ficheiros modificados",
"logging_enable_description": "Activar rexistro",
"logging_level_description": "Cando estea activado, que nivel de rexistro usar.",
@@ -153,6 +153,18 @@
"machine_learning_min_detection_score_description": "Puntuación mínima de confianza para que unha cara sexa detectada, de 0 a 1. Valores máis baixos detectarán máis caras pero poden resultar en falsos positivos.",
"machine_learning_min_recognized_faces": "Mínimo de caras recoñecidas",
"machine_learning_min_recognized_faces_description": "O número mínimo de caras recoñecidas para que se cree unha persoa. Aumentar isto fai que o Recoñecemento Facial sexa máis preciso a costa de aumentar a posibilidade de que unha cara non se asigne a unha persoa.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Emprega aprendizaxe automática para recoñecer texto en imaxes",
"machine_learning_ocr_enabled": "Activa o OCR",
"machine_learning_ocr_enabled_description": "Se está desactivado, as imaxes non se someterán a recoñecemento de texto.",
"machine_learning_ocr_max_resolution": "Resolución máxima",
"machine_learning_ocr_max_resolution_description": "As previsualizacións por enriba desta resolución redimensionaranse mantendo a proporción. Os valores máis altos son máis precisos, pero tardan máis en procesarse e usan máis memoria.",
"machine_learning_ocr_min_detection_score": "Puntuación mínima de detección",
"machine_learning_ocr_min_detection_score_description": "Puntuación mínima de confianza para que o texto sexa detectado, de 0 a 1. Os valores máis baixos detectarán máis texto, pero poden producir falsos positivos.",
"machine_learning_ocr_min_recognition_score": "Puntuación mínima de recoñecemento",
"machine_learning_ocr_min_score_recognition_description": "Puntuación mínima de confianza para que o texto detectado sexa recoñecido, de 0 a 1. Os valores máis baixos recoñecerán máis texto, pero poden producir falsos positivos.",
"machine_learning_ocr_model": "Modelo OCR",
"machine_learning_ocr_model_description": "Os modelos de servidor son máis precisos que os modelos móbiles, pero tardan máis en procesarse e usan máis memoria.",
"machine_learning_settings": "Configuración da Aprendizaxe Automática",
"machine_learning_settings_description": "Xestionar funcións e configuracións da aprendizaxe automática",
"machine_learning_smart_search": "Busca Intelixente",
@@ -210,6 +222,8 @@
"notification_email_ignore_certificate_errors_description": "Ignorar erros de validación do certificado TLS (non recomendado)",
"notification_email_password_description": "Contrasinal a usar ao autenticarse co servidor de correo electrónico",
"notification_email_port_description": "Porto do servidor de correo electrónico (p. ex. 25, 465 ou 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Usar SMTPS (SMTP sobre TLS)",
"notification_email_sent_test_email_button": "Enviar correo de proba e gardar",
"notification_email_setting_description": "Configuración para enviar notificacións por correo electrónico",
"notification_email_test_email": "Enviar correo de proba",
@@ -242,6 +256,7 @@
"oauth_storage_quota_default_description": "Cota en GiB a empregar cando non se proporciona ningunha declaración.",
"oauth_timeout": "Tempo máximo de espera da solicitude",
"oauth_timeout_description": "Tempo máximo de espera para as solicitudes en milisegundos",
"ocr_job_description": "Emprega aprendizaxe automática para recoñecer texto en imaxes",
"password_enable_description": "Iniciar sesión con correo electrónico e contrasinal",
"password_settings": "Inicio de sesión con contrasinal",
"password_settings_description": "Xestionar a configuración de inicio de sesión con contrasinal",
@@ -273,7 +288,7 @@
"storage_template_date_time_sample": "Tempo de mostra {date}",
"storage_template_enable_description": "Activar o motor de modelos de almacenamento",
"storage_template_hash_verification_enabled": "Verificación de hash activada",
"storage_template_hash_verification_enabled_description": "Activa a verificación de hash. Non desactive isto a menos que estea seguro das implicacións.",
"storage_template_hash_verification_enabled_description": "Activa a verificación de hash. Non desactive isto a menos que estea seguro das implicacións",
"storage_template_migration": "Migración do modelo de almacenamento",
"storage_template_migration_description": "Aplicar o <link>{template}</link> actual aos activos cargados previamente",
"storage_template_migration_info": "O modelo de almacenamento converterá todas as extensións a minúsculas. Os cambios no modelo só se aplicarán aos activos novos. Para aplicar retroactivamente o modelo aos activos cargados previamente, execute o <link>{job}</link>.",
@@ -332,7 +347,7 @@
"transcoding_max_b_frames": "Máximo de B-frames",
"transcoding_max_b_frames_description": "Valores máis altos melloran a eficiencia da compresión, pero ralentizan a codificación. Pode non ser compatible coa aceleración por hardware en dispositivos máis antigos. 0 desactiva os B-frames, mentres que -1 establece este valor automaticamente.",
"transcoding_max_bitrate": "Bitrate máximo",
"transcoding_max_bitrate_description": "Establecer un bitrate máximo pode facer que os tamaños dos ficheiros sexan máis predicibles a un custo menor para a calidade. A 720p, os valores típicos son 2600 kbit/s para VP9 ou HEVC, ou 4500 kbit/s para H.264. Desactivado se se establece en 0.",
"transcoding_max_bitrate_description": "Establecer unha taxa de bits máxima pode facer que os tamaños dos ficheiros sexan máis predicibles a un custo menor na calidade. En 720p, os valores típicos son 2600 kbit/s para VP9 ou HEVC, ou 4500 kbit/s para H.264. Desactivado se se establece en 0. Cando non se especifica unha unidade, asúmese k (para kbit/s); polo tanto, 5000, 5000k e 5M (para Mbit/s) son equivalentes.",
"transcoding_max_keyframe_interval": "Intervalo máximo de fotogramas clave",
"transcoding_max_keyframe_interval_description": "Establece a distancia máxima de fotogramas entre fotogramas clave. Valores máis baixos empeoran a eficiencia da compresión, pero melloran os tempos de busca e poden mellorar a calidade en escenas con movemento rápido. 0 establece este valor automaticamente.",
"transcoding_optimal_description": "Vídeos cunha resolución superior á obxectivo ou que non estean nun formato aceptado",
@@ -350,7 +365,7 @@
"transcoding_target_resolution": "Resolución obxectivo",
"transcoding_target_resolution_description": "Resolucións máis altas poden preservar máis detalles pero tardan máis en codificarse, teñen tamaños de ficheiro máis grandes e poden reducir a capacidade de resposta da aplicación.",
"transcoding_temporal_aq": "AQ Temporal",
"transcoding_temporal_aq_description": "Aplícase só a NVENC. Aumenta a calidade de escenas de alto detalle e baixo movemento. Pode non ser compatible con dispositivos máis antigos.",
"transcoding_temporal_aq_description": "Aplícase só a NVENC. A Cuantización Adaptativa Temporal aumenta a calidade das escenas con moito detalle e pouco movemento. Pode que non sexa compatible con dispositivos máis antigos.",
"transcoding_threads": "Fíos",
"transcoding_threads_description": "Valores máis altos levan a unha codificación máis rápida, pero deixan menos marxe para que o servidor procese outras tarefas mentres está activo. Este valor non debería ser maior que o número de núcleos da CPU. Maximiza a utilización se se establece en 0.",
"transcoding_tone_mapping": "Mapeo de tons",
@@ -401,11 +416,11 @@
"advanced_settings_prefer_remote_subtitle": "Algúns dispositivos tardan moito en cargar as miniaturas de ficheiros locais. Active esta opción para cargar imaxes remotas no seu lugar.",
"advanced_settings_prefer_remote_title": "Preferir imaxes remotas",
"advanced_settings_proxy_headers_subtitle": "Definir cabeceiras de proxy que Immich debería enviar con cada solicitude de rede",
"advanced_settings_proxy_headers_title": "Cabeceiras de Proxy",
"advanced_settings_proxy_headers_title": "Cabeceiras de proxy personalizadas [EXPERIMENTAL]",
"advanced_settings_readonly_mode_subtitle": "Activa o modo de só lectura, no que as fotos só se poden visualizar; opcións como seleccionar varias imaxes, compartir, enviar a outros dispositivos ou eliminar están deshabilitadas. Active/desactive o modo de só lectura a través do avatar do usuario na pantalla principal",
"advanced_settings_readonly_mode_title": "Modo de só lectura",
"advanced_settings_self_signed_ssl_subtitle": "Omite a verificación do certificado SSL para o punto final do servidor. Requirido para certificados autofirmados.",
"advanced_settings_self_signed_ssl_title": "Permitir certificados SSL autofirmados",
"advanced_settings_self_signed_ssl_title": "Permitir certificados SSL autofirmados [EXPERIMENTAL]",
"advanced_settings_sync_remote_deletions_subtitle": "Eliminar ou restaurar automaticamente un activo neste dispositivo cando esa acción se realiza na web",
"advanced_settings_sync_remote_deletions_title": "Sincronizar eliminacións remotas [EXPERIMENTAL]",
"advanced_settings_tile_subtitle": "Configuración de usuario avanzado",
@@ -414,6 +429,7 @@
"age_months": "Idade: {months, plural, one {# mes} other {# meses}}",
"age_year_months": "Idade: 1 ano e {months, plural, one {# mes} other {# meses}}",
"age_years": "Idade: {years, plural, one {# ano} other {# anos}}",
"album": "Álbum",
"album_added": "Álbum engadido",
"album_added_notification_setting_description": "Recibir unha notificación por correo electrónico cando sexa engadido a un álbum compartido",
"album_cover_updated": "Portada do álbum actualizada",
@@ -459,16 +475,21 @@
"allow_edits": "Permitir edicións",
"allow_public_user_to_download": "Permitir que o usuario público descargue",
"allow_public_user_to_upload": "Permitir que o usuario público cargue",
"allowed": "Permitido",
"alt_text_qr_code": "Imaxe de código QR",
"anti_clockwise": "Sentido antihorario",
"api_key": "Chave API",
"api_key_description": "Este valor só se mostrará unha vez. Asegúrese de copialo antes de pechar a xanela.",
"api_key_empty": "O nome da súa chave API non pode estar baleiro",
"api_keys": "Chaves API",
"app_architecture_variant": "Variante (Arquitectura)",
"app_bar_signout_dialog_content": "Está seguro de que quere pechar sesión?",
"app_bar_signout_dialog_ok": "Si",
"app_bar_signout_dialog_title": "Pechar sesión",
"app_download_links": "Ligazóns de Descarga da Aplicación",
"app_settings": "Configuración da Aplicación",
"app_stores": "Tendas de aplicacións",
"app_update_available": "Hai unha actualización da aplicación dispoñible",
"appears_in": "Aparece en",
"apply_count": "Aplicar ({count, number})",
"archive": "Arquivo",
@@ -552,6 +573,7 @@
"backup_albums_sync": "Sincronización de álbums da copia de seguridade",
"backup_all": "Todo",
"backup_background_service_backup_failed_message": "Erro ao facer copia de seguridade dos activos. Reintentando…",
"backup_background_service_complete_notification": "Copia de seguridade dos recursos completada",
"backup_background_service_connection_failed_message": "Erro ao conectar co servidor. Reintentando…",
"backup_background_service_current_upload_notification": "Subindo {filename}",
"backup_background_service_default_notification": "Comprobando novos activos…",
@@ -661,6 +683,8 @@
"change_password_description": "Esta é a primeira vez que inicia sesión no sistema ou solicitouse un cambio do seu contrasinal. Introduza o novo contrasinal a continuación.",
"change_password_form_confirm_password": "Confirmar Contrasinal",
"change_password_form_description": "Ola {name},\n\nEsta é a primeira vez que inicia sesión no sistema ou solicitouse un cambio do seu contrasinal. Introduza o novo contrasinal a continuación.",
"change_password_form_log_out": "Pechar sesión en todos os outros dispositivos",
"change_password_form_log_out_description": "Recoméndase pechar sesión en todos os outros dispositivos",
"change_password_form_new_password": "Novo Contrasinal",
"change_password_form_password_mismatch": "Os contrasinais non coinciden",
"change_password_form_reenter_new_password": "Reintroducir Novo Contrasinal",
@@ -687,8 +711,8 @@
"client_cert_import_success_msg": "Certificado de cliente importado",
"client_cert_invalid_msg": "Ficheiro de certificado inválido ou contrasinal incorrecto",
"client_cert_remove_msg": "Certificado de cliente eliminado",
"client_cert_subtitle": "Só admite o formato PKCS12 (.p12, .pfx). A importación/eliminación de certificados está dispoñible antes de iniciar sesión",
"client_cert_title": "Certificado de Cliente SSL",
"client_cert_subtitle": "Soporta só o formato PKCS12 (.p12, .pfx). A importación ou eliminación de certificados está dispoñible antes de iniciar sesión",
"client_cert_title": "Certificado de cliente SSL [EXPERIMENTAL]",
"clockwise": "Sentido horario",
"close": "Pechar",
"collapse": "Contraer",
@@ -700,7 +724,6 @@
"comments_and_likes": "Comentarios e Gústames",
"comments_are_disabled": "Os comentarios están desactivados",
"common_create_new_album": "Crear novo álbum",
"common_server_error": "Por favor, comprobe a súa conexión de rede, asegúrese de que o servidor sexa accesible e que as versións da aplicación/servidor sexan compatibles.",
"completed": "Completado",
"confirm": "Confirmar",
"confirm_admin_password": "Confirmar Contrasinal do Administrador",
@@ -739,6 +762,7 @@
"create": "Crear",
"create_album": "Crear álbum",
"create_album_page_untitled": "Sen título",
"create_api_key": "Crear chave API",
"create_library": "Crear Biblioteca",
"create_link": "Crear ligazón",
"create_link_to_share": "Crear ligazón para compartir",
@@ -768,6 +792,7 @@
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Escuro",
"dark_theme": "Alternar tema escuro",
"date": "Data",
"date_after": "Data posterior a",
"date_and_time": "Data e Hora",
"date_before": "Data anterior a",
@@ -870,8 +895,6 @@
"edit_description_prompt": "Por favor, seleccione unha nova descrición:",
"edit_exclusion_pattern": "Editar patrón de exclusión",
"edit_faces": "Editar caras",
"edit_import_path": "Editar ruta de importación",
"edit_import_paths": "Editar Rutas de Importación",
"edit_key": "Editar chave",
"edit_link": "Editar ligazón",
"edit_location": "Editar localización",
@@ -882,7 +905,6 @@
"edit_tag": "Editar etiqueta",
"edit_title": "Editar Título",
"edit_user": "Editar usuario",
"edited": "Editado",
"editor": "Editor",
"editor_close_without_save_prompt": "Os cambios non se gardarán",
"editor_close_without_save_title": "Pechar editor?",
@@ -944,7 +966,6 @@
"failed_to_stack_assets": "Erro ao apilar activos",
"failed_to_unstack_assets": "Erro ao desapilar activos",
"failed_to_update_notification_status": "Erro ao actualizar o estado das notificacións",
"import_path_already_exists": "Esta ruta de importación xa existe.",
"incorrect_email_or_password": "Correo electrónico ou contrasinal incorrectos",
"paths_validation_failed": "{paths, plural, one {# ruta fallou} other {# rutas fallaron}} na validación",
"profile_picture_transparent_pixels": "As imaxes de perfil non poden ter píxeles transparentes. Por favor, faga zoom e/ou mova a imaxe.",
@@ -954,7 +975,6 @@
"unable_to_add_assets_to_shared_link": "Non se puideron engadir activos á ligazón compartida",
"unable_to_add_comment": "Non se puido engadir o comentario",
"unable_to_add_exclusion_pattern": "Non se puido engadir o patrón de exclusión",
"unable_to_add_import_path": "Non se puido engadir a ruta de importación",
"unable_to_add_partners": "Non se puideron engadir compañeiros/as",
"unable_to_add_remove_archive": "Non se puido {archived, select, true {eliminar activo do} other {engadir activo ao}} arquivo",
"unable_to_add_remove_favorites": "Non se puido {favorite, select, true {engadir activo a} other {eliminar activo de}} favoritos",
@@ -977,12 +997,10 @@
"unable_to_delete_asset": "Non se puido eliminar o activo",
"unable_to_delete_assets": "Erro ao eliminar activos",
"unable_to_delete_exclusion_pattern": "Non se puido eliminar o patrón de exclusión",
"unable_to_delete_import_path": "Non se puido eliminar a ruta de importación",
"unable_to_delete_shared_link": "Non se puido eliminar a ligazón compartida",
"unable_to_delete_user": "Non se puido eliminar o usuario",
"unable_to_download_files": "Non se puideron descargar os ficheiros",
"unable_to_edit_exclusion_pattern": "Non se puido editar o patrón de exclusión",
"unable_to_edit_import_path": "Non se puido editar a ruta de importación",
"unable_to_empty_trash": "Non se puido baleirar o lixo",
"unable_to_enter_fullscreen": "Non se puido entrar en pantalla completa",
"unable_to_exit_fullscreen": "Non se puido saír da pantalla completa",
@@ -1038,6 +1056,7 @@
"exif_bottom_sheet_description_error": "Erro ao actualizar a descrición",
"exif_bottom_sheet_details": "DETALLES",
"exif_bottom_sheet_location": "LOCALIZACIÓN",
"exif_bottom_sheet_no_description": "Sen descrición",
"exif_bottom_sheet_people": "PERSOAS",
"exif_bottom_sheet_person_add_person": "Engadir nome",
"exit_slideshow": "Saír da Presentación",
@@ -1076,6 +1095,7 @@
"features_setting_description": "Xestionar as funcións da aplicación",
"file_name": "Nome do ficheiro",
"file_name_or_extension": "Nome do ficheiro ou extensión",
"file_size": "Tamaño do arquivo",
"filename": "Nome do ficheiro",
"filetype": "Tipo de ficheiro",
"filter": "Filtro",
@@ -1115,11 +1135,10 @@
"hash_asset": "Facer hash do recurso",
"hashed_assets": "Recursos cun hash",
"hashing": "Aplicando hash",
"header_settings_add_header_tip": "Engadir Cabeceira",
"header_settings_add_header_tip": "Engadir cabeceira",
"header_settings_field_validator_msg": "O valor non pode estar baleiro",
"header_settings_header_name_input": "Nome da cabeceira",
"header_settings_header_value_input": "Valor da cabeceira",
"headers_settings_tile_subtitle": "Definir cabeceiras de proxy que a aplicación debería enviar con cada solicitude de rede",
"headers_settings_tile_title": "Cabeceiras de proxy personalizadas",
"hi_user": "Ola {name} ({email})",
"hide_all_people": "Ocultar todas as persoas",
@@ -1172,6 +1191,8 @@
"import_path": "Ruta de importación",
"in_albums": "En {count, plural, one {# álbum} other {# álbums}}",
"in_archive": "No arquivo",
"in_year": "No {year}",
"in_year_selector": "No",
"include_archived": "Incluír arquivados",
"include_shared_albums": "Incluír álbums compartidos",
"include_shared_partner_assets": "Incluír activos de compañeiro/a compartidos",
@@ -1208,6 +1229,7 @@
"language_setting_description": "Seleccione a súa lingua preferida",
"large_files": "Ficheiros Grandes",
"last": "Último/a",
"last_months": "{count, plural, one {O mes pasado} other {Os últimos # meses}}",
"last_seen": "Visto por última vez",
"latest_version": "Última Versión",
"latitude": "Latitude",
@@ -1240,6 +1262,7 @@
"local_media_summary": "Resumo de Contido Local",
"local_network": "Rede local",
"local_network_sheet_info": "A aplicación conectarase ao servidor a través desta URL cando use a rede wifi especificada",
"location": "Localización",
"location_permission": "Permiso de localización",
"location_permission_content": "Para usar a función de cambio automático, Immich necesita permiso de localización precisa para poder ler o nome da rede wifi actual",
"location_picker_choose_on_map": "Elixir no mapa",
@@ -1289,6 +1312,10 @@
"main_menu": "Menú principal",
"make": "Marca",
"manage_geolocation": "Xestionar a localización",
"manage_media_access_rationale": "Requírese este permiso para xestionar correctamente o traslado dos recursos ao lixo e a súa restauración desde el.",
"manage_media_access_settings": "Abrir axustes",
"manage_media_access_subtitle": "Permitir que a aplicación Immich xestione e mova ficheiros multimedia.",
"manage_media_access_title": "Acceso á xestión de medios",
"manage_shared_links": "Xestionar ligazóns compartidas",
"manage_sharing_with_partners": "Xestionar compartición con compañeiros/as",
"manage_the_app_settings": "Xestionar a configuración da aplicación",
@@ -1344,12 +1371,15 @@
"minute": "Minuto",
"minutes": "Minutos",
"missing": "Faltantes",
"mobile_app": "Aplicación Móbil",
"mobile_app_download_onboarding_note": "Descarga a aplicación móbil complementaria usando as seguintes opcións",
"model": "Modelo",
"month": "Mes",
"monthly_title_text_date_format": "MMMM a",
"more": "Máis",
"move": "Mover",
"move_off_locked_folder": "Mover fóra do cartafol bloqueado",
"move_to": "Mover a",
"move_to_lock_folder_action_prompt": "{count} engadido/a ao cartafol bloqueado",
"move_to_locked_folder": "Mover ao cartafol bloqueado",
"move_to_locked_folder_confirmation": "Estas fotos e vídeo eliminaranse de todos os álbums e só serán visíbeis dende o cartafol bloqueado",
@@ -1362,6 +1392,8 @@
"my_albums": "Os meus álbums",
"name": "Nome",
"name_or_nickname": "Nome ou alcume",
"navigate": "Navegar",
"navigate_to_time": "Navegar ata Hora",
"network_requirement_photos_upload": "Usar datos móbiles para facer copia de seguridade das fotos",
"network_requirement_videos_upload": "Usar datos móbiles para facer copia de seguridade dos vídeos",
"network_requirements": "Requisitos de rede",
@@ -1371,11 +1403,13 @@
"never": "Nunca",
"new_album": "Novo Álbum",
"new_api_key": "Nova Chave API",
"new_date_range": "Novo rango de datas",
"new_password": "Novo contrasinal",
"new_person": "Nova persoa",
"new_pin_code": "Novo código PIN",
"new_pin_code_subtitle": "Esta é a túa primeira vez accedendo á carpeta segura. Crea un código PIN para acceder de maneira segura a esta páxina",
"new_timeline": "Nova liña de tempo",
"new_update": "Nova actualización",
"new_user_created": "Novo usuario creado",
"new_version_available": "NOVA VERSIÓN DISPOÑIBLE",
"newest_first": "Máis recentes primeiro",
@@ -1389,22 +1423,32 @@
"no_assets_message": "PREMA PARA CARGAR A SÚA PRIMEIRA FOTO",
"no_assets_to_show": "Non hai activos para mostrar",
"no_cast_devices_found": "Non se atoparon dispositivos de transmisión",
"no_checksum_local": "Non hai suma de verificación dispoñible - non se poden obter os activos locais",
"no_checksum_remote": "Non hai suma de verificación dispoñible - non se pode obter o activo remoto",
"no_devices": "Dispositivos non autorizados",
"no_duplicates_found": "Non se atoparon duplicados.",
"no_exif_info_available": "Non hai información EXIF dispoñible",
"no_explore_results_message": "Suba máis fotos para explorar a súa colección.",
"no_favorites_message": "Engada favoritos para atopar rapidamente as súas mellores fotos e vídeos",
"no_libraries_message": "Cree unha biblioteca externa para ver as súas fotos e vídeos",
"no_local_assets_found": "Non se atoparon elementos locais con esta suma de comprobación",
"no_locked_photos_message": "As fotos e vídeos no cartafol con chave están ocultos e non aparecerán mentres navegas ou buscas na túa biblioteca.",
"no_name": "Sen Nome",
"no_notifications": "Sen notificacións",
"no_people_found": "Non se atoparon persoas coincidentes",
"no_places": "Sen lugares",
"no_remote_assets_found": "Non se atoparon activos remotos con esta suma de verificación",
"no_results": "Sen resultados",
"no_results_description": "Probe cun sinónimo ou palabra chave máis xeral",
"no_shared_albums_message": "Cree un álbum para compartir fotos e vídeos con persoas na súa rede",
"no_uploads_in_progress": "Non hai cargas en curso",
"not_allowed": "Non permitido",
"not_available": "Non dispoñible",
"not_in_any_album": "Non está en ningún álbum",
"not_selected": "Non seleccionado",
"note_apply_storage_label_to_previously_uploaded assets": "Nota: Para aplicar a Etiqueta de Almacenamento a activos cargados previamente, execute o",
"notes": "Notas",
"nothing_here_yet": "Aínda nada por aquí",
"notification_permission_dialog_content": "Para activar as notificacións, vaia a Axustes e seleccione permitir.",
"notification_permission_list_tile_content": "Conceda permiso para activar as notificacións.",
"notification_permission_list_tile_enable_button": "Activar Notificacións",
@@ -1412,14 +1456,22 @@
"notification_toggle_setting_description": "Activar notificacións por correo electrónico",
"notifications": "Notificacións",
"notifications_setting_description": "Xestionar notificacións",
"oauth": "OAuth",
"obtainium_configurator": "Configurador de Obtainium",
"obtainium_configurator_instructions": "Emprega Obtainium para instalar e actualizar a aplicación de Android directamente desde o lanzamento do GitHub de Immich. Crea unha chave API e selecciona unha variante para xerar o teu enlace de configuración de Obtainium",
"ocr": "OCR",
"official_immich_resources": "Recursos Oficiais de Immich",
"offline": "Fóra de liña",
"offset": "Desprazamento",
"ok": "Aceptar",
"oldest_first": "Máis antigos primeiro",
"on_this_device": "Neste dispositivo",
"onboarding": "Primeiros pasos",
"onboarding_locale_description": "Selecciona o teu idioma preferido. Podes cambialo máis tarde na túa configuración.",
"onboarding_privacy_description": "As seguintes funcións (opcionais) dependen de servizos externos e poden desactivarse en calquera momento na configuración da administración.",
"onboarding_server_welcome_description": "Imos configurar a túa instancia con algunhas opcións comúns.",
"onboarding_theme_description": "Elixa un tema de cor para a súa instancia. Pode cambialo máis tarde na súa configuración.",
"onboarding_user_welcome_description": "Imos comezar!",
"onboarding_welcome_user": "Benvido/a, {user}",
"online": "En liña",
"only_favorites": "Só favoritos",
@@ -1429,10 +1481,13 @@
"open_the_search_filters": "Abrir os filtros de busca",
"options": "Opcións",
"or": "ou",
"organize_into_albums": "Organizar en álbums",
"organize_into_albums_description": "Poñer as fotos existentes en álbums usando as opcións de sincronización actuais",
"organize_your_library": "Organizar a súa biblioteca",
"original": "orixinal",
"other": "Outro",
"other_devices": "Outros dispositivos",
"other_entities": "Outras entidades",
"other_variables": "Outras variables",
"owned": "Propio",
"owner": "Propietario",
@@ -1476,6 +1531,8 @@
"permanently_delete_assets_prompt": "Está seguro de que quere eliminar permanentemente {count, plural, one {este activo?} other {estes <b>#</b> activos?}} Isto tamén {count, plural, one {o eliminará do seu} other {os eliminará dos seus}} álbum(s).",
"permanently_deleted_asset": "Activo eliminado permanentemente",
"permanently_deleted_assets_count": "Eliminados permanentemente {count, plural, one {# activo} other {# activos}}",
"permission": "Permiso",
"permission_empty": "O teu permiso non debe estar baleiro",
"permission_onboarding_back": "Atrás",
"permission_onboarding_continue_anyway": "Continuar de todos os xeitos",
"permission_onboarding_get_started": "Comezar",
@@ -1485,6 +1542,9 @@
"permission_onboarding_permission_limited": "Permiso limitado. Para permitir que Immich faga copia de seguridade e xestione toda a súa colección da galería, conceda permisos de fotos e vídeos en Configuración.",
"permission_onboarding_request": "Immich require permiso para ver as súas fotos e vídeos.",
"person": "Persoa",
"person_age_months": "{months, plural, one {# mes} other {# meses}} de idade",
"person_age_year_months": "1 ano, {months, plural, one {# mes} other {# meses}} de idade",
"person_age_years": "{years, plural, one {# ano} other {# anos}} de idade",
"person_birthdate": "Nacido/a o {date}",
"person_hidden": "{name}{hidden, select, true { (oculto)} other {}}",
"photo_shared_all_users": "Parece que compartiu as súas fotos con todos os usuarios ou non ten ningún usuario co que compartir.",
@@ -1493,6 +1553,12 @@
"photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Fotos}}",
"photos_from_previous_years": "Fotos de anos anteriores",
"pick_a_location": "Elixir unha localización",
"pick_custom_range": "Rango personalizado",
"pick_date_range": "Seleccionar un rango de datas",
"pin_code_changed_successfully": "Código PIN cambiado correctamente",
"pin_code_reset_successfully": "Código PIN restablecido correctamente",
"pin_code_setup_successfully": "Código PIN configurado correctamente",
"pin_verification": "Verificación do código PIN",
"place": "Lugar",
"places": "Lugares",
"places_count": "{count, plural, one {{count, number} Lugar} other {{count, number} Lugares}}",
@@ -1500,22 +1566,29 @@
"play_memories": "Reproducir recordos",
"play_motion_photo": "Reproducir Foto en Movemento",
"play_or_pause_video": "Reproducir ou pausar vídeo",
"play_original_video": "Reproducir o vídeo orixinal",
"play_original_video_setting_description": "Preferir a reprodución dos vídeos orixinais en vez dos vídeos transcodificados. Se o recurso orixinal non é compatible, pode que non se reproduza correctamente.",
"play_transcoded_video": "Reproducir vídeo transcodificado",
"please_auth_to_access": "Por favor, autentícate para acceder",
"port": "Porto",
"preferences_settings_subtitle": "Xestionar as preferencias da aplicación",
"preferences_settings_title": "Preferencias",
"preparing": "Preparando",
"preset": "Preaxuste",
"preview": "Vista previa",
"previous": "Anterior",
"previous_memory": "Recordo anterior",
"previous_or_next_day": "Día seguinte / Día anterior",
"previous_or_next_month": "Mes seguinte / Mes anterior",
"previous_or_next_photo": "Foto anterior ou seguinte",
"previous_or_next_year": "Ano seguinte / Ano anterior",
"primary": "Principal",
"privacy": "Privacidade",
"profile": "Perfil",
"profile_drawer_app_logs": "Rexistros",
"profile_drawer_client_out_of_date_major": "A aplicación móbil está desactualizada. Por favor, actualice á última versión maior.",
"profile_drawer_client_out_of_date_minor": "A aplicación móbil está desactualizada. Por favor, actualice á última versión menor.",
"profile_drawer_client_server_up_to_date": "Cliente e Servidor están actualizados",
"profile_drawer_server_out_of_date_major": "O servidor está desactualizado. Por favor, actualice á última versión maior.",
"profile_drawer_server_out_of_date_minor": "O servidor está desactualizado. Por favor, actualice á última versión menor.",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Modo só lectura activado. Mantén premido o ícone do avatar do usuario para saír.",
"profile_image_of_user": "Imaxe de perfil de {user}",
"profile_picture_set": "Imaxe de perfil establecida.",
"public_album": "Álbum público",
@@ -1534,6 +1607,7 @@
"purchase_failed_activation": "Erro ao activar! Por favor, comprobe o seu correo electrónico para a chave do produto correcta!",
"purchase_individual_description_1": "Para un individuo",
"purchase_individual_description_2": "Estado de seguidor/a",
"purchase_individual_title": "Individual",
"purchase_input_suggestion": "Ten unha chave de produto? Introduza a chave a continuación",
"purchase_license_subtitle": "Apoie Immich para contribuír ao desenvolvemento continuado do servizo",
"purchase_lifetime_description": "Contribución vitalicia",
@@ -1551,12 +1625,17 @@
"purchase_server_description_2": "Estado de seguidor/a",
"purchase_server_title": "Servidor",
"purchase_settings_server_activated": "A chave do produto do servidor é xestionada polo administrador",
"query_asset_id": "Consultar o ID do activo",
"queue_status": "Pondo en cola {count}/{total}",
"rating": "Clasificación por estrelas",
"rating_clear": "Borrar clasificación",
"rating_count": "{count, plural, one {# estrela} other {# estrelas}}",
"rating_description": "Mostrar a clasificación EXIF no panel de información",
"reaction_options": "Opcións de reacción",
"read_changelog": "Ler Rexistro de Cambios",
"readonly_mode_disabled": "Modo só lectura desactivado",
"readonly_mode_enabled": "Modo só lectura activado",
"ready_for_upload": "Listo para a carga",
"reassign": "Reasignar",
"reassigned_assets_to_existing_person": "Reasignados {count, plural, one {# activo} other {# activos}} a {name, select, null {unha persoa existente} other {{name}}}",
"reassigned_assets_to_new_person": "Reasignados {count, plural, one {# activo} other {# activos}} a unha nova persoa",
@@ -1579,6 +1658,9 @@
"refreshing_faces": "Actualizando caras",
"refreshing_metadata": "Actualizando metadatos",
"regenerating_thumbnails": "Rexenerando miniaturas",
"remote": "Remoto",
"remote_assets": "Activos Remotos",
"remote_media_summary": "Resumo de Medios Remotos",
"remove": "Eliminar",
"remove_assets_album_confirmation": "Está seguro de que quere eliminar {count, plural, one {# activo} other {# activos}} do álbum?",
"remove_assets_shared_link_confirmation": "Está seguro de que quere eliminar {count, plural, one {# activo} other {# activos}} desta ligazón compartida?",
@@ -1586,10 +1668,15 @@
"remove_custom_date_range": "Eliminar rango de datas personalizado",
"remove_deleted_assets": "Eliminar Activos Eliminados",
"remove_from_album": "Eliminar do álbum",
"remove_from_album_action_prompt": "{count} eliminado(s) do álbum",
"remove_from_favorites": "Eliminar de favoritos",
"remove_from_lock_folder_action_prompt": "{count} eliminado(s) do cartafol con chave",
"remove_from_locked_folder": "Eliminar do cartafol con chave",
"remove_from_locked_folder_confirmation": "Estás seguro de que queres mover estas fotos e vídeos fóra do cartafol con chave? Serán visibles na túa biblioteca.",
"remove_from_shared_link": "Eliminar da ligazón compartida",
"remove_memory": "Eliminar recordo",
"remove_photo_from_memory": "Eliminar foto deste recordo",
"remove_tag": "Eliminar a etiqueta",
"remove_url": "Eliminar URL",
"remove_user": "Eliminar usuario",
"removed_api_key": "Chave API eliminada: {name}",
@@ -1610,24 +1697,38 @@
"reset": "Restablecer",
"reset_password": "Restablecer contrasinal",
"reset_people_visibility": "Restablecer visibilidade das persoas",
"reset_pin_code": "Restablecer o código PIN",
"reset_pin_code_description": "Se esqueciches o teu código PIN, podes contactar co administrador do servidor para restablecelo",
"reset_pin_code_success": "Código PIN restablecido correctamente",
"reset_pin_code_with_password": "Sempre podes restablecer o teu código PIN coa túa contrasinal",
"reset_sqlite": "Restablecer a Base de Datos SQLite",
"reset_sqlite_confirmation": "Estás seguro de que queres restablecer a base de datos SQLite? Terás que pechar a sesión e iniciar sesión de novo para sincronizar os datos outra vez",
"reset_sqlite_success": "Base de datos SQLite restablecida correctamente",
"reset_to_default": "Restablecer ao predeterminado",
"resolution": "Resolución",
"resolve_duplicates": "Resolver duplicados",
"resolved_all_duplicates": "Resolvéronse todos os duplicados",
"restore": "Restaurar",
"restore_all": "Restaurar todo",
"restore_trash_action_prompt": "{count} restaurado(s) do lixo",
"restore_user": "Restaurar usuario",
"restored_asset": "Activo restaurado",
"resume": "Reanudar",
"resume_paused_jobs": "Retomar {count, plural, one {# traballo pausado} other {# traballos pausados}}",
"retry_upload": "Reintentar carga",
"review_duplicates": "Revisar duplicados",
"review_large_files": "Revisar ficheiros grandes",
"role": "Rol",
"role_editor": "Editor",
"role_viewer": "Visor",
"running": "Executándose",
"save": "Gardar",
"save_to_gallery": "Gardar na galería",
"saved": "Gardo",
"saved_api_key": "Chave API gardada",
"saved_profile": "Perfil gardado",
"saved_settings": "Configuración gardada",
"say_something": "Dicir algo...",
"say_something": "Dicir algo",
"scaffold_body_error_occurred": "Ocorreu un erro",
"scan_all_libraries": "Escanear Todas as Bibliotecas",
"scan_library": "Escanear",
@@ -1640,6 +1741,9 @@
"search_by_description_example": "Día de sendeirismo en Sapa",
"search_by_filename": "Buscar por nome de ficheiro ou extensión",
"search_by_filename_example": "p. ex. IMG_1234.JPG ou PNG",
"search_by_ocr": "Buscar mediante OCR",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Buscar modelo de lente...",
"search_camera_make": "Buscar marca de cámara...",
"search_camera_model": "Buscar modelo de cámara...",
"search_city": "Buscar cidade...",
@@ -1656,6 +1760,7 @@
"search_filter_location_title": "Seleccionar localización",
"search_filter_media_type": "Tipo de Medio",
"search_filter_media_type_title": "Seleccionar tipo de medio",
"search_filter_ocr": "Buscar por OCR",
"search_filter_people_title": "Seleccionar persoas",
"search_for": "Buscar por",
"search_for_existing_person": "Buscar persoa existente",
@@ -1670,6 +1775,7 @@
"search_page_no_places": "Non hai Información de Lugares Dispoñible",
"search_page_screenshots": "Capturas de pantalla",
"search_page_search_photos_videos": "Busca as súas fotos e vídeos",
"search_page_selfies": "Selfies",
"search_page_things": "Cousas",
"search_page_view_all_button": "Ver todo",
"search_page_your_activity": "A súa actividade",
@@ -1693,6 +1799,7 @@
"select_album_cover": "Seleccionar portada do álbum",
"select_all": "Seleccionar todo",
"select_all_duplicates": "Seleccionar todos os duplicados",
"select_all_in": "Seleccionar todo en {group}",
"select_avatar_color": "Seleccionar cor do avatar",
"select_face": "Seleccionar cara",
"select_featured_photo": "Seleccionar foto destacada",
@@ -1700,11 +1807,13 @@
"select_keep_all": "Seleccionar conservar todo",
"select_library_owner": "Seleccionar propietario da biblioteca",
"select_new_face": "Seleccionar nova cara",
"select_person_to_tag": "Seleccionar unha persoa para etiquetar",
"select_photos": "Seleccionar fotos",
"select_trash_all": "Seleccionar mover todo ao lixo",
"select_user_for_sharing_page_err_album": "Erro ao crear o álbum",
"selected": "Seleccionado",
"selected_count": "{count, plural, other {# seleccionados}}",
"selected_gps_coordinates": "Coordenadas GPS seleccionadas",
"send_message": "Enviar mensaxe",
"send_welcome_email": "Enviar correo electrónico de benvida",
"server_endpoint": "Punto Final do Servidor",
@@ -1712,7 +1821,9 @@
"server_info_box_server_url": "URL do Servidor",
"server_offline": "Servidor Fóra de Liña",
"server_online": "Servidor En Liña",
"server_privacy": "Privacidade do Servidor",
"server_stats": "Estatísticas do Servidor",
"server_update_available": "Hai unha actualización do servidor dispoñible",
"server_version": "Versión do Servidor",
"set": "Establecer",
"set_as_album_cover": "Establecer como portada do álbum",
@@ -1721,6 +1832,7 @@
"set_date_of_birth": "Establecer data de nacemento",
"set_profile_picture": "Establecer imaxe de perfil",
"set_slideshow_to_fullscreen": "Poñer Presentación a pantalla completa",
"set_stack_primary_asset": "Establecer como activo principal",
"setting_image_viewer_help": "O visor de detalles carga primeiro a miniatura pequena, despois carga a vista previa de tamaño medio (se está activada), e finalmente carga o orixinal (se está activado).",
"setting_image_viewer_original_subtitle": "Activar para cargar a imaxe orixinal a resolución completa (grande!). Desactivar para reducir o uso de datos (tanto na rede como na caché do dispositivo).",
"setting_image_viewer_original_title": "Cargar imaxe orixinal",
@@ -1740,16 +1852,21 @@
"setting_notifications_subtitle": "Axustar as súas preferencias de notificación",
"setting_notifications_total_progress_subtitle": "Progreso xeral da carga (feitos/total activos)",
"setting_notifications_total_progress_title": "Mostrar progreso total da copia de seguridade en segundo plano",
"setting_video_viewer_auto_play_subtitle": "Reproducir vídeos automaticamente cando se abren",
"setting_video_viewer_auto_play_title": "Reproducir vídeos automaticamente",
"setting_video_viewer_looping_title": "Bucle",
"setting_video_viewer_original_video_subtitle": "Ao transmitir un vídeo desde o servidor, reproducir o orixinal aínda que haxa unha transcodificación dispoñible. Pode provocar buffering. Os vídeos dispoñibles localmente reprodúcense en calidade orixinal independentemente desta configuración.",
"setting_video_viewer_original_video_title": "Forzar vídeo orixinal",
"settings": "Configuración",
"settings_require_restart": "Por favor, reinicie Immich para aplicar esta configuración",
"settings_saved": "Configuración gardada",
"setup_pin_code": "Configurar un código PIN",
"share": "Compartir",
"share_action_prompt": "Compartidos {count} activos",
"share_add_photos": "Engadir fotos",
"share_assets_selected": "{count} seleccionados",
"share_dialog_preparing": "Preparando...",
"share_link": "Ligazón para Compartir",
"shared": "Compartido",
"shared_album_activities_input_disable": "O comentario está desactivado",
"shared_album_activity_remove_content": "Quere eliminar esta actividade?",
@@ -1767,6 +1884,7 @@
"shared_link_clipboard_copied_massage": "Copiado ao portapapeis",
"shared_link_clipboard_text": "Ligazón: {link}\nContrasinal: {password}",
"shared_link_create_error": "Erro ao crear ligazón compartida",
"shared_link_custom_url_description": "Acceder a esta ligazón compartida cun URL personalizado",
"shared_link_edit_description_hint": "Introduza a descrición da compartición",
"shared_link_edit_expire_after_option_day": "1 día",
"shared_link_edit_expire_after_option_days": "{count} días",
@@ -1789,8 +1907,10 @@
"shared_link_expires_second": "Caduca en {count} segundo",
"shared_link_expires_seconds": "Caduca en {count} segundos",
"shared_link_individual_shared": "Compartido individualmente",
"shared_link_info_chip_metadata": "EXIF",
"shared_link_manage_links": "Xestionar ligazóns Compartidas",
"shared_link_options": "Opcións da ligazón compartida",
"shared_link_password_description": "Requirir un contrasinal para acceder a esta ligazón compartida",
"shared_links": "Ligazóns compartidas",
"shared_links_description": "Compartir fotos e vídeos cunha ligazón",
"shared_photos_and_videos_count": "{assetCount, plural, other {# fotos e vídeos compartidos.}}",
@@ -1825,6 +1945,7 @@
"show_slideshow_transition": "Mostrar transición da presentación",
"show_supporter_badge": "Insignia de seguidor/a",
"show_supporter_badge_description": "Mostrar unha insignia de seguidor/a",
"show_text_search_menu": "Mostrar o menú de busca de texto",
"shuffle": "Aleatorio",
"sidebar": "Barra lateral",
"sidebar_display_description": "Mostrar unha ligazón á vista na barra lateral",
@@ -1840,12 +1961,14 @@
"sort_created": "Data de creación",
"sort_items": "Número de elementos",
"sort_modified": "Data de modificación",
"sort_newest": "Foto máis recente",
"sort_oldest": "Foto máis antiga",
"sort_people_by_similarity": "Ordenar persoas por similitude",
"sort_recent": "Foto máis recente",
"sort_title": "Título",
"source": "Fonte",
"stack": "Apilar",
"stack_action_prompt": "{count} apilados",
"stack_duplicates": "Apilar duplicados",
"stack_select_one_photo": "Seleccionar unha foto principal para a pila",
"stack_selected_photos": "Apilar fotos seleccionadas",
@@ -1853,16 +1976,20 @@
"stacktrace": "Rastro da Pila",
"start": "Iniciar",
"start_date": "Data de inicio",
"start_date_before_end_date": "A data de inicio debe ser anterior á data de fin",
"state": "Estado",
"status": "Estado",
"stop_casting": "Deixade de emitir",
"stop_motion_photo": "Deter Foto en Movemento",
"stop_photo_sharing": "Deixar de compartir as súas fotos?",
"stop_photo_sharing_description": "{partner} xa non poderá acceder ás súas fotos.",
"stop_sharing_photos_with_user": "Deixar de compartir as súas fotos con este usuario",
"storage": "Almacenamento",
"storage_label": "Etiqueta de almacenamento",
"storage_quota": "Cota de Almacenamento",
"storage_usage": "{used} de {available} usado",
"submit": "Enviar",
"success": "Éxito",
"suggestions": "Suxestións",
"sunrise_on_the_beach": "Amencer na praia",
"support": "Soporte",
@@ -1872,6 +1999,10 @@
"sync": "Sincronizar",
"sync_albums": "Sincronizar álbums",
"sync_albums_manual_subtitle": "Sincronizar todos os vídeos e fotos cargados aos álbums de copia de seguridade seleccionados",
"sync_local": "Sincronizar Local",
"sync_remote": "Sincronizar Remoto",
"sync_status": "Estado de Sincronización",
"sync_status_subtitle": "Ver e xestionar o sistema de sincronización",
"sync_upload_album_setting_subtitle": "Crear e subir as súas fotos e vídeos aos álbums seleccionados en Immich",
"tag": "Etiqueta",
"tag_assets": "Etiquetar activos",
@@ -1882,6 +2013,7 @@
"tag_updated": "Etiqueta actualizada: {tag}",
"tagged_assets": "Etiquetados {count, plural, one {# activo} other {# activos}}",
"tags": "Etiquetas",
"tap_to_run_job": "Tocar para executar tarefa",
"template": "Modelo",
"theme": "Tema",
"theme_selection": "Selección de tema",
@@ -1901,18 +2033,24 @@
"theme_setting_three_stage_loading_title": "Activar carga en tres etapas",
"they_will_be_merged_together": "Fusionaranse xuntos",
"third_party_resources": "Recursos de Terceiros",
"time": "Hora",
"time_based_memories": "Recordos baseados no tempo",
"time_based_memories_duration": "Número de segundos para mostrar cada imaxe.",
"timeline": "Liña de tempo",
"timezone": "Fuso horario",
"to_archive": "Arquivar",
"to_change_password": "Cambiar contrasinal",
"to_favorite": "Favorito",
"to_login": "Iniciar sesión",
"to_multi_select": "Para a selección múltiple",
"to_parent": "Ir ao pai",
"to_select": "Para seleccionar",
"to_trash": "Lixo",
"toggle_settings": "Alternar configuración",
"total": "Total",
"total_usage": "Uso total",
"trash": "Lixo",
"trash_action_prompt": "{count} movidos ao lixo",
"trash_all": "Mover Todo ao Lixo",
"trash_count": "Lixo ({count, number})",
"trash_delete_asset": "Mover ao Lixo/Eliminar Activo",
@@ -1926,10 +2064,17 @@
"trash_page_select_assets_btn": "Seleccionar activos",
"trash_page_title": "Lixo ({count})",
"trashed_items_will_be_permanently_deleted_after": "Os elementos no lixo eliminaranse permanentemente despois de {days, plural, one {# día} other {# días}}.",
"troubleshoot": "Solucionar problemas",
"type": "Tipo",
"unable_to_change_pin_code": "Non é posible cambiar o código PIN",
"unable_to_check_version": "Non se puido verificar a versión da aplicación ou do servidor",
"unable_to_setup_pin_code": "Non é posible configurar o código PIN",
"unarchive": "Desarquivar",
"unarchive_action_prompt": "{count} eliminados do Arquivo",
"unarchived_count": "{count, plural, other {Desarquivados #}}",
"undo": "Desfacer",
"unfavorite": "Desmarcar como favorito",
"unfavorite_action_prompt": "{count} eliminados de Favoritos",
"unhide_person": "Mostrar persoa",
"unknown": "Descoñecido",
"unknown_country": "País Descoñecido",
@@ -1945,15 +2090,23 @@
"unsaved_change": "Cambio sen gardar",
"unselect_all": "Deseleccionar todo",
"unselect_all_duplicates": "Deseleccionar todos os duplicados",
"unselect_all_in": "Desmarcar todo en {group}",
"unstack": "Desapilar",
"unstack_action_prompt": "{count} desapilados",
"unstacked_assets_count": "Desapilados {count, plural, one {# activo} other {# activos}}",
"untagged": "Sen etiquetar",
"up_next": "A continuación",
"update_location_action_prompt": "Actualizar a localización de {count} elementos seleccionados con:",
"updated_at": "Actualizado",
"updated_password": "Contrasinal actualizado",
"upload": "Subir",
"upload_action_prompt": "{count} en cola de espera para cargar",
"upload_concurrency": "Concorrencia de subida",
"upload_details": "Detalles da Carga",
"upload_dialog_info": "Quere facer copia de seguridade do(s) Activo(s) seleccionado(s) no servidor?",
"upload_dialog_title": "Subir Activo",
"upload_errors": "Subida completada con {count, plural, one {# erro} other {# erros}}. Actualice a páxina para ver os novos activos subidos.",
"upload_finished": "Carga finalizada",
"upload_progress": "Restantes {remaining, number} - Procesados {processed, number}/{total, number}",
"upload_skipped_duplicates": "Omitidos {count, plural, one {# activo duplicado} other {# activos duplicados}}",
"upload_status_duplicates": "Duplicados",
@@ -1962,7 +2115,10 @@
"upload_success": "Subida exitosa. Actualice a páxina para ver os novos activos subidos.",
"upload_to_immich": "Subir a Immich ({count})",
"uploading": "Subindo",
"uploading_media": "Cargando multimedia",
"url": "URL",
"usage": "Uso",
"use_biometric": "Usar biometría",
"use_current_connection": "usar conexión actual",
"use_custom_date_range": "Usar rango de datas personalizado no seu lugar",
"user": "Usuario",
@@ -1980,6 +2136,7 @@
"user_usage_stats_description": "Ver estatísticas de uso da conta",
"username": "Nome de usuario",
"users": "Usuarios",
"users_added_to_album_count": "Engadido/s {count, plural, one {# usuario} other {# usuarios}} ao álbum",
"utilities": "Utilidades",
"validate": "Validar",
"validate_endpoint_error": "Por favor, introduza unha URL válida",
@@ -2006,7 +2163,9 @@
"view_next_asset": "Ver seguinte activo",
"view_previous_asset": "Ver activo anterior",
"view_qr_code": "Ver código QR",
"view_similar_photos": "Ver fotos semellantes",
"view_stack": "Ver Pila",
"view_user": "Ver Usuario",
"viewer_remove_from_stack": "Eliminar da Pila",
"viewer_stack_use_as_main_asset": "Usar como Activo Principal",
"viewer_unstack": "Desapilar",
@@ -2017,10 +2176,13 @@
"welcome": "Benvido/a",
"welcome_to_immich": "Benvido/a a Immich",
"wifi_name": "Nome da wifi",
"workflow": "Fluxo de traballo",
"wrong_pin_code": "Código PIN incorrecto",
"year": "Ano",
"years_ago": "Hai {years, plural, one {# ano} other {# anos}}",
"yes": "Si",
"you_dont_have_any_shared_links": "Non ten ningunha ligazón compartida",
"your_wifi_name": "O nome da súa wifi",
"zoom_image": "Ampliar Imaxe"
"zoom_image": "Ampliar Imaxe",
"zoom_to_bounds": "Axustar ao perímetro"
}

View File

@@ -17,7 +17,6 @@
"add_birthday": "הוספת יום הולדת",
"add_endpoint": "הוסף כתובת URL",
"add_exclusion_pattern": "הוספת דפוס החרגה",
"add_import_path": "הוספת נתיב יבוא",
"add_location": "הוספת מיקום",
"add_more_users": "הוספת עוד משתמשים",
"add_partner": "הוספת שותף",
@@ -33,6 +32,7 @@
"add_to_albums": "הוספה לאלבומים",
"add_to_albums_count": "הוסף ({count}) לאלבום",
"add_to_shared_album": "הוספה לאלבום משותף",
"add_upload_to_stack": "הוסף את ההעלאה לערימה",
"add_url": "הוספת קישור",
"added_to_archive": "נוסף לארכיון",
"added_to_favorites": "נוסף למועדפים",
@@ -111,7 +111,6 @@
"jobs_failed": "{jobCount, plural, other {# נכשלו}}",
"library_created": "נוצרה ספרייה: {library}",
"library_deleted": "ספרייה נמחקה",
"library_import_path_description": "ציין תיקיה לייבוא. תיקייה זו, כולל תיקיות משנה, תיסרק עבור תמונות וסרטונים.",
"library_scanning": "סריקה תקופתית",
"library_scanning_description": "הגדר סריקת ספרייה תקופתית",
"library_scanning_enable_description": "אפשר סריקת ספרייה תקופתית",
@@ -119,7 +118,7 @@
"library_settings_description": "ניהול הגדרות ספרייה חיצונית",
"library_tasks_description": "סרוק ספריות חיצוניות עבור תמונות חדשות ו/או שהשתנו",
"library_watching_enable_description": "עקוב אחר שינויי קבצים בספריות חיצוניות",
"library_watching_settings": "צפיית ספרייה (ניסיוני)",
"library_watching_settings": "צפייה בספרייה [ניסיוני]",
"library_watching_settings_description": "עקוב אוטומטית אחר שינויי קבצים",
"logging_enable_description": "אפשר רישום ביומן",
"logging_level_description": "כאשר פועל, באיזה רמת יומן לתעד.",
@@ -153,6 +152,18 @@
"machine_learning_min_detection_score_description": "ציון ביטחון מינימלי לאיתור פנים מ-0 עד 1. ערכים נמוכים יותר יאתרו יותר פנים אך עלולים לגרום לתוצאות חיוביות שגויות.",
"machine_learning_min_recognized_faces": "מינימום פנים מזוהים",
"machine_learning_min_recognized_faces_description": "המספר המינימלי של פנים מזוהים ליצירת אדם. הגדלת ערך זה הופכת את זיהוי הפנים למדויק יותר בעלות של הגברת הסיכוי שלא יוקצו פנים לאדם.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "השתמש בלמידת מכונה לזיהוי טקסט בתמונות",
"machine_learning_ocr_enabled": "הפעלת OCR",
"machine_learning_ocr_enabled_description": "אם מבוטל, תמונות לא יעברו זיהוי טקסט.",
"machine_learning_ocr_max_resolution": "רזולוציה מירבית",
"machine_learning_ocr_max_resolution_description": "תצוגות מקדימות מעל רזולוציה זו ישונו תוך שמירה על יחס גובה לרוחב. ערכים גבוהים הם מדויקים יותר, אך דורשים יותר זמן עיבוד וזיכרון.",
"machine_learning_ocr_min_detection_score": "ציון איתור מזערי",
"machine_learning_ocr_min_detection_score_description": "ציון ביטחון מזערי לאיתור טקסט בטווח 0-1. ערכים נמוכים יאתרו יותר טקסט אך עלולים לגרום לאיתורים שגויים.",
"machine_learning_ocr_min_recognition_score": "ציון זיהוי מזערי",
"machine_learning_ocr_min_score_recognition_description": "ציון ביטחון מזערי לזיהוי טקסט שאותר בטווח 0-1. ערכים נמוכים יזהו יותר טקסט אך עלולים לגרום לזיהויים שגויים.",
"machine_learning_ocr_model": "מודל OCR",
"machine_learning_ocr_model_description": "מודלי שרת הינם מדויקים יותר ממודלי טלפון, אך לוקחים יותר זמן עיבוד וצורכים יותר זיכרון.",
"machine_learning_settings": "הגדרות למידת מכונה",
"machine_learning_settings_description": "ניהול התכונות וההגדרות של למידת המכונה",
"machine_learning_smart_search": "חיפוש חכם",
@@ -210,6 +221,8 @@
"notification_email_ignore_certificate_errors_description": "התעלם משגיאות אימות תעודת TLS (לא מומלץ)",
"notification_email_password_description": "סיסמה לשימוש בעת אימות עם שרת הדוא\"ל",
"notification_email_port_description": "יציאה של שרת הדוא\"ל (למשל 25, 465, או 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "השתמש ב-SMTPS (פרוטוקול SMTP מעל TLS)",
"notification_email_sent_test_email_button": "שלח דוא\"ל בדיקה ושמור",
"notification_email_setting_description": "הגדרות לשליחת התראות דוא\"ל",
"notification_email_test_email": "שלח דוא\"ל בדיקה",
@@ -242,6 +255,7 @@
"oauth_storage_quota_default_description": "מכסה ב-GiB לשימוש כאשר לא מסופקת דרישה.",
"oauth_timeout": "הבקשה נכשלה הזמן הקצוב הסתיים",
"oauth_timeout_description": "זמן קצוב לבקשות (במילישניות)",
"ocr_job_description": "השתמש בלמידת מכונה לזיהוי טקסט בתמונות",
"password_enable_description": "התחבר עם דוא\"ל וסיסמה",
"password_settings": "סיסמת התחברות",
"password_settings_description": "ניהול הגדרות סיסמת התחברות",
@@ -332,7 +346,7 @@
"transcoding_max_b_frames": "B-פריימים מרביים",
"transcoding_max_b_frames_description": "ערכים גבוהים יותר משפרים את יעילות הדחיסה, אך מאטים את הקידוד. ייתכן שלא יהיה תואם עם האצת חומרה במכשירים ישנים יותר. 0 משבית את B-פריימים, בעוד ש1- מגדיר את הערך זה באופן אוטומטי.",
"transcoding_max_bitrate": "קצב סיביות מרבי",
"transcoding_max_bitrate_description": "קביעת קצב סיביות מרבי יכולה להפוך את גדלי הקבצים לצפויים יותר בעלות קלה לאיכות. ב-720p, ערכים טיפוסיים הם 2600 kbit/s עבור VP9 או HEVC, או 4500 kbit/s עבור H.264. מושבת אם מוגדר ל-0.",
"transcoding_max_bitrate_description": "קביעת קצב סיביות מרבי יכולה להפוך את גדלי הקבצים לצפויים יותר בעלות קלה לאיכות. ב-720p, ערכים טיפוסיים הם 2600 kbit/s עבור VP9 או HEVC, או 4500 kbit/s עבור H.264. מושבת אם מוגדר ל-0. אם לא הוגדרו יחידות, ייעשה שימוש ב-k (עבור kbit/s)ף כלומר 5000, 5000k ו-5M (עבור Mbit/s) שקולים.",
"transcoding_max_keyframe_interval": "מרווח תמונת מפתח מרבי",
"transcoding_max_keyframe_interval_description": "מגדיר את מרחק הפריימים המרבי בין תמונות מפתח. ערכים נמוכים גורעים את יעילות הדחיסה, אך משפרים את זמני החיפוש ועשויים לשפר את האיכות בסצנות עם תנועה מהירה. 0 מגדיר ערך זה באופן אוטומטי.",
"transcoding_optimal_description": "סרטונים גבוהים מרזולוציית היעד או לא בפורמט מקובל",
@@ -350,7 +364,7 @@
"transcoding_target_resolution": "רזולוציה יעד",
"transcoding_target_resolution_description": "רזולוציות גבוהות יותר יכולות לשמר פרטים רבים יותר אך לוקחות זמן רב יותר לקידוד, יש להן גדלי קבצים גדולים יותר, ויכולות להפחית את תגובתיות היישום.",
"transcoding_temporal_aq": "AQ מבוסס זמן",
"transcoding_temporal_aq_description": "חל רק על NVENC. מגביר את האיכות של סצנות עם רמת פירוט גבוהה בהילוך איטי. ייתכן שלא יהיה תואם למכשירים ישנים יותר.",
"transcoding_temporal_aq_description": "חל רק על NVENC. כימות מסתגל לפי זמן מגביר את האיכות של סצנות עם רמת פירוט גבוהה בהילוך איטי. ייתכן שלא יהיה תואם למכשירים ישנים יותר.",
"transcoding_threads": "תהליכונים",
"transcoding_threads_description": "ערכים גבוהים יותר מובילים לקידוד מהיר יותר, אך משאירים פחות מקום לשרת לעבד משימות אחרות בעודו פעיל. ערך זה לא אמור להיות יותר ממספר ליבות המעבד. ממקסם את הניצול אם מוגדר ל-0.",
"transcoding_tone_mapping": "מיפוי גוונים",
@@ -401,11 +415,11 @@
"advanced_settings_prefer_remote_subtitle": "במכשירים מסוימים טעינת תמונות ממוזערות מקבצים מקומיים עלולה להיות איטית במיוחד. הפעל הגדרה זו כדי לטעון תמונות מרוחקות במקום זאת.",
"advanced_settings_prefer_remote_title": "העדף תמונות מרוחקות",
"advanced_settings_proxy_headers_subtitle": "הגדר proxy headers שהיישום צריך לשלוח עם כל בקשת רשת",
"advanced_settings_proxy_headers_title": "כותרות פרוקסי",
"advanced_settings_proxy_headers_title": "כותרות פרוקסי [ניסיוני]",
"advanced_settings_readonly_mode_subtitle": "מאפשר את מצב לקריאה בלבד בו התמונות ניתנות לצפייה בלבד, דברים כמו בחירת תמונות מרובות, שיתוף, שידור, מחיקה הם כולם מושבתים. אפשר/השבת מצב לקריאה בלבד באמצעות יצגן המשתמש מהמסך הראשי",
"advanced_settings_readonly_mode_title": "מצב לקריאה בלבד",
"advanced_settings_readonly_mode_title": "מצב קריאה בלבד",
"advanced_settings_self_signed_ssl_subtitle": "מדלג על אימות תעודת SSL עבור כתובת URL של השרת. דרוש עבור תעודות בחתימה עצמית.",
"advanced_settings_self_signed_ssl_title": "התר תעודות SSL בחתימה עצמית",
"advanced_settings_self_signed_ssl_title": "התר תעודות SSL בחתימה עצמית [ניסיוני]",
"advanced_settings_sync_remote_deletions_subtitle": "מחק או שחזר תמונה במכשיר זה באופן אוטומטי כאשר פעולה זו נעשית בדפדפן",
"advanced_settings_sync_remote_deletions_title": "סנכרן מחיקות שבוצעו במכשירים אחרים [נסיוני]",
"advanced_settings_tile_subtitle": "הגדרות משתמש מתקדם",
@@ -465,10 +479,14 @@
"api_key_description": "הערך הזה יוצג רק פעם אחת. נא לוודא שהעתקת אותו לפני סגירת החלון.",
"api_key_empty": "מפתח ה-API שלך לא אמור להיות ריק",
"api_keys": "מפתחות API",
"app_architecture_variant": "וריאנט (ארכיטקטורה)",
"app_bar_signout_dialog_content": "האם את/ה בטוח/ה שברצונך להתנתק?",
"app_bar_signout_dialog_ok": "כן",
"app_bar_signout_dialog_title": "התנתק",
"app_download_links": "קישורים להורדת האפליקציה",
"app_settings": "הגדרות יישום",
"app_stores": "חנויות אפליקציה",
"app_update_available": "יש עדכון לאפליקציה",
"appears_in": "מופיע ב",
"apply_count": "החל ({count, number})",
"archive": "ארכיון",
@@ -552,6 +570,7 @@
"backup_albums_sync": "סנכרון אלבומי גיבוי",
"backup_all": "הכל",
"backup_background_service_backup_failed_message": "נכשל בגיבוי תמונות. מנסה שוב…",
"backup_background_service_complete_notification": "גיבוי הנכסים הושלם",
"backup_background_service_connection_failed_message": "נכשל בהתחברות לשרת. מנסה שוב…",
"backup_background_service_current_upload_notification": "מעלה {filename}",
"backup_background_service_default_notification": "מחפש תמונות חדשות…",
@@ -661,6 +680,8 @@
"change_password_description": "זאת או הפעם הראשונה שהתחברת למערכת או שנעשתה בקשה לשינוי הסיסמה שלך. נא להזין את הסיסמה החדשה למטה.",
"change_password_form_confirm_password": "אשר סיסמה",
"change_password_form_description": "הי {name},\n\nזאת או הפעם הראשונה שאת/ה מתחבר/ת למערכת או שנעשתה בקשה לשינוי הסיסמה שלך. נא להזין את הסיסמה החדשה למטה.",
"change_password_form_log_out": "התנתק מכל שאר המכשירים",
"change_password_form_log_out_description": "מומלץ להתנתק מכל שאר הרכיבים",
"change_password_form_new_password": "סיסמה חדשה",
"change_password_form_password_mismatch": "סיסמאות לא תואמות",
"change_password_form_reenter_new_password": "הכנס שוב סיסמה חדשה",
@@ -688,7 +709,7 @@
"client_cert_invalid_msg": "קובץ תעודה לא תקין או סיסמה שגויה",
"client_cert_remove_msg": "תעודת לקוח הוסרה",
"client_cert_subtitle": "תומך בפורמט PKCS12 (.p12, .pfx) בלבד. ייבוא/הסרה של תעודה זמינה רק לפני התחברות",
"client_cert_title": "תעודת לקוח SSL",
"client_cert_title": "תעודת לקוח SSL [ניסיוני]",
"clockwise": "עם כיוון השעון",
"close": "סגור",
"collapse": "כווץ",
@@ -700,7 +721,6 @@
"comments_and_likes": "תגובות & לייקים",
"comments_are_disabled": "תגובות מושבתות",
"common_create_new_album": "צור אלבום חדש",
"common_server_error": "נא לבדוק את חיבור הרשת שלך, תוודא/י שהשרת נגיש ושגרסאות אפליקציה/שרת תואמות.",
"completed": "הושלמו",
"confirm": "אישור",
"confirm_admin_password": "אישור סיסמת מנהל",
@@ -739,6 +759,7 @@
"create": "צור",
"create_album": "צור אלבום",
"create_album_page_untitled": "ללא כותרת",
"create_api_key": "יצירת מפתח API",
"create_library": "צור ספרייה",
"create_link": "צור קישור",
"create_link_to_share": "צור קישור לשיתוף",
@@ -768,6 +789,7 @@
"daily_title_text_date_year": "E, MMM dd, yyyy",
"dark": "כהה",
"dark_theme": "הפעל/כבה מצב כהה",
"date": "תאריך",
"date_after": "תאריך אחרי",
"date_and_time": "תאריך ושעה",
"date_before": "תאריך לפני",
@@ -870,8 +892,6 @@
"edit_description_prompt": "אנא בחר תיאור חדש:",
"edit_exclusion_pattern": "ערוך דפוס החרגה",
"edit_faces": "ערוך פנים",
"edit_import_path": "ערוך נתיב יבוא",
"edit_import_paths": "ערוך נתיבי ייבוא",
"edit_key": "ערוך מפתח",
"edit_link": "ערוך קישור",
"edit_location": "ערוך מיקום",
@@ -882,7 +902,6 @@
"edit_tag": "ערוך תג",
"edit_title": "ערוך כותרת",
"edit_user": "ערוך משתמש",
"edited": "נערך",
"editor": "עורך",
"editor_close_without_save_prompt": "השינויים לא יישמרו",
"editor_close_without_save_title": "לסגור את העורך?",
@@ -944,7 +963,6 @@
"failed_to_stack_assets": "יצירת ערימת תמונות נכשלה",
"failed_to_unstack_assets": "ביטול ערימת תמונות נכשלה",
"failed_to_update_notification_status": "שגיאה בעדכון ההתראה",
"import_path_already_exists": "נתיב הייבוא הזה כבר קיים.",
"incorrect_email_or_password": "דוא\"ל או סיסמה שגויים",
"paths_validation_failed": "{paths, plural, one {נתיב # נכשל} other {# נתיבים נכשלו}} אימות",
"profile_picture_transparent_pixels": "תמונות פרופיל אינן יכולות לכלול פיקסלים שקופים. נא להגדיל ו/או להזיז את התמונה.",
@@ -954,7 +972,6 @@
"unable_to_add_assets_to_shared_link": "לא ניתן להוסיף תמונות לקישור משותף",
"unable_to_add_comment": "לא ניתן להוסיף תגובה",
"unable_to_add_exclusion_pattern": "לא ניתן להוסיף דפוס החרגה",
"unable_to_add_import_path": "לא ניתן להוסיף נתיב ייבוא",
"unable_to_add_partners": "לא ניתן להוסיף שותפים",
"unable_to_add_remove_archive": "לא ניתן {archived, select, true {להסיר תמונה מ} other {להוסיף תמונה ל}}ארכיון",
"unable_to_add_remove_favorites": "לא ניתן {favorite, select, true {להוסיף תמונה ל} other {להסיר תמונה מ}}מועדפים",
@@ -977,12 +994,10 @@
"unable_to_delete_asset": "לא ניתן למחוק את התמונה",
"unable_to_delete_assets": "שגיאה במחיקת התמונות",
"unable_to_delete_exclusion_pattern": "לא ניתן למחוק דפוס החרגה",
"unable_to_delete_import_path": "לא ניתן למחוק את נתיב הייבוא",
"unable_to_delete_shared_link": "לא ניתן למחוק קישור משותף",
"unable_to_delete_user": "לא ניתן למחוק משתמש",
"unable_to_download_files": "לא ניתן להוריד קבצים",
"unable_to_edit_exclusion_pattern": "לא ניתן לערוך דפוס החרגה",
"unable_to_edit_import_path": "לא ניתן לערוך את נתיב הייבוא",
"unable_to_empty_trash": "לא ניתן לרוקן אשפה",
"unable_to_enter_fullscreen": "לא ניתן להיכנס למסך מלא",
"unable_to_exit_fullscreen": "לא ניתן לצאת ממסך מלא",
@@ -1038,6 +1053,7 @@
"exif_bottom_sheet_description_error": "שגיאה בעדכון התיאור",
"exif_bottom_sheet_details": "פרטים",
"exif_bottom_sheet_location": "מיקום",
"exif_bottom_sheet_no_description": "ללא תיאור",
"exif_bottom_sheet_people": "אנשים",
"exif_bottom_sheet_person_add_person": "הוסף שם",
"exit_slideshow": "צא ממצגת שקופיות",
@@ -1076,6 +1092,7 @@
"features_setting_description": "ניהול תכונות היישום",
"file_name": "שם הקובץ",
"file_name_or_extension": "שם קובץ או סיומת",
"file_size": "גודל קובץ",
"filename": "שם קובץ",
"filetype": "סוג קובץ",
"filter": "סנן",
@@ -1119,7 +1136,6 @@
"header_settings_field_validator_msg": "ערך אינו יכול להיות ריק",
"header_settings_header_name_input": "שם כותרת",
"header_settings_header_value_input": "ערך כותרת",
"headers_settings_tile_subtitle": "הגדר כותרות פרוקסי שהיישום צריך לשלוח עם כל בקשת רשת",
"headers_settings_tile_title": "כותרות פרוקסי מותאמות",
"hi_user": "היי {name}, ({email})",
"hide_all_people": "הסתר את כל האנשים",
@@ -1240,6 +1256,7 @@
"local_media_summary": "סיכום של מדיה מקומית",
"local_network": "רשת מקומית",
"local_network_sheet_info": "היישום יתחבר לשרת דרך הכתובת הזאת כאשר משתמשים ברשת האינטרנט האלחוטי שמצוינת",
"location": "מיקום",
"location_permission": "הרשאת מיקום",
"location_permission_content": "כדי להשתמש בתכונת ההחלפה האוטומטית, היישום צריך הרשאה למיקום מדויק על מנת לקרוא את השם של רשת האינטרנט האלחוטי",
"location_picker_choose_on_map": "בחר על מפה",
@@ -1289,6 +1306,8 @@
"main_menu": "תפריט ראשי",
"make": "תוצרת",
"manage_geolocation": "נהל מיקום",
"manage_media_access_settings": "פתח הגדרות",
"manage_media_access_subtitle": "אפשר לאפליקציית Immich לנהל ולהזיז קבצי מדיה.",
"manage_shared_links": "ניהול קישורים משותפים",
"manage_sharing_with_partners": "ניהול שיתוף עם שותפים",
"manage_the_app_settings": "ניהול הגדרות האפליקציה",
@@ -1344,6 +1363,8 @@
"minute": "דקה",
"minutes": "דקות",
"missing": "חסרים",
"mobile_app": "אפליקציה לטלפון",
"mobile_app_download_onboarding_note": "הורד את האפליקציה המלווה באחת מהאפשרויות הבאות",
"model": "דגם",
"month": "חודש",
"monthly_title_text_date_format": "MMMM y",
@@ -1362,6 +1383,8 @@
"my_albums": "האלבומים שלי",
"name": "שם",
"name_or_nickname": "שם או כינוי",
"navigate": "נווט",
"navigate_to_time": "נווט אל זמן",
"network_requirement_photos_upload": "השתמש בנתונים ניידים לגיבוי תמונות",
"network_requirement_videos_upload": "השתמש בנתונים ניידים לגיבוי סרטונים",
"network_requirements": "דרישות רשת",
@@ -1371,11 +1394,13 @@
"never": "אף פעם",
"new_album": "אלבום חדש",
"new_api_key": "מפתח API חדש",
"new_date_range": "טווח תאריך חדש",
"new_password": "סיסמה חדשה",
"new_person": "אדם חדש",
"new_pin_code": "קוד PIN חדש",
"new_pin_code_subtitle": "זאת הפעם הראשונה שנכנסת לתיקיה הנעולה. צור קוד PIN כדי לאבטח את הגישה לדף זה",
"new_timeline": "ציר הזמן החדש",
"new_update": "עדכון חדש",
"new_user_created": "משתמש חדש נוצר",
"new_version_available": "גרסה חדשה זמינה",
"newest_first": "החדש ביותר ראשון",
@@ -1421,6 +1446,9 @@
"notifications": "התראות",
"notifications_setting_description": "ניהול התראות",
"oauth": "OAuth",
"obtainium_configurator": "הגדרות Obtainium",
"obtainium_configurator_instructions": "השתמש ב-Obtainium כגדי להתקין ולעדכן את אפליקציית האנדרואיד ישירות לגרסאות הגיטהאב של Immich. צור מפתח API ובחר וריאנט כדי ליצור קישור קונפיגורציה עבור Obtainium",
"ocr": "OCR",
"official_immich_resources": "מקורות רשמיים של Immich",
"offline": "לא מקוון",
"offset": "קיזוז",
@@ -1525,6 +1553,9 @@
"play_memories": "נגן זכרונות",
"play_motion_photo": "הפעל תמונה עם תנועה",
"play_or_pause_video": "הפעל או השהה סרטון",
"play_original_video": "נגן את הווידיאו המקורי",
"play_original_video_setting_description": "העדף לנגן סרטונים המקוריים על פני סרטונים משועתקים. אם הסרטון המקורי אינו תואם הוא עלול להתנגן לא נכון.",
"play_transcoded_video": "נגן סרטון משועתק",
"please_auth_to_access": "אנא אמת את זהותך כדי לגשת",
"port": "יציאה",
"preferences_settings_subtitle": "ניהול העדפות יישום",
@@ -1542,13 +1573,9 @@
"privacy": "פרטיות",
"profile": "פרופיל",
"profile_drawer_app_logs": "יומן",
"profile_drawer_client_out_of_date_major": "גרסת היישום לנייד מיושנת. נא לעדכן לגרסה הראשית האחרונה.",
"profile_drawer_client_out_of_date_minor": "גרסת היישום לנייד מיושנת. נא לעדכן לגרסה המשנית האחרונה.",
"profile_drawer_client_server_up_to_date": "היישום והשרת מעודכנים",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "מצב לקריאה בלבד מופעל. לחץ לחיצה ארוכה על סמל היצגן של המשתמש כדי לצאת.",
"profile_drawer_server_out_of_date_major": "השרת אינו מעודכן. נא לעדכן לגרסה הראשית האחרונה.",
"profile_drawer_server_out_of_date_minor": "השרת אינו מעודכן. נא לעדכן לגרסה המשנית האחרונה.",
"profile_image_of_user": "תמונת פרופיל של {user}",
"profile_picture_set": "תמונת פרופיל נבחרה.",
"public_album": "אלבום ציבורי",
@@ -1665,6 +1692,7 @@
"reset_sqlite_confirmation": "האם אתה בטוח שברצונך לאפס את מסד הנתונים SQLite? יהיה עליך להתנתק ולהתחבר מחדש כדי לסנכרן את הנתונים מחדש",
"reset_sqlite_success": "איפוס מסד הנתונים SQLite בוצע בהצלחה",
"reset_to_default": "אפס לברירת מחדל",
"resolution": "רזולוציה",
"resolve_duplicates": "פתור כפילויות",
"resolved_all_duplicates": "כל הכפילויות נפתרו",
"restore": "שחזר",
@@ -1683,6 +1711,7 @@
"running": "פועל",
"save": "שמור",
"save_to_gallery": "שמור לגלריה",
"saved": "נשמר",
"saved_api_key": "מפתח API שמור",
"saved_profile": "פרופיל שמור",
"saved_settings": "הגדרות שמורות",
@@ -1699,6 +1728,9 @@
"search_by_description_example": "יום טיול בסאפה",
"search_by_filename": "חיפוש לפי שם קובץ או סיומת",
"search_by_filename_example": "לדוגמא IMG_1234.JPG או PNG",
"search_by_ocr": "חיפוש לפי OCR",
"search_by_ocr_example": "לאטה",
"search_camera_lens_model": "חיפוש סוג עדשה...",
"search_camera_make": "חיפוש תוצרת המצלמה...",
"search_camera_model": "חפש דגם המצלמה...",
"search_city": "חיפוש עיר...",
@@ -1715,6 +1747,7 @@
"search_filter_location_title": "בחר מיקום",
"search_filter_media_type": "סוג מדיה",
"search_filter_media_type_title": "בחר סוג מדיה",
"search_filter_ocr": "חיפוש לפי OCR",
"search_filter_people_title": "בחר אנשים",
"search_for": "חיפוש",
"search_for_existing_person": "חיפוש אדם קיים",
@@ -1777,6 +1810,7 @@
"server_online": "החיבור לשרת פעיל",
"server_privacy": "פרטיות השרת",
"server_stats": "סטטיסטיקות שרת",
"server_update_available": "עדכון שרת זמין",
"server_version": "גרסת שרת",
"set": "הגדר",
"set_as_album_cover": "הגדר כעטיפת האלבום",
@@ -1805,6 +1839,8 @@
"setting_notifications_subtitle": "התאם את העדפות ההתראה שלך",
"setting_notifications_total_progress_subtitle": "התקדמות העלאה כללית (בוצע/סה״כ תמונות)",
"setting_notifications_total_progress_title": "הראה סה״כ התקדמות גיבוי ברקע",
"setting_video_viewer_auto_play_subtitle": "נגן סרטונים אוטומטית כשהם נפתחים",
"setting_video_viewer_auto_play_title": "נגן סרטונים אוטומטית",
"setting_video_viewer_looping_title": "הפעלה חוזרת",
"setting_video_viewer_original_video_subtitle": "כאשר מזרימים סרטון מהשרת, נגן את המקורי אפילו כשהמרת קידוד זמינה. עלול להוביל לתקיעות. סרטונים זמינים מקומית מנוגנים באיכות מקורית ללא קשר להגדרה זו.",
"setting_video_viewer_original_video_title": "כפה סרטון מקורי",
@@ -1984,6 +2020,7 @@
"theme_setting_three_stage_loading_title": "אפשר טעינה בשלושה שלבים",
"they_will_be_merged_together": "הם יתמזגו יחד",
"third_party_resources": "משאבי צד שלישי",
"time": "זמן",
"time_based_memories": "זכרונות מבוססי זמן",
"timeline": "ציר זמן",
"timezone": "אזור זמן",
@@ -2016,6 +2053,7 @@
"troubleshoot": "פתור בעיות",
"type": "סוג",
"unable_to_change_pin_code": "לא ניתן לשנות את קוד ה PIN",
"unable_to_check_version": "לא ניתן לבדוק את גרסאת האפליקציה או השרת",
"unable_to_setup_pin_code": "לא ניתן להגדיר קוד PIN",
"unarchive": "הוצא מארכיון",
"unarchive_action_prompt": "{count} הוסרו מהארכיון",

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
{
"about": "O",
"about": "Pojedinosti",
"account": "Račun",
"account_settings": "Postavke računa",
"acknowledge": "Potvrdi",
@@ -17,7 +17,6 @@
"add_birthday": "Dodaj rođendan",
"add_endpoint": "Dodaj krajnju točku",
"add_exclusion_pattern": "Dodaj uzorak izuzimanja",
"add_import_path": "Dodaj putanju uvoza",
"add_location": "Dodaj lokaciju",
"add_more_users": "Dodaj još korisnika",
"add_partner": "Dodaj partnera",
@@ -76,7 +75,7 @@
"exclusion_pattern_description": "Uzorci izuzimanja omogućuju vam da ignorirate datoteke i mape prilikom skeniranja svoje biblioteke. Ovo je korisno ako imate mape koje sadrže datoteke koje ne želite uvesti, kao što su RAW datoteke.",
"external_library_management": "Upravljanje vanjskom bibliotekom",
"face_detection": "Detekcija lica",
"face_detection_description": "Detektirajte lica u stavkama pomoću strojnog učenja. Za videozapise se uzima u obzir samo sličica. \"Osvježi\" (ponovno) obrađuje sve stavke. \"Poništi\" dodatno briše sve trenutne podatke o licu. \"Nedostaje\" stavlja u red čekanja stavke koje još nisu obrađene. Detektirana lica bit će stavljena u red čekanja za Prepoznavanje lica nakon što se dovrši Detekcija lica, grupirajući ih u postojeće ili nove osobe.",
"face_detection_description": "Detektirajte lica u stavkama pomoću strojnog učenja. Za videozapise se uzima u obzir samo sličica. \"Osvježi\" (ponovno) obrađuje sve stavke. \"Poništi\" dodatno briše sve trenutne podatke o licu. \"Nedostaje\" stavlja u red čekanja stavke koje još nisu obrađene. Detektirana lica bit će stavljena u red čekanja za prepoznavanje lica nakon što se dovrši detekcija lica, grupirajući ih u postojeće ili nove osobe.",
"facial_recognition_job_description": "Grupirajte otkrivena lica u osobe. Ovaj korak se izvršava nakon što je Detekcija lica dovršena. \"Resetiraj\" (ponovno) grupira sva lica. \"Nedostaje\" stavlja u red lica kojima nije dodijeljena osoba.",
"failed_job_command": "Naredba {command} nije uspjela za posao: {job}",
"force_delete_user_warning": "UPOZORENJE: Ovo će odmah ukloniti korisnika i sve pripadajuće stavke. Ovo se ne može poništiti i datoteke se ne mogu vratiti.",
@@ -109,18 +108,17 @@
"job_settings_description": "Upravljajte istovremenošću poslova",
"job_status": "Status posla",
"jobs_delayed": "{jobCount, plural, other {# odgođenih}}",
"jobs_failed": "{jobCount, plural, other {# failed}}",
"jobs_failed": "{jobCount, plural, one {# neuspješan} few {# neuspješna} other {# neuspješnih}}",
"library_created": "Stvorena biblioteka: {library}",
"library_deleted": "Biblioteka izbrisana",
"library_import_path_description": "Navedite mapu za uvoz. Ova će se mapa, uključujući podmape, skenirati u potrazi za slikama i videozapisima.",
"library_scanning": "Periodično Skeniranje",
"library_scanning": "Periodično skeniranje",
"library_scanning_description": "Konfigurirajte periodično skeniranje biblioteke",
"library_scanning_enable_description": "Omogući periodično skeniranje biblioteke",
"library_settings": "Externa biblioteka",
"library_settings": "Vanjska biblioteka",
"library_settings_description": "Upravljajte postavkama vanjske biblioteke",
"library_tasks_description": "Skeniraj vanjske biblioteke za nove i/ili promijenjene stavke",
"library_watching_enable_description": "Pratite vanjske biblioteke za promjena datoteke",
"library_watching_settings": "Gledanje biblioteke (EKSPERIMENTALNO)",
"library_watching_settings": "Gledanje biblioteke [EKSPERIMENTALNO]",
"library_watching_settings_description": "Automatsko praćenje promijenjenih datoteke",
"logging_enable_description": "Omogući zapisivanje",
"logging_level_description": "Kada je omogućeno, koju razinu zapisivanja koristiti.",
@@ -131,7 +129,7 @@
"machine_learning_availability_checks_interval_description": "Interval u milisekundama između provjera dostupnosti",
"machine_learning_clip_model": "CLIP model",
"machine_learning_clip_model_description": "Naziv CLIP modela navedenog <link>ovdje</link>. Imajte na umu da morate ponovno pokrenuti posao 'Pametno Pretraživanje' za sve slike nakon promjene modela.",
"machine_learning_duplicate_detection": "Detekcija Duplikata",
"machine_learning_duplicate_detection": "Detekcija duplikata",
"machine_learning_duplicate_detection_enabled": "Omogući detekciju duplikata",
"machine_learning_duplicate_detection_enabled_description": "Ako je onemogućeno, potpuno identične stavke i dalje će biti deduplicirane.",
"machine_learning_duplicate_detection_setting_description": "Upotrijebite CLIP ugradnje da biste pronašli vjerojatne duplikate",
@@ -162,16 +160,16 @@
"manage_log_settings": "Upravljanje postavkama zapisivanje",
"map_dark_style": "Tamni stil",
"map_enable_description": "Omogući značajke karte",
"map_gps_settings": "Postavke Karte i GPS-a",
"map_gps_settings_description": "Upravljajte Postavkama Karte i GPS-a (Obrnuto Geokodiranje)",
"map_gps_settings": "Postavke karte i GPS-a",
"map_gps_settings_description": "Upravljajte postavkama karte i GPS-a (obrnutog geokodiranja)",
"map_implications": "Značajka karte se oslanja na vanjsku uslugu pločica (tiles.immich.cloud)",
"map_light_style": "Svijetli stil",
"map_manage_reverse_geocoding_settings": "Upravljajte postavkama <link>Obrnutog Geokodiranja</link>",
"map_manage_reverse_geocoding_settings": "Upravljajte postavkama <link>Obrnutog geokodiranja</link>",
"map_reverse_geocoding": "Obrnuto Geokodiranje",
"map_reverse_geocoding_enable_description": "Omogući obrnuto geokodiranje",
"map_reverse_geocoding_settings": "Postavke Obrnuto Geokodiranje",
"map_reverse_geocoding_settings": "Postavke Obrnutog geokodiranja",
"map_settings": "Karta",
"map_settings_description": "Upravljanje postavkama karte",
"map_settings_description": "Upravljajte postavkama karte",
"map_style_description": "URL na style.json temu karte",
"memory_cleanup_job": "Čišćenje memorije",
"memory_generate_job": "Generiranje memorije",
@@ -179,7 +177,7 @@
"metadata_extraction_job_description": "Izdvojite metapodatke iz svake stavke, kao što su GPS, lica i rezolucija",
"metadata_faces_import_setting": "Omogući uvoz lica",
"metadata_faces_import_setting_description": "Uvezite lica iz EXIF podataka slike i sidecar datoteka",
"metadata_settings": "Postavke Metapodataka",
"metadata_settings": "Postavke metapodataka",
"metadata_settings_description": "Upravljanje postavkama metapodataka",
"migration_job": "Migracija",
"migration_job_description": "Premjestite sličice za stavke i lica u najnoviju strukturu mapa",
@@ -199,7 +197,7 @@
"nightly_tasks_sync_quota_usage_setting_description": "Ažuriraj korisničku kvotu za pohranu na temelju trenutne potrošnje",
"no_paths_added": "Nema dodanih putanja",
"no_pattern_added": "Nije dodan uzorak",
"note_apply_storage_label_previous_assets": "Napomena: Da biste primijenili Oznaku pohrane na prethodno prenesene stavke, pokrenite",
"note_apply_storage_label_previous_assets": "Napomena: Da biste primijenili oznaku pohrane na prethodno prenesene stavke, pokrenite",
"note_cannot_be_changed_later": "NAPOMENA: Ovo se ne može promijeniti kasnije!",
"notification_email_from_address": "Od adrese",
"notification_email_from_address_description": "E-mail adresa pošiljatelja, na primjer: \"Immich Photo Server <noreply@example.com>\". Obavezno koristite adresu s koje vam je dopušteno slanje e-pošte.",
@@ -208,6 +206,8 @@
"notification_email_ignore_certificate_errors_description": "Ignoriraj pogreške provjere valjanosti TLS certifikata (nije preporučeno)",
"notification_email_password_description": "Lozinka za korištenje pri autentifikaciji s poslužiteljem e-pošte",
"notification_email_port_description": "Port poslužitelja e-pošte (npr. 25, 465, ili 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Koristi SMTPS (SMTP umjesto TLS)",
"notification_email_sent_test_email_button": "Pošaljite probni e-mail i spremi",
"notification_email_setting_description": "Postavke za slanje e-mail obavijeste",
"notification_email_test_email": "Pošalji probni e-mail",
@@ -215,7 +215,7 @@
"notification_email_test_email_sent": "Testna e-poruka poslana je na {email}. Provjerite svoju pristiglu poštu.",
"notification_email_username_description": "Korisničko ime koje se koristi pri autentifikaciji s poslužiteljem e-pošte",
"notification_enable_email_notifications": "Omogući obavijesti putem e-pošte",
"notification_settings": "Postavke Obavijesti",
"notification_settings": "Postavke obavijesti",
"notification_settings_description": "Upravljanje postavkama obavijesti, uključujući e-poštu",
"oauth_auto_launch": "Automatsko pokretanje",
"oauth_auto_launch_description": "Automatski pokrenite OAuth prijavu nakon navigacije na stranicu za prijavu",
@@ -237,7 +237,7 @@
"oauth_storage_quota_claim": "Zahtjev za kvotom pohrane",
"oauth_storage_quota_claim_description": "Automatski postavite korisničku kvotu pohrane na vrijednost ovog zahtjeva.",
"oauth_storage_quota_default": "Zadana kvota pohrane (GiB)",
"oauth_storage_quota_default_description": "Kvota u GiB koja će se koristiti kada nema zahtjeva",
"oauth_storage_quota_default_description": "Kvota u GiB koja će se koristiti kada nema zahtjeva.",
"oauth_timeout": "Istek vremena zahtjeva",
"oauth_timeout_description": "Istek vremena zahtjeva je u milisekundama",
"password_enable_description": "Prijava s email adresom i zaporkom",
@@ -266,7 +266,7 @@
"sidecar_job": "Sidecar metapodaci",
"sidecar_job_description": "Otkrijte ili sinkronizirajte sidecar metapodatke iz datotečnog sustava",
"slideshow_duration_description": "Broj sekundi za prikaz svake slike",
"smart_search_job_description": "Pokrenite strojno učenje na stavkama za korištenje Pametnog pretraživanja",
"smart_search_job_description": "Pokrenite strojno učenje na stavkama za korištenje pametnog pretraživanja",
"storage_template_date_time_description": "Vremenska oznaka stvaranja stavke koristi se za informacije o datumu i vremenu",
"storage_template_date_time_sample": "Vrijeme uzorka {date}",
"storage_template_enable_description": "Omogući mehanizam predloška za pohranu",
@@ -274,7 +274,7 @@
"storage_template_hash_verification_enabled_description": "Omogućuje hash provjeru, nemojte je onemogućiti osim ako niste sigurni u implikacije",
"storage_template_migration": "Migracija predloška za pohranu",
"storage_template_migration_description": "Primijenite trenutni <link>{template}</link> na prethodno prenesene stavke",
"storage_template_migration_info": "Predložak za pohranu pretvorit će sve datotečne nastavke u mala slova. Promjene predloška primijenit će se samo na nove stavke. Da biste retroaktivno primijenili predložak na prethodno prenesene stavke, pokrenite <link>{job}<link>.",
"storage_template_migration_info": "Predložak za pohranu pretvorit će sve datotečne nastavke u mala slova. Promjene predloška primijenit će se samo na nove stavke. Da biste retroaktivno primijenili predložak na prethodno prenesene stavke, pokrenite <link>{job}</link>.",
"storage_template_migration_job": "Posao Migracije Predloška Pohrane",
"storage_template_more_details": "Za više pojedinosti o ovoj značajci pogledajte <template-link>Predložak pohrane</template-link> i njegove <implications-link>implikacije</implications-link>",
"storage_template_onboarding_description_v2": "Kada je omogućena, ova će značajka automatski organizira datoteke prema predlošku koji je definirao korisnik. Za više informacija pogledajte <link>dokumentaciju</link>.",
@@ -282,13 +282,13 @@
"storage_template_settings": "Predložak pohrane",
"storage_template_settings_description": "Upravljajte strukturom mape i nazivom datoteke učitane stavke",
"storage_template_user_label": "<code>{label}</code> je korisnička oznaka za pohranu",
"system_settings": "Postavke Sustava",
"system_settings": "Postavke sustava",
"tag_cleanup_job": "Čišćenje oznaka",
"template_email_available_tags": "Možete koristiti sljedeće varijable u vašem predlošku:{tags}",
"template_email_if_empty": "Ukoliko je predložak prazan, koristit će se zadana e-mail adresa.",
"template_email_invite_album": "Predložak za pozivnicu u album",
"template_email_preview": "Pregled",
"template_email_settings": "E-mail Predlošci",
"template_email_settings": "E-mail predlošci",
"template_email_update_album": "Ažuriraj Album Predložak",
"template_email_welcome": "Predložak e-maila dobrodošlice",
"template_settings": "Predložak Obavijesti",
@@ -321,20 +321,20 @@
"transcoding_constant_rate_factor": "Faktor konstantne stope (-crf)",
"transcoding_constant_rate_factor_description": "Razina kvalitete videa. Uobičajene vrijednosti su 23 za H.264, 28 za HEVC, 31 za VP9 i 35 za AV1. Niže je bolje, ali stvara veće datoteke.",
"transcoding_disabled_description": "Nemojte transkodirati nijedan videozapis, može prekinuti reprodukciju na nekim klijentima",
"transcoding_encoding_options": "Opcije Kodiranja",
"transcoding_encoding_options": "Opcije kodiranja",
"transcoding_encoding_options_description": "Postavi kodeke, rezoluciju, kvalitetu i druge opcije za kodirane videje",
"transcoding_hardware_acceleration": "Hardversko Ubrzanje",
"transcoding_hardware_acceleration": "Hardversko ubrzanje",
"transcoding_hardware_acceleration_description": "Eksperimentalno: brže transkodiranje, ali može smanjiti kvalitetu pri istoj brzini prijenosa",
"transcoding_hardware_decoding": "Hardversko dekodiranje",
"transcoding_hardware_decoding_setting_description": "Odnosi se samo na NVENC, QSV i RKMPP. Omogućuje ubrzanje s kraja na kraj umjesto samo ubrzavanja kodiranja. Možda neće raditi na svim videozapisima.",
"transcoding_max_b_frames": "Maksimalni B-frameovi",
"transcoding_max_b_frames_description": "Više vrijednosti poboljšavaju učinkovitost kompresije, ali usporavaju kodiranje. Možda nije kompatibilan s hardverskim ubrzanjem na starijim uređajima. 0 onemogućuje B-frameove, dok -1 automatski postavlja ovu vrijednost.",
"transcoding_max_bitrate": "Maksimalne brzina prijenosa (bitrate)",
"transcoding_max_bitrate_description": "Postavljanje maksimalne brzine prijenosa može učiniti veličine datoteka predvidljivijima uz manji trošak za kvalitetu. Pri 720p, tipične vrijednosti su 2600 kbit/s za VP9 ili HEVC ili 4500 kbit/s za H.264. Onemogućeno ako je postavljeno na 0.",
"transcoding_max_bitrate_description": "Postavljanje maksimalne brzine prijenosa može učiniti veličine datoteka predvidljivijima uz manji gubitak kvalitete. Pri 720p, tipične vrijednosti su 2600 kbit/s za VP9 ili HEVC, te 4500 kbit/s za H.264. Onemogućeno ako je postavljeno na 0. Kada nije navedena mjerna jedinica, pretpostavlja se k (za kbit/s); stoga su 5000, 5000k i 5M (za Mbit/s) ekvivalentni.",
"transcoding_max_keyframe_interval": "Maksimalni interval ključnih sličica",
"transcoding_max_keyframe_interval_description": "Postavlja maksimalnu udaljenost slika između ključnih kadrova. Niže vrijednosti pogoršavaju učinkovitost kompresije, ali poboljšavaju vrijeme traženja i mogu poboljšati kvalitetu u scenama s brzim kretanjem. 0 automatski postavlja ovu vrijednost.",
"transcoding_optimal_description": "Videozapisi koji su veći od ciljne rezolucije ili nisu u prihvatljivom formatu",
"transcoding_policy": "Politika Transkodiranja",
"transcoding_policy": "Pravila transkodiranja",
"transcoding_policy_description": "Postavi kada će video biti transkodiran",
"transcoding_preferred_hardware_device": "Preferirani hardverski uređaj",
"transcoding_preferred_hardware_device_description": "Odnosi se samo na VAAPI i QSV. Postavlja dri node koji se koristi za hardversko transkodiranje.",
@@ -343,12 +343,12 @@
"transcoding_reference_frames": "Referentne slike",
"transcoding_reference_frames_description": "Broj slika za referencu prilikom komprimiranja određene slike. Više vrijednosti poboljšavaju učinkovitost kompresije, ali usporavaju kodiranje. 0 automatski postavlja ovu vrijednost.",
"transcoding_required_description": "Samo videozapisi koji nisu u prihvaćenom formatu",
"transcoding_settings": "Postavke Video Transkodiranja",
"transcoding_settings": "Postavke video transkodiranja",
"transcoding_settings_description": "Upravljaj koji videozapisi će se transkodirati i kako ih obraditi",
"transcoding_target_resolution": "Ciljana rezolucija",
"transcoding_target_resolution_description": "Veće razlučivosti mogu sačuvati više detalja, ali trebaju dulje za kodiranje, imaju veće veličine datoteka i mogu smanjiti odziv aplikacije.",
"transcoding_temporal_aq": "Vremenski AQ",
"transcoding_temporal_aq_description": "Odnosi se samo na NVENC. Povećava kvalitetu scena s puno detalja i malo pokreta. Možda nije kompatibilan sa starijim uređajima.",
"transcoding_temporal_aq_description": "Odnosi se samo na NVENC. Vremenska adaptivna kvantizacija povećava kvalitetu scena s mnogim detaljima i malo kretanja. Možda nije kompatibilno sa starijim uređajima.",
"transcoding_threads": "Sljedovi (Threads)",
"transcoding_threads_description": "Više vrijednosti dovode do bržeg kodiranja, ali ostavljaju manje prostora poslužitelju za obradu drugih zadataka dok je aktivan. Ova vrijednost ne smije biti veća od broja CPU jezgri. Maksimalno povećava iskorištenje ako je postavljeno na 0.",
"transcoding_tone_mapping": "Tonsko preslikavanje",
@@ -359,10 +359,10 @@
"transcoding_two_pass_encoding_setting_description": "Transkodiranje u dva prolaza za proizvodnju bolje kodiranih videozapisa. Kada je omogućena maksimalna brzina prijenosa (potrebna za rad s H.264 i HEVC), ovaj način rada koristi raspon brzine prijenosa na temelju maksimalne brzine prijenosa i zanemaruje CRF. Za VP9, CRF se može koristiti ako je maksimalna brzina prijenosa onemogućena.",
"transcoding_video_codec": "Video kodek",
"transcoding_video_codec_description": "VP9 ima visoku učinkovitost i web-kompatibilnost, ali treba dulje za transkodiranje. HEVC ima sličnu izvedbu, ali ima slabiju web kompatibilnost. H.264 široko je kompatibilan i brzo se transkodira, ali proizvodi mnogo veće datoteke. AV1 je najučinkovitiji kodek, ali nema podršku na starijim uređajima.",
"trash_enabled_description": "Omogućite značajke Smeća",
"trash_enabled_description": "Omogući značajke smeća",
"trash_number_of_days": "Broj dana",
"trash_number_of_days_description": "Broj dana za čuvanje stavki u smeću prije njihovog trajnog uklanjanja",
"trash_settings": "Postavke Smeća",
"trash_settings": "Postavke smeća",
"trash_settings_description": "Upravljanje postavkama smeća",
"unlink_all_oauth_accounts": "Odspoji sve OAuth račune",
"unlink_all_oauth_accounts_description": "Zapamtite da odspojite sve OAuth račune prije prelaska na novog pružatelja usluge.",
@@ -398,10 +398,12 @@
"advanced_settings_log_level_title": "Razina zapisivanja: {level}",
"advanced_settings_prefer_remote_subtitle": "Neki uređaji sporo učitavaju sličice s lokalnih stavki. Aktivirajte ovu postavku kako biste umjesto toga učitali slike s udaljenih izvora.",
"advanced_settings_prefer_remote_title": "Preferiraj udaljene slike",
"advanced_settings_proxy_headers_subtitle": "Definirajte zaglavlja posrednika koja Immich treba slati sa svakim mrežnim zahtjevom.",
"advanced_settings_proxy_headers_title": "Proxy zaglavlja",
"advanced_settings_proxy_headers_subtitle": "Definirajte proxy zaglavlja koja Immich treba poslati sa svakim mrežnim zahtjevom",
"advanced_settings_proxy_headers_title": "Prilagođeni proxy zaglavlja [EKSPERIMENTALNO]",
"advanced_settings_readonly_mode_subtitle": "Omogućuje način rada za čitanje u kojem se fotografije mogu samo pregledavati, a stvari poput odabira više slika, dijeljenja, emitiranja i brisanja su onemogućene. Omogući/onemogući način rada za čitanje putem korisničkog avatara s glavnog zaslona",
"advanced_settings_readonly_mode_title": "Read-only mod",
"advanced_settings_self_signed_ssl_subtitle": "Preskoči provjeru SSL certifikata za krajnju točku poslužitelja. Potrebno za samo-potpisane certifikate.",
"advanced_settings_self_signed_ssl_title": "Dopusti samo-potpisane SSL certifikate",
"advanced_settings_self_signed_ssl_title": "Dopusti samopotpisane SSL certifikate [EKSPERIMENTALNO]",
"advanced_settings_sync_remote_deletions_subtitle": "Automatski izbriši ili obnovi stavku na ovom uređaju kada se ta radnja izvrši na webu",
"advanced_settings_sync_remote_deletions_title": "Sinkroniziraj udaljena brisanja [EKSPERIMENTALNO]",
"advanced_settings_tile_subtitle": "Postavke za napredne korisnike",
@@ -449,7 +451,7 @@
"albums_on_device_count": "Albumi na uređaju ({count})",
"all": "Sve",
"all_albums": "Svi albumi",
"all_people": "Svi ljudi",
"all_people": "Sve osobe",
"all_videos": "Svi videi",
"allow_dark_mode": "Dozvoli tamni način",
"allow_edits": "Dozvoli izmjene",
@@ -460,12 +462,16 @@
"api_key": "API Ključ",
"api_key_description": "Ova će vrijednost biti prikazana samo jednom. Obavezno ju kopirajte prije zatvaranja prozora.",
"api_key_empty": "Naziv vašeg API ključa ne smije biti prazan",
"api_keys": "API Ključevi",
"api_keys": "API ključevi",
"app_architecture_variant": "Varijanta(Arhitektura)",
"app_bar_signout_dialog_content": "Jeste li sigurni da se želite odjaviti?",
"app_bar_signout_dialog_ok": "Da",
"app_bar_signout_dialog_title": "Odjavi se",
"app_download_links": "Poveznica za preuzimanje aplikacije",
"app_settings": "Postavke aplikacije",
"app_update_available": "Ažuriranje aplikacije je dostupno",
"appears_in": "Pojavljuje se u",
"apply_count": "Primijeni ({count, number})",
"archive": "Arhiva",
"archive_action_prompt": "{count} dodano u arhivu",
"archive_or_unarchive_photo": "Arhivirajte ili dearhivirajte fotografiju",
@@ -474,7 +480,7 @@
"archive_size": "Veličina arhive",
"archive_size_description": "Konfigurirajte veličinu arhive za preuzimanja (u GiB)",
"archived": "Arhivirano",
"archived_count": "{count, plural, other {Archived #}}",
"archived_count": "{count, plural, one {Arhivirana #} few {Arhivirane #} other {Arhivirano #}}",
"are_these_the_same_person": "Je li ovo ista osoba?",
"are_you_sure_to_do_this": "Jeste li sigurni da to želite učiniti?",
"asset_action_delete_err_read_only": "Nije moguće izbrisati stavke samo za čitanje, preskakanje",
@@ -511,22 +517,22 @@
"assets_cannot_be_added_to_album_count": "{count, plural, one {Stavka se ne može} other {Stavke se ne mogu}} dodati u album",
"assets_cannot_be_added_to_albums": "{count, plural, one {Stavka se ne može} few {Stavke se ne mogu} other {Stavki se ne može}} dodati ni u jedan album",
"assets_count": "{count, plural, one {# stavka} few {# stavke} other {# stavki}}",
"assets_deleted_permanently": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbrisano # stavki}}",
"assets_deleted_permanently": "{count, plural, one {# stavka trajno izbrisana} few {# stavke trajno izbrisane} other {# stavki trajno izbrisano}}",
"assets_deleted_permanently_from_server": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbrisano # stavki}} s Immich servera",
"assets_downloaded_failed": "{count, plural, one {Preuzeta # datoteka {error} datoteka nije uspjela} few {Preuzete # datoteke - {error} datoteke nisu uspjele} other {Preuzeto # datoteka {error} datoteke nisu uspjele}}",
"assets_downloaded_successfully": "{count, plural, one {Uspješno preuzeta # datoteka} few {Uspješno preuzete # datoteke} other {Uspješno preueto # datoteka}}",
"assets_moved_to_trash_count": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavk premještenoi}} u smeće",
"assets_permanently_deleted_count": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbrisano # stavki}}",
"assets_removed_count": "{count, plural, one {Uklonjena # stavka} few {Uklonjene # stavke} other {Uklonjeno # stavki}}",
"assets_removed_permanently_from_device": "{count} resurs(i) trajno uklonjen(i) s vašeg uređaja",
"assets_restore_confirmation": "Jeste li sigurni da želite obnoviti sve svoje resurse bačene u otpad? Ne možete poništiti ovu radnju! Imajte na umu da se bilo koji izvanmrežni resursi ne mogu obnoviti na ovaj način.",
"assets_restored_count": "Vraćeno {count, plural, one {# asset} other {# assets}}",
"assets_restored_successfully": "{count} resurs(i) uspješno obnovljen(i)",
"assets_trashed": "{count} resurs(i) premješten(i) u smeće",
"assets_trashed_count": "Bačeno u smeće {count, plural, one {# asset} other {# assets}}",
"assets_trashed_from_server": "{count} resurs(i) premješten(i) u smeće s Immich poslužitelja",
"assets_were_part_of_album_count": "{count, plural, one {Asset was} other {Assets were}} već dio albuma",
"assets_were_part_of_albums_count": "{count, plural, one {Datoteka je već bila dio albuma} few {Datoteke su već bile dio albuma} other {Datoteka je već bila dio albuma}}",
"assets_removed_permanently_from_device": "{count, plural, one {# stavka trajno uklonjena} few {# stavke trajno uklonjene} other {# stavki trajno uklonjeno}} s vašeg uređaja",
"assets_restore_confirmation": "Jeste li sigurni da želite vratiti sve svoje izbrisane stavke? Ovu radnju ne možete poništiti! Imajte na umu da se na ovaj način ne mogu vratiti izvanmrežne stavke.",
"assets_restored_count": "{count, plural, one {Vraćena # stavka} few {Vraćene # stavke} other {Vraćeno # stavki}}",
"assets_restored_successfully": "{count, plural, one {# stavka uspješno obnovljena} few {# stavke uspješno obnovljene} other {# stavki uspješno obnovljeno}}",
"assets_trashed": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavki premješteno}} u smeće",
"assets_trashed_count": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavki premješteno}} u smeće",
"assets_trashed_from_server": "{count, plural, one {# stavka premještena} few {# stavke premještene} other {# stavki premješteno}} u smeće s Immich poslužitelja",
"assets_were_part_of_album_count": "{count, plural, one {Stavka je već bila} other {Stavke su već bile}} dio albuma",
"assets_were_part_of_albums_count": "{count, plural, one {Stavka je već bila} other {Stavke su već bile}} dio albuma",
"authorized_devices": "Ovlašteni uređaji",
"automatic_endpoint_switching_subtitle": "Povežite se lokalno preko naznačene Wi-Fi mreže kada je dostupna i koristite alternativne veze na drugim lokacijama",
"automatic_endpoint_switching_title": "Automatsko prebacivanje URL-a",
@@ -538,17 +544,18 @@
"backup": "Sigurnosna kopija",
"backup_album_selection_page_albums_device": "Albumi na uređaju ({count})",
"backup_album_selection_page_albums_tap": "Dodirnite za uključivanje, dvostruki dodir za isključivanje",
"backup_album_selection_page_assets_scatter": "Resursi mogu biti raspoređeni u više albuma. Stoga, albumi mogu biti uključeni ili isključeni tijekom procesa sigurnosnog kopiranja.",
"backup_album_selection_page_assets_scatter": "Stavke se mogu raspršiti po više albuma. Stoga se albumi mogu uključiti ili isključiti tijekom postupka sigurnosnog kopiranja.",
"backup_album_selection_page_select_albums": "Odabrani albumi",
"backup_album_selection_page_selection_info": "Informacije o odabiru",
"backup_album_selection_page_total_assets": "Ukupan broj jedinstvenih resursa",
"backup_album_selection_page_total_assets": "Ukupan broj jedinstvenih stavki",
"backup_all": "Sve",
"backup_background_service_backup_failed_message": "Neuspješno sigurnosno kopiranje resursa. Pokušavam ponovo…",
"backup_background_service_backup_failed_message": "Neuspješno sigurnosno kopiranje stavki. Ponovno pokušavanje…",
"backup_background_service_complete_notification": "Sigurnosno kopiranje stavki dovršeno",
"backup_background_service_connection_failed_message": "Neuspješno povezivanje s poslužiteljem. Pokušavam ponovo…",
"backup_background_service_current_upload_notification": "Šaljem {filename}",
"backup_background_service_default_notification": "Provjera novih resursa…",
"backup_background_service_default_notification": "Provjera novih stavki…",
"backup_background_service_error_title": "Pogreška pri sigurnosnom kopiranju",
"backup_background_service_in_progress_notification": "Sigurnosno kopiranje vaših resursa…",
"backup_background_service_in_progress_notification": "Sigurnosno kopiranje vaših stavki…",
"backup_background_service_upload_failure_notification": "Neuspješno slanje {filename}",
"backup_controller_page_albums": "Sigurnosno kopiranje albuma",
"backup_controller_page_background_app_refresh_disabled_content": "Omogućite osvježavanje aplikacije u pozadini u Postavke > Opće Postavke > Osvježavanje Aplikacija u Pozadini kako biste koristili sigurnosno kopiranje u pozadini.",
@@ -560,8 +567,8 @@
"backup_controller_page_background_battery_info_title": "Optimizacije baterije",
"backup_controller_page_background_charging": "Samo tijekom punjenja",
"backup_controller_page_background_configure_error": "Neuspješno konfiguriranje pozadinske usluge",
"backup_controller_page_background_delay": "Odgođeno sigurnosno kopiranje novih resursa: {duration}",
"backup_controller_page_background_description": "Uključite pozadinsku uslugu kako biste automatski sigurnosno kopirali nove resurse bez potrebe za otvaranjem aplikacije",
"backup_controller_page_background_delay": "Odgoda sigurnosnog kopiranja novih stavki: {duration}",
"backup_controller_page_background_description": "Uključite pozadinsku uslugu za automatsko sigurnosno kopiranje svih novih stavki bez potrebe za otvaranjem aplikacije",
"backup_controller_page_background_is_off": "Automatsko sigurnosno kopiranje u pozadini je isključeno",
"backup_controller_page_background_is_on": "Automatsko sigurnosno kopiranje u pozadini je uključeno",
"backup_controller_page_background_turn_off": "Isključite pozadinsku uslugu",
@@ -571,7 +578,7 @@
"backup_controller_page_backup_selected": "Odabrani: ",
"backup_controller_page_backup_sub": "Sigurnosno kopirane fotografije i videozapisi",
"backup_controller_page_created": "Kreirano: {date}",
"backup_controller_page_desc_backup": "Uključite sigurnosno kopiranje u prvom planu kako biste automatski prenijeli nove resurse na poslužitelj prilikom otvaranja aplikacije.",
"backup_controller_page_desc_backup": "Uključite sigurnosno kopiranje u prvom planu kako biste automatski prenijeli nove stavke na poslužitelj prilikom otvaranja aplikacije.",
"backup_controller_page_excluded": "Izuzeto: ",
"backup_controller_page_failed": "Neuspješno ({count})",
"backup_controller_page_filename": "Naziv datoteke: {filename} [{size}]",
@@ -591,7 +598,7 @@
"backup_controller_page_turn_on": "Uključite sigurnosno kopiranje u prvom planu",
"backup_controller_page_uploading_file_info": "Slanje informacija o datoteci",
"backup_err_only_album": "Nije moguće ukloniti jedini album",
"backup_info_card_assets": "resursi",
"backup_info_card_assets": "stavke",
"backup_manual_cancelled": "Otkazano",
"backup_manual_in_progress": "Slanje već u tijeku. Pokšuajte nakon nekog vremena",
"backup_manual_success": "Uspijeh",
@@ -611,15 +618,15 @@
"bugs_and_feature_requests": "Bugovi i zahtjevi za značajke",
"build": "Sagradi (Build)",
"build_image": "Sagradi (Build) Image",
"bulk_delete_duplicates_confirmation": "Jeste li sigurni da želite skupno izbrisati {count, plural, one {# duplicate asset} other {# duplicate asset}}? Ovo će zadržati najveće sredstvo svake grupe i trajno izbrisati sve druge duplikate. Ne možete poništiti ovu radnju!",
"bulk_delete_duplicates_confirmation": "Jeste li sigurni da želite skupno izbrisati {count, plural, one {# dupliciranu stavku} few {# duplicirane stavke} other {# dupliciranih stavki}}? Ovo će zadržati najveću stavku svake grupe i trajno izbrisati sve druge duplikate. Ne možete poništiti ovu radnju!",
"bulk_keep_duplicates_confirmation": "Jeste li sigurni da želite zadržati {count, plural, one {# duplicate asset} other {# duplicate asset}}? Ovo će riješiti sve duplicirane grupe bez brisanja ičega.",
"bulk_trash_duplicates_confirmation": "Jeste li sigurni da želite na veliko baciti u smeće {count, plural, one {# duplicate asset} other {# duplicate asset}}? Ovo će zadržati najveće sredstvo svake grupe i baciti sve ostale duplikate u smeće.",
"bulk_trash_duplicates_confirmation": "Jeste li sigurni da želite skupno u smeće premjestiti {count, plural, one {# dupliciranu stavku} few {# duplicirane stavke} other {# dupliciranih stavki}}? Ovo će zadržati najveću stavku svake grupe i premjestiti sve ostale duplikate u smeće.",
"buy": "Kupi Immich",
"cache_settings_clear_cache_button": "Očisti predmemoriju",
"cache_settings_clear_cache_button_title": "Briše predmemoriju aplikacije. Ovo će značajno utjecati na performanse aplikacije dok se predmemorija ponovno ne izgradi.",
"cache_settings_duplicated_assets_clear_button": "OČISTI",
"cache_settings_duplicated_assets_subtitle": "Fotografije i videozapisi koje je aplikacija ignorira",
"cache_settings_duplicated_assets_title": "Duplicirani resursi ({count})",
"cache_settings_duplicated_assets_subtitle": "Fotografije i videozapisi koje aplikacija ignorira",
"cache_settings_duplicated_assets_title": "Duplicirane stavke ({count})",
"cache_settings_statistics_album": "Sličice biblioteke",
"cache_settings_statistics_full": "Pune slike",
"cache_settings_statistics_shared": "Sličice dijeljenih albuma",
@@ -676,8 +683,8 @@
"client_cert_import_success_msg": "Klijentski certifikat je uvezen",
"client_cert_invalid_msg": "Neispravna datoteka certifikata ili pogrešna lozinka",
"client_cert_remove_msg": "Klijentski certifikat je uklonjen",
"client_cert_subtitle": "Podržava samo PKCS12 (.p12, .pfx) format. Uvoz/uklanjanje certifikata moguće je samo prije prijave",
"client_cert_title": "SSL klijentski certifikat",
"client_cert_subtitle": "Podržava samo PKCS12 (.p12, .pfx) format. Uvoz/uklanjanje certifikata dostupno je samo prije prijave",
"client_cert_title": "SSL klijentski certifikat [EKSPERIMENTALNO]",
"clockwise": "U smjeru kazaljke na satu",
"close": "Zatvori",
"collapse": "Sažmi",
@@ -689,13 +696,12 @@
"comments_and_likes": "Komentari i lajkovi",
"comments_are_disabled": "Komentari onemogućeni",
"common_create_new_album": "Kreiraj novi album",
"common_server_error": "Provjerite svoju mrežnu vezu, osigurajte da je poslužitelj dostupan i da su verzije aplikacije/poslužitelja kompatibilne.",
"completed": "Dovršeno",
"confirm": "Potvrdi",
"confirm_admin_password": "Potvrdite lozinku administratora",
"confirm_delete_face": "Jeste li sigurni da želite izbrisati lice {name} iz resursa?",
"confirm_delete_face": "Jeste li sigurni da želite izbrisati lice {name} iz stavke?",
"confirm_delete_shared_link": "Jeste li sigurni da želite izbrisati ovu zajedničku vezu?",
"confirm_keep_this_delete_others": "Sva druga sredstva u nizu bit će izbrisana osim ovog sredstva. Jeste li sigurni da želite nastaviti?",
"confirm_keep_this_delete_others": "Sve druge stavke u stogu bit će izbrisane osim ove stavke. Jeste li sigurni da želite nastaviti?",
"confirm_new_pin_code": "Potvrdi novi PIN kod",
"confirm_password": "Potvrdite lozinku",
"confirm_tag_face": "Želite li označiti ovo lice kao {name}?",
@@ -711,7 +717,7 @@
"control_bottom_app_bar_edit_location": "Uredi lokaciju",
"control_bottom_app_bar_edit_time": "Uredi datum i vrijeme",
"control_bottom_app_bar_share_link": "Podijeli poveznicu",
"control_bottom_app_bar_share_to": "Podijeli s...",
"control_bottom_app_bar_share_to": "Dijeli s",
"control_bottom_app_bar_trash_from_immich": "Premjesti u smeće",
"copied_image_to_clipboard": "Slika je kopirana u međuspremnik.",
"copied_to_clipboard": "Kopirano u međuspremnik!",
@@ -734,7 +740,7 @@
"create_link_to_share_description": "Dopusti svakome s vezom da vidi odabrane fotografije",
"create_new": "KREIRAJ NOVO",
"create_new_person": "Stvorite novu osobu",
"create_new_person_hint": "Dodijelite odabrana sredstva novoj osobi",
"create_new_person_hint": "Dodijelite odabrane stavke novoj osobi",
"create_new_user": "Kreiraj novog korisnika",
"create_shared_album_page_share_add_assets": "DODAJ STAVKE",
"create_shared_album_page_share_select_photos": "Odaberi fotografije",
@@ -772,7 +778,7 @@
"default_locale": "Zadana lokalizacija",
"default_locale_description": "Oblikujte datume i brojeve na temelju jezika preglednika",
"delete": "Izbriši",
"delete_action_confirmation_message": "Jeste li sigurni da želite izbrisati ovaj sadržaj? Ova radnja će premjestiti sadržaj u smeće na poslužitelju i upitat će vas želite li ga izbrisati i lokalno",
"delete_action_confirmation_message": "Jeste li sigurni da želite izbrisati ovu stavku? Ova radnja će premjestiti stavku u smeće poslužitelja i pitati vas želite li ju izbrisati lokalno",
"delete_action_prompt": "{count} izbrisano",
"delete_album": "Izbriši album",
"delete_api_key_prompt": "Jeste li sigurni da želite izbrisati ovaj API ključ?",
@@ -799,7 +805,7 @@
"delete_tag_confirmation_prompt": "Jeste li sigurni da želite izbrisati oznaku {tagName}?",
"delete_user": "Izbriši korisnika",
"deleted_shared_link": "Izbrisana dijeljena poveznica",
"deletes_missing_assets": "Briše sredstva koja nedostaju s diska",
"deletes_missing_assets": "Briše stavke koje nedostaju na disku",
"description": "Opis",
"description_input_hint_text": "Dodaj opis...",
"description_input_submit_error": "Pogreška pri ažuriranju opisa, provjerite zapisnik za više detalja",
@@ -816,12 +822,12 @@
"display_options": "Mogućnosti prikaza",
"display_order": "Redoslijed prikaza",
"display_original_photos": "Prikaz originalnih fotografija",
"display_original_photos_setting_description": "Radije prikažite izvornu fotografiju kada gledate materijal umjesto sličica kada je izvorni materijal kompatibilan s webom. To može rezultirati sporijim brzinama prikaza fotografija.",
"display_original_photos_setting_description": "Radije prikažite izvornu fotografiju kada gledate stavku umjesto sličica kada je izvorna stavka kompatibilna s webom. To može rezultirati sporijim brzinama prikaza fotografija.",
"do_not_show_again": "Ne prikazuj više ovu poruku",
"documentation": "Dokumentacija",
"done": "Gotovo",
"download": "Preuzmi",
"download_action_prompt": "Preuzimanje {count} sadržaja",
"download_action_prompt": "Preuzimanje {count, plural, one {# stavke} few {# stavke} other {# stavki}}",
"download_canceled": "Preuzimanje otkazano",
"download_complete": "Preuzimanje završeno",
"download_enqueue": "Preuzimanje dodano u red",
@@ -833,13 +839,13 @@
"download_notfound": "Preuzimanje nije pronađeno",
"download_paused": "Preuzimanje pauzirano",
"download_settings": "Preuzmi",
"download_settings_description": "Upravljajte postavkama koje se odnose na preuzimanje sredstava",
"download_settings_description": "Upravljajte postavkama vezanim uz preuzimanje stavki",
"download_started": "Preuzimanje započeto",
"download_sucess": "Preuzimanje uspješno",
"download_sucess_android": "Medij je preuzet u DCIM/Immich",
"download_waiting_to_retry": "Čeka se ponovni pokušaj",
"downloading": "Preuzimanje",
"downloading_asset_filename": "Preuzimanje materijala {filename}",
"downloading_asset_filename": "Preuzimanje stavke {filename}",
"downloading_media": "Preuzimanje medija",
"drop_files_to_upload": "Ispustite datoteke bilo gdje za prijenos",
"duplicates": "Duplikati",
@@ -858,8 +864,6 @@
"edit_description_prompt": "Molimo odaberite novi opis:",
"edit_exclusion_pattern": "Uredi uzorak izuzimanja",
"edit_faces": "Uređivanje lica",
"edit_import_path": "Uredi put uvoza",
"edit_import_paths": "Uredi Uvozne Putanje",
"edit_key": "Ključ za uređivanje",
"edit_link": "Uredi poveznicu",
"edit_location": "Uredi lokaciju",
@@ -870,7 +874,6 @@
"edit_tag": "Uredi oznaku",
"edit_title": "Uredi Naslov",
"edit_user": "Uredi korisnika",
"edited": "Uređeno",
"editor": "Urednik",
"editor_close_without_save_prompt": "Promjene neće biti spremljene",
"editor_close_without_save_title": "Zatvoriti uređivač?",
@@ -880,7 +883,7 @@
"email_notifications": "Obavijesti putem e-maila",
"empty_folder": "Ova mapa je prazna",
"empty_trash": "Isprazni smeće",
"empty_trash_confirmation": "Jeste li sigurni da želite isprazniti smeće? Time će se iz Immicha trajno ukloniti sva sredstva u otpadu.\nNe možete poništiti ovu radnju!",
"empty_trash_confirmation": "Jeste li sigurni da želite isprazniti smeće? Time će se iz Immicha trajno ukloniti sve stavke u smeću.\nNe možete poništiti ovu radnju!",
"enable": "Omogući",
"enable_backup": "Omogući sigurnosnu kopiju",
"enable_biometric_auth_description": "Unesite svoj PIN kod za omogućavanje biometrijske autentikacije",
@@ -898,57 +901,55 @@
"error_tag_face_bounding_box": "Pogreška pri označavanju lica nije moguće dohvatiti koordinate granica (bounding box)",
"error_title": "Greška - Nešto je pošlo krivo",
"errors": {
"cannot_navigate_next_asset": "Nije moguće prijeći na sljedeći materijal",
"cannot_navigate_previous_asset": "Nije moguće prijeći na prethodni materijal",
"cannot_navigate_next_asset": "Nije moguće prijeći na sljedeću stavku",
"cannot_navigate_previous_asset": "Nije moguće prijeći na prethodnu stavku",
"cant_apply_changes": "Nije moguće primijeniti promjene",
"cant_change_activity": "Nije moguće {enabled, select, true {onemogućiti} other {omogućiti}} aktivnost",
"cant_change_asset_favorite": "Nije moguće promijeniti favorita za sredstvo",
"cant_change_metadata_assets_count": "Nije moguće promijeniti metapodatke {count, plural, one {# asset} other {# assets}}",
"cant_change_asset_favorite": "Nije moguće promijeniti favorita za stavku",
"cant_change_metadata_assets_count": "Nije moguće promijeniti metapodatke {count, plural, one {# stavke} few {# stavke} other {# stavki}}",
"cant_get_faces": "Ne mogu dobiti lica",
"cant_get_number_of_comments": "Ne mogu dobiti broj komentara",
"cant_search_people": "Ne mogu pretraživati ljude",
"cant_search_places": "Ne mogu pretraživati mjesta",
"error_adding_assets_to_album": "Pogreška pri dodavanju materijala u album",
"error_adding_assets_to_album": "Pogreška pri dodavanju stavki u album",
"error_adding_users_to_album": "Pogreška pri dodavanju korisnika u album",
"error_deleting_shared_user": "Pogreška pri brisanju dijeljenog korisnika",
"error_downloading": "Pogreška pri preuzimanju {filename}",
"error_hiding_buy_button": "Pogreška pri skrivanju gumba za kupnju",
"error_removing_assets_from_album": "Pogreška prilikom uklanjanja materijala iz albuma, provjerite konzolu za više pojedinosti",
"error_selecting_all_assets": "Pogreška pri odabiru svih sredstava",
"error_removing_assets_from_album": "Pogreška prilikom uklanjanja stavki iz albuma, provjerite konzolu za više detalja",
"error_selecting_all_assets": "Pogreška pri odabiru svih stavki",
"exclusion_pattern_already_exists": "Ovaj uzorak izuzimanja već postoji.",
"failed_to_create_album": "Izrada albuma nije uspjela",
"failed_to_create_shared_link": "Stvaranje dijeljene veze nije uspjelo",
"failed_to_edit_shared_link": "Nije uspjelo uređivanje dijeljene poveznice",
"failed_to_get_people": "Dohvaćanje ljudi nije uspjelo",
"failed_to_keep_this_delete_others": "Zadržavanje ovog sredstva i brisanje ostalih sredstava nije uspjelo",
"failed_to_load_asset": "Učitavanje sredstva nije uspjelo",
"failed_to_load_assets": "Učitavanje sredstava nije uspjelo",
"failed_to_get_people": "Dohvaćanje osoba nije uspjelo",
"failed_to_keep_this_delete_others": "Zadržavanje ove stavke i brisanje ostalih stavki nije uspjelo",
"failed_to_load_asset": "Učitavanje stavke nije uspjelo",
"failed_to_load_assets": "Učitavanje stavki nije uspjelo",
"failed_to_load_notifications": "Neuspješno učitavanje obavijesti",
"failed_to_load_people": "Učitavanje ljudi nije uspjelo",
"failed_to_load_people": "Učitavanje osoba nije uspjelo",
"failed_to_remove_product_key": "Uklanjanje ključa proizvoda nije uspjelo",
"failed_to_reset_pin_code": "Neuspješno resetiranje PIN koda",
"failed_to_stack_assets": "Slaganje sredstava nije uspjelo",
"failed_to_unstack_assets": "Nije uspjelo uklanjanje snopa sredstava",
"failed_to_stack_assets": "Slaganje stavki nije uspjelo",
"failed_to_unstack_assets": "Razdvajanje stavki nije uspjelo",
"failed_to_update_notification_status": "Neuspješno ažuriranje statusa obavijesti",
"import_path_already_exists": "Ovaj uvozni put već postoji.",
"incorrect_email_or_password": "Netočna adresa e-pošte ili lozinka",
"paths_validation_failed": "{paths, plural, one {# putanja nije prošla} other {# putanje nisu prošle}} provjeru valjanosti",
"profile_picture_transparent_pixels": "Profilne slike ne smiju imati prozirne piksele. Povećajte i/ili pomaknite sliku.",
"quota_higher_than_disk_size": "Postavili ste kvotu veću od veličine diska",
"something_went_wrong": "Nešto je pošlo po zlu",
"unable_to_add_album_users": "Nije moguće dodati korisnike u album",
"unable_to_add_assets_to_shared_link": "Nije moguće dodati sredstva na dijeljenu poveznicu",
"unable_to_add_assets_to_shared_link": "Nije moguće dodati stavke u dijeljenu vezu",
"unable_to_add_comment": "Nije moguće dodati komentar",
"unable_to_add_exclusion_pattern": "Nije moguće dodati uzorak izuzimanja",
"unable_to_add_import_path": "Nije moguće dodati putanju uvoza",
"unable_to_add_partners": "Nije moguće dodati partnere",
"unable_to_add_remove_archive": "Nije moguće {archived, select, true {ukloniti resurs iz} other {dodati resurs u}} arhivu",
"unable_to_add_remove_archive": "Nije moguće {archived, select, true {ukloniti stavku iz} other {dodati stavku u}} arhivu",
"unable_to_add_remove_favorites": "Nije moguće {favorite, select, true {add asset to} other {remove asset from}} favorite",
"unable_to_archive_unarchive": "Nije moguće {archived, select, true {arhivirati} other {dearhivirati}}",
"unable_to_change_album_user_role": "Nije moguće promijeniti ulogu korisnika albuma",
"unable_to_change_date": "Nije moguće promijeniti datum",
"unable_to_change_description": "Nije moguće promijeniti opis",
"unable_to_change_favorite": "Nije moguće promijeniti favorita za sredstvo",
"unable_to_change_favorite": "Nije moguće promijeniti favorita za stavku",
"unable_to_change_location": "Nije moguće promijeniti lokaciju",
"unable_to_change_password": "Nije moguće promijeniti lozinku",
"unable_to_change_visibility": "Nije moguće promijeniti vidljivost za {count, plural, one {# osobu} other {# osobe}}",
@@ -960,15 +961,13 @@
"unable_to_create_library": "Nije moguće stvoriti biblioteku",
"unable_to_create_user": "Nije moguće stvoriti korisnika",
"unable_to_delete_album": "Nije moguće izbrisati album",
"unable_to_delete_asset": "Nije moguće izbrisati sredstvo",
"unable_to_delete_assets": "Pogreška pri brisanju sredstava",
"unable_to_delete_asset": "Nije moguće izbrisati stavku",
"unable_to_delete_assets": "Pogreška pri brisanju stavki",
"unable_to_delete_exclusion_pattern": "Nije moguće izbrisati uzorak izuzimanja",
"unable_to_delete_import_path": "Nije moguće izbrisati put uvoza",
"unable_to_delete_shared_link": "Nije moguće izbrisati dijeljenu poveznicu",
"unable_to_delete_user": "Nije moguće izbrisati korisnika",
"unable_to_download_files": "Nije moguće preuzeti datoteke",
"unable_to_edit_exclusion_pattern": "Nije moguće urediti uzorak izuzimanja",
"unable_to_edit_import_path": "Nije moguće urediti put uvoza",
"unable_to_empty_trash": "Nije moguće isprazniti otpad",
"unable_to_enter_fullscreen": "Nije moguće otvoriti cijeli zaslon",
"unable_to_exit_fullscreen": "Nije moguće izaći iz cijelog zaslona",
@@ -981,19 +980,19 @@
"unable_to_log_out_device": "Nije moguće odjaviti uređaj",
"unable_to_login_with_oauth": "Nije moguće prijaviti se pomoću OAutha",
"unable_to_play_video": "Nije moguće reproducirati video",
"unable_to_reassign_assets_existing_person": "Nije moguće ponovno dodijeliti imovinu na {name, select, null {postojeću osobu} other {{name}}}",
"unable_to_reassign_assets_new_person": "Nije moguće ponovno dodijeliti imovinu novoj osobi",
"unable_to_reassign_assets_existing_person": "Nije moguće ponovno dodijeliti stavke {name, select, null {postojećoj osobi} other {{name}}}",
"unable_to_reassign_assets_new_person": "Nije moguće ponovno dodijeliti stavke novoj osobi",
"unable_to_refresh_user": "Nije moguće osvježiti korisnika",
"unable_to_remove_album_users": "Nije moguće ukloniti korisnike iz albuma",
"unable_to_remove_api_key": "Nije moguće ukloniti API ključ",
"unable_to_remove_assets_from_shared_link": "Nije moguće ukloniti sredstva iz dijeljene poveznice",
"unable_to_remove_assets_from_shared_link": "Nije moguće ukloniti stavke iz dijeljene veze",
"unable_to_remove_library": "Nije moguće ukloniti biblioteku",
"unable_to_remove_partner": "Nije moguće ukloniti partnera",
"unable_to_remove_reaction": "Nije moguće ukloniti reakciju",
"unable_to_reset_password": "Nije moguće ponovno postaviti lozinku",
"unable_to_reset_pin_code": "Nije moguće poništiti PIN kod",
"unable_to_resolve_duplicate": "Nije moguće razriješiti duplikat",
"unable_to_restore_assets": "Nije moguće vratiti imovinu",
"unable_to_restore_assets": "Nije moguće vratiti stavke",
"unable_to_restore_trash": "Nije moguće vratiti otpad",
"unable_to_restore_user": "Nije moguće vratiti korisnika",
"unable_to_save_album": "Nije moguće spremiti album",
@@ -1007,7 +1006,7 @@
"unable_to_set_feature_photo": "Nije moguće postaviti istaknutu fotografiju",
"unable_to_set_profile_picture": "Nije moguće postaviti profilnu sliku",
"unable_to_submit_job": "Nije moguće poslati posao",
"unable_to_trash_asset": "Nije moguće baciti sredstvo u smeće",
"unable_to_trash_asset": "Nije moguće premjestiti stavku u smeće",
"unable_to_unlink_account": "Nije moguće prekinuti vezu računa",
"unable_to_unlink_motion_video": "Nije moguće prekinuti vezu videozapisa pokreta",
"unable_to_update_album_cover": "Nije moguće ažurirati omot albuma",
@@ -1049,13 +1048,13 @@
"face_unassigned": "Nedodijeljeno",
"failed": "Neuspješno",
"failed_to_authenticate": "Neuspješna autentikacija",
"failed_to_load_assets": "Neuspjelo učitavanje stavki",
"failed_to_load_assets": "Učitavanje stavki nije uspjelo",
"failed_to_load_folder": "Neuspjelo učitavanje mape",
"favorite": "Omiljeno",
"favorite_action_prompt": "{count} dodano u Omiljeno",
"favorite_or_unfavorite_photo": "Omiljena ili neomiljena fotografija",
"favorites": "Omiljene",
"favorites_page_no_favorites": "Nema pronađenih omiljenih stavki",
"favorites_page_no_favorites": "Nema pronađenih favorita",
"feature_photo_updated": "Istaknuta fotografija ažurirana",
"features": "Značajke",
"features_setting_description": "Upravljajte značajkama aplikacije",
@@ -1076,8 +1075,9 @@
"forgot_pin_code_question": "Zaboravili ste svoj PIN?",
"forward": "Naprijed",
"gcast_enabled": "Google Cast",
"gcast_enabled_description": "Ova značajka učitava vanjske resurse s Googlea kako bi radila.",
"gcast_enabled_description": "Ova značajka učitava vanjske stavke s Googlea kako bi radila.",
"general": "Općenito",
"geolocation_instruction_location": "Kliknite na stavku s GPS koordinatama da biste koristili njezinu lokaciju ili odaberite lokaciju izravno s karte",
"get_help": "Potražite pomoć",
"get_wifiname_error": "Nije moguće dohvatiti naziv Wi-Fi mreže. Provjerite imate li potrebna dopuštenja i jeste li povezani na Wi-Fi mrežu",
"getting_started": "Početak Rada",
@@ -1094,14 +1094,13 @@
"haptic_feedback_switch": "Omogući haptičku povratnu informaciju",
"haptic_feedback_title": "Haptička povratna informacija",
"has_quota": "Ima kvotu",
"hash_asset": "Hash sadržaja",
"hashed_assets": "Hashirani sadržaji",
"hash_asset": "Hashiraj stavku",
"hashed_assets": "Hashirane stavke",
"hashing": "Hashiranje",
"header_settings_add_header_tip": "Dodaj zaglavlje",
"header_settings_field_validator_msg": "Vrijednost ne može biti prazna",
"header_settings_header_name_input": "Naziv zaglavlja",
"header_settings_header_value_input": "Vrijednost zaglavlja",
"headers_settings_tile_subtitle": "Definirajte proxy zaglavlja koja aplikacija treba slati sa svakim mrežnim zahtjevom",
"headers_settings_tile_title": "Prilagođena proxy zaglavlja",
"hi_user": "Bok {name} ({email})",
"hide_all_people": "Sakrij sve ljude",
@@ -1111,21 +1110,21 @@
"hide_person": "Sakrij osobu",
"hide_unnamed_people": "Sakrij neimenovane osobe",
"home_page_add_to_album_conflicts": "Dodano {added} stavki u album {album}. {failed} stavki je već u albumu.",
"home_page_add_to_album_err_local": "Lokalne stavke još nije moguće dodati u albume, preskačem",
"home_page_add_to_album_err_local": "Lokalne stavke još nije moguće dodati u albume, preskakanje",
"home_page_add_to_album_success": "Dodano {added} stavki u album {album}.",
"home_page_album_err_partner": "Još nije moguće dodati partnerske stavke u album, preskačem",
"home_page_archive_err_local": "Lokalne stavke još nije moguće arhivirati, preskačem",
"home_page_archive_err_partner": "Partnerske stavke nije moguće arhivirati, preskačem",
"home_page_album_err_partner": "Još nije moguće dodati partnerove stavke u album, preskakanje",
"home_page_archive_err_local": "Lokalne stavke još nije moguće arhivirati, preskakanje",
"home_page_archive_err_partner": "Partnerove stavke nije moguće arhivirati, preskakanje",
"home_page_building_timeline": "Izrada vremenske crte",
"home_page_delete_err_partner": "Nije moguće izbrisati partnerske stavke, preskačem",
"home_page_delete_remote_err_local": "Lokalne stavke su u odabiru za udaljeno brisanje, preskačem",
"home_page_favorite_err_local": "Lokalne stavke još nije moguće označiti kao omiljene, preskačem",
"home_page_favorite_err_partner": "Partnerske stavke još nije moguće označiti kao omiljene, preskačem",
"home_page_delete_err_partner": "Nije moguće izbrisati partnerove stavke, preskakanje",
"home_page_delete_remote_err_local": "Lokalne stavke su u odabiru za udaljeno brisanje, preskakanje",
"home_page_favorite_err_local": "Lokalne stavke još nije moguće označiti kao favorite, preskakanje",
"home_page_favorite_err_partner": "Partnerove stavke još nije moguće označiti kao favorite, preskakanje",
"home_page_first_time_notice": "Ako prvi put koristite aplikaciju, svakako odaberite album za sigurnosnu kopiju kako bi vremenska crta mogla prikazati fotografije i videozapise",
"home_page_locked_error_local": "Nije moguće premjestiti lokalne resurse u zaključanu mapu, preskačem",
"home_page_locked_error_partner": "Nije moguće premjestiti partnerske resurse u zaključanu mapu, preskačem",
"home_page_share_err_local": "Lokalne stavke nije moguće dijeliti putem poveznice, preskačem",
"home_page_upload_err_limit": "Moguće je prenijeti najviše 30 stavki odjednom, preskačem",
"home_page_locked_error_local": "Nije moguće premjestiti lokalne stavke u zaključanu mapu, preskakanje",
"home_page_locked_error_partner": "Nije moguće premjestiti partnerove stavke u zaključanu mapu, preskakanje",
"home_page_share_err_local": "Lokalne stavke nije moguće dijeliti putem poveznice, preskakanje",
"home_page_upload_err_limit": "Moguće je prenijeti najviše 30 stavki odjednom, preskakanje",
"host": "Domaćin",
"hour": "Sat",
"hours": "Sati",
@@ -1156,7 +1155,7 @@
"in_archive": "U arhivi",
"include_archived": "Uključi arhivirano",
"include_shared_albums": "Uključi dijeljene albume",
"include_shared_partner_assets": "Uključite zajedničku imovinu partnera",
"include_shared_partner_assets": "Uključi zajedničke stavke partnera",
"individual_share": "Pojedinačni udio",
"individual_shares": "Pojedinačna dijeljenja",
"info": "Informacije",
@@ -1181,7 +1180,7 @@
"keep": "Zadrži",
"keep_all": "Zadrži Sve",
"keep_this_delete_others": "Zadrži ovo, izbriši ostale",
"kept_this_deleted_others": "Zadržana je ova datoteka i izbrisano {count, plural, one {# datoteka} other {# datoteka}}",
"kept_this_deleted_others": "Zadržana je ova stavka i {count, plural, one {izbrisana # datoteka} few {izbrisane # datoteke} other {izbrisano # datoteka}}",
"keyboard_shortcuts": "Prečaci tipkovnice",
"language": "Jezik",
"language_no_results_subtitle": "Pokušajte prilagoditi pojam za pretraživanje",
@@ -1202,7 +1201,7 @@
"library_options": "Mogućnosti biblioteke",
"library_page_device_albums": "Albumi na uređaju",
"library_page_new_album": "Novi album",
"library_page_sort_asset_count": "Broj resursa",
"library_page_sort_asset_count": "Broj stavki",
"library_page_sort_created": "Datum kreiranja",
"library_page_sort_last_modified": "Zadnja izmjena",
"library_page_sort_title": "Naslov albuma",
@@ -1217,8 +1216,8 @@
"loading": "Učitavanje",
"loading_search_results_failed": "Učitavanje rezultata pretraživanja nije uspjelo",
"local": "Lokalno",
"local_asset_cast_failed": "Nije moguće reproducirati sadržaj koji nije prenesen na poslužitelj",
"local_assets": "Lokalni sadržaji",
"local_asset_cast_failed": "Nije moguće emitirati stavku koja nije prenesena na poslužitelj",
"local_assets": "Lokalne stavke",
"local_network": "Lokalna mreža",
"local_network_sheet_info": "Aplikacija će se povezati s poslužiteljem putem ovog URL-a kada koristi određenu Wi-Fi mrežu",
"location_permission": "Dozvola za lokaciju",
@@ -1275,7 +1274,7 @@
"manage_your_devices": "Upravljajte uređajima na kojima ste prijavljeni",
"manage_your_oauth_connection": "Upravljajte svojom OAuth vezom",
"map": "Karta",
"map_assets_in_bounds": "{count, plural, =0 {Nema fotografija na ovom području} one {# fotografija} few {#fotografije} other {# fotografija}}",
"map_assets_in_bounds": "{count, plural, =0 {Nema fotografija na ovom području} one {# fotografija} few {# fotografije} other {# fotografija}}",
"map_cannot_get_user_location": "Nije moguće dohvatiti lokaciju korisnika",
"map_location_dialog_yes": "Da",
"map_location_picker_page_use_location": "Koristi ovu lokaciju",
@@ -1301,6 +1300,7 @@
"mark_as_read": "Označi kao pročitano",
"marked_all_as_read": "Označeno sve kao pročitano",
"matches": "Podudaranja",
"matching_assets": "Odgovarajuće stavke",
"media_type": "Vrsta medija",
"memories": "Sjećanja",
"memories_all_caught_up": "Sve ste pregledali",
@@ -1312,10 +1312,10 @@
"memory_lane_title": "Traka sjećanja {title}",
"menu": "Izbornik",
"merge": "Spoji",
"merge_people": "Spajanje ljudi",
"merge_people": "Spoji osobe",
"merge_people_limit": "Možete spojiti najviše 5 lica odjednom",
"merge_people_prompt": "Želite li spojiti ove ljude? Ova radnja je nepovratna.",
"merge_people_successfully": "Uspješno spajanje ljudi",
"merge_people_successfully": "Uspješno spajanje osoba",
"merged_people_count": "{count, plural, one {# Spojena osoba} other {# Spojene osobe}}",
"minimize": "Minimiziraj",
"minute": "Minuta",
@@ -1330,11 +1330,11 @@
"move_to_lock_folder_action_prompt": "{count} dodano u zaključanu mapu",
"move_to_locked_folder": "Premjesti u zaključanu mapu",
"move_to_locked_folder_confirmation": "Ove fotografije i videozapis bit će uklonjeni iz svih albuma i bit će vidljivi samo iz zaključane mape",
"moved_to_archive": "Premješteno {count, plural, one {# resurs} other {# resursa}} u arhivu",
"moved_to_library": "Premješteno {count, plural, one {# resurs} other {# resursa}} u biblioteku",
"moved_to_archive": "{count, plural, one {Premještena # stavka} few {Premještene # stavke} other {Premješteno # stavki}} u arhivu",
"moved_to_library": "{count, plural, one {Premještena # stavka} few {Premještene # stavke} other {Premješteno # stavki}} u biblioteku",
"moved_to_trash": "Premješteno u smeće",
"multiselect_grid_edit_date_time_err_read_only": "Nije moguće urediti datum stavki samo za čitanje, preskačem",
"multiselect_grid_edit_gps_err_read_only": "Nije moguće urediti lokaciju stavki samo za čitanje, preskačem",
"multiselect_grid_edit_date_time_err_read_only": "Nije moguće urediti datum stavki označenih kao samo za čitanje, preskakanje",
"multiselect_grid_edit_gps_err_read_only": "Nije moguće urediti lokaciju stavki označenih kao samo za čitanje, preskakanje",
"mute_memories": "Isključi uspomene",
"my_albums": "Moji albumi",
"name": "Ime",
@@ -1364,23 +1364,27 @@
"no_assets_message": "KLIKNITE DA PRENESETE SVOJU PRVU FOTOGRAFIJU",
"no_assets_to_show": "Nema stavki za prikaz",
"no_cast_devices_found": "Nisu pronađeni uređaji za reprodukciju",
"no_checksum_local": "Nema dostupnog kontrolnog zbroja - nije moguće dohvatiti lokalne stavke",
"no_checksum_remote": "Nema dostupnog kontrolnog zbroja - nije moguće dohvatiti udaljenu stavku",
"no_duplicates_found": "Nisu pronađeni duplikati.",
"no_exif_info_available": "Nema dostupnih exif podataka",
"no_explore_results_message": "Prenesite više fotografija da istražite svoju zbirku.",
"no_favorites_message": "Dodajte favorite kako biste brzo pronašli svoje najbolje slike i videozapise",
"no_libraries_message": "Stvorite vanjsku biblioteku za pregled svojih fotografija i videozapisa",
"no_local_assets_found": "Nisu pronađene lokalne stavke s ovim kontrolnim zbrojem",
"no_locked_photos_message": "Fotografije i videozapisi u zaključanoj mapi su skriveni i neće se prikazivati dok pregledavate ili pretražujete svoju biblioteku.",
"no_name": "Bez imena",
"no_notifications": "Nema notifikacija",
"no_people_found": "Nema pronađenih odgovarajućih osoba",
"no_places": "Nema mjesta",
"no_remote_assets_found": "Nisu pronađene udaljene stavke s ovim kontrolnim zbrojem",
"no_results": "Nema rezultata",
"no_results_description": "Pokušajte sa sinonimom ili općenitijom ključnom riječi",
"no_shared_albums_message": "Stvorite album za dijeljenje fotografija i videozapisa s osobama u svojoj mreži",
"no_uploads_in_progress": "Nema aktivnih prijenosa",
"not_in_any_album": "Ni u jednom albumu",
"not_selected": "Nije odabrano",
"note_apply_storage_label_to_previously_uploaded assets": "Napomena: Da biste primijenili Oznaku za skladištenje na prethodno prenesena sredstva, pokrenite",
"note_apply_storage_label_to_previously_uploaded assets": "Napomena: Da biste primijenili oznaku pohrane na prethodno prenesene stavke, pokrenite",
"notes": "Bilješke",
"nothing_here_yet": "Ovdje još nema ničega",
"notification_permission_dialog_content": "Da biste omogućili obavijesti, idite u Postavke i odaberite dopusti.",
@@ -1422,7 +1426,7 @@
"owner": "Vlasnik",
"partner": "Partner",
"partner_can_access": "{partner} može pristupiti",
"partner_can_access_assets": "Sve vaše fotografije i videi osim onih u arhivi i smeću",
"partner_can_access_assets": "Sve vaše fotografije i videozapisi osim onih u arhivi i smeću",
"partner_can_access_location": "Mjesto otkuda je slika otkinuta",
"partner_list_user_photos": "{user} fotografije",
"partner_list_view_all": "Prikaži sve",
@@ -1449,17 +1453,17 @@
"pause_memories": "Pauziraj sjećanja",
"paused": "Pauzirano",
"pending": "Na čekanju",
"people": "Ljudi",
"people": "Osobe",
"people_edits_count": "Izmjenjeno {count, plural, one {# osoba} other {# osobe}}",
"people_feature_description": "Pregledavanje fotografija i videozapisa grupiranih po osobama",
"people_sidebar_description": "Prikažite poveznicu na Osobe na bočnoj traci",
"permanent_deletion_warning": "Upozorenje za nepovratno brisanje",
"permanent_deletion_warning_setting_description": "Prikaži upozorenje prilikom trajnog brisanja sredstava",
"permanent_deletion_warning_setting_description": "Prikaži upozorenje prilikom trajnog brisanja stavki",
"permanently_delete": "Nepovratno obriši",
"permanently_delete_assets_count": "Trajno izbriši {count, plural, one {datoteku} other {datoteke}}",
"permanently_delete_assets_prompt": "Da li ste sigurni da želite trajni izbrisati {count, plural, one {ovu datoteku?} other {ove <b>#</b> datoteke?}}Ovo će ih također ukloniti {count, plural, one {iz njihovog} other {iz njihovih}} albuma.",
"permanently_deleted_asset": "Trajno izbrisano sredstvo",
"permanently_deleted_assets_count": "Trajno izbrisano {count, plural, one {# datoteka} other {# datoteke}}",
"permanently_delete_assets_prompt": "Jeste li sigurni da želite trajno izbrisati {count, plural, one {ovu stavku?} other {ove <b>#</b> stavke?}} Ovo će {count, plural, one {ju također ukloniti iz njezinog} other {ih također ukloniti iz njihovih}} albuma.",
"permanently_deleted_asset": "Trajno izbrisana stavka",
"permanently_deleted_assets_count": "Trajno {count, plural, one {izbrisana # stavka} few {izbrisane # stavke} other {izbisano # stavki}}",
"permission": "Dozvola",
"permission_empty": "Vaša dozvola ne smije biti prazna",
"permission_onboarding_back": "Natrag",
@@ -1493,6 +1497,7 @@
"play_memories": "Pokreni sjećanja",
"play_motion_photo": "Reproduciraj Pokretnu fotografiju",
"play_or_pause_video": "Reproducirajte ili pauzirajte video",
"play_original_video_setting_description": "Preferirajte reprodukciju originalnih videozapisa umjesto transkodiranih videozapisa. Ako originalna stavka nije kompatibilna, možda se neće ispravno reproducirati.",
"please_auth_to_access": "Molimo autentificirajte se za pristup",
"port": "Port",
"preferences_settings_subtitle": "Upravljajte postavkama aplikacije",
@@ -1509,12 +1514,8 @@
"privacy": "Privatnost",
"profile": "Profil",
"profile_drawer_app_logs": "Zapisnici",
"profile_drawer_client_out_of_date_major": "Mobilna aplikacija je zastarjela. Ažurirajte na najnoviju glavnu verziju.",
"profile_drawer_client_out_of_date_minor": "Mobilna aplikacija je zastarjela. Ažurirajte na najnoviju manju verziju.",
"profile_drawer_client_server_up_to_date": "Klijent i poslužitelj su ažurirani",
"profile_drawer_github": "GitHub",
"profile_drawer_server_out_of_date_major": "Poslužitelj je zastario. Ažurirajte na najnoviju glavnu verziju.",
"profile_drawer_server_out_of_date_minor": "Poslužitelj je zastario. Ažurirajte na najnoviju manju verziju.",
"profile_image_of_user": "Profilna slika korisnika {user}",
"profile_picture_set": "Profilna slika postavljena.",
"public_album": "Javni album",
@@ -1551,6 +1552,7 @@
"purchase_server_description_2": "Status podupiratelja",
"purchase_server_title": "Poslužitelj (Server)",
"purchase_settings_server_activated": "Ključem proizvoda poslužitelja upravlja administrator",
"query_asset_id": "Ispitaj ID stavke",
"queue_status": "Stavljanje u red {count}/{total}",
"rating": "Broj zvjezdica",
"rating_clear": "Obriši ocjenu",
@@ -1559,9 +1561,9 @@
"reaction_options": "Mogućnosti reakcije",
"read_changelog": "Pročitajte Dnevnik promjena",
"reassign": "Ponovno dodijeli",
"reassigned_assets_to_existing_person": "Ponovo dodijeljeno{count, plural, one {# datoteka} other {# datoteke}} postojećoj {name, select, null {osobi} other {{name}}}",
"reassigned_assets_to_new_person": "Ponovo dodijeljeno {count, plural, one {# datoteka} other {# datoteke}} novoj osobi",
"reassing_hint": "Dodijelite odabrane datoteke postojećoj osobi",
"reassigned_assets_to_existing_person": "Ponovno dodijeljeno {count, plural, one {# stavka} few {# stavke} other {# stavki}} {name, select, null {postojećoj osobi} other {{name}}}",
"reassigned_assets_to_new_person": "{count, plural, one {# stavka ponovno dodijeljena} few {# stavke ponovno dodijeljene} other {# stavki ponovno dodijeljeno}} novoj osobi",
"reassing_hint": "Dodijelite odabrane stavke postojećoj osobi",
"recent": "Nedavno",
"recent-albums": "Nedavni albumi",
"recent_searches": "Nedavne pretrage",
@@ -1581,13 +1583,13 @@
"refreshing_metadata": "Osvježavanje metapodataka",
"regenerating_thumbnails": "Obnavljanje sličica",
"remote": "Udaljeno",
"remote_assets": "Udaljeni sadržaji",
"remote_assets": "Udaljene stavke",
"remove": "Ukloni",
"remove_assets_album_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# datoteku} other {# datoteke}} iz albuma?",
"remove_assets_shared_link_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# datoteku} other {# datoteke}} iz ove dijeljene veze?",
"remove_assets_title": "Ukloniti datoteke?",
"remove_assets_album_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# stavku} few {# stavke} other {# stavki}} iz albuma?",
"remove_assets_shared_link_confirmation": "Jeste li sigurni da želite ukloniti {count, plural, one {# stavku} few {# stavke} other {# stavki}} iz ove dijeljene veze?",
"remove_assets_title": "Ukloniti stavke?",
"remove_custom_date_range": "Ukloni prilagođeni datumski raspon",
"remove_deleted_assets": "Ukloni izbrisana sredstva",
"remove_deleted_assets": "Ukloni izbrisane stavke",
"remove_from_album": "Ukloni iz albuma",
"remove_from_album_action_prompt": "{count} uklonjeno iz albuma",
"remove_from_favorites": "Ukloni iz favorita",
@@ -1606,7 +1608,7 @@
"removed_from_favorites_count": "{count, plural, other {Uklonjeno #}} iz omiljenih",
"removed_memory": "Uklonjena uspomena",
"removed_photo_from_memory": "Uklonjena fotografija iz uspomene",
"removed_tagged_assets": "Uklonjena oznaka iz {count, plural, one {# datoteke} other {# datoteka}}",
"removed_tagged_assets": "Uklonjena oznaka iz {count, plural, one {# stavke} few {# stavke} other {# stavki}}",
"rename": "Preimenuj",
"repair": "Popravi",
"repair_no_results_message": "Nepraćene datoteke i datoteke koje nedostaju pojavit će se ovdje",
@@ -1617,7 +1619,7 @@
"rescan": "Ponovno skeniraj",
"reset": "Resetiraj",
"reset_password": "Resetiraj lozinku",
"reset_people_visibility": "Poništi vidljivost ljudi",
"reset_people_visibility": "Poništi vidljivost osoba",
"reset_pin_code": "Resetiraj PIN kod",
"reset_pin_code_description": "Ako ste zaboravili svoj PIN kod, možete kontaktirati administratora poslužitelja da ga resetira",
"reset_pin_code_success": "PIN kod je uspješno resetiran",
@@ -1632,7 +1634,7 @@
"restore_all": "Oporavi sve",
"restore_trash_action_prompt": "{count} vraćeno iz smeća",
"restore_user": "Vrati korisnika",
"restored_asset": "Obnovljena datoteka",
"restored_asset": "Obnovljena stavka",
"resume": "Nastavi",
"retry_upload": "Ponovi prijenos",
"review_duplicates": "Pregledajte duplikate",
@@ -1679,7 +1681,7 @@
"search_for": "Traži",
"search_for_existing_person": "Potražite postojeću osobu",
"search_no_more_result": "Nema više rezultata",
"search_no_people": "Nema ljudi",
"search_no_people": "Nema osoba",
"search_no_people_named": "Nema osoba s imenom \"{name}\"",
"search_no_result": "Nema rezultata, pokušajte s drugim pojmom za pretraživanje ili kombinacijom",
"search_options": "Opcije pretraživanja",
@@ -1703,7 +1705,7 @@
"search_suggestion_list_smart_search_hint_1": "Pametna pretraga je omogućena prema zadanim postavkama, za pretraživanje metapodataka koristite sintaksu ",
"search_suggestion_list_smart_search_hint_2": "m:vaš-pojam-pretrage",
"search_tags": "Traži oznake...",
"search_timezone": "Pretraži vremenske zone",
"search_timezone": "Pretraživanje vremenske zone...",
"search_type": "Vrsta pretraživanja",
"search_your_photos": "Pretražite svoje fotografije",
"searching_locales": "Traženje lokaliteta...",
@@ -1744,7 +1746,7 @@
"set_date_of_birth": "Postavi datum rođenja",
"set_profile_picture": "Postavi profilnu sliku",
"set_slideshow_to_fullscreen": "Postavi prezentaciju na cijeli zaslon",
"set_stack_primary_asset": "Postavi kao glavni sadržaj",
"set_stack_primary_asset": "Postavi kao glavnu stavku",
"setting_image_viewer_help": "Preglednik detalja prvo učitava malu sličicu, zatim učitava pregled srednje veličine (ako je omogućen), te na kraju učitava original (ako je omogućen).",
"setting_image_viewer_original_subtitle": "Omogućite za učitavanje originalne slike pune rezolucije (velika!). Onemogućite za smanjenje potrošnje podataka (i mrežne i na predmemoriji uređaja).",
"setting_image_viewer_original_title": "Učitaj originalnu sliku",
@@ -1759,10 +1761,10 @@
"setting_notifications_notify_minutes": "{count} minuta",
"setting_notifications_notify_never": "nikad",
"setting_notifications_notify_seconds": "{count} sekundi",
"setting_notifications_single_progress_subtitle": "Detaljne informacije o napretku prijenosa po stavci",
"setting_notifications_single_progress_subtitle": "Detaljne informacije o napretku prijenosa po stavki",
"setting_notifications_single_progress_title": "Prikaži detaljni napredak sigurnosnog kopiranja u pozadini",
"setting_notifications_subtitle": "Prilagodite postavke obavijesti",
"setting_notifications_total_progress_subtitle": "Ukupni napredak prijenosa (završeno/ukupno stavki)",
"setting_notifications_total_progress_subtitle": "Ukupni napredak prijenosa (završeno/ukupan broj stavki)",
"setting_notifications_total_progress_title": "Prikaži ukupni napredak sigurnosnog kopiranja u pozadini",
"setting_video_viewer_looping_title": "Ponavljanje",
"setting_video_viewer_original_video_subtitle": "Prilikom strujanja videozapisa s poslužitelja, reproducirajte original čak i kada je dostupna transkodirana verzija. Može doći do međuspremanja. Videozapisi dostupni lokalno reproduciraju se u originalnoj kvaliteti bez obzira na ovu postavku.",
@@ -1772,9 +1774,9 @@
"settings_saved": "Postavke su spremljene",
"setup_pin_code": "Postavi PIN kod",
"share": "Podijeli",
"share_action_prompt": "Podijeljeno {count} sadržaja",
"share_action_prompt": "{count, plural, one {Podijeljena # stavka} few {Podijeljene # stavke} other {Podijeljeno # stavki}}",
"share_add_photos": "Dodaj fotografije",
"share_assets_selected": "{count} odabrano",
"share_assets_selected": "{count, plural, one {# odabran} few {# odabrana} other {# odabrano}}",
"share_dialog_preparing": "Priprema...",
"share_link": "Podijeli Link",
"shared": "Podijeljeno",
@@ -1823,7 +1825,7 @@
"shared_link_password_description": "Zahtjevaj loziku za pristup ovom dijeljenom linku",
"shared_links": "Dijeljene poveznice",
"shared_links_description": "Podijelite fotografije i videozapise putem poveznice",
"shared_photos_and_videos_count": "{assetCount, plural, =1 {# podijeljena fotografija ili videozapis.} few {# podijeljene fotografije i videozapisa.} other {# podijeljenih fotografija i videozapisa.}}",
"shared_photos_and_videos_count": "{assetCount, plural, one {# podijeljena fotografija ili videozapis.} few {# podijeljene fotografije i videozapisa.} other {# podijeljenih fotografija i videozapisa.}}",
"shared_with_me": "Podijeljeno sa mnom",
"shared_with_partner": "Podijeljeno s {partner}",
"sharing": "Dijeljenje",
@@ -1881,7 +1883,7 @@
"stack_duplicates": "Složi duplikate",
"stack_select_one_photo": "Odaberi jednu glavnu fotografiju za slaganje",
"stack_selected_photos": "Složi odabrane fotografije",
"stacked_assets_count": "Složeno {count, plural, =1 {# stavka} few {# stavke} other {# stavki}}",
"stacked_assets_count": "{count, plural, one {Složena # stavka} few {Složene # stavke} other {Složeno # stavki}}",
"stacktrace": "Pracenje stoga",
"start": "Početak",
"start_date": "Datum početka",
@@ -1919,7 +1921,7 @@
"tag_not_found_question": "Nije moguće pronaći oznaku? <link>Napravite novu oznaku.</link>",
"tag_people": "Označi osobe",
"tag_updated": "Ažurirana oznaka: {tag}",
"tagged_assets": "Označena {count, plural, =1 {# stavka} few {# stavke} other {# stavki}}",
"tagged_assets": "{count, plural, =1 {Označena # stavka} few {Označene # stavke} other {Označeno # stavki}}",
"tags": "Oznake",
"tap_to_run_job": "Dodirnite za pokretanje zadatka",
"template": "Predložak",
@@ -1961,7 +1963,7 @@
"trash_emptied": "Ispražnjeno smeće",
"trash_no_results_message": "Ovdje će se prikazati bačene fotografije i videozapisi.",
"trash_page_delete_all": "Izbriši sve",
"trash_page_empty_trash_dialog_content": "Želite li isprazniti svoje stavke u smeću? Ove stavke bit će trajno uklonjene iz Immicha",
"trash_page_empty_trash_dialog_content": "Želite li isprazniti svoje stavke u smeću? Ove stavke će biti trajno uklonjene iz Immicha",
"trash_page_info": "Stavke u smeću bit će trajno izbrisane nakon {days} dana",
"trash_page_no_assets": "Nema stavki u smeću",
"trash_page_restore_all": "Vrati sve",
@@ -1995,21 +1997,22 @@
"unselect_all_in": "Poništi odabir svih u {group}",
"unstack": "Razdvoji",
"unstack_action_prompt": "{count} razloženo",
"unstacked_assets_count": "Razdvojena {count, plural, =1 {# stavka} few {# stavke} other {# stavki}}",
"unstacked_assets_count": "{count, plural, one {Razdvojena # stavka} few {Razvdvojene # stavke} other {Razdvojeno # stavki}}",
"untagged": "Bez oznaka",
"up_next": "Sljedeće",
"update_location_action_prompt": "Ažuriraj lokaciju ({count, plural, one {# odabrane stavke} few {# odabrane stavke} other {# odabranih stavki}}) s:",
"updated_at": "Ažurirano",
"updated_password": "Lozinka ažurirana",
"upload": "Prijenos",
"upload_action_prompt": "{count} u redu za prijenos",
"upload_concurrency": "Istovremeni prijenosi",
"upload_details": "Detalji prijenosa",
"upload_dialog_info": "Želite li sigurnosno kopirati odabranu stavku(e) na poslužitelj?",
"upload_dialog_info": "Želite li sigurnosno kopirati odabrane stavke na poslužitelj?",
"upload_dialog_title": "Prenesi stavku",
"upload_errors": "Prijenos završen s {count, plural, =1 {# greškom} few {# greške} other {# grešaka}}, osvježite stranicu da biste vidjeli nove prenesene stavke.",
"upload_errors": "Prijenos završen s {count, plural, one {# greškom} few {# greške} other {# grešaka}}, osvježite stranicu da biste vidjeli nove prenesene stavke.",
"upload_finished": "Prijenos završen",
"upload_progress": "Preostalo {remaining, number} - Obrađeno {processed, number}/{total, number}",
"upload_skipped_duplicates": "Preskočena {count, plural, =1 {# duplicirana stavka} few {# duplicirane stavke} other {# dupliciranih stavki}}",
"upload_skipped_duplicates": "Preskočena {count, plural, one {# duplicirana stavka} few {# duplicirane stavke} other {# dupliciranih stavki}}",
"upload_status_duplicates": "Duplikati",
"upload_status_errors": "Greške",
"upload_status_uploaded": "Preneseno",
@@ -2025,7 +2028,7 @@
"user": "Korisnik",
"user_has_been_deleted": "Ovaj korisnik je izbrisan.",
"user_id": "ID korisnika",
"user_liked": "{user} je označio/la sviđa mi se {type, select, photo {ovu fotografiju} video {ovaj videozapis} asset {ovu stavku} other {to}}",
"user_liked": "{user} je lajkao/la {type, select, photo {ovu fotografiju} video {ovaj videozapis} asset {ovu stavku} other {to}}",
"user_pin_code_settings": "PIN kod",
"user_pin_code_settings_description": "Upravljajte svojim PIN kodom",
"user_privacy": "Privatnost korisnika",
@@ -2037,7 +2040,7 @@
"user_usage_stats_description": "Pregledajte statistiku korištenja računa",
"username": "Korisničko ime",
"users": "Korisnici",
"users_added_to_album_count": "Dodan{o/a} {count, plural, one {# korisnik} few {# korisnika} other {# korisnika}} u album",
"users_added_to_album_count": "{count, plural, one {Dodan # korisnik} few {Dodana # korisnika} other {Dodano # korisnika}} u album",
"utilities": "Alati",
"validate": "Provjeri valjanost",
"validate_endpoint_error": "Molimo unesite valjanu URL adresu",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Születésnap hozzáadása",
"add_endpoint": "Végpont megadása",
"add_exclusion_pattern": "Kihagyási minta (pattern) hozzáadása",
"add_import_path": "Importálási útvonal hozzáadása",
"add_location": "Helyszín megadása",
"add_more_users": "További felhasználók hozzáadása",
"add_partner": "Partner hozzáadása",
@@ -33,6 +32,7 @@
"add_to_albums": "Hozzáadás albumokhoz",
"add_to_albums_count": "Hozzáadás albumokhoz ({count})",
"add_to_shared_album": "Felvétel megosztott albumba",
"add_upload_to_stack": "Feltöltés hozzáadása csoporthoz",
"add_url": "URL hozzáadása",
"added_to_archive": "Hozzáadva az archívumhoz",
"added_to_favorites": "Hozzáadva a kedvencekhez",
@@ -111,7 +111,6 @@
"jobs_failed": "{jobCount, plural, other {# sikertelen}}",
"library_created": "Képtár létrehozva: {library}",
"library_deleted": "Képtár törölve",
"library_import_path_description": "Add meg az importálandó mappát. A rendszer ebben a mappában és összes almappájában fog képeket és videókat keresni.",
"library_scanning": "Időszakos Átfésülés",
"library_scanning_description": "A képtár időszakos átfésülésének beállítása",
"library_scanning_enable_description": "Képtár időszakos átfésülésének engedélyezése",
@@ -119,7 +118,7 @@
"library_settings_description": "Külső képtár beállításainak kezelése",
"library_tasks_description": "Külső könyvtárak szkennelése új és/vagy módosított elemek után",
"library_watching_enable_description": "Külső képtár változásainak figyelése",
"library_watching_settings": "Képtár figyelése (KÍSÉRLETI)",
"library_watching_settings": "Könyvtár figyelése [KÍSÉRLETI]",
"library_watching_settings_description": "Megváltozott fájlok automatikus észlelése",
"logging_enable_description": "Naplózás engedélyezése",
"logging_level_description": "Ha be van kapcsolva, milyen részletességű legyen a naplózás.",
@@ -149,10 +148,22 @@
"machine_learning_max_detection_distance_description": "Két kép közötti maximális távolság, amely esetében még duplikációnak tekintendők (0.001 és 0.1 közötti érték). Minél magasabb az érték, annál több lesz a megtalált duplikáció, de a hamis találatok esélye is egyre nagyobb.",
"machine_learning_max_recognition_distance": "Maximum felismerési távolság",
"machine_learning_max_recognition_distance_description": "Két arc közötti maximális távolság, amely alapján ugyanazon személynek tekinthetők, 0 és 2 között. Ennek csökkentése megakadályozhatja, hogy két különböző személyt ugyanannak a személynek jelöljünk, míg a növelése megakadályozhatja, hogy ugyanazt a személyt két különböző személyként jelöljük. Vedd figyelembe, hogy könnyebb két személyt összevonni, mint egy személyt kettéválasztani, ezért lehetőség szerint inkább alacsonyabb küszöbértéket válassz.",
"machine_learning_min_detection_score": "Minimum keresési pontszám",
"machine_learning_min_detection_score": "Minimális észlelési érték",
"machine_learning_min_detection_score_description": "Az arcok észleléséhez szükséges minimális megbízhatósági pontszám 0 és 1 között. Minél alacsonyabb az érték, annál több lesz a megtalált arc, de a hamis találatok esélye is egyre nagyobb.",
"machine_learning_min_recognized_faces": "Minimum felismert arc",
"machine_learning_min_recognized_faces_description": "Egy személy létrehozásához szükséges minimálisan felismert arcok száma. Ennek növelésével a arcfelismerés pontosabbá válik, azonban növeli annak az esélyét, hogy egy arc nem rendelődik hozzá egy személyhez.",
"machine_learning_ocr": "OCR (Optikai karakterfelismerés)",
"machine_learning_ocr_description": "Gépi tanulás használata a képeken megjelenő szövegek felismerésére",
"machine_learning_ocr_enabled": "OCR engedélyezése",
"machine_learning_ocr_enabled_description": "Kikapcsolt állapotban a képeken nem történik szövegfelismerés.",
"machine_learning_ocr_max_resolution": "Maximális felbontás",
"machine_learning_ocr_max_resolution_description": "Az ennél nagyobb felbontású előnézetek átméretezésre kerülnek a képarány megtartásával. A magasabb értékeknél az előnézetek pontosabbak, de ez hosszabb feldolgozási időt és több memóriát igényel.",
"machine_learning_ocr_min_detection_score": "Minimális észlelési érték",
"machine_learning_ocr_min_detection_score_description": "A szövegfelismerés minimális bizalmi szintje 0 és 1 között. Az alacsonyabb érték több szöveget észlelhet, de növeli a téves találatok esélyét.",
"machine_learning_ocr_min_recognition_score": "Minimális felismerési érték",
"machine_learning_ocr_min_score_recognition_description": "A szövegfelismerés minimális bizalmi szintje 0 és 1 között. Az alacsonyabb értékek több szöveget ismerhetnek fel, de növelhetik a téves találatok számát.",
"machine_learning_ocr_model": "Szövegfelismerő modell (OCR)",
"machine_learning_ocr_model_description": "A szervermodellek pontosabbak, mint a mobilmodellek, de hosszabb feldolgozási időt és több memóriát igényelnek.",
"machine_learning_settings": "Gépi Tanulási Beállítások",
"machine_learning_settings_description": "Gépi tanulási funkciók és beállítások kezelése",
"machine_learning_smart_search": "Okos Keresés",
@@ -210,6 +221,8 @@
"notification_email_ignore_certificate_errors_description": "TLS tanúsítvány érvényességi hibák figyelmen kívül hagyása (nem ajánlott)",
"notification_email_password_description": "Az email szerverrel való hitelesítéshez használt jelszó",
"notification_email_port_description": "Email szerver portja (pl. 25, 465 vagy 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "SMTPS használata (SMTP TLS-en keresztül)",
"notification_email_sent_test_email_button": "Teszt email küldése és mentés",
"notification_email_setting_description": "Email értesítés küldés beállításai",
"notification_email_test_email": "Teszt email küldése",
@@ -242,6 +255,7 @@
"oauth_storage_quota_default_description": "Alapértelmezett tárhely kvóta GiB-ban, amennyiben a felhasználó nem jelezte az igényét.",
"oauth_timeout": "Kérés időkorlátja",
"oauth_timeout_description": "Kérések időkorlátja milliszekundumban",
"ocr_job_description": "Gépi tanulás használata a képeken lévő szövegek felismerésére",
"password_enable_description": "Bejelentkezés emaillel és jelszóval",
"password_settings": "Jelszavas Bejelentkezés",
"password_settings_description": "Jelszavas bejelentkezés beállítások kezelése",
@@ -332,7 +346,7 @@
"transcoding_max_b_frames": "B-képkockák maximum száma",
"transcoding_max_b_frames_description": "Nagyobb értékek megnövelik a tömörítés hatékonyságát, de lelassítják a kódolást. Nem minden hardvereszköz támogatja. A 0 érték kikapcsolja a B-képkockákat, míg -1 esetén a szoftver magának választ értéket.",
"transcoding_max_bitrate": "Maximum bitráta",
"transcoding_max_bitrate_description": "Maximum bitráta beállítása konzisztensebb fájlméretet eredményez egy kevés minőségi romlás árán. 720p esetén jellemző érték lehet 2600 kbit/s a VP9 vagy HEVC kódoláshoz, 4500 kbit/s a H.264 kódoláshoz. A 0 érték esetén nincs maximum bitráta.",
"transcoding_max_bitrate_description": "Maximum bitráta beállítása konzisztensebb fájlméretet eredményez egy kevés minőségi romlás árán. 720p esetén jellemző érték lehet 2600 kbit/s a VP9 vagy HEVC kódoláshoz, 4500 kbit/s a H.264 kódoláshoz. A 0 érték esetén nincs maximum bitráta. Ha nincs megadva mértékegység, alapértelmezetten „k” (kbit/s) értendő - tehát az 5000, 5000k és az 5M (Mbit/s) azonos beállítások.",
"transcoding_max_keyframe_interval": "Maximum kulcskocka intervallum",
"transcoding_max_keyframe_interval_description": "Beállítja a kulcskockák közötti legnagyobb lehetséges távolságot. Alacsony érték csökkenti a tömörítési hatékonyságot, de lejátszás közben az előre- és hátratekerés gyorsabb, valamint javíthatja a gyorsan mozgó jelenetek képminőségét. 0 esetén a szoftver magának állítja be az értéket.",
"transcoding_optimal_description": "A célfelbontásnál nagyobb vagy a nem elfogadott formátumú videókat",
@@ -350,7 +364,7 @@
"transcoding_target_resolution": "Célfelbontás",
"transcoding_target_resolution_description": "A magasabb felbontás jobb minőségben őrzi meg a részleteket, de tovább tart létrehozni, nagyobb fájlmérethez vezet és belassíthatja az alkalmazást.",
"transcoding_temporal_aq": "Időbeli (Temporal) AQ",
"transcoding_temporal_aq_description": "Csak NVENC esetén. Növeli a nagyon részletes, keveset mozgó videóanyag minőségét. Nem minden régi eszköz támogatja.",
"transcoding_temporal_aq_description": "Csak NVENC esetén. Az Időbeli Adaptív Kvantálás növeli a nagyon részletes, keveset mozgó videóanyag minőségét. Nem minden régi eszköz támogatja.",
"transcoding_threads": "Folyamatok száma",
"transcoding_threads_description": "Magas értékek esetén gyorsabban kódol, viszont kevesebb erőforrást hagy a szerver többi folyamatának. Nem ajánlott a CPU magjainak számánál nagyobb érték beállítása. A 0 érték maximalizálja a processzor kihasználását.",
"transcoding_tone_mapping": "Tónusleképezés (tone-mapping)",
@@ -401,11 +415,11 @@
"advanced_settings_prefer_remote_subtitle": "Néhány eszköz fájdalmasan lassan tölti be az eszközön lévő indexképeket. Ez a beállítás inkább a távoli képeket (a szerverről) tölti be helyettük.",
"advanced_settings_prefer_remote_title": "Távoli képek előnyben részesítése",
"advanced_settings_proxy_headers_subtitle": "Add meg azokat a proxy fejléceket, amiket az app elküldjön minden hálózati kérésnél",
"advanced_settings_proxy_headers_title": "Proxy Fejlécek",
"advanced_settings_proxy_headers_title": "Egyedi Proxy Fejlécek [KÍSÉRLETI]",
"advanced_settings_readonly_mode_subtitle": "Bekapcsol egy írásvédett módot ahol csak fotókat nézni lehetséges, egyebek, mint több kép kiválasztása, megosztás, kivetítés és törlés ki vannak kapcsolva. Ki/bekapcsolható a felhasználó ikonjáról a fő képernyőn",
"advanced_settings_readonly_mode_title": "Írásvédett Mód",
"advanced_settings_readonly_mode_title": "Írásvédett mód",
"advanced_settings_self_signed_ssl_subtitle": "Nem ellenőrzi a szerver SSL tanúsítványát. Önaláírt tanúsítvány esetén szükséges beállítás.",
"advanced_settings_self_signed_ssl_title": "Önaláírt SSL tanúsítványok engedélyezése",
"advanced_settings_self_signed_ssl_title": "Önaláírt SSL tanúsítványok engedélyezése [KÍSÉRLETI]",
"advanced_settings_sync_remote_deletions_subtitle": "Automatikusan törölni vagy visszaállítani egy elemet ezen az eszközön, ha az adott műveletet a weben hajtották végre",
"advanced_settings_sync_remote_deletions_title": "Távoli törlések szinkronizálása [KÍSÉRLETI FUNKCIÓ]",
"advanced_settings_tile_subtitle": "Haladó felhasználói beállítások",
@@ -465,10 +479,14 @@
"api_key_description": "Ez csak most az egyszer jelenik meg. Az ablak bezárása előtt feltétlenül másold.",
"api_key_empty": "Az API Kulcs név nem kéne, hogy üres legyen",
"api_keys": "API Kulcsok",
"app_architecture_variant": "Variant (Architektúra)",
"app_bar_signout_dialog_content": "Biztos, hogy ki szeretnél jelentkezni?",
"app_bar_signout_dialog_ok": "Igen",
"app_bar_signout_dialog_title": "Kijelentkezés",
"app_download_links": "App letöltési linkek",
"app_settings": "Alkalmazás Beállítások",
"app_stores": "App Store-ok",
"app_update_available": "Egy új frissítés érhető el",
"appears_in": "Itt szerepel",
"apply_count": "Alkalmaz ({count, number})",
"archive": "Archívum",
@@ -552,6 +570,7 @@
"backup_albums_sync": "Backup albumok szinkronizálása",
"backup_all": "Összes",
"backup_background_service_backup_failed_message": "Az elemek mentése sikertelen. Újrapróbálkozás…",
"backup_background_service_complete_notification": "Az adatok mentése befejeződött",
"backup_background_service_connection_failed_message": "A szerverhez csatlakozás sikertelen. Újrapróbálkozás…",
"backup_background_service_current_upload_notification": "Feltöltés {filename}",
"backup_background_service_default_notification": "Új elemek ellenőrzése…",
@@ -661,6 +680,8 @@
"change_password_description": "Most jelentkezel be a rendszerbe első alkalommal, vagy valaki jelszó-változtatást kezdeményezett. Kérjük, add meg az új jelszót.",
"change_password_form_confirm_password": "Jelszó Megerősítése",
"change_password_form_description": "Szia {name}!\n\nMost jelentkezel be először a rendszerbe vagy más okból szükséges a jelszavad meváltoztatása. Kérjük, add meg új jelszavad.",
"change_password_form_log_out": "Kijelentkezés az összes többi eszközről",
"change_password_form_log_out_description": "Javasolt kijelentkezni az összes többi eszközről",
"change_password_form_new_password": "Új Jelszó",
"change_password_form_password_mismatch": "A beírt jelszavak nem egyeznek",
"change_password_form_reenter_new_password": "Jelszó (Még Egyszer)",
@@ -687,8 +708,8 @@
"client_cert_import_success_msg": "Kliens tanúsítvány importálva",
"client_cert_invalid_msg": "Érvénytelen tanúsítvány fájl vagy hibás jelszó",
"client_cert_remove_msg": "Kliens tanúsítvány eltávolítva",
"client_cert_subtitle": "Csak a PKCS12 (.p12, .pfx) formátum támogatott. Tanúsítvány Importálása/Eltávolítása csak a bejelentkezés előtt lehetséges",
"client_cert_title": "SSL Kliens Tanúsítvány",
"client_cert_subtitle": "Csak a PKCS12 (.p12, .pfx) formátum támogatott. Tanúsítvány importálása/eltávolítása csak a bejelentkezés előtt lehetséges",
"client_cert_title": "SSL kliens tanúsítvány [KÍSÉRLETI]",
"clockwise": "Óramutató járásával megegyező irány",
"close": "Bezárás",
"collapse": "Összecsuk",
@@ -700,7 +721,6 @@
"comments_and_likes": "Megjegyzések és reakciók",
"comments_are_disabled": "A megjegyzések le vannak tiltva",
"common_create_new_album": "Új album létrehozása",
"common_server_error": "Kérjük, ellenőrizd a hálózati kapcsolatot, gondoskodj róla, hogy a szerver elérhető legyen, valamint az alkalmazás és a szerver kompatibilis verziójú legyen.",
"completed": "Kész",
"confirm": "Jóváhagy",
"confirm_admin_password": "Admin Jelszó Újból",
@@ -739,6 +759,7 @@
"create": "Létrehoz",
"create_album": "Album létrehozása",
"create_album_page_untitled": "Névtelen",
"create_api_key": "API kulcs létrehozása",
"create_library": "Képtár Létrehozása",
"create_link": "Link létrehozása",
"create_link_to_share": "Megosztási link létrehozása",
@@ -768,6 +789,7 @@
"daily_title_text_date_year": "yyyy MMM dd (E)",
"dark": "Sötét",
"dark_theme": "Sötét téma kapcsolása",
"date": "Dátum",
"date_after": "Dátumtól",
"date_and_time": "Dátum és Idő",
"date_before": "Dátumig",
@@ -870,8 +892,6 @@
"edit_description_prompt": "Kérlek válassz egy új leírást:",
"edit_exclusion_pattern": "Kizárási minta (pattern) módosítása",
"edit_faces": "Arcok módosítása",
"edit_import_path": "Importálási útvonal módosítása",
"edit_import_paths": "Importálási Útvonalak Módosítása",
"edit_key": "Kulcs módosítása",
"edit_link": "Link módosítása",
"edit_location": "Hely módosítása",
@@ -882,7 +902,6 @@
"edit_tag": "Címke módosítása",
"edit_title": "Cím Módosítása",
"edit_user": "Felhasználó módosítása",
"edited": "Módosítva",
"editor": "Szerkesztő",
"editor_close_without_save_prompt": "A változtatások nem lesznek elmentve",
"editor_close_without_save_title": "Szerkesztő bezárása?",
@@ -944,7 +963,6 @@
"failed_to_stack_assets": "Elemek csoportosítása sikertelen",
"failed_to_unstack_assets": "Csoportosított elemek szétszedése sikertelen",
"failed_to_update_notification_status": "Értesítés státusz frissítése sikertelen",
"import_path_already_exists": "Ez az importálási útvonal már létezik.",
"incorrect_email_or_password": "Helytelen email vagy jelszó",
"paths_validation_failed": "A(z) {paths, plural, one {# elérési útvonal} other {# elérési útvonal}} érvényesítése sikertelen",
"profile_picture_transparent_pixels": "Profilképek nem tartalmazhatnak átlátszó pixeleket. Közelíts rá és/vagy mozgasd a képet.",
@@ -954,7 +972,6 @@
"unable_to_add_assets_to_shared_link": "Elemeket megosztott linkhez adása sikertelen",
"unable_to_add_comment": "Hozzászólás sikertelen",
"unable_to_add_exclusion_pattern": "Kivétel minta (pattern) hozzáadása sikertelen",
"unable_to_add_import_path": "Importálási útvonal hozzáadása sikertelen",
"unable_to_add_partners": "Partnerek hozzáadása sikertelen",
"unable_to_add_remove_archive": "Az elem {archived, select, true {eltávolítása at Archívumból} other {hozzáadása Archívumhoz}} sikertelen",
"unable_to_add_remove_favorites": "Az elem {favorite, select, true {eltávolítása a Kedvencekből} other {hozzáadása a Kedvencekhez}} sikertelen",
@@ -977,12 +994,10 @@
"unable_to_delete_asset": "Elem törlése sikertelen",
"unable_to_delete_assets": "Hiba az elemek törlésekor",
"unable_to_delete_exclusion_pattern": "Kizárási minta (pattern) törlése sikertelen",
"unable_to_delete_import_path": "Import útvonal törlése sikertelen",
"unable_to_delete_shared_link": "Megosztott link törlése sikertelen",
"unable_to_delete_user": "Felhasználó törlése sikertelen",
"unable_to_download_files": "Fájlok letöltése sikertelen",
"unable_to_edit_exclusion_pattern": "Kizárási minta (pattern) módosítása sikertelen",
"unable_to_edit_import_path": "Import útvonal módosítása sikertelen",
"unable_to_empty_trash": "Lomtár ürítése sikertelen",
"unable_to_enter_fullscreen": "Teljes képernyőre váltás sikertelen",
"unable_to_exit_fullscreen": "Kilépés a teljes képernyős módból sikertelen",
@@ -1038,6 +1053,7 @@
"exif_bottom_sheet_description_error": "Hiba a leírás frissítésekor",
"exif_bottom_sheet_details": "RÉSZLETEK",
"exif_bottom_sheet_location": "HELY",
"exif_bottom_sheet_no_description": "Nincs leírás",
"exif_bottom_sheet_people": "EMBEREK",
"exif_bottom_sheet_person_add_person": "Elnevez",
"exit_slideshow": "Kilépés a Diavetítésből",
@@ -1076,6 +1092,7 @@
"features_setting_description": "Az alkalmazás jellemzőinek kezelése",
"file_name": "Fájlnév",
"file_name_or_extension": "Fájlnév vagy kiterjesztés",
"file_size": "Fájlméret",
"filename": "Fájlnév",
"filetype": "Fájltípus",
"filter": "Szűrő",
@@ -1115,11 +1132,10 @@
"hash_asset": "Elem hash-elése",
"hashed_assets": "Hash-elt elemek",
"hashing": "Hash-elés folyamatban",
"header_settings_add_header_tip": "Fejléc Hozzáadása",
"header_settings_add_header_tip": "Fejléc hozzáadása",
"header_settings_field_validator_msg": "Az érték nem lehet üres",
"header_settings_header_name_input": "Fejléc neve",
"header_settings_header_value_input": "Fejléc értéke",
"headers_settings_tile_subtitle": "Add meg azokat a proxy fejléceket, amiket az app elküldjön minden hálózati kérésnél",
"headers_settings_tile_title": "Egyéni proxy fejlécek",
"hi_user": "Szia {name} ({email})",
"hide_all_people": "Minden személy elrejtése",
@@ -1240,6 +1256,7 @@
"local_media_summary": "Helyi média összegzés",
"local_network": "Helyi hálózat",
"local_network_sheet_info": "Az alkalmazés ezen az URL címen fogja elérni a szervert, ha a megadott WiFi hálózathoz van csatlankozva",
"location": "Lokáció",
"location_permission": "Helymeghatározási engedély",
"location_permission_content": "A Hálózatok automatikus váltásához az Immich-nek szüksége van a pontos helymeghatározásra, hogy az alkalmazás le tudja kérni a Wi-Fi hálózat nevét",
"location_picker_choose_on_map": "Válassz a térképen",
@@ -1344,6 +1361,8 @@
"minute": "Perc",
"minutes": "Percek",
"missing": "Hiányzók",
"mobile_app": "Mobilapplikáció",
"mobile_app_download_onboarding_note": "Töltse le a kiegészítő mobilalkalmazást az alábbi opciók segítségével",
"model": "Modell",
"month": "Hónap",
"monthly_title_text_date_format": "y MMMM",
@@ -1362,6 +1381,8 @@
"my_albums": "Saját albumaim",
"name": "Név",
"name_or_nickname": "Név vagy becenév",
"navigate": "Navigáció",
"navigate_to_time": "Navigálás adott időponthoz",
"network_requirement_photos_upload": "Mobil adatforgalmat használjon a fényképek biztonsági mentéséhez",
"network_requirement_videos_upload": "Mobil adatforgalmat használjon a videók biztonsági mentéséhez",
"network_requirements": "Hálózati követelmények",
@@ -1371,6 +1392,7 @@
"never": "Soha",
"new_album": "Új Album",
"new_api_key": "Új API Kulcs",
"new_date_range": "Új dátumtartomány",
"new_password": "Új jelszó",
"new_person": "Új személy",
"new_pin_code": "Új PIN kód",
@@ -1421,6 +1443,9 @@
"notifications": "Értesítések",
"notifications_setting_description": "Értesítések kezelése",
"oauth": "OAuth",
"obtainium_configurator": "Obtainium Konfigurátor",
"obtainium_configurator_instructions": "Az Obtainium segítségével közvetlenül az Immich GitHub-os kiadásából telepítheted és frissítheted az Android-alkalmazást. Hozz létre egy API-kulcsot és válassz egy változatot az Obtainium konfigurációs hivatkozás elkészítéséhez",
"ocr": "OCR",
"official_immich_resources": "Hivatalos Immich Források",
"offline": "Nem elérhető (offline)",
"offset": "Eltolás",
@@ -1525,6 +1550,9 @@
"play_memories": "Emlékek lejátszása",
"play_motion_photo": "Mozgókép lejátszása",
"play_or_pause_video": "Videó elindítása vagy megállítása",
"play_original_video": "Eredeti videó lejátszása",
"play_original_video_setting_description": "A rendszer az eredeti videók lejátszását részesíti előnyben a transzkódolt verziókkal szemben. Ha az eredeti fájl nem kompatibilis, előfordulhat, hogy nem játszható le megfelelően.",
"play_transcoded_video": "Transzkódolt videó lejátszása",
"please_auth_to_access": "Kérlek jelentkezz be a hozzáféréshez",
"port": "Port",
"preferences_settings_subtitle": "Alkalmazásbeállítások kezelése",
@@ -1542,13 +1570,9 @@
"privacy": "Magánszféra",
"profile": "Profil",
"profile_drawer_app_logs": "Naplók",
"profile_drawer_client_out_of_date_major": "A mobilalkalmazás elavult. Kérjük, frissítsd a legfrisebb főverzióra.",
"profile_drawer_client_out_of_date_minor": "A mobilalkalmazás elavult. Kérjük, frissítsd a legfrisebb alverzióra.",
"profile_drawer_client_server_up_to_date": "A Kliens és a Szerver is naprakész",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Csak olvasható mód engedélyezve. A kilépéshez hosszan nyomja meg a felhasználói avatar ikont.",
"profile_drawer_server_out_of_date_major": "A szerver elavult. Kérjük, frissítsd a legfrisebb főverzióra.",
"profile_drawer_server_out_of_date_minor": "A szerver elavult. Kérjük, frissítsd a legfrisebb alverzióra.",
"profile_image_of_user": "{user} profilképe",
"profile_picture_set": "Profilkép beállítva.",
"public_album": "Nyilvános album",
@@ -1665,6 +1689,7 @@
"reset_sqlite_confirmation": "Biztosan vissza szeretnéd állítani az SQLite adatbázist? Az adatok újraszinkronizálásához ki kell jelentkezed, majd újra be kell lépned",
"reset_sqlite_success": "SQLite adatbázis sikeresen visszaállítva",
"reset_to_default": "Visszaállítás alapállapotba",
"resolution": "Felbontás",
"resolve_duplicates": "Duplikátumok feloldása",
"resolved_all_duplicates": "Minden duplikátum feloldása",
"restore": "Visszaállít",
@@ -1699,6 +1724,9 @@
"search_by_description_example": "Túrázós nap Szapában",
"search_by_filename": "Keresés fájlnév vagy kiterjesztés alapján",
"search_by_filename_example": "például IMG_1234.JPG vagy PNG",
"search_by_ocr": "Keresés szövegfelismeréssel (OCR)",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Keresés objektívmodell alapján...",
"search_camera_make": "Kameragyártó keresése...",
"search_camera_model": "Kameramodell keresése...",
"search_city": "Város keresése...",
@@ -1715,6 +1743,7 @@
"search_filter_location_title": "Válassz helyet",
"search_filter_media_type": "Média Típus",
"search_filter_media_type_title": "Válassz média típust",
"search_filter_ocr": "Keresés szövegfelismeréssel (OCR)",
"search_filter_people_title": "Válassz embereket",
"search_for": "Keresés",
"search_for_existing_person": "Már meglévő személy keresése",
@@ -1777,6 +1806,7 @@
"server_online": "Szerver Elérhető",
"server_privacy": "Szerver biztonság",
"server_stats": "Szerver Statisztikák",
"server_update_available": "Szerverfrissítés érhető el",
"server_version": "Szerver Verzió",
"set": "Beállít",
"set_as_album_cover": "Beállítás albumborítóként",
@@ -1805,9 +1835,11 @@
"setting_notifications_subtitle": "Értesítési beállítások módosítása",
"setting_notifications_total_progress_subtitle": "Átfogó feltöltési folyamat (kész/összes elem)",
"setting_notifications_total_progress_title": "Mutassa a háttérben történő mentés teljes folyamatát",
"setting_video_viewer_auto_play_subtitle": "A videók automatikus lejátszása megnyitáskor",
"setting_video_viewer_auto_play_title": "Videók automatikus lejátszása",
"setting_video_viewer_looping_title": "Ismétlés",
"setting_video_viewer_original_video_subtitle": "A szerverről történő videólejátszás során az eredeti videó lejátszása még akkor is, ha van optimalizált, átkódolt verzió. Akadozó lejátszást eredményezhet. A helyi eszközön eleve elérhető videókat mindenképpen eredeti minőségben játszuk le.",
"setting_video_viewer_original_video_title": "Eredeti videó lejátszása",
"setting_video_viewer_original_video_title": "Mindig az eredeti videó lejátszása",
"settings": "Beállítások",
"settings_require_restart": "Ennek a beállításnak az érvénybe lépéséhez indítsd újra az Immich-et",
"settings_saved": "Beállítások elmentve",
@@ -1984,6 +2016,7 @@
"theme_setting_three_stage_loading_title": "Háromlépcsős betöltés engedélyezése",
"they_will_be_merged_together": "Egyesítve lesznek",
"third_party_resources": "Harmadik Féltől Származó Források",
"time": "Idő",
"time_based_memories": "Emlékek idő alapján",
"timeline": "Idővonal",
"timezone": "Időzóna",
@@ -2016,6 +2049,7 @@
"troubleshoot": "Hibaelhárítás",
"type": "Típus",
"unable_to_change_pin_code": "Sikertelen PIN kód változtatás",
"unable_to_check_version": "Az alkalmazás vagy a szerver verziója nem ellenőrizhető",
"unable_to_setup_pin_code": "Sikertelen PIN kód beállítás",
"unarchive": "Archívumból kivesz",
"unarchive_action_prompt": "{count} eltávolítva az Archívumból",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Tambahkan Tanggal Lahir",
"add_endpoint": "Tambahkan titik akhir",
"add_exclusion_pattern": "Tambahkan pola pengecualian",
"add_import_path": "Tambahkan jalur impor",
"add_location": "Tambahkan lokasi",
"add_more_users": "Tambahkan lebih banyak pengguna",
"add_partner": "Tambahkan partner",
@@ -112,7 +111,6 @@
"jobs_failed": "{jobCount, plural, other {# gagal}}",
"library_created": "Pustaka dibuat: {library}",
"library_deleted": "Pustaka dihapus",
"library_import_path_description": "Tentukan folder untuk diimpor. Folder ini, termasuk subfolder, akan dipindai gambar dan videonya.",
"library_scanning": "Pemindaian Berkala",
"library_scanning_description": "Atur pemindaian pustaka berkala",
"library_scanning_enable_description": "Aktifkan pemindaian pustaka berkala",
@@ -120,7 +118,7 @@
"library_settings_description": "Kelola pengaturan pustaka eksternal",
"library_tasks_description": "Pindai pustaka eksternal untuk aset baru dan/atau berubah",
"library_watching_enable_description": "Pantau perubahan berkas dalam pustaka eksternal",
"library_watching_settings": "Pemantauan pustaka (UJI COBA)",
"library_watching_settings": "Pemantauan pustaka [UJI COBA]",
"library_watching_settings_description": "Pantau berkas yang telah diubah secara otomatis",
"logging_enable_description": "Aktifkan log",
"logging_level_description": "Ketika diaktifkan, tingkat log apa yang digunakan.",
@@ -154,8 +152,20 @@
"machine_learning_min_detection_score_description": "Nilai keyakinan minimum untuk sebuah wajah untuk dideteksi dari 0 sampai 1. Nilai yang lebih rendah akan mendeteksi lebih banyak wajah tetapi dapat mengakibatkan positif palsu.",
"machine_learning_min_recognized_faces": "Wajah terkenal minimum",
"machine_learning_min_recognized_faces_description": "Jumlah minimum wajah yang dikenal untuk seseorang untuk dibuat. Meningkatkan ini membuat Pengenalan Wajah lebih tepat dengan kemungkinan bahwa sebuah wajah tidak dikaitkan dengan seseorang.",
"machine_learning_settings": "Pengaturan Pembelajaran Mesin",
"machine_learning_settings_description": "Keola fitur dan pengaturan pembelajaran mesin",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Gunakan pembelajaran mesin untuk mengenali teks di dalam gambar",
"machine_learning_ocr_enabled": "Aktfikan OCR",
"machine_learning_ocr_enabled_description": "Jika dinonaktifkan, gambar-gambar tidak akan mengalami pengenalan teks.",
"machine_learning_ocr_max_resolution": "Resolusi maksimum",
"machine_learning_ocr_max_resolution_description": "Pratinjau di atas resolusi ini akan disesuaikan ukurannya sambil mempertahankan aspek rasio. Nilai yang lebih tinggi lebih akurat, tetapi membutuhkan waktu yang lama untuk memproses dan membutuhkan memori lebih banyak.",
"machine_learning_ocr_min_detection_score": "Skor deteksi minimum",
"machine_learning_ocr_min_detection_score_description": "Skor kepercayaan minimum untuk teks yang akan dideteksi berkisar antara 0-1. Nilai yang lebih rendah akan mendeteksi teks yang lebih banyak, tetapi dapat menyebabkan hasil yang positif palsu.",
"machine_learning_ocr_min_recognition_score": "Skor pengenalan minimum",
"machine_learning_ocr_min_score_recognition_description": "Skor kepercayaan minimum untuk teks yang akan dideteksi berkisar antara 0-1. Nilai yang lebih rendah akan mendeteksi teks yang lebih banyak, tetapi dapat menyebabkan hasil yang positif palsu.",
"machine_learning_ocr_model": "Model OCR",
"machine_learning_ocr_model_description": "Model server lebih akurat daripada model mobile, tetapi membutuhkan waktu yang lebih lama untuk memproses dan menggunakan memori yang lebih banyak.",
"machine_learning_settings": "Pengaturan Mesin Pembelajaran",
"machine_learning_settings_description": "Kelola fitur dan pengaturan mesin pembelajaran",
"machine_learning_smart_search": "Pencarian Pintar",
"machine_learning_smart_search_description": "Cari gambar secara semantik menggunakan penyematan CLIP",
"machine_learning_smart_search_enabled": "Aktifkan pencarian pintar",
@@ -211,6 +221,8 @@
"notification_email_ignore_certificate_errors_description": "Abaikan eror validasi sertifikat TLS (tidak disarankan)",
"notification_email_password_description": "Kata sandi yang digunakan ketika mengautentikasi dengan server surel",
"notification_email_port_description": "Porta server surel (mis. 25, 465, atau 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Gunakan SMTPS (SMTP melalui TLS)",
"notification_email_sent_test_email_button": "Kirim surel uji coba dan simpan",
"notification_email_setting_description": "Pengaturan pengiriman notifikasi surel",
"notification_email_test_email": "Kirim surel uji coba",
@@ -243,6 +255,7 @@
"oauth_storage_quota_default_description": "Kuota dalam GiB akan digunakan jika tidak ada klaim yang diberikan.",
"oauth_timeout": "Waktu Permintaan Habis",
"oauth_timeout_description": "Waktu habis untuk permintaan dalam milidetik",
"ocr_job_description": "Gunakan mesin pembelajaran untuk mengenali teks di dalam gambar",
"password_enable_description": "Masuk dengan surel dan kata sandi",
"password_settings": "Log Masuk Kata Sandi",
"password_settings_description": "Kelola pengaturan log masuk kata sandi",
@@ -466,10 +479,14 @@
"api_key_description": "Nilai ini hanya akan ditampilkan sekali. Pastikan untuk menyalin sebelum menutup jendela ini.",
"api_key_empty": "Nama Kunci API Anda seharusnya jangan kosong",
"api_keys": "Kunci API",
"app_architecture_variant": "Varian (Arsitektur)",
"app_bar_signout_dialog_content": "Apakah kamu yakin ingin keluar akun?",
"app_bar_signout_dialog_ok": "Ya",
"app_bar_signout_dialog_title": "Keluar akun",
"app_download_links": "Link Download Aplikasi",
"app_settings": "Pengaturan Aplikasi",
"app_stores": "App Stores",
"app_update_available": "Pembaruan aplikasi tersedia",
"appears_in": "Muncul dalam",
"apply_count": "Terapkan ({count, number})",
"archive": "Arsip",
@@ -553,6 +570,7 @@
"backup_albums_sync": "Sinkronisasi cadangan album",
"backup_all": "Semua",
"backup_background_service_backup_failed_message": "Gagal mencadangkan aset. Mencoba lagi…",
"backup_background_service_complete_notification": "Pencadangan aset selesai",
"backup_background_service_connection_failed_message": "Koneksi ke server gagal. Mencoba ulang…",
"backup_background_service_current_upload_notification": "Mengunggah {filename}",
"backup_background_service_default_notification": "Memeriksa aset baru…",
@@ -662,6 +680,8 @@
"change_password_description": "Ini merupakan pertama kali Anda masuk ke sistem atau ada permintaan untuk mengubah kata sandi Anda. Silakan masukkan kata sandi baru di bawah.",
"change_password_form_confirm_password": "Konfirmasi Sandi",
"change_password_form_description": "Halo {name},\n\nIni pertama kali anda masuk ke dalam sistem atau terdapat permintaan penggantian kata sandi. Harap masukkan password baru.",
"change_password_form_log_out": "Keluar dari semua perangkat lain",
"change_password_form_log_out_description": "Disarankan untuk keluar dari semua perangkat lain",
"change_password_form_new_password": "Sandi Baru",
"change_password_form_password_mismatch": "Sandi tidak cocok",
"change_password_form_reenter_new_password": "Masukkan Ulang Sandi Baru",
@@ -701,7 +721,6 @@
"comments_and_likes": "Komentar & suka",
"comments_are_disabled": "Komentar dinonaktifkan",
"common_create_new_album": "Buat album baru",
"common_server_error": "Koneksi gagal, pastikan server dapat diakses dan memiliki versi yang kompatibel.",
"completed": "Selesai",
"confirm": "Konfirmasi",
"confirm_admin_password": "Konfirmasi Kata Sandi Admin",
@@ -740,6 +759,7 @@
"create": "Buat",
"create_album": "Buat album",
"create_album_page_untitled": "Tak berjudul",
"create_api_key": "Buat kunci API",
"create_library": "Buat Pustaka",
"create_link": "Buat tautan",
"create_link_to_share": "Buat tautan untuk dibagikan",
@@ -769,6 +789,7 @@
"daily_title_text_date_year": "E, dd MMM yyyy",
"dark": "Gelap",
"dark_theme": "Nyalakan mode gelap",
"date": "Tanggal",
"date_after": "Tanggal setelah",
"date_and_time": "Tanggal dan Waktu",
"date_before": "Tanggal sebelum",
@@ -871,8 +892,6 @@
"edit_description_prompt": "Silakan pilih deskripsi baru:",
"edit_exclusion_pattern": "Sunting pola pengecualian",
"edit_faces": "Sunting wajah",
"edit_import_path": "Sunting jalur pengimporan",
"edit_import_paths": "Sunting Jalur Pengimporan",
"edit_key": "Sunting kunci",
"edit_link": "Sunting tautan",
"edit_location": "Sunting lokasi",
@@ -883,7 +902,6 @@
"edit_tag": "Ubah tag",
"edit_title": "Sunting Judul",
"edit_user": "Sunting pengguna",
"edited": "Disunting",
"editor": "Penyunting",
"editor_close_without_save_prompt": "Perubahan tidak akan di simpan",
"editor_close_without_save_title": "Tutup editor?",
@@ -945,7 +963,6 @@
"failed_to_stack_assets": "Gagal menumpuk aset",
"failed_to_unstack_assets": "Gagal membatalkan penumpukan aset",
"failed_to_update_notification_status": "Gagal membarui status notifikasi",
"import_path_already_exists": "Jalur pengimporan ini sudah ada.",
"incorrect_email_or_password": "Surel atau kata sandi tidak benar",
"paths_validation_failed": "{paths, plural, one {# jalur} other {# jalur}} gagal validasi",
"profile_picture_transparent_pixels": "Foto profil tidak dapat memiliki piksel transparan. Silakan perbesar dan/atau pindah posisi gambar.",
@@ -955,7 +972,6 @@
"unable_to_add_assets_to_shared_link": "Tidak dapat menambahkan aset ke tautan terbagi",
"unable_to_add_comment": "Tidak dapat menambahkan komentar",
"unable_to_add_exclusion_pattern": "Tidak dapat menambahkan pola pengecualian",
"unable_to_add_import_path": "Tidak dapat menambahkan jalur pengimporan",
"unable_to_add_partners": "Tidak dapat menambahkan partner",
"unable_to_add_remove_archive": "Tidak dapat {archived, select, true {menghapus aset dari} other {menambahkan aset ke}} arsip",
"unable_to_add_remove_favorites": "Tidak dapat {favorite, select, true {menambahkan aset ke} other {menghapus aset dari}} favorit",
@@ -978,12 +994,10 @@
"unable_to_delete_asset": "Tidak dapat menghapus aset",
"unable_to_delete_assets": "Terjadi eror menghapus aset",
"unable_to_delete_exclusion_pattern": "Tidak dapat menghapus pola pengecualian",
"unable_to_delete_import_path": "Tidak dapat menghapus jalur pengimporan",
"unable_to_delete_shared_link": "Tidak dapat menghapus tautan terbagi",
"unable_to_delete_user": "Tidak dapat menghapus pengguna",
"unable_to_download_files": "Tidak dapat mengunduh berkas",
"unable_to_edit_exclusion_pattern": "Tidak dapat menyunting pola pengecualian",
"unable_to_edit_import_path": "Tidak dapat menyunting jalur pengimporan",
"unable_to_empty_trash": "Tidak dapat menghapus sampah",
"unable_to_enter_fullscreen": "Tidak dapat memasuki layar penuh",
"unable_to_exit_fullscreen": "Tidak dapat keluar dari layar penuh",
@@ -1039,6 +1053,7 @@
"exif_bottom_sheet_description_error": "Galat saat memperbaharui deskripsi",
"exif_bottom_sheet_details": "RINCIAN",
"exif_bottom_sheet_location": "LOKASI",
"exif_bottom_sheet_no_description": "Tidak ada deskripsi",
"exif_bottom_sheet_people": "ORANG",
"exif_bottom_sheet_person_add_person": "Tambah nama",
"exit_slideshow": "Keluar dari Salindia",
@@ -1077,6 +1092,7 @@
"features_setting_description": "Kelola fitur aplikasi",
"file_name": "Nama berkas",
"file_name_or_extension": "Nama berkas atau ekstensi",
"file_size": "Ukuran berkas",
"filename": "Nama berkas",
"filetype": "Jenis berkas",
"filter": "Filter",
@@ -1116,11 +1132,10 @@
"hash_asset": "Aset Hash",
"hashed_assets": "Aset yang di-hash",
"hashing": "Proses Hash",
"header_settings_add_header_tip": "Tambahkan Header",
"header_settings_add_header_tip": "Tambahkan header",
"header_settings_field_validator_msg": "Nilai tidak boleh kosong",
"header_settings_header_name_input": "Nama Header",
"header_settings_header_value_input": "Nilai Header",
"headers_settings_tile_subtitle": "Menentukan header proksi yang akan dikirimkan oleh aplikasi pada setiap permintaan jaringan",
"header_settings_header_name_input": "Nama header",
"header_settings_header_value_input": "Nilai header",
"headers_settings_tile_title": "Header proksi kustom",
"hi_user": "Hai {name} ({email})",
"hide_all_people": "Sembunyikan semua orang",
@@ -1241,6 +1256,7 @@
"local_media_summary": "Ringkasan Media Lokal",
"local_network": "Jaringan Lokal",
"local_network_sheet_info": "Aplikasi akan terhubung ke server melalui URL ini saat menggunakan jaringan Wi-Fi yang ditentukan",
"location": "Lokasi",
"location_permission": "Izin lokasi",
"location_permission_content": "Untuk menggunakan fitur pengalihan otomatis, Immich memerlukan izin lokasi yang akurat agar dapat membaca nama jaringan Wi-Fi saat ini",
"location_picker_choose_on_map": "Pilih di peta",
@@ -1345,6 +1361,8 @@
"minute": "Menit",
"minutes": "Menit",
"missing": "Hilang",
"mobile_app": "Aplikasi Seluler",
"mobile_app_download_onboarding_note": "Unduh aplikasi seluler pendamping dengan menggunakan opsi berikut",
"model": "Model",
"month": "Bulan",
"monthly_title_text_date_format": "BBBB t",
@@ -1363,6 +1381,8 @@
"my_albums": "Album saya",
"name": "Nama",
"name_or_nickname": "Nama atau nama panggilan",
"navigate": "Navigasi",
"navigate_to_time": "Navigasi ke Waktu",
"network_requirement_photos_upload": "Gunakan data seluler untuk cadangkan foto",
"network_requirement_videos_upload": "Gunakan data seluler untuk cadangkan video",
"network_requirements": "Persyaratan Jaringan",
@@ -1372,6 +1392,7 @@
"never": "Tidak pernah",
"new_album": "Album baru",
"new_api_key": "Kunci API Baru",
"new_date_range": "Rentang tanggal baru",
"new_password": "Kata sandi baru",
"new_person": "Orang baru",
"new_pin_code": "Kode PIN baru",
@@ -1422,6 +1443,9 @@
"notifications": "Notifikasi",
"notifications_setting_description": "Kelola notifikasi",
"oauth": "OAuth",
"obtainium_configurator": "Konfigurator Obtainium",
"obtainium_configurator_instructions": "Gunakan Obtainium untuk menginstal dan memperbarui aplikasi Android secara langsung dari rilis GitHub Immich. Buat kunci API dan pilih varian untuk membuat tautan konfigurasi Obtainium anda",
"ocr": "OCR",
"official_immich_resources": "Sumber Daya Immich Resmi",
"offline": "Luring",
"offset": "Ofset",
@@ -1526,6 +1550,9 @@
"play_memories": "Putar kenangan",
"play_motion_photo": "Putar Foto Gerak",
"play_or_pause_video": "Putar atau jeda video",
"play_original_video": "Putar video asli",
"play_original_video_setting_description": "Lebih menyukai memutar video asli daripada video yang telah dikonversi. Jika aset asli tidak kompatibel, video mungkin tidak dapat diputar dengan benar.",
"play_transcoded_video": "Putar video yang telah dikonversi",
"please_auth_to_access": "Silakan autentikasi untuk mengakses",
"port": "Porta",
"preferences_settings_subtitle": "Kelola preferensi aplikasi",
@@ -1543,13 +1570,9 @@
"privacy": "Privasi",
"profile": "Profil",
"profile_drawer_app_logs": "Log",
"profile_drawer_client_out_of_date_major": "Versi app seluler ini sudah kedaluwarsa. Silakan perbarui ke versi major terbaru.",
"profile_drawer_client_out_of_date_minor": "Versi app seluler ini sudah kedaluwarsa. Silakan perbarui ke versi minor terbaru.",
"profile_drawer_client_server_up_to_date": "Klien dan server menjalankan versi terbaru",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Mode baca-saja aktif. Tekan lama ikon avatar pengguna untuk keluar.",
"profile_drawer_server_out_of_date_major": "Versi server ini telah kedaluwarsa. Silakan perbarui ke versi major terbaru.",
"profile_drawer_server_out_of_date_minor": "Versi server ini telah kedaluwarsa. Silakan perbarui ke versi minor terbaru.",
"profile_image_of_user": "Foto profil dari {user}",
"profile_picture_set": "Foto profil ditetapkan.",
"public_album": "Album publik",
@@ -1666,6 +1689,7 @@
"reset_sqlite_confirmation": "Apakah Anda yakin ingin mengatur ulang basis data SQLite? Setelah tindakan ini, Anda harus keluar lalu masuk kembali untuk melakukan sinkronisasi ulang data",
"reset_sqlite_success": "Berhasil mengatur ulang basis data SQLite",
"reset_to_default": "Atur ulang ke bawaan",
"resolution": "Resolusi",
"resolve_duplicates": "Mengatasi duplikat",
"resolved_all_duplicates": "Semua duplikat terselesaikan",
"restore": "Pulihkan",
@@ -1684,6 +1708,7 @@
"running": "Berjalan",
"save": "Simpan",
"save_to_gallery": "Simpan ke galeri",
"saved": "Disimpan",
"saved_api_key": "Kunci API Tersimpan",
"saved_profile": "Profil disimpan",
"saved_settings": "Pengaturan disimpan",
@@ -1700,6 +1725,9 @@
"search_by_description_example": "Hari mendaki di Sapa",
"search_by_filename": "Cari berdasarkan nama berkas atau ekstensi",
"search_by_filename_example": "mis. IMG_1234.JPG atau PNG",
"search_by_ocr": "Cari dengan OCR",
"search_by_ocr_example": "Latte",
"search_camera_lens_model": "Pencarian model lensa...",
"search_camera_make": "Cari merek kamera...",
"search_camera_model": "Cari model kamera...",
"search_city": "Cari kota...",
@@ -1716,6 +1744,7 @@
"search_filter_location_title": "Pilih Lokasi",
"search_filter_media_type": "Tipe Media",
"search_filter_media_type_title": "Pilih jenis media",
"search_filter_ocr": "Cari dengan OCR",
"search_filter_people_title": "Pilih orang",
"search_for": "Cari",
"search_for_existing_person": "Cari orang yang sudah ada",
@@ -1778,6 +1807,7 @@
"server_online": "Server Daring",
"server_privacy": "Privasi server",
"server_stats": "Statistik Server",
"server_update_available": "Pembaruan server tersedia",
"server_version": "Versi Server",
"set": "Atur",
"set_as_album_cover": "Atur sebagai kover album",
@@ -1806,6 +1836,8 @@
"setting_notifications_subtitle": "Atur setelan notifikasi",
"setting_notifications_total_progress_subtitle": "Progres keseluruhan unggahan (selesai/total aset)",
"setting_notifications_total_progress_title": "Tampilkan progres total pencadangan latar belakang",
"setting_video_viewer_auto_play_subtitle": "Otomatis memutar video saat dibuka",
"setting_video_viewer_auto_play_title": "Putar video secara otomatis",
"setting_video_viewer_looping_title": "Ulangi",
"setting_video_viewer_original_video_subtitle": "Ketika melakukan streaming video dari server, sistem akan memutar versi asli meskipun tersedia hasil transkode. Pengaturan ini dapat menyebabkan terjadinya buffering. Video yang tersedia secara lokal akan selalu diputar dalam kualitas asli tanpa terpengaruh oleh pengaturan ini.",
"setting_video_viewer_original_video_title": "Paksa video asli",
@@ -1985,6 +2017,7 @@
"theme_setting_three_stage_loading_title": "Aktifkan pemuatan tiga tahap",
"they_will_be_merged_together": "Mereka akan digabungkan bersama",
"third_party_resources": "Sumber Daya Pihak Ketiga",
"time": "Waktu",
"time_based_memories": "Kenangan berbasis waktu",
"timeline": "Lini masa",
"timezone": "Zona waktu",
@@ -2017,6 +2050,7 @@
"troubleshoot": "Pemecahan Masalah",
"type": "Jenis",
"unable_to_change_pin_code": "Tidak dapat mengubah kode PIN",
"unable_to_check_version": "Tidak dapat memeriksa versi aplikasi atau server",
"unable_to_setup_pin_code": "Tidak dapat memasang kode PIN",
"unarchive": "Keluarkan dari arsip",
"unarchive_action_prompt": "Sebanyak {count} item telah dihapus dari Arsip",

View File

@@ -17,7 +17,6 @@
"add_birthday": "Aggiungi compleanno",
"add_endpoint": "Aggiungi un endpoint",
"add_exclusion_pattern": "Aggiungi un pattern di esclusione",
"add_import_path": "Aggiungi un percorso per limportazione",
"add_location": "Aggiungi posizione",
"add_more_users": "Aggiungi altri utenti",
"add_partner": "Aggiungi partner",
@@ -32,6 +31,7 @@
"add_to_album_toggle": "Attiva/disattiva selezione per {album}",
"add_to_albums": "Aggiungi ad album",
"add_to_albums_count": "Aggiungi ad album ({count})",
"add_to_bottom_bar": "Aggiungi a",
"add_to_shared_album": "Aggiungi ad album condiviso",
"add_upload_to_stack": "Aggiungi caricamento allo stack",
"add_url": "Aggiungi URL",
@@ -76,7 +76,7 @@
"exclusion_pattern_description": "I modelli di esclusione ti permettono di ignorare file e cartelle durante la scansione della tua libreria. Questo è utile se hai cartelle che contengono file che non vuoi importare, come ad esempio, i file RAW.",
"external_library_management": "Gestione Librerie Esterne",
"face_detection": "Rilevamento Volti",
"face_detection_description": "Rileva i volti presenti negli assets utilizzando il machine learning. Per i video, viene presa in considerazione solo la miniatura. \"Aggiorna\" (ri-)processerà tutti gli assets. \"Reset\" inoltre elimina tutti i dati dei volti correnti. \"Mancanti\" seleziona solo gli assets che non sono ancora stati processati. I volti rilevati verranno selezionati per il riconoscimento facciale dopo che il rilevamento dei volti sarà stato completato, raggruppandoli in persone esistenti e/o nuove.",
"face_detection_description": "Rileva i volti presenti negli asset utilizzando il machine-learning. Per i video, viene presa in considerazione solo la miniatura. Utilizzare \"Ripristina\" per cancellare tutti i volti presenti, \"Ricarica\" per processare di nuovo tutti gli asset, \"Mancanti\" processa solo gli asset che non sono ancora stati processati. I volti rilevati verranno selezionati per il riconoscimento facciale dopo che il rilevamento dei volti sarà stato completato, raggruppandoli in persone esistenti e/o nuove.",
"facial_recognition_job_description": "Raggruppa i volti rilevati in persone. Questo processo viene eseguito dopo che il rilevamento volti è stato completato. \"Reset\" (ri-)unisce tutti i volti. \"Mancanti\" processa i volti che non hanno una persona assegnata.",
"failed_job_command": "Il comando {command} è fallito per il processo: {job}",
"force_delete_user_warning": "ATTENZIONE: Questo rimuoverà immediatamente l'utente e tutti i suoi assets. Non è possibile tornare indietro e i file non potranno essere recuperati.",
@@ -112,7 +112,6 @@
"jobs_failed": "{jobCount, plural, one {# fallito} other {# falliti}}",
"library_created": "Creata libreria: {library}",
"library_deleted": "Libreria eliminata",
"library_import_path_description": "Specifica una cartella da importare. Questa cartella e le sue sottocartelle, verranno analizzate per cercare immagini e video.",
"library_scanning": "Scansione periodica",
"library_scanning_description": "Configura la scansione periodica della libreria",
"library_scanning_enable_description": "Attiva la scansione periodica della libreria",
@@ -120,7 +119,7 @@
"library_settings_description": "Gestisci le impostazioni della libreria esterna",
"library_tasks_description": "Scansiona le librerie esterne per risorse nuove o modificate",
"library_watching_enable_description": "Osserva le librerie esterne per cambiamenti",
"library_watching_settings": "Osserva librerie (SPERIMENTALE)",
"library_watching_settings": "Osserva librerie [SPERIMENTALE]",
"library_watching_settings_description": "Osserva automaticamente i cambiamenti dei file",
"logging_enable_description": "Attiva il logging",
"logging_level_description": "Quando attivato, che livello di log utilizzare.",
@@ -154,6 +153,18 @@
"machine_learning_min_detection_score_description": "Punteggio di confidenza minimo per rilevare un volto, da 0 a 1. Valori più bassi rileveranno più volti, ma potrebbero generare risultati fasulli.",
"machine_learning_min_recognized_faces": "Minimo numero di volti rilevati",
"machine_learning_min_recognized_faces_description": "Il numero minimo di volti riconosciuti per creare una persona. Aumentando questo valore si rende il riconoscimento facciale più preciso, ma aumenta la possibilità che un volto non venga assegnato a una persona.",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "Utilizza il machine learning per riconoscere il testo nelle immagini",
"machine_learning_ocr_enabled": "Attiva OCR",
"machine_learning_ocr_enabled_description": "Se disattivato, le immagini non saranno sottoposte al riconoscimento del testo.",
"machine_learning_ocr_max_resolution": "Massima risoluzione",
"machine_learning_ocr_max_resolution_description": "L'anteprima maggiore di questa risoluzione verrà ridimensionata preservando le proporzioni. Valori maggiori sono più accurati, ma impiegano più tempo per essere processati e usano più memoria.",
"machine_learning_ocr_min_detection_score": "Punteggio minimo di rilevamento",
"machine_learning_ocr_min_detection_score_description": "Punteggio minimo di affidabilità per il rilevamento del testo da 0 a 1. Valori più bassi rileveranno più testo, ma potrebbero generare falsi positivi.",
"machine_learning_ocr_min_recognition_score": "Punteggio minimo di riconoscimento",
"machine_learning_ocr_min_score_recognition_description": "Punteggio minimo di affidabilità per il riconoscimento del testo da 0 a 1. Valori più bassi rileveranno più testo, ma potrebbero generare falsi positivi.",
"machine_learning_ocr_model": "Modello OCR",
"machine_learning_ocr_model_description": "I modelli server sono più accurati dei modelli mobile, ma impiegano più tempo nel processo e utilizzano più memoria.",
"machine_learning_settings": "Impostazioni Machine Learning",
"machine_learning_settings_description": "Gestisci le impostazioni e le funzionalità del machine learning",
"machine_learning_smart_search": "Ricerca Intelligente",
@@ -161,6 +172,10 @@
"machine_learning_smart_search_enabled": "Attiva ricerca intelligente",
"machine_learning_smart_search_enabled_description": "Se disabilitato le immagini non saranno codificate per la ricerca intelligente.",
"machine_learning_url_description": "URL del server machine learning. Se sono stati forniti più di un URL, verrà testato un server alla volta finché uno non risponderà, in ordine dal primo all'ultimo. I server che non rispondono saranno temporaneamente ignorati finché non torneranno online.",
"maintenance_settings": "Manutenzione",
"maintenance_settings_description": "Metti Immich in modalità manutenzione.",
"maintenance_start": "Avvia modalità manutenzione",
"maintenance_start_error": "Errore nell'avvio della modalità manutenzione.",
"manage_concurrency": "Gestisci Concorrenza",
"manage_log_settings": "Gestisci le impostazioni dei log",
"map_dark_style": "Tema scuro",
@@ -211,6 +226,8 @@
"notification_email_ignore_certificate_errors_description": "Ignora errori TLS di validazione del certificato (sconsigliato)",
"notification_email_password_description": "Password da usare per l'autenticazione con il server email",
"notification_email_port_description": "Porta del server email (es. 25, 465, 587)",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "Usa SMTPS (SMTP over TLS)",
"notification_email_sent_test_email_button": "Invia email di prova e salva",
"notification_email_setting_description": "Impostazioni per le notifiche via email",
"notification_email_test_email": "Invia email di prova",
@@ -243,6 +260,7 @@
"oauth_storage_quota_default_description": "Limite in GiB da usare quanto nessuna dichiarazione di ambito(claim) è stata fornita.",
"oauth_timeout": "Timeout Richiesta",
"oauth_timeout_description": "Timeout per le richieste, espresso in millisecondi",
"ocr_job_description": "Utilizza il machine learning per riconoscere il testo nelle immagini",
"password_enable_description": "Login con email e password",
"password_settings": "Login con password",
"password_settings_description": "Gestisci impostazioni del login con password",
@@ -333,7 +351,7 @@
"transcoding_max_b_frames": "B-frames Massimi",
"transcoding_max_b_frames_description": "Valori più alti migliorano l'efficienza di compressione, ma rallentano l'encoding. Potrebbero non essere compatibili con l'accelerazione hardware su dispositivi più vecchi. 0 disabilita i B-frames, mentre -1 imposta questo valore automaticamente.",
"transcoding_max_bitrate": "Bitrate massimo",
"transcoding_max_bitrate_description": "Impostare un bitrate massimo può rendere le dimensioni dei file più prevedibili a un costo minore per la qualità. A 720p, i valori tipici sono 2600 kbit/s per VP9 o HEVC, o 4500 kbit/s per H.264. Disabilitato se impostato su 0.",
"transcoding_max_bitrate_description": "Impostare un bitrate massimo può rendere le dimensioni dei file più prevedibili a un costo minore per la qualità. A 720p, i valori tipici sono 2600 kbit/s per VP9 o HEVC, o 4500 kbit/s per H.264. Disabilitato se impostato su 0. Quando non viene specificata alcuna unità, si presume k (per kbit/s); pertanto 5000, 5000k e 5M (per Mbit/s) sono equivalenti.",
"transcoding_max_keyframe_interval": "Intervallo massimo dei keyframe",
"transcoding_max_keyframe_interval_description": "Imposta la distanza massima tra i keyframe. Valori più bassi peggiorano l'efficienza di compressione, però migliorano i tempi di ricerca e possono migliorare la qualità nelle scene con movimenti rapidi. 0 imposta questo valore automaticamente.",
"transcoding_optimal_description": "Video con risoluzione più alta rispetto alla risoluzione desiderata o in formato non accettato",
@@ -351,7 +369,7 @@
"transcoding_target_resolution": "Risoluzione desiderata",
"transcoding_target_resolution_description": "Risoluzioni più elevate possono preservare più dettagli ma richiedono più tempo per la codifica, producono file di dimensioni maggiori e possono ridurre la reattività dell'applicazione.",
"transcoding_temporal_aq": "AQ temporale",
"transcoding_temporal_aq_description": "Si applica solo a NVENC. Aumenta la qualità delle scene con molto dettaglio e poco movimento. Potrebbe non essere compatibile con dispositivi più vecchi.",
"transcoding_temporal_aq_description": "Si applica solo a NVENC. La Quantizzazione Adattiva Temporale aumenta la qualità delle scene con molto dettaglio e poco movimento. Potrebbe non essere compatibile con dispositivi più vecchi.",
"transcoding_threads": "Thread",
"transcoding_threads_description": "Valori più alti portano a una codifica più veloce, ma lasciano meno spazio al server per elaborare altre attività durante l'attività. Questo valore non dovrebbe essere superiore al numero di core CPU. Massimizza l'utilizzo se impostato su 0.",
"transcoding_tone_mapping": "Mappatura della tonalità",
@@ -402,11 +420,11 @@
"advanced_settings_prefer_remote_subtitle": "Alcuni dispositivi sono estremamente lenti a caricare le miniature da risorse locali. Attiva questa impostazione per caricare invece le immagini remote.",
"advanced_settings_prefer_remote_title": "Preferisci immagini remote",
"advanced_settings_proxy_headers_subtitle": "Definisci gli header per i proxy che Immich dovrebbe inviare con ogni richiesta di rete",
"advanced_settings_proxy_headers_title": "Header Proxy",
"advanced_settings_proxy_headers_title": "Header Proxy Personalizzato [SPERIMENTALE]",
"advanced_settings_readonly_mode_subtitle": "Abilita la modalità di sola lettura in cui le foto possono essere solo visualizzate, mentre funzioni come la selezione di più immagini, la condivisione, la trasmissione e l'eliminazione sono tutte disabilitate. Abilita/Disabilita la sola lettura tramite l'avatar dell'utente dalla schermata principale",
"advanced_settings_readonly_mode_title": "Modalità di sola lettura",
"advanced_settings_self_signed_ssl_subtitle": "Salta la verifica dei certificati SSL del server. Richiesto con l'uso di certificati self-signed.",
"advanced_settings_self_signed_ssl_title": "Consenti certificati SSL self-signed",
"advanced_settings_self_signed_ssl_title": "Consenti certificati SSL self-signed [SPERIMENTALE]",
"advanced_settings_sync_remote_deletions_subtitle": "Rimuovi o ripristina automaticamente un elemento su questo dispositivo quando l'azione è stata fatta via web",
"advanced_settings_sync_remote_deletions_title": "Sincronizza le cancellazioni remote [SPERIMENTALE]",
"advanced_settings_tile_subtitle": "Impostazioni avanzate dell'utente",
@@ -415,6 +433,7 @@
"age_months": "Età {months, plural, one {# mese} other {# mesi}}",
"age_year_months": "Età 1 anno, {months, plural, one {# mese} other {# mesi}}",
"age_years": "{years, plural, other {Età #}}",
"album": "Album",
"album_added": "Album aggiunto",
"album_added_notification_setting_description": "Ricevi una notifica email quando sei aggiunto ad un album condiviso",
"album_cover_updated": "Copertina dell'album aggiornata",
@@ -460,16 +479,21 @@
"allow_edits": "Permetti modifiche",
"allow_public_user_to_download": "Permetti agli utenti pubblici di scaricare",
"allow_public_user_to_upload": "Permetti agli utenti pubblici di caricare",
"allowed": "Consentito",
"alt_text_qr_code": "Immagine QR",
"anti_clockwise": "Senso anti-orario",
"api_key": "Chiave API",
"api_key_description": "Questo valore verrà mostrato una sola volta. Assicurati di copiarlo prima di chiudere la finestra.",
"api_key_empty": "Il nome della chiave API non dovrebbe essere vuoto",
"api_keys": "Chiavi API",
"app_architecture_variant": "Variante (Architettura)",
"app_bar_signout_dialog_content": "Sei sicuro di volerti disconnettere?",
"app_bar_signout_dialog_ok": "Si",
"app_bar_signout_dialog_title": "Disconnetti",
"app_download_links": "Link per il download dell'app",
"app_settings": "Impostazioni Applicazione",
"app_stores": "App Stores",
"app_update_available": "Aggiornamento App disponibile",
"appears_in": "Compare in",
"apply_count": "Applica ({count, number})",
"archive": "Archivio",
@@ -553,6 +577,7 @@
"backup_albums_sync": "Sincronizzazione album di backup",
"backup_all": "Tutti",
"backup_background_service_backup_failed_message": "È stato impossibile fare il backup dei contenuti. Riprovo…",
"backup_background_service_complete_notification": "Backup completato",
"backup_background_service_connection_failed_message": "Impossibile connettersi al server. Riprovo…",
"backup_background_service_current_upload_notification": "Caricamento di {filename} in corso",
"backup_background_service_default_notification": "Ricerca di nuovi contenuti…",
@@ -662,6 +687,8 @@
"change_password_description": "È stato richiesto di cambiare la password (oppure è la prima volta che accedi). Inserisci la tua nuova password qui sotto.",
"change_password_form_confirm_password": "Conferma Password",
"change_password_form_description": "Ciao {name},\n\nQuesto è la prima volta che accedi al sistema oppure è stato fatto una richiesta di cambiare la password. Per favore inserisca la nuova password qui sotto.",
"change_password_form_log_out": "Log out da tutti gli altri dispositivi",
"change_password_form_log_out_description": "È consigliato il log out da tutti gli altri dispositivi",
"change_password_form_new_password": "Nuova Password",
"change_password_form_password_mismatch": "Le password non coincidono",
"change_password_form_reenter_new_password": "Inserisci ancora la nuova password",
@@ -689,7 +716,7 @@
"client_cert_invalid_msg": "File certificato invalido o password errata",
"client_cert_remove_msg": "Certificato client rimosso",
"client_cert_subtitle": "Supporta solo il formato PKCS12 (.p12, .pfx). L'importazione/rimozione del certificato è disponibile solo prima del login",
"client_cert_title": "Certificato Client SSL",
"client_cert_title": "Certificato Client SSL [SPERIMENTALE]",
"clockwise": "Senso orario",
"close": "Chiudi",
"collapse": "Restringi",
@@ -701,7 +728,6 @@
"comments_and_likes": "Commenti & mi piace",
"comments_are_disabled": "I commenti sono disabilitati",
"common_create_new_album": "Crea nuovo Album",
"common_server_error": "Verifica la connessione di rete, assicurati che il server sia raggiungibile e che le versioni dellapp e del server siano compatibili.",
"completed": "Completato",
"confirm": "Conferma",
"confirm_admin_password": "Conferma password dell'amministratore",
@@ -740,6 +766,7 @@
"create": "Crea",
"create_album": "Crea album",
"create_album_page_untitled": "Senza titolo",
"create_api_key": "Crea chiave API",
"create_library": "Crea libreria",
"create_link": "Crea link",
"create_link_to_share": "Crea link da condividere",
@@ -769,6 +796,7 @@
"daily_title_text_date_year": "E, dd MMM, yyyy",
"dark": "Scuro",
"dark_theme": "Imposta tema scuro",
"date": "Data",
"date_after": "Dopo la data",
"date_and_time": "Data e ora",
"date_before": "Prima della data",
@@ -871,8 +899,6 @@
"edit_description_prompt": "Selezionare una nuova descrizione:",
"edit_exclusion_pattern": "Modifica pattern di esclusione",
"edit_faces": "Modifica volti",
"edit_import_path": "Modifica percorso di importazione",
"edit_import_paths": "Modifica Percorsi di Importazione",
"edit_key": "Modifica chiave",
"edit_link": "Modifica link",
"edit_location": "Modifica posizione",
@@ -883,7 +909,6 @@
"edit_tag": "Modifica tag",
"edit_title": "Modifica Titolo",
"edit_user": "Modifica utente",
"edited": "Modificato",
"editor": "Editor",
"editor_close_without_save_prompt": "Le modifiche non verranno salvate",
"editor_close_without_save_title": "Vuoi chiudere l'editor?",
@@ -945,7 +970,6 @@
"failed_to_stack_assets": "Errore durante il raggruppamento degli assets",
"failed_to_unstack_assets": "Errore durante la separazione degli assets",
"failed_to_update_notification_status": "Aggiornamento stato notifiche fallito",
"import_path_already_exists": "Questo percorso di importazione già esiste.",
"incorrect_email_or_password": "Email o password non corretta",
"paths_validation_failed": "{paths, plural, one {# percorso} other {# percorsi}} hanno fallito la validazione",
"profile_picture_transparent_pixels": "Le foto profilo non possono avere pixel trasparenti. Riprova ingrandendo e/o muovendo l'immagine.",
@@ -955,7 +979,6 @@
"unable_to_add_assets_to_shared_link": "Impossibile aggiungere gli assets al link condiviso",
"unable_to_add_comment": "Impossibile aggiungere commento",
"unable_to_add_exclusion_pattern": "Impossibile aggiungere pattern di esclusione",
"unable_to_add_import_path": "Impossibile aggiungere percorso di importazione",
"unable_to_add_partners": "Impossibile aggiungere compagni",
"unable_to_add_remove_archive": "Impossibile {archived, select, true {rimuovere l'asset dall'archivio} other {aggiungere l'asset all'archivio}}",
"unable_to_add_remove_favorites": "Impossibile {favorite, select, true {rimuovere l'asset dai} other {aggiungere l'asset ai}} preferiti",
@@ -978,12 +1001,10 @@
"unable_to_delete_asset": "Impossibile cancellare asset",
"unable_to_delete_assets": "Errore durante l'eliminazione degli asset",
"unable_to_delete_exclusion_pattern": "Impossibile cancellare pattern di esclusione",
"unable_to_delete_import_path": "Impossibile cancellare percorso di importazione",
"unable_to_delete_shared_link": "Impossibile cancellare link condiviso",
"unable_to_delete_user": "Impossibile cancellare utente",
"unable_to_download_files": "Impossibile scaricare i file",
"unable_to_edit_exclusion_pattern": "Impossibile modificare pattern di esclusione",
"unable_to_edit_import_path": "Impossibile cambiare percorso di importazione",
"unable_to_empty_trash": "Impossibile svuotare il cestino",
"unable_to_enter_fullscreen": "Impossibile aprire l'applicazione a schermo intero",
"unable_to_exit_fullscreen": "Impossibile uscire dallo schermo intero",
@@ -1078,6 +1099,7 @@
"features_setting_description": "Gestisci le funzionalità dell'app",
"file_name": "Nome file",
"file_name_or_extension": "Nome file o estensione",
"file_size": "Dimensione del file",
"filename": "Nome file",
"filetype": "Tipo file",
"filter": "Filtro",
@@ -1117,11 +1139,10 @@
"hash_asset": "Risorsa hash",
"hashed_assets": "Risorse hash",
"hashing": "Hashing",
"header_settings_add_header_tip": "Aggiungi Header",
"header_settings_add_header_tip": "Aggiungi header",
"header_settings_field_validator_msg": "Il valore non può essere vuoto",
"header_settings_header_name_input": "Nome header",
"header_settings_header_value_input": "Valore header",
"headers_settings_tile_subtitle": "Definisci gli header per i proxy che l'app deve inviare con ogni richiesta di rete",
"headers_settings_tile_title": "Header proxy personalizzati",
"hi_user": "Ciao {name} ({email})",
"hide_all_people": "Nascondi tutte le persone",
@@ -1174,6 +1195,8 @@
"import_path": "Importa percorso",
"in_albums": "In {count, plural, one {# album} other {# album}}",
"in_archive": "In archivio",
"in_year": "Nel {year}",
"in_year_selector": "Nel",
"include_archived": "Includi Archiviati",
"include_shared_albums": "Includi album condivisi",
"include_shared_partner_assets": "Includi elementi condivisi dai compagni",
@@ -1210,6 +1233,7 @@
"language_setting_description": "Seleziona la tua lingua predefinita",
"large_files": "File pesanti",
"last": "Ultimo",
"last_months": "{count, plural, one {Ultimo mese} other {Ultimi # mesi}}",
"last_seen": "Ultimo accesso",
"latest_version": "Ultima Versione",
"latitude": "Latitudine",
@@ -1242,6 +1266,7 @@
"local_media_summary": "Riepilogo dei Media Locali",
"local_network": "Rete locale",
"local_network_sheet_info": "L'app si collegherà al server tramite questo URL quando è in uso la rete Wi-Fi specificata",
"location": "Posizione",
"location_permission": "Permesso di localizzazione",
"location_permission_content": "Per usare la funzione di cambio automatico, Immich necessita del permesso di localizzazione così da poter leggere il nome della rete Wi-Fi in uso",
"location_picker_choose_on_map": "Scegli una mappa",
@@ -1289,8 +1314,17 @@
"loop_videos_description": "Abilita per riprodurre automaticamente un video in loop nel visualizzatore dei dettagli.",
"main_branch_warning": "Stai utilizzando una versione di sviluppo. Ti consigliamo vivamente di utilizzare una versione di rilascio!",
"main_menu": "Menu Principale",
"maintenance_description": "Immich è stato posto in <link>modalità manutenzione</link>.",
"maintenance_end": "Termina modalità manutenzione",
"maintenance_end_error": "Errore nel terminare la modalità manutenzione.",
"maintenance_logged_in_as": "Accesso effettuato come {user}",
"maintenance_title": "Temporaneamente non disponibile",
"make": "Produttore",
"manage_geolocation": "Gestisci posizione",
"manage_media_access_rationale": "Questo permesso è richiesto per gestire correttamente lo spostamento del materiale nel cestino e per recuperarlo da esso.",
"manage_media_access_settings": "Apri impostazioni",
"manage_media_access_subtitle": "Permetti all'app di Immich di gestire e spostare file multimediali.",
"manage_media_access_title": "Accesso alla gestione di contenuti multimediali",
"manage_shared_links": "Gestisci link condivisi",
"manage_sharing_with_partners": "Gestisci la condivisione con i compagni",
"manage_the_app_settings": "Gestisci le impostazioni dell'applicazione",
@@ -1346,12 +1380,15 @@
"minute": "Minuto",
"minutes": "Minuti",
"missing": "Mancanti",
"mobile_app": "App Cellulare",
"mobile_app_download_onboarding_note": "Scarica lapp mobile dedicata utilizzando una delle seguenti opzioni",
"model": "Modello",
"month": "Mese",
"monthly_title_text_date_format": "MMMM y",
"more": "Di più",
"move": "Sposta",
"move_off_locked_folder": "Sposta al di fuori della cartella privata",
"move_to": "Sposta in",
"move_to_lock_folder_action_prompt": "{count} elementi aggiunti alla cartella sicura",
"move_to_locked_folder": "Sposta nella cartella privata",
"move_to_locked_folder_confirmation": "Queste foto e video verranno rimossi da tutti gli album, e saranno visibili solo dalla cartella privata",
@@ -1364,6 +1401,8 @@
"my_albums": "I miei album",
"name": "Nome",
"name_or_nickname": "Nome o soprannome",
"navigate": "Naviga",
"navigate_to_time": "Navigazione alla data",
"network_requirement_photos_upload": "Utilizza la connessione dati per il backup delle foto",
"network_requirement_videos_upload": "Utilizza la connessione dati per il backup dei video",
"network_requirements": "Requisiti di rete",
@@ -1373,11 +1412,13 @@
"never": "Mai",
"new_album": "Nuovo Album",
"new_api_key": "Nuova Chiave di API",
"new_date_range": "Nuovo intervallo di date",
"new_password": "Nuova password",
"new_person": "Nuova persona",
"new_pin_code": "Nuovo codice PIN",
"new_pin_code_subtitle": "Questa è la prima volta che accedi alla cartella privata. Crea un codice PIN per accedere in modo sicuro a questa pagina",
"new_timeline": "Nuova Timeline",
"new_update": "Nuovo aggiornamento",
"new_user_created": "Nuovo utente creato",
"new_version_available": "NUOVA VERSIONE DISPONIBILE",
"newest_first": "Prima recenti",
@@ -1393,6 +1434,7 @@
"no_cast_devices_found": "Nessun dispositivo di trasmissione trovato",
"no_checksum_local": "Nessun checksum disponibile: impossibile recuperare gli assets locali",
"no_checksum_remote": "Nessun checksum disponibile: impossibile recuperare l'asset remoto",
"no_devices": "Nessun device autorizzato",
"no_duplicates_found": "Nessun duplicato trovato.",
"no_exif_info_available": "Nessuna informazione exif disponibile",
"no_explore_results_message": "Carica più foto per esplorare la tua collezione.",
@@ -1409,6 +1451,7 @@
"no_results_description": "Prova ad usare un sinonimo oppure una parola chiave più generica",
"no_shared_albums_message": "Crea un album per condividere foto e video con le persone nella tua rete",
"no_uploads_in_progress": "Nessun upload in corso",
"not_allowed": "Non permesso",
"not_available": "N/A",
"not_in_any_album": "In nessun album",
"not_selected": "Non selezionato",
@@ -1423,6 +1466,9 @@
"notifications": "Notifiche",
"notifications_setting_description": "Gestisci notifiche",
"oauth": "OAuth",
"obtainium_configurator": "Configuratore Obtainium",
"obtainium_configurator_instructions": "Utilizza Obtainium per installare e aggiornare l'app Android direttamente dalla versione rilasciata su GitHub da Immich. Crea una chiave API e seleziona una variante per creare il tuo link di configurazione Obtainium",
"ocr": "OCR",
"official_immich_resources": "Risorse Ufficiali Immich",
"offline": "Offline",
"offset": "Offset",
@@ -1516,6 +1562,8 @@
"photos_count": "{count, plural, one {{count, number} Foto} other {{count, number} Foto}}",
"photos_from_previous_years": "Foto dagli anni scorsi",
"pick_a_location": "Scegli una posizione",
"pick_custom_range": "Intervallo personalizzato",
"pick_date_range": "Seleziona un periodo temporale",
"pin_code_changed_successfully": "Codice PIN cambiato correttamente",
"pin_code_reset_successfully": "Codice PIN resettato con successo",
"pin_code_setup_successfully": "Codice PIN impostato correttamente",
@@ -1527,6 +1575,9 @@
"play_memories": "Riproduci ricordi",
"play_motion_photo": "Riproduci foto in movimento",
"play_or_pause_video": "Avvia o metti in pausa il video",
"play_original_video": "Riproduci il video originale",
"play_original_video_setting_description": "Preferisci la riproduzione dei video originali anzichè ricodificarli. Se l'originale non è compatibile non sarà riprodotto correttamente.",
"play_transcoded_video": "Riproduci video ricodificato",
"please_auth_to_access": "Autenticati per accedere",
"port": "Porta",
"preferences_settings_subtitle": "Gestisci le preferenze dell'app",
@@ -1544,13 +1595,9 @@
"privacy": "Privacy",
"profile": "Profilo",
"profile_drawer_app_logs": "Registri",
"profile_drawer_client_out_of_date_major": "Lapp non è aggiornata. Aggiorna allultima versione principale.",
"profile_drawer_client_out_of_date_minor": "L'applicazione non è aggiornata. Aggiorna all'ultima versione minore.",
"profile_drawer_client_server_up_to_date": "Client e server sono aggiornati",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "Modalità di sola lettura abilitata. Tieni premuto sull'avatar dell'utente per disabilitarla.",
"profile_drawer_server_out_of_date_major": "Il server non è aggiornato. Aggiorna all'ultima versione principale.",
"profile_drawer_server_out_of_date_minor": "Il server non è aggiornato. Aggiorna all'ultima versione minore.",
"profile_image_of_user": "Immagine profilo di {user}",
"profile_picture_set": "Foto profilo impostata.",
"public_album": "Album pubblico",
@@ -1667,6 +1714,7 @@
"reset_sqlite_confirmation": "Vuoi davvero reimpostare il database SQLite? Dovrai disconnetterti e riconnetterti per risincronizzare i dati",
"reset_sqlite_success": "Database SQLite reimpostato correttamente",
"reset_to_default": "Ripristina i valori predefiniti",
"resolution": "Risoluzione",
"resolve_duplicates": "Risolvi duplicati",
"resolved_all_duplicates": "Tutti i duplicati sono stati risolti",
"restore": "Ripristina",
@@ -1685,6 +1733,7 @@
"running": "In esecuzione",
"save": "Salva",
"save_to_gallery": "Salva in galleria",
"saved": "Salvato",
"saved_api_key": "Chiave API salvata",
"saved_profile": "Profilo salvato",
"saved_settings": "Impostazioni salvate",
@@ -1701,6 +1750,9 @@
"search_by_description_example": "Giornata di escursioni a Sapa",
"search_by_filename": "Cerca per nome del file o estensione",
"search_by_filename_example": "es. IMG_1234.JPG o PNG",
"search_by_ocr": "Ricerca tramite OCR",
"search_by_ocr_example": "Caffè Latte",
"search_camera_lens_model": "Cerca il modello del'obiettivo...",
"search_camera_make": "Cerca produttore fotocamera...",
"search_camera_model": "Cerca modello fotocamera...",
"search_city": "Cerca città...",
@@ -1717,6 +1769,7 @@
"search_filter_location_title": "Seleziona posizione",
"search_filter_media_type": "Tipo di media",
"search_filter_media_type_title": "Seleziona il tipo di media",
"search_filter_ocr": "Cerca tramite OCR",
"search_filter_people_title": "Seleziona persone",
"search_for": "Cerca per",
"search_for_existing_person": "Cerca per persona esistente",
@@ -1778,7 +1831,10 @@
"server_offline": "Server Offline",
"server_online": "Server Online",
"server_privacy": "Privacy del Server",
"server_restarting_description": "Questa pagina si aggiornerà per un momento.",
"server_restarting_title": "Il server si sta riavviando",
"server_stats": "Statistiche Server",
"server_update_available": "Aggiornamento Server disponibile",
"server_version": "Versione Server",
"set": "Imposta",
"set_as_album_cover": "Imposta come copertina album",
@@ -1807,6 +1863,8 @@
"setting_notifications_subtitle": "Cambia le impostazioni di notifica",
"setting_notifications_total_progress_subtitle": "Avanzamento complessivo del caricamento (completati/risorse totali)",
"setting_notifications_total_progress_title": "Mostra avanzamento del backup in background",
"setting_video_viewer_auto_play_subtitle": "Avvia automaticamente la riproduzione dei video quando vengono aperti",
"setting_video_viewer_auto_play_title": "Riproduci video automaticamente",
"setting_video_viewer_looping_title": "Looping",
"setting_video_viewer_original_video_subtitle": "Quando riproduci un video dal server, riproduci l'originale anche se è disponibile una versione transcodificata. Questo potrebbe portare a buffering. I video disponibili localmente sono sempre riprodotti a qualità originale indipendentemente da questa impostazione.",
"setting_video_viewer_original_video_title": "Forza video originale",
@@ -1986,7 +2044,9 @@
"theme_setting_three_stage_loading_title": "Abilita il caricamento a tre stage",
"they_will_be_merged_together": "Verranno uniti insieme",
"third_party_resources": "Risorse di Terze Parti",
"time": "Orario",
"time_based_memories": "Ricordi basati sul tempo",
"time_based_memories_duration": "Numero di secondi per visualizzare ciascuna immagine.",
"timeline": "Linea temporale",
"timezone": "Fuso orario",
"to_archive": "Archivio",
@@ -2018,6 +2078,7 @@
"troubleshoot": "Risoluzione dei problemi",
"type": "Tipo",
"unable_to_change_pin_code": "Impossibile cambiare il codice PIN",
"unable_to_check_version": "Impossibile controllare la versione del server o dell'app",
"unable_to_setup_pin_code": "Impossibile configurare il codice PIN",
"unarchive": "Annulla l'archiviazione",
"unarchive_action_prompt": "{count} elementi rimossi dall'Archivio",
@@ -2126,6 +2187,7 @@
"welcome": "Benvenuto",
"welcome_to_immich": "Benvenuto in Immich",
"wifi_name": "Nome rete Wi-Fi",
"workflow": "Flusso di lavoro",
"wrong_pin_code": "Codice PIN errato",
"year": "Anno",
"years_ago": "{years, plural, one {# anno} other {# anni}} fa",

View File

@@ -17,7 +17,6 @@
"add_birthday": "誕生日を設定",
"add_endpoint": "エンドポイントを追加",
"add_exclusion_pattern": "除外パターンを追加",
"add_import_path": "インポートパスを追加",
"add_location": "場所を追加",
"add_more_users": "ユーザーを追加",
"add_partner": "パートナーを追加",
@@ -33,6 +32,7 @@
"add_to_albums": "アルバムに追加",
"add_to_albums_count": "{count}つのアルバムへ追加",
"add_to_shared_album": "共有アルバムに追加",
"add_upload_to_stack": "スタックにアップロードを追加",
"add_url": "URLを追加",
"added_to_archive": "アーカイブにしました",
"added_to_favorites": "お気に入りに追加済",
@@ -111,7 +111,6 @@
"jobs_failed": "{jobCount, plural, other {#件}}の失敗",
"library_created": "作成されたライブラリ:{library}",
"library_deleted": "ライブラリは削除されました",
"library_import_path_description": "インポートするフォルダを指定します。このフォルダはサブフォルダを含めて、画像と動画のスキャンが行われます。",
"library_scanning": "定期スキャン",
"library_scanning_description": "ライブラリの定期スキャン設定",
"library_scanning_enable_description": "ライブラリ定期スキャンの有効化",
@@ -119,7 +118,7 @@
"library_settings_description": "外部ライブラリ設定を管理します",
"library_tasks_description": "アセットが追加または変更された外部ライブラリをスキャンする",
"library_watching_enable_description": "外部ライブラリのファイル変更を監視",
"library_watching_settings": "ライブラリ監視(実験的)",
"library_watching_settings": "ライブラリ監視(実験的機能",
"library_watching_settings_description": "変更されたファイルを自動的に監視",
"logging_enable_description": "ログの有効化",
"logging_level_description": "有効な場合に使用されるログ レベル。",
@@ -153,6 +152,18 @@
"machine_learning_min_detection_score_description": "顔を検出するための最低信頼スコアを0から1の範囲で設定します。値を低くするとより多くの顔を検出できますが、誤検出の可能性が高くなります。",
"machine_learning_min_recognized_faces": "顔認識の最低値",
"machine_learning_min_recognized_faces_description": "人物として作成されるために必要な最低認識顔数を設定します。この値を増やすと顔認識の精度が向上しますが、その代わりに顔が人物として認識されない可能性も高くなります。",
"machine_learning_ocr": "OCR",
"machine_learning_ocr_description": "画像内の文字を認識するために機械学習を使用する",
"machine_learning_ocr_enabled": "OCRを有効にする",
"machine_learning_ocr_enabled_description": "無効にすると、画像は文字認識されません.",
"machine_learning_ocr_max_resolution": "最大解像度",
"machine_learning_ocr_max_resolution_description": "この解像度を超えるプレビューは、アスペクト比を維持しながらサイズが変更されます。値を大きくすると精度は向上しますが、処理に時間がかかり、メモリ使用量も増加します。",
"machine_learning_ocr_min_detection_score": "検出スコアの最低値",
"machine_learning_ocr_min_detection_score_description": "検出するテキストの最小信頼度スコアを0から1の範囲で設定します。値が低いほど多くのテキストが検出されますが、誤検出が発生する可能性があります。",
"machine_learning_ocr_min_recognition_score": "認識スコアの最小値",
"machine_learning_ocr_min_score_recognition_description": "検出されたテキストを認識するための最低信頼スコアを0から1の範囲で設定します。。値が低いほど多くのテキストが認識されますが、誤検出が発生する可能性があります。",
"machine_learning_ocr_model": "OCRモデル",
"machine_learning_ocr_model_description": "サーバーモデルはモバイルモデルよりも正確ですが、処理に時間がかかり、メモリも多く使用します。",
"machine_learning_settings": "機械学習設定",
"machine_learning_settings_description": "機械学習の機能と設定を管理します",
"machine_learning_smart_search": "スマートサーチ",
@@ -160,6 +171,10 @@
"machine_learning_smart_search_enabled": "スマートサーチを有効にします",
"machine_learning_smart_search_enabled_description": "無効にすると、画像はスマートサーチ用にエンコードされません。",
"machine_learning_url_description": "機械学習サーバーのURL。複数のURLが設定された場合は1つずつサーバーが正常に応答するまで接続を試みます。応答のないサーバーはオンラインになるまで一時的に無視されます。",
"maintenance_settings": "メンテナンス",
"maintenance_settings_description": "Immichをメンテナンスモードにする。",
"maintenance_start": "メンテナンスモードを開始する",
"maintenance_start_error": "メンテナンスモードの開始に失敗しました。",
"manage_concurrency": "同時実行数の管理",
"manage_log_settings": "ログ設定を管理します",
"map_dark_style": "ダークモード",
@@ -210,6 +225,8 @@
"notification_email_ignore_certificate_errors_description": "TLS証明書の検証エラーを無視します非推奨",
"notification_email_password_description": "メールサーバーでの認証時に使用するパスワードを設定します",
"notification_email_port_description": "メールサーバーのポート番号を指定します25, 465, 587",
"notification_email_secure": "SMTPS",
"notification_email_secure_description": "SMTPSを使用 (SMTP over TLS)",
"notification_email_sent_test_email_button": "テストメールを送信して設定を保存",
"notification_email_setting_description": "メール通知の送信設定",
"notification_email_test_email": "テストメールを送信",
@@ -242,6 +259,7 @@
"oauth_storage_quota_default_description": "クレームが提供されていない場合に使用されるクォータをGiB単位で設定します。",
"oauth_timeout": "リクエストタイムアウト",
"oauth_timeout_description": "リクエストのタイムアウトまでの時間(ms)",
"ocr_job_description": "機械学習を使用して画像内のテキストを認識する",
"password_enable_description": "メールアドレスとパスワードでログイン",
"password_settings": "パスワード ログイン",
"password_settings_description": "パスワード ログイン設定を管理します",
@@ -332,7 +350,7 @@
"transcoding_max_b_frames": "最大Bフレーム",
"transcoding_max_b_frames_description": "値を高くすると圧縮効率が向上しますが、エンコード速度が遅くなります。古いデバイスのハードウェアアクセラレーションでは対応していない場合があります。\"0\" はBフレームを無効にし、\"-1\" はこの値を自動的に設定します。",
"transcoding_max_bitrate": "最大ビットレート",
"transcoding_max_bitrate_description": "最大ビットレートを設定すると、品質にわずかな影響を与えながらも、ファイルサイズを予測しやすくなります。720pの場合、一般的な値は VP9 や HEVC で \"2600 kbit/s\"、H.264 で \"4500 kbit/s\" です。\"0\" に設定すると無効になります。",
"transcoding_max_bitrate_description": "最大ビットレートを設定すると、品質にわずかな影響を与えながらも、ファイルサイズを予測しやすくなります。720pの場合、一般的な値は VP9 や HEVC で \"2600 kbit/s\"、H.264 で \"4500 kbit/s\" です。\"0\" に設定すると無効になります。単位が指定されていない場合、k(kbit/s)が適用されます。したがって5000、5000k、5M(5Mbit/s)は等しい設定値です。",
"transcoding_max_keyframe_interval": "最大キーフレーム間隔",
"transcoding_max_keyframe_interval_description": "キーフレーム間の最大フレーム間隔を設定します。値を低くすると圧縮効率が悪化しますが、シーク時間が改善され、動きの速いシーンの品質が向上する場合があります。\"0\" に設定すると、この値が自動的に設定されます。",
"transcoding_optimal_description": "設定解像度を超える動画、または容認されていない形式の動画",
@@ -350,7 +368,7 @@
"transcoding_target_resolution": "解像度",
"transcoding_target_resolution_description": "解像度を高くすると細かなディテールを保持できますが、エンコードに時間がかかり、ファイルサイズが大きくなり、アプリの応答性が低下する可能性があります。",
"transcoding_temporal_aq": "適応的量子化(Temporal AQ)",
"transcoding_temporal_aq_description": "NVEncにのみ適用されます。高精細で動きの少ないシーンの画質を向上させます。古いデバイスとの互換性はありません。",
"transcoding_temporal_aq_description": "NVEncにのみ適用されます。Temporal AQは高精細で動きの少ないシーンの画質を向上させます。古いデバイスとの互換性はありません。",
"transcoding_threads": "スレッド数",
"transcoding_threads_description": "値を高くするとエンコード速度が速くなりますが、アクティブな間はサーバーが他のタスクを処理する余裕が少なくなります。この値はCPUのコア数を超えないようにする必要があります。\"0\" に設定すると、最大限利用されます。",
"transcoding_tone_mapping": "トーンマッピング",
@@ -401,11 +419,11 @@
"advanced_settings_prefer_remote_subtitle": "デバイスによっては、デバイス上にあるサムネイルのロードに非常に時間がかかることがあります。このオプションを有効にする事により、サーバーから直接画像をロードすることが可能です。",
"advanced_settings_prefer_remote_title": "リモートを優先する",
"advanced_settings_proxy_headers_subtitle": "プロキシヘッダを設定する",
"advanced_settings_proxy_headers_title": "プロキシヘッダ",
"advanced_settings_proxy_headers_title": "カスタムプロキシヘッダ [実験的]",
"advanced_settings_readonly_mode_subtitle": "読み取り専用モードを有効にすると、写真の複数選択や、共有、削除、キャスト機能が無効になります。メインスクリーンのユーザーアバターから有効/無効を切り替えられます",
"advanced_settings_readonly_mode_title": "読み取り専用モード",
"advanced_settings_self_signed_ssl_subtitle": "SSLのチェックをスキップする。自己署名証明書が必要です。",
"advanced_settings_self_signed_ssl_title": "自己署名証明書を許可する",
"advanced_settings_self_signed_ssl_title": "自己署名証明書を許可する [実験的]",
"advanced_settings_sync_remote_deletions_subtitle": "Webでこの操作を行った際に、自動的にこのデバイス上から当該アセットを削除または復元する",
"advanced_settings_sync_remote_deletions_title": "リモート削除の同期 [試験運用]",
"advanced_settings_tile_subtitle": "追加ユーザー設定",
@@ -414,6 +432,7 @@
"age_months": "生後 {months,plural, one {#か月} other {#か月}}",
"age_year_months": "1歳{months,plural, one {#か月} other {#か月}}",
"age_years": "{years,plural, one {#歳} other {#歳}}",
"album": "アルバム",
"album_added": "アルバム追加",
"album_added_notification_setting_description": "共有アルバムに追加されたときEメール通知を受信する",
"album_cover_updated": "アルバムカバー更新",
@@ -459,6 +478,7 @@
"allow_edits": "編集を許可",
"allow_public_user_to_download": "一般ユーザーによるダウンロードを許可",
"allow_public_user_to_upload": "一般ユーザーによるアップロードを許可",
"allowed": "許可されている",
"alt_text_qr_code": "QRコード画像",
"anti_clockwise": "反時計回り",
"api_key": "APIキー",
@@ -468,7 +488,10 @@
"app_bar_signout_dialog_content": "サインアウトしますか?",
"app_bar_signout_dialog_ok": "はい",
"app_bar_signout_dialog_title": "サインアウト",
"app_download_links": "アプリのダウンロードリンク",
"app_settings": "アプリ設定",
"app_stores": "アプリストア",
"app_update_available": "アプリのアップデートが利用可能です",
"appears_in": "これらに含まれます",
"apply_count": "適用 ({count, number})",
"archive": "アーカイブ",
@@ -538,7 +561,7 @@
"autoplay_slideshow": "スライドショーを自動再生",
"back": "戻る",
"back_close_deselect": "戻る、閉じる、選択解除",
"background_backup_running_error": "バックグラウンドのバックアップがすでに行われている最中です。そのため、マニュアルでのバックアップを開始することはできません",
"background_backup_running_error": "バックグラウンドのバックアップがすでに行われている最中です。そのため、マニュアルでのバックアップを開始することはできません",
"background_location_permission": "バックグラウンド位置情報アクセス",
"background_location_permission_content": "正常にWi-Fiの名前(SSID)を獲得するにはアプリが常に詳細な位置情報にアクセスできる必要があります",
"background_options": "バックグラウンドの動作オプション",
@@ -552,6 +575,7 @@
"backup_albums_sync": "アルバム同期状態をバックアップ",
"backup_all": "すべて",
"backup_background_service_backup_failed_message": "アップロードに失敗しました。リトライ中…",
"backup_background_service_complete_notification": "アセットのバックアップが完了しました",
"backup_background_service_connection_failed_message": "サーバーに接続できません。リトライ中…",
"backup_background_service_current_upload_notification": "{filename}をアップロード中",
"backup_background_service_default_notification": "新しい写真を確認中…",
@@ -661,6 +685,8 @@
"change_password_description": "これは、初めてのサインインであるか、パスワードの変更要求が行われたかのいずれかです。 新しいパスワードを下に入力してください。",
"change_password_form_confirm_password": "確定",
"change_password_form_description": "{name}さん こんにちは\n\nサーバーにアクセスするのが初めてか、パスワードリセットのリクエストがされました。新しいパスワードを入力してください。",
"change_password_form_log_out": "他の全てのデバイスからログアウトさせる",
"change_password_form_log_out_description": "他のすべてのデバイスからログアウトすることをお勧めします",
"change_password_form_new_password": "新しいパスワード",
"change_password_form_password_mismatch": "パスワードが一致しません",
"change_password_form_reenter_new_password": "再度パスワードを入力してください",
@@ -687,8 +713,8 @@
"client_cert_import_success_msg": "クライアント証明書が導入されました",
"client_cert_invalid_msg": "パスワードが間違っているか証明書が無効です",
"client_cert_remove_msg": "クライアント証明書が削除されました",
"client_cert_subtitle": "PKCS12 (.p12 .pfx) フォーマットのみ対応されてます。証明書の導入や削除はログイン前のみ行えます",
"client_cert_title": "SSLクライアント証明書",
"client_cert_subtitle": "PKCS12 (.p12 .pfx) フォーマットのみ対応しています。証明書の導入や削除はログイン前のみ行えます",
"client_cert_title": "SSLクライアント証明書 [実験的]",
"clockwise": "時計回り",
"close": "閉じる",
"collapse": "展開",
@@ -700,7 +726,6 @@
"comments_and_likes": "コメントといいね",
"comments_are_disabled": "コメントは無効化されています",
"common_create_new_album": "アルバムを作成",
"common_server_error": "ネットワーク接続を確認し、サーバーが接続できる状態にあるか確認してください。アプリとサーバーのバージョンが一致しているかも確認してください。",
"completed": "完了",
"confirm": "確認",
"confirm_admin_password": "管理者パスワードを確認",
@@ -739,6 +764,7 @@
"create": "作成",
"create_album": "アルバムを作成",
"create_album_page_untitled": "無題のタイトル",
"create_api_key": "APIキーを作成",
"create_library": "ライブラリを作成",
"create_link": "リンクを作る",
"create_link_to_share": "共有リンクを作る",
@@ -768,6 +794,7 @@
"daily_title_text_date_year": "yyyy MM DD, EE",
"dark": "ダークモード",
"dark_theme": "ダークモード切り替え",
"date": "日付",
"date_after": "この日以降",
"date_and_time": "日付と時間",
"date_before": "この日以前",
@@ -870,8 +897,6 @@
"edit_description_prompt": "新しい説明文を選んでください:",
"edit_exclusion_pattern": "除外パターンを編集",
"edit_faces": "顔を編集",
"edit_import_path": "インポートパスを編集",
"edit_import_paths": "インポートパスを編集",
"edit_key": "キーを編集",
"edit_link": "リンクを編集する",
"edit_location": "位置情報を編集",
@@ -882,7 +907,6 @@
"edit_tag": "タグを編集する",
"edit_title": "タイトルを編集",
"edit_user": "ユーザーを編集",
"edited": "編集しました",
"editor": "編集画面",
"editor_close_without_save_prompt": "変更は破棄されます",
"editor_close_without_save_title": "編集画面を閉じますか?",
@@ -944,7 +968,6 @@
"failed_to_stack_assets": "アセットをスタックできませんでした",
"failed_to_unstack_assets": "アセットをスタックから解除することができませんでした",
"failed_to_update_notification_status": "通知ステータスの更新に失敗しました",
"import_path_already_exists": "このインポートパスは既に存在します。",
"incorrect_email_or_password": "メールアドレスまたはパスワードが間違っています",
"paths_validation_failed": "{paths, plural, one {#個} other {#個}}のパスの検証に失敗しました",
"profile_picture_transparent_pixels": "プロフィール写真には透明ピクセルを含めることはできません。画像を拡大/縮小したり移動してください。",
@@ -954,7 +977,6 @@
"unable_to_add_assets_to_shared_link": "アセットを共有リンクに追加できません",
"unable_to_add_comment": "コメントを追加できません",
"unable_to_add_exclusion_pattern": "除外パターンを追加できません",
"unable_to_add_import_path": "インポートパスを追加できません",
"unable_to_add_partners": "パートナーを追加できません",
"unable_to_add_remove_archive": "アーカイブ{archived, select, true {からアセットを削除} other {にアセットを追加}}できません",
"unable_to_add_remove_favorites": "項目をお気に入り{favorite, select, true {に追加} other {の解除}}できませんでした",
@@ -977,12 +999,10 @@
"unable_to_delete_asset": "項目を削除できません",
"unable_to_delete_assets": "項目を削除中のエラー",
"unable_to_delete_exclusion_pattern": "除外パターンを削除できません",
"unable_to_delete_import_path": "インポートパスを削除できません",
"unable_to_delete_shared_link": "共有リンクを削除できません",
"unable_to_delete_user": "ユーザーを削除できません",
"unable_to_download_files": "ファイルをダウンロードできません",
"unable_to_edit_exclusion_pattern": "除外パターンを編集できません",
"unable_to_edit_import_path": "インポートパスを編集できません",
"unable_to_empty_trash": "ゴミ箱を空にできません",
"unable_to_enter_fullscreen": "フルスクリーンにできません",
"unable_to_exit_fullscreen": "フルスクリーンを解除できません",
@@ -1038,6 +1058,7 @@
"exif_bottom_sheet_description_error": "説明文をアップデートできませんでした",
"exif_bottom_sheet_details": "詳細",
"exif_bottom_sheet_location": "撮影場所",
"exif_bottom_sheet_no_description": "説明なし",
"exif_bottom_sheet_people": "人物",
"exif_bottom_sheet_person_add_person": "名前を追加",
"exit_slideshow": "スライドショーを終わる",
@@ -1076,6 +1097,7 @@
"features_setting_description": "アプリの機能を管理する",
"file_name": "ファイル名",
"file_name_or_extension": "ファイル名または拡張子",
"file_size": "ファイルサイズ",
"filename": "ファイル名",
"filetype": "ファイルタイプ",
"filter": "フィルター",
@@ -1119,7 +1141,6 @@
"header_settings_field_validator_msg": "ヘッダを空白にはできません",
"header_settings_header_name_input": "ヘッダの名前",
"header_settings_header_value_input": "ヘッダのバリュー",
"headers_settings_tile_subtitle": "プロキシヘッダを設定する",
"headers_settings_tile_title": "カスタムプロキシヘッダ",
"hi_user": "こんにちは、{name}( {email})さん",
"hide_all_people": "全ての人物を非表示",
@@ -1172,6 +1193,7 @@
"import_path": "インポートパス",
"in_albums": "{count, plural, one {#件のアルバム} other {#件のアルバム}}の中",
"in_archive": "アーカイブ済み",
"in_year": "{year}年",
"include_archived": "アーカイブ済みを含める",
"include_shared_albums": "共有アルバムを含める",
"include_shared_partner_assets": "パートナーがシェアしたアセットを含める",
@@ -1240,6 +1262,7 @@
"local_media_summary": "ローカルメディアのまとめ",
"local_network": "ローカルネットワーク",
"local_network_sheet_info": "アプリは指定されたWi-Fiに繋がっている時サーバーへの接続を下記のURLで行います",
"location": "位置情報",
"location_permission": "位置情報権限",
"location_permission_content": "自動URL切り替えを使用するにはWi-Fiの名前(SSID)を取得する必要があり、正常に機能するにはアプリが常に詳細な位置情報にアクセスできる必要があります",
"location_picker_choose_on_map": "マップを選択",
@@ -1287,8 +1310,16 @@
"loop_videos_description": "有効にすると詳細表示で自動的に動画がループします。",
"main_branch_warning": "開発版を使っているようです。リリース版の使用を強く推奨します!",
"main_menu": "メインメニュー",
"maintenance_description": "Immich は <link>メンテナンスモード</link>中です。",
"maintenance_end": "メンテナンスモードを終了する",
"maintenance_end_error": "メンテナンスモードの終了に失敗しました。",
"maintenance_logged_in_as": "現在 {user}としてログインしています",
"maintenance_title": "一時的に利用不可能",
"make": "メーカー",
"manage_geolocation": "位置情報を編集",
"manage_media_access_settings": "設定を開く",
"manage_media_access_subtitle": "Immichアプリにメディアファイルの管理と移動を許可する。",
"manage_media_access_title": "メディア管理アクセス",
"manage_shared_links": "共有済みのリンクを管理",
"manage_sharing_with_partners": "パートナーとの共有を管理します",
"manage_the_app_settings": "アプリの設定を管理します",
@@ -1344,12 +1375,15 @@
"minute": "分",
"minutes": "分",
"missing": "欠落",
"mobile_app": "モバイルアプリ",
"mobile_app_download_onboarding_note": "以下のオプションを使用してコンパニオンモバイルアプリをダウンロードしてください",
"model": "モデル",
"month": "月",
"monthly_title_text_date_format": "yyyy MM",
"more": "もっと表示",
"move": "移動",
"move_off_locked_folder": "鍵付きフォルダーから出す",
"move_to": "移動先は",
"move_to_lock_folder_action_prompt": "{count}項目を鍵付きフォルダーに追加しました",
"move_to_locked_folder": "鍵付きフォルダーへ移動",
"move_to_locked_folder_confirmation": "これらの写真や動画はすべてのアルバムから外され、鍵付きフォルダー内でのみ閲覧可能になります",
@@ -1362,6 +1396,7 @@
"my_albums": "私のアルバム",
"name": "名前",
"name_or_nickname": "名前またはニックネーム",
"navigate": "ナビゲート",
"network_requirement_photos_upload": "モバイル通信を使用して写真のバックアップを行う",
"network_requirement_videos_upload": "モバイル通信を使用して動画のバックアップを行う",
"network_requirements": "ネットワークの要件",
@@ -1371,11 +1406,13 @@
"never": "行わない",
"new_album": "新たなアルバム",
"new_api_key": "新しいAPI キー",
"new_date_range": "新しい日付範囲",
"new_password": "新しいパスワード",
"new_person": "新しい人物",
"new_pin_code": "新しいPINコード",
"new_pin_code_subtitle": "鍵付きフォルダーを利用するのが初めてのようです。PINコードを作成してください",
"new_timeline": "新たなタイムライン",
"new_update": "新たな更新",
"new_user_created": "新しいユーザーが作成されました",
"new_version_available": "新しいバージョンが利用可能",
"newest_first": "最新順",
@@ -1391,6 +1428,7 @@
"no_cast_devices_found": "キャスト先のデバイスが見つかりません",
"no_checksum_local": "チェックサムが見つかりません - デバイス上の項目を取得できないようです",
"no_checksum_remote": "チェックサムが見つかりません - サーバー上の項目を取得できないようです",
"no_devices": "許可されたデバイスがありません",
"no_duplicates_found": "重複は見つかりませんでした。",
"no_exif_info_available": "exif情報が利用できません",
"no_explore_results_message": "コレクションを探索するにはさらに写真をアップロードしてください。",
@@ -1407,6 +1445,7 @@
"no_results_description": "同義語やより一般的なキーワードを試してください",
"no_shared_albums_message": "アルバムを作成して写真や動画を共有しましょう",
"no_uploads_in_progress": "アップロードは行われていません",
"not_allowed": "許可されていません",
"not_available": "適用なし",
"not_in_any_album": "どのアルバムにも入っていない",
"not_selected": "選択なし",
@@ -1421,6 +1460,9 @@
"notifications": "通知",
"notifications_setting_description": "通知を管理します",
"oauth": "OAuth",
"obtainium_configurator": "Obtainiumの設定",
"obtainium_configurator_instructions": "Obtainiumを使用すると、Immich GitHubのリリースから直接Androidアプリをインストールおよびアップデートできます。APIキーを作成し、バリアントを選択してObtainiumの設定リンクを作成してください",
"ocr": "OCR",
"official_immich_resources": "公式Immichリソース",
"offline": "オフライン",
"offset": "オフセット",
@@ -1514,6 +1556,7 @@
"photos_count": "{count, plural, one {{count, number}枚の写真} other {{count, number}枚の写真}}",
"photos_from_previous_years": "以前の年の写真",
"pick_a_location": "場所を選択",
"pick_date_range": "日付範囲の選択",
"pin_code_changed_successfully": "PINコードを変更しました",
"pin_code_reset_successfully": "PINコードをリセットしました",
"pin_code_setup_successfully": "PINコードをセットアップしました",
@@ -1525,6 +1568,9 @@
"play_memories": "メモリーを再生",
"play_motion_photo": "モーションビデオを再生",
"play_or_pause_video": "動画を再生または一時停止",
"play_original_video": "オリジナルの動画を再生",
"play_original_video_setting_description": "トランスコードされた動画よりも、オリジナルの動画を優先して再生します。オリジナルのアセットが互換性がない場合、正しく再生されない可能性があります。",
"play_transcoded_video": "トランスコード済みの動画を再生する",
"please_auth_to_access": "アクセスするには認証が必要です",
"port": "ポートレート",
"preferences_settings_subtitle": "アプリに関する設定",
@@ -1542,13 +1588,9 @@
"privacy": "プライバシー",
"profile": "プロフィール",
"profile_drawer_app_logs": "ログ",
"profile_drawer_client_out_of_date_major": "アプリが更新されてません。最新のバージョンに更新してください",
"profile_drawer_client_out_of_date_minor": "アプリが更新されてません。最新のバージョンに更新してください",
"profile_drawer_client_server_up_to_date": "すべて最新版です",
"profile_drawer_github": "GitHub",
"profile_drawer_readonly_mode": "読み取り専用モードが有効です。ユーザーのアイコンを長押しして読み取り専用モードを解除してください。",
"profile_drawer_server_out_of_date_major": "サーバーが更新されてません。最新のバージョンに更新してください",
"profile_drawer_server_out_of_date_minor": "サーバーが更新されてません。最新のバージョンに更新してください",
"profile_image_of_user": "{user} のプロフィール画像",
"profile_picture_set": "プロフィール画像が設定されました。",
"public_album": "公開アルバム",
@@ -1665,6 +1707,7 @@
"reset_sqlite_confirmation": "SQLiteを本当にリセットしますかデータを再び同期するためにログアウトし再ログインをする必要があります",
"reset_sqlite_success": "SQLiteデータベースのリセットに成功しました",
"reset_to_default": "デフォルトにリセット",
"resolution": "解像度",
"resolve_duplicates": "重複を解決する",
"resolved_all_duplicates": "全ての重複を解決しました",
"restore": "復元",
@@ -1683,6 +1726,7 @@
"running": "実行中",
"save": "保存",
"save_to_gallery": "ギャラリーに保存",
"saved": "保存しました",
"saved_api_key": "APIキーを保存しました",
"saved_profile": "プロフィールを保存しました",
"saved_settings": "設定を保存しました",
@@ -1699,6 +1743,9 @@
"search_by_description_example": "サパでハイキングした日",
"search_by_filename": "ファイル名もしくは拡張子で検索",
"search_by_filename_example": "例: IMG_1234.JPG もしくは PNG",
"search_by_ocr": "OCR検索",
"search_by_ocr_example": "お茶",
"search_camera_lens_model": "レンズモデルで検索…",
"search_camera_make": "カメラメーカーを検索…",
"search_camera_model": "カメラのモデルを検索…",
"search_city": "市町村を検索…",
@@ -1715,6 +1762,7 @@
"search_filter_location_title": "場所を選択",
"search_filter_media_type": "メディアの種類",
"search_filter_media_type_title": "メディアの種類を選択",
"search_filter_ocr": "OCRで検索",
"search_filter_people_title": "人物を選択",
"search_for": "検索",
"search_for_existing_person": "既存の人物を検索",
@@ -1776,7 +1824,10 @@
"server_offline": "サーバーがオフラインです",
"server_online": "サーバーがオンラインです",
"server_privacy": "サーバープライバシー",
"server_restarting_description": "このページはすぐに更新されます。",
"server_restarting_title": "サーバーは再起動しています",
"server_stats": "サーバー統計",
"server_update_available": "サーバーのアップデートが利用可能です",
"server_version": "サーバーバージョン",
"set": "設定",
"set_as_album_cover": "アルバムカバーとして設定",
@@ -1805,6 +1856,8 @@
"setting_notifications_subtitle": "通知設定を変更する",
"setting_notifications_total_progress_subtitle": "アップロードの進行状況 (完了済み/全体枚数)",
"setting_notifications_total_progress_title": "全体のバックアップの進行状況を表示",
"setting_video_viewer_auto_play_subtitle": "動画を開くと自動で再生されます",
"setting_video_viewer_auto_play_title": "動画の自動再生",
"setting_video_viewer_looping_title": "動画をループする",
"setting_video_viewer_original_video_subtitle": "動画をストリーミングする際に、トランスコードされた動画が存在していても、あえてオリジナル画質の動画を再生します。ストリーミングに待ち時間が生じるかもしれません。なお、デバイス上に保存されている動画はこの設定の有無に関わらず、オリジナル画質の動画を再生します。",
"setting_video_viewer_original_video_title": "常にオリジナル画質の動画を再生する",
@@ -1984,7 +2037,9 @@
"theme_setting_three_stage_loading_title": "三段階読み込みをオンにする",
"they_will_be_merged_together": "これらは一緒に統合されます",
"third_party_resources": "サードパーティーリソース",
"time": "時刻",
"time_based_memories": "過去の思い出",
"time_based_memories_duration": "各写真を表示する秒数。",
"timeline": "タイムライン",
"timezone": "タイムゾーン",
"to_archive": "アーカイブ",
@@ -2016,6 +2071,7 @@
"troubleshoot": "トラブルシューティング",
"type": "タイプ",
"unable_to_change_pin_code": "PINコードを変更できませんでした",
"unable_to_check_version": "アプリまたはサーバーのバージョンをチェックできませんでした",
"unable_to_setup_pin_code": "PINコードをセットアップできませんでした",
"unarchive": "アーカイブを解除",
"unarchive_action_prompt": "{count}項目をアーカイブから除きました",
@@ -2124,6 +2180,7 @@
"welcome": "ようこそ",
"welcome_to_immich": "Immichにようこそ",
"wifi_name": "Wi-Fiの名前(SSID)",
"workflow": "ワークフロー",
"wrong_pin_code": "PINコードが間違っています",
"year": "年",
"years_ago": "{years, plural, one {#年} other {#年}}前",

Some files were not shown because too many files have changed in this diff Show More