From ea39bb356581f744c7e046cec08fd4f40bbd2875 Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Thu, 1 Jan 2026 09:55:46 -0600 Subject: [PATCH 01/98] update copyright (#21485) --- docs/docusaurus.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index c0295faae..be0c54c9d 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -170,7 +170,7 @@ const config: Config = { ], }, ], - copyright: `Copyright © ${new Date().getFullYear()} Blake Blackshear`, + copyright: `Copyright © ${new Date().getFullYear()} Frigate, Inc.`, }, }, plugins: [ From 7e5d98dbabbd4b02293eafef7f2df312c27a4c91 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sun, 11 Jan 2026 05:42:33 -0800 Subject: [PATCH 02/98] fix: Correctly apply API filter for "reviewed" (#21600) --- frigate/api/review.py | 2 ++ frigate/test/http_api/base_http_test.py | 18 +++++++--- frigate/test/http_api/test_http_event.py | 7 ++-- frigate/test/http_api/test_http_review.py | 44 +++++++++++++++++++++++ 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/frigate/api/review.py b/frigate/api/review.py index 5f6fbc13b..76619dcb2 100644 --- a/frigate/api/review.py +++ b/frigate/api/review.py @@ -144,6 +144,8 @@ async def review( (UserReviewStatus.has_been_reviewed == False) | (UserReviewStatus.has_been_reviewed.is_null()) ) + elif reviewed == 1: + review_query = review_query.where(UserReviewStatus.has_been_reviewed == True) # Apply ordering and limit review_query = ( diff --git a/frigate/test/http_api/base_http_test.py b/frigate/test/http_api/base_http_test.py index 85249092c..16ded63f8 100644 --- a/frigate/test/http_api/base_http_test.py +++ b/frigate/test/http_api/base_http_test.py @@ -171,8 +171,8 @@ class BaseTestHttp(unittest.TestCase): def insert_mock_event( self, id: str, - start_time: float = datetime.datetime.now().timestamp(), - end_time: float = datetime.datetime.now().timestamp() + 20, + start_time: float | None = None, + end_time: float | None = None, has_clip: bool = True, top_score: int = 100, score: int = 0, @@ -180,6 +180,11 @@ class BaseTestHttp(unittest.TestCase): camera: str = "front_door", ) -> Event: """Inserts a basic event model with a given id.""" + if start_time is None: + start_time = datetime.datetime.now().timestamp() + if end_time is None: + end_time = start_time + 20 + return Event.insert( id=id, label="Mock", @@ -229,11 +234,16 @@ class BaseTestHttp(unittest.TestCase): def insert_mock_recording( self, id: str, - start_time: float = datetime.datetime.now().timestamp(), - end_time: float = datetime.datetime.now().timestamp() + 20, + start_time: float | None = None, + end_time: float | None = None, motion: int = 0, ) -> Event: """Inserts a recording model with a given id.""" + if start_time is None: + start_time = datetime.datetime.now().timestamp() + if end_time is None: + end_time = start_time + 20 + return Recordings.insert( id=id, path=id, diff --git a/frigate/test/http_api/test_http_event.py b/frigate/test/http_api/test_http_event.py index 44c4fd3ec..fc895fabf 100644 --- a/frigate/test/http_api/test_http_event.py +++ b/frigate/test/http_api/test_http_event.py @@ -96,16 +96,17 @@ class TestHttpApp(BaseTestHttp): assert len(events) == 0 def test_get_event_list_limit(self): + now = datetime.now().timestamp() id = "123456.random" id2 = "54321.random" with AuthTestClient(self.app) as client: - super().insert_mock_event(id) + super().insert_mock_event(id, start_time=now + 1) events = client.get("/events").json() assert len(events) == 1 assert events[0]["id"] == id - super().insert_mock_event(id2) + super().insert_mock_event(id2, start_time=now) events = client.get("/events").json() assert len(events) == 2 @@ -144,7 +145,7 @@ class TestHttpApp(BaseTestHttp): assert events[0]["id"] == id2 assert events[1]["id"] == id - events = client.get("/events", params={"sort": "score_des"}).json() + events = client.get("/events", params={"sort": "score_desc"}).json() assert len(events) == 2 assert events[0]["id"] == id assert events[1]["id"] == id2 diff --git a/frigate/test/http_api/test_http_review.py b/frigate/test/http_api/test_http_review.py index 7c6615bac..ca73c8706 100644 --- a/frigate/test/http_api/test_http_review.py +++ b/frigate/test/http_api/test_http_review.py @@ -196,6 +196,50 @@ class TestHttpReview(BaseTestHttp): assert len(response_json) == 1 assert response_json[0]["id"] == id + def test_get_review_with_reviewed_filter_unreviewed(self): + """Test that reviewed=0 returns only unreviewed items.""" + now = datetime.now().timestamp() + + with AuthTestClient(self.app) as client: + id_unreviewed = "123456.unreviewed" + id_reviewed = "123456.reviewed" + super().insert_mock_review_segment(id_unreviewed, now, now + 2) + super().insert_mock_review_segment(id_reviewed, now, now + 2) + self._insert_user_review_status(id_reviewed, reviewed=True) + + params = { + "reviewed": 0, + "after": now - 1, + "before": now + 3, + } + response = client.get("/review", params=params) + assert response.status_code == 200 + response_json = response.json() + assert len(response_json) == 1 + assert response_json[0]["id"] == id_unreviewed + + def test_get_review_with_reviewed_filter_reviewed(self): + """Test that reviewed=1 returns only reviewed items.""" + now = datetime.now().timestamp() + + with AuthTestClient(self.app) as client: + id_unreviewed = "123456.unreviewed" + id_reviewed = "123456.reviewed" + super().insert_mock_review_segment(id_unreviewed, now, now + 2) + super().insert_mock_review_segment(id_reviewed, now, now + 2) + self._insert_user_review_status(id_reviewed, reviewed=True) + + params = { + "reviewed": 1, + "after": now - 1, + "before": now + 3, + } + response = client.get("/review", params=params) + assert response.status_code == 200 + response_json = response.json() + assert len(response_json) == 1 + assert response_json[0]["id"] == id_reviewed + #################################################################################################################### ################################### GET /review/summary Endpoint ################################################# #################################################################################################################### From 7b5a1b7284ffda8b02f5df2d8c592df2bc8d8c31 Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Sun, 11 Jan 2026 09:48:03 -0600 Subject: [PATCH 03/98] ensure cloudflare pages are indexed by google (#21606) * ensure cloudflare pages are indexed by google * avoid indexing dev-docs as well --- docs/static/_headers | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docs/static/_headers diff --git a/docs/static/_headers b/docs/static/_headers new file mode 100644 index 000000000..7327dc463 --- /dev/null +++ b/docs/static/_headers @@ -0,0 +1,8 @@ +https://:project.pages.dev/* + X-Robots-Tag: noindex + +https://:version.:project.pages.dev/* + X-Robots-Tag: noindex + +https://docs-dev.frigate.video/* + X-Robots-Tag: noindex \ No newline at end of file From 91cc6747b6f1d67e8f3cc52b71fa73e58fe88bde Mon Sep 17 00:00:00 2001 From: GuoQing Liu <842607283@qq.com> Date: Mon, 12 Jan 2026 23:15:27 +0800 Subject: [PATCH 04/98] i18n miscellaneous fixes (#21614) * fix: fix face library unknown label i18n wrong * fix: fix review genai threat level i18n * fix: fix preview unknown label i18n * fix: fix AM/PM i18n display issue --- web/src/components/card/ClassificationCard.tsx | 4 ++-- web/src/components/overlay/chip/GenAISummaryChip.tsx | 8 +++++--- web/src/components/player/PreviewThumbnailPlayer.tsx | 4 +++- web/src/utils/dateUtil.ts | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/web/src/components/card/ClassificationCard.tsx b/web/src/components/card/ClassificationCard.tsx index ffd28a0d0..6581d109a 100644 --- a/web/src/components/card/ClassificationCard.tsx +++ b/web/src/components/card/ClassificationCard.tsx @@ -164,7 +164,7 @@ export const ClassificationCard = forwardRef< )} >
- {data.name == "unknown" + {data.name.toLowerCase() == "unknown" ? t("details.unknown") : data.name.toLowerCase() == "none" ? t("details.none") @@ -336,7 +336,7 @@ export function GroupedClassificationCard({ {classifiedEvent?.label && classifiedEvent.label !== "none" ? classifiedEvent.label - : t(noClassificationLabel)} + : t(noClassificationLabel, { ns: i18nLibrary })} {classifiedEvent?.label && classifiedEvent.label !== "none" && classifiedEvent.score !== undefined && ( diff --git a/web/src/components/overlay/chip/GenAISummaryChip.tsx b/web/src/components/overlay/chip/GenAISummaryChip.tsx index 46fefdc67..d5f7a9969 100644 --- a/web/src/components/overlay/chip/GenAISummaryChip.tsx +++ b/web/src/components/overlay/chip/GenAISummaryChip.tsx @@ -57,7 +57,7 @@ export function GenAISummaryDialog({ !aiAnalysis || (!aiAnalysis.potential_threat_level && !aiAnalysis.other_concerns) ) { - return "None"; + return t("label.none", { ns: "common" }); } let concerns = ""; @@ -74,7 +74,9 @@ export function GenAISummaryDialog({ label = t("securityConcern", { ns: "views/events" }); break; default: - label = THREAT_LEVEL_LABELS[threatLevel as ThreatLevel] || "Unknown"; + label = + THREAT_LEVEL_LABELS[threatLevel as ThreatLevel] || + t("details.unknown", { ns: "views/classificationModel" }); } concerns = `• ${label}\n`; } @@ -83,7 +85,7 @@ export function GenAISummaryDialog({ concerns += `• ${c}\n`; }); - return concerns || "None"; + return concerns || t("label.none", { ns: "common" }); }, [aiAnalysis, t]); // layout diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index 30339599a..517a83e7c 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -342,7 +342,9 @@ export default function PreviewThumbnailPlayer({ default: return ( THREAT_LEVEL_LABELS[threatLevel as ThreatLevel] || - "Unknown" + t("details.unknown", { + ns: "views/classificationModel", + }) ); } })()} diff --git a/web/src/utils/dateUtil.ts b/web/src/utils/dateUtil.ts index b007a9573..cc541214c 100644 --- a/web/src/utils/dateUtil.ts +++ b/web/src/utils/dateUtil.ts @@ -165,7 +165,7 @@ export const formatUnixTimestampToDateTime = ( // Uppercase AM/PM for 12-hour formats if (date_format.includes("a") || date_format.includes("aaa")) { formatted = formatted.replace(/am|pm/gi, (match) => - match.toUpperCase(), + i18n.t(`time.${match.toLowerCase()}`, { ns: "common" }).toUpperCase(), ); } return formatted; @@ -217,7 +217,7 @@ export const formatUnixTimestampToDateTime = ( // Uppercase AM/PM in fallback if (options.hour12) { fallbackFormatted = fallbackFormatted.replace(/am|pm/gi, (match) => - match.toUpperCase(), + i18n.t(`time.${match.toLowerCase()}`, { ns: "common" }).toUpperCase(), ); } return fallbackFormatted; From 2c34e1ec1051d776df6c44b7cb6711a44ec24693 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 12 Jan 2026 20:36:38 -0700 Subject: [PATCH 05/98] Miscellaneous fixes (0.17 beta) (#21607) * Strip model name before training * Handle options file for go2rtc option * Make reviewed optional and add null to API call * Send reviewed for dashboard * Allow setting context size for openai compatible endpoints * push empty go2rtc config to avoid homekit error in log * Add option to set runtime options for LLM providers * Docs --------- Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> --- .../rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run | 4 +-- .../rootfs/usr/local/go2rtc/create_config.py | 24 ++++++++++++-- docs/docs/configuration/genai/config.md | 33 ++++++++++++++----- docs/docs/configuration/reference.md | 3 ++ .../api/defs/query/review_query_parameters.py | 2 +- frigate/config/camera/genai.py | 3 ++ frigate/genai/azure-openai.py | 1 + frigate/genai/gemini.py | 6 +++- frigate/genai/ollama.py | 6 +++- frigate/genai/openai.py | 22 +++++++++++-- frigate/util/classification.py | 7 ++++ web/public/locales/en/config/genai.json | 5 ++- web/src/pages/Events.tsx | 2 +- web/src/views/live/LiveDashboardView.tsx | 1 + 14 files changed, 99 insertions(+), 20 deletions(-) diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run index d3aa34236..349027bd1 100755 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run @@ -54,8 +54,8 @@ function setup_homekit_config() { local config_path="$1" if [[ ! -f "${config_path}" ]]; then - echo "[INFO] Creating empty HomeKit config file..." - echo 'homekit: {}' > "${config_path}" + echo "[INFO] Creating empty config file for HomeKit..." + echo '{}' > "${config_path}" fi # Convert YAML to JSON for jq processing diff --git a/docker/main/rootfs/usr/local/go2rtc/create_config.py b/docker/main/rootfs/usr/local/go2rtc/create_config.py index 8b8aef6d9..fb701a9b6 100644 --- a/docker/main/rootfs/usr/local/go2rtc/create_config.py +++ b/docker/main/rootfs/usr/local/go2rtc/create_config.py @@ -23,8 +23,28 @@ sys.path.remove("/opt/frigate") yaml = YAML() # Check if arbitrary exec sources are allowed (defaults to False for security) -ALLOW_ARBITRARY_EXEC = os.environ.get( - "GO2RTC_ALLOW_ARBITRARY_EXEC", "false" +allow_arbitrary_exec = None +if "GO2RTC_ALLOW_ARBITRARY_EXEC" in os.environ: + allow_arbitrary_exec = os.environ.get("GO2RTC_ALLOW_ARBITRARY_EXEC") +elif ( + os.path.isdir("/run/secrets") + and os.access("/run/secrets", os.R_OK) + and "GO2RTC_ALLOW_ARBITRARY_EXEC" in os.listdir("/run/secrets") +): + allow_arbitrary_exec = ( + Path(os.path.join("/run/secrets", "GO2RTC_ALLOW_ARBITRARY_EXEC")) + .read_text() + .strip() + ) +# check for the add-on options file +elif os.path.isfile("/data/options.json"): + with open("/data/options.json") as f: + raw_options = f.read() + options = json.loads(raw_options) + allow_arbitrary_exec = options.get("go2rtc_allow_arbitrary_exec") + +ALLOW_ARBITRARY_EXEC = allow_arbitrary_exec is not None and str( + allow_arbitrary_exec ).lower() in ("true", "1", "yes") FRIGATE_ENV_VARS = {k: v for k, v in os.environ.items() if k.startswith("FRIGATE_")} diff --git a/docs/docs/configuration/genai/config.md b/docs/docs/configuration/genai/config.md index 7e5618b5b..3a54eeddf 100644 --- a/docs/docs/configuration/genai/config.md +++ b/docs/docs/configuration/genai/config.md @@ -41,12 +41,12 @@ If you are trying to use a single model for Frigate and HomeAssistant, it will n The following models are recommended: -| Model | Notes | -| ----------------- | -------------------------------------------------------------------- | -| `qwen3-vl` | Strong visual and situational understanding, higher vram requirement | -| `Intern3.5VL` | Relatively fast with good vision comprehension | -| `gemma3` | Strong frame-to-frame understanding, slower inference times | -| `qwen2.5-vl` | Fast but capable model with good vision comprehension | +| Model | Notes | +| ------------- | -------------------------------------------------------------------- | +| `qwen3-vl` | Strong visual and situational understanding, higher vram requirement | +| `Intern3.5VL` | Relatively fast with good vision comprehension | +| `gemma3` | Strong frame-to-frame understanding, slower inference times | +| `qwen2.5-vl` | Fast but capable model with good vision comprehension | :::note @@ -61,10 +61,10 @@ genai: provider: ollama base_url: http://localhost:11434 model: minicpm-v:8b - provider_options: # other Ollama client options can be defined + provider_options: # other Ollama client options can be defined keep_alive: -1 options: - num_ctx: 8192 # make sure the context matches other services that are using ollama + num_ctx: 8192 # make sure the context matches other services that are using ollama ``` ## Google Gemini @@ -120,6 +120,23 @@ To use a different OpenAI-compatible API endpoint, set the `OPENAI_BASE_URL` env ::: +:::tip + +For OpenAI-compatible servers (such as llama.cpp) that don't expose the configured context size in the API response, you can manually specify the context size in `provider_options`: + +```yaml +genai: + provider: openai + base_url: http://your-llama-server + model: your-model-name + provider_options: + context_size: 8192 # Specify the configured context size +``` + +This ensures Frigate uses the correct context window size when generating prompts. + +::: + ## Azure OpenAI Microsoft offers several vision models through Azure OpenAI. A subscription is required. diff --git a/docs/docs/configuration/reference.md b/docs/docs/configuration/reference.md index cccaf3eaa..206d7012e 100644 --- a/docs/docs/configuration/reference.md +++ b/docs/docs/configuration/reference.md @@ -696,6 +696,9 @@ genai: # Optional additional args to pass to the GenAI Provider (default: None) provider_options: keep_alive: -1 + # Optional: Options to pass during inference calls (default: {}) + runtime_options: + temperature: 0.7 # Optional: Configuration for audio transcription # NOTE: only the enabled option can be overridden at the camera level diff --git a/frigate/api/defs/query/review_query_parameters.py b/frigate/api/defs/query/review_query_parameters.py index ee9af740e..6d01d824d 100644 --- a/frigate/api/defs/query/review_query_parameters.py +++ b/frigate/api/defs/query/review_query_parameters.py @@ -10,7 +10,7 @@ class ReviewQueryParams(BaseModel): cameras: str = "all" labels: str = "all" zones: str = "all" - reviewed: int = 0 + reviewed: Union[int, SkipJsonSchema[None]] = None limit: Union[int, SkipJsonSchema[None]] = None severity: Union[SeverityEnum, SkipJsonSchema[None]] = None before: Union[float, SkipJsonSchema[None]] = None diff --git a/frigate/config/camera/genai.py b/frigate/config/camera/genai.py index 3c6baeb15..a4d9199af 100644 --- a/frigate/config/camera/genai.py +++ b/frigate/config/camera/genai.py @@ -26,3 +26,6 @@ class GenAIConfig(FrigateBaseModel): provider_options: dict[str, Any] = Field( default={}, title="GenAI Provider extra options." ) + runtime_options: dict[str, Any] = Field( + default={}, title="Options to pass during inference calls." + ) diff --git a/frigate/genai/azure-openai.py b/frigate/genai/azure-openai.py index eba8b47c0..eb08f7786 100644 --- a/frigate/genai/azure-openai.py +++ b/frigate/genai/azure-openai.py @@ -64,6 +64,7 @@ class OpenAIClient(GenAIClient): }, ], timeout=self.timeout, + **self.genai_config.runtime_options, ) except Exception as e: logger.warning("Azure OpenAI returned an error: %s", str(e)) diff --git a/frigate/genai/gemini.py b/frigate/genai/gemini.py index f94448d75..01e8ef758 100644 --- a/frigate/genai/gemini.py +++ b/frigate/genai/gemini.py @@ -35,10 +35,14 @@ class GeminiClient(GenAIClient): for img in images ] + [prompt] try: + # Merge runtime_options into generation_config if provided + generation_config_dict = {"candidate_count": 1} + generation_config_dict.update(self.genai_config.runtime_options) + response = self.provider.generate_content( data, generation_config=genai.types.GenerationConfig( - candidate_count=1, + **generation_config_dict ), request_options=genai.types.RequestOptions( timeout=self.timeout, diff --git a/frigate/genai/ollama.py b/frigate/genai/ollama.py index a54141e4d..ab6d3c0b3 100644 --- a/frigate/genai/ollama.py +++ b/frigate/genai/ollama.py @@ -58,11 +58,15 @@ class OllamaClient(GenAIClient): ) return None try: + ollama_options = { + **self.provider_options, + **self.genai_config.runtime_options, + } result = self.provider.generate( self.genai_config.model, prompt, images=images if images else None, - **self.provider_options, + **ollama_options, ) logger.debug( f"Ollama tokens used: eval_count={result.get('eval_count')}, prompt_eval_count={result.get('prompt_eval_count')}" diff --git a/frigate/genai/openai.py b/frigate/genai/openai.py index 631cb3480..1fb0dd852 100644 --- a/frigate/genai/openai.py +++ b/frigate/genai/openai.py @@ -22,9 +22,14 @@ class OpenAIClient(GenAIClient): def _init_provider(self): """Initialize the client.""" - return OpenAI( - api_key=self.genai_config.api_key, **self.genai_config.provider_options - ) + # Extract context_size from provider_options as it's not a valid OpenAI client parameter + # It will be used in get_context_size() instead + provider_opts = { + k: v + for k, v in self.genai_config.provider_options.items() + if k != "context_size" + } + return OpenAI(api_key=self.genai_config.api_key, **provider_opts) def _send(self, prompt: str, images: list[bytes]) -> Optional[str]: """Submit a request to OpenAI.""" @@ -56,6 +61,7 @@ class OpenAIClient(GenAIClient): }, ], timeout=self.timeout, + **self.genai_config.runtime_options, ) if ( result is not None @@ -73,6 +79,16 @@ class OpenAIClient(GenAIClient): if self.context_size is not None: return self.context_size + # First check provider_options for manually specified context size + # This is necessary for llama.cpp and other OpenAI-compatible servers + # that don't expose the configured runtime context size in the API response + if "context_size" in self.genai_config.provider_options: + self.context_size = self.genai_config.provider_options["context_size"] + logger.debug( + f"Using context size {self.context_size} from provider_options for model {self.genai_config.model}" + ) + return self.context_size + try: models = self.provider.models.list() for model in models.data: diff --git a/frigate/util/classification.py b/frigate/util/classification.py index f4206b346..643f77d3b 100644 --- a/frigate/util/classification.py +++ b/frigate/util/classification.py @@ -43,6 +43,7 @@ def write_training_metadata(model_name: str, image_count: int) -> None: model_name: Name of the classification model image_count: Number of images used in training """ + model_name = model_name.strip() clips_model_dir = os.path.join(CLIPS_DIR, model_name) os.makedirs(clips_model_dir, exist_ok=True) @@ -70,6 +71,7 @@ def read_training_metadata(model_name: str) -> dict[str, any] | None: Returns: Dictionary with last_training_date and last_training_image_count, or None if not found """ + model_name = model_name.strip() clips_model_dir = os.path.join(CLIPS_DIR, model_name) metadata_path = os.path.join(clips_model_dir, TRAINING_METADATA_FILE) @@ -95,6 +97,7 @@ def get_dataset_image_count(model_name: str) -> int: Returns: Total count of images across all categories """ + model_name = model_name.strip() dataset_dir = os.path.join(CLIPS_DIR, model_name, "dataset") if not os.path.exists(dataset_dir): @@ -126,6 +129,7 @@ class ClassificationTrainingProcess(FrigateProcess): "TF_KERAS_MOBILENET_V2_WEIGHTS_URL", "", ) + model_name = model_name.strip() super().__init__( stop_event=None, priority=PROCESS_PRIORITY_LOW, @@ -292,6 +296,7 @@ class ClassificationTrainingProcess(FrigateProcess): def kickoff_model_training( embeddingRequestor: EmbeddingsRequestor, model_name: str ) -> None: + model_name = model_name.strip() requestor = InterProcessRequestor() requestor.send_data( UPDATE_MODEL_STATE, @@ -359,6 +364,7 @@ def collect_state_classification_examples( model_name: Name of the classification model cameras: Dict mapping camera names to normalized crop coordinates [x1, y1, x2, y2] (0-1) """ + model_name = model_name.strip() dataset_dir = os.path.join(CLIPS_DIR, model_name, "dataset") # Step 1: Get review items for the cameras @@ -714,6 +720,7 @@ def collect_object_classification_examples( model_name: Name of the classification model label: Object label to collect (e.g., "person", "car") """ + model_name = model_name.strip() dataset_dir = os.path.join(CLIPS_DIR, model_name, "dataset") temp_dir = os.path.join(dataset_dir, "temp") os.makedirs(temp_dir, exist_ok=True) diff --git a/web/public/locales/en/config/genai.json b/web/public/locales/en/config/genai.json index 084b921c2..fed679d9e 100644 --- a/web/public/locales/en/config/genai.json +++ b/web/public/locales/en/config/genai.json @@ -15,6 +15,9 @@ }, "provider_options": { "label": "GenAI Provider extra options." + }, + "runtime_options": { + "label": "Options to pass during inference calls." } } -} \ No newline at end of file +} diff --git a/web/src/pages/Events.tsx b/web/src/pages/Events.tsx index a9867cf58..6d610e45c 100644 --- a/web/src/pages/Events.tsx +++ b/web/src/pages/Events.tsx @@ -205,7 +205,7 @@ export default function Events() { cameras: reviewSearchParams["cameras"], labels: reviewSearchParams["labels"], zones: reviewSearchParams["zones"], - reviewed: 1, + reviewed: null, // We want both reviewed and unreviewed items as we filter in the UI before: reviewSearchParams["before"] || last24Hours.before, after: reviewSearchParams["after"] || last24Hours.after, }; diff --git a/web/src/views/live/LiveDashboardView.tsx b/web/src/views/live/LiveDashboardView.tsx index 50179fd9b..e9729182f 100644 --- a/web/src/views/live/LiveDashboardView.tsx +++ b/web/src/views/live/LiveDashboardView.tsx @@ -114,6 +114,7 @@ export default function LiveDashboardView({ { limit: 10, severity: "alert", + reviewed: 0, cameras: alertCameras, }, ]); From b2d1fdf7eb6573701d1045b40d3b274ed51de1fe Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:51 +0100 Subject: [PATCH 06/98] Translated using Weblate (Turkish) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (136 of 136 strings) Co-authored-by: Emircanos Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/tr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/tr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/tr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/tr/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/tr/common.json | 3 ++- web/public/locales/tr/views/events.json | 6 +++++- web/public/locales/tr/views/explore.json | 5 ++++- web/public/locales/tr/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/tr/common.json b/web/public/locales/tr/common.json index 311cca81f..c38ffa37d 100644 --- a/web/public/locales/tr/common.json +++ b/web/public/locales/tr/common.json @@ -232,7 +232,8 @@ "show": "{{item}} öğesini göster", "ID": "ID", "none": "Hiçbiri", - "all": "Tümü" + "all": "Tümü", + "other": "Diğer" }, "notFound": { "documentTitle": "Bulunamadı - Frigate", diff --git a/web/public/locales/tr/views/events.json b/web/public/locales/tr/views/events.json index ae9a0d463..d0d30072a 100644 --- a/web/public/locales/tr/views/events.json +++ b/web/public/locales/tr/views/events.json @@ -5,7 +5,11 @@ "empty": { "detection": "İncelenecek tespit öğesi yok", "alert": "İncelenecek uyarı öğesi yok", - "motion": "Hareket verisi bulunamadı" + "motion": "Hareket verisi bulunamadı", + "recordingsDisabled": { + "title": "Kayıt özelliği etkinleştirilmelidir", + "description": "İnceleme öğeleri yalnızca bir kamera için kayıt özelliği etkinleştirildiğinde oluşturulabilir." + } }, "timeline": "Zaman şeridi", "events": { diff --git a/web/public/locales/tr/views/explore.json b/web/public/locales/tr/views/explore.json index de2055e1a..60aa8648c 100644 --- a/web/public/locales/tr/views/explore.json +++ b/web/public/locales/tr/views/explore.json @@ -80,7 +80,10 @@ "title": "Özellikleri düzenle", "desc": "Bu {{label}} için sınıflandırma özelliklerini seçin" }, - "attributes": "Sınıflandırma Özellikleri" + "attributes": "Sınıflandırma Özellikleri", + "title": { + "label": "Başlık" + } }, "generativeAI": "Üretken Yapay Zeka", "exploreIsUnavailable": { diff --git a/web/public/locales/tr/views/system.json b/web/public/locales/tr/views/system.json index b2aceb6d7..2311ae5cf 100644 --- a/web/public/locales/tr/views/system.json +++ b/web/public/locales/tr/views/system.json @@ -53,7 +53,14 @@ "otherProcesses": { "title": "Diğer İşlemler", "processCpuUsage": "İşlem CPU Kullanımı", - "processMemoryUsage": "İşlem Bellek Kullanımı" + "processMemoryUsage": "İşlem Bellek Kullanımı", + "series": { + "go2rtc": "go2rtc", + "recording": "kayıt", + "embeddings": "gömülü vektörler", + "audio_detector": "ses detektörü", + "review_segment": "inceleme bölümü" + } }, "detector": { "title": "Algılayıcılar", From 8a52d830651ec3bc86ccb50aed2096df93562069 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:51 +0100 Subject: [PATCH 07/98] Translated using Weblate (Lithuanian) Currently translated at 92.3% (121 of 131 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (46 of 46 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (13 of 13 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (55 of 55 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Lithuanian) Currently translated at 68.9% (451 of 654 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (74 of 74 strings) Translated using Weblate (Lithuanian) Currently translated at 90.4% (123 of 136 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (49 of 49 strings) Translated using Weblate (Lithuanian) Currently translated at 95.3% (204 of 214 strings) Translated using Weblate (Lithuanian) Currently translated at 56.5% (69 of 122 strings) Co-authored-by: Hosted Weblate Co-authored-by: MaBeniu Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-camera/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/lt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/lt/ Translation: Frigate NVR/common Translation: Frigate NVR/components-camera Translation: Frigate NVR/components-dialog Translation: Frigate NVR/components-filter Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-exports Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-search Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/lt/common.json | 9 +- web/public/locales/lt/components/camera.json | 2 +- web/public/locales/lt/components/dialog.json | 8 +- web/public/locales/lt/components/filter.json | 4 + .../locales/lt/views/classificationModel.json | 85 ++++++++++++++++--- web/public/locales/lt/views/events.json | 25 ++++-- web/public/locales/lt/views/explore.json | 58 ++++++++++++- web/public/locales/lt/views/exports.json | 6 ++ web/public/locales/lt/views/faceLibrary.json | 5 +- web/public/locales/lt/views/search.json | 3 +- web/public/locales/lt/views/settings.json | 56 ++++++------ web/public/locales/lt/views/system.json | 7 +- 12 files changed, 212 insertions(+), 56 deletions(-) diff --git a/web/public/locales/lt/common.json b/web/public/locales/lt/common.json index 0930c68da..712e004cf 100644 --- a/web/public/locales/lt/common.json +++ b/web/public/locales/lt/common.json @@ -78,7 +78,10 @@ "formattedTimestampFilename": { "12hour": "MM-dd-yy-h-mm-ss-a", "24hour": "MM-dd-yy-HH-mm-ss" - } + }, + "inProgress": "Apdorojama", + "invalidStartTime": "Netinkamas pradžios laikas", + "invalidEndTime": "Netinkamas pabaigos laikas" }, "unit": { "speed": { @@ -99,7 +102,9 @@ } }, "label": { - "back": "Eiti atgal" + "back": "Eiti atgal", + "hide": "Slėpti {{item}}", + "show": "Rodyti {{item}}" }, "button": { "apply": "Pritaikyti", diff --git a/web/public/locales/lt/components/camera.json b/web/public/locales/lt/components/camera.json index 7f4f5d857..2e3ef8a87 100644 --- a/web/public/locales/lt/components/camera.json +++ b/web/public/locales/lt/components/camera.json @@ -77,7 +77,7 @@ "showOptions": "Rodyti Pasirinkimus", "hideOptions": "Slėpti Pasirinkimus" }, - "boundingBox": "Ribojantis Kvadratas", + "boundingBox": "Apribojantis Stačiakampis", "timestamp": "Laiko žymė", "zones": "Zonos", "mask": "Maskuotė", diff --git a/web/public/locales/lt/components/dialog.json b/web/public/locales/lt/components/dialog.json index 28069cb91..ae5760132 100644 --- a/web/public/locales/lt/components/dialog.json +++ b/web/public/locales/lt/components/dialog.json @@ -71,12 +71,13 @@ "export": "Eksportuoti", "selectOrExport": "Pasirinkti ar Eksportuoti", "toast": { - "success": "Sėkmingai pradėtas eksportavimas. Įrašą galima peržiūrėti /exports kataloge.", + "success": "Sėkmingai pradėtas eksportavimas. Peržiūrėti įrašą exports puslapyje.", "error": { "failed": "Nepavyko pradėti eksportavimo: {{error}}", "endTimeMustAfterStartTime": "Pabaigos Laikas privalo būti vėliau nei pradžios laikas", "noVaildTimeSelected": "Nėra pasirinkto tinkamo laikotarpio" - } + }, + "view": "Žiūrėti" } }, "recording": { @@ -116,6 +117,7 @@ "search": { "placeholder": "Ieškoti pagal etiketę arba sub etiketę..." }, - "noImages": "Šiai kamerai miniatiūrų nerasta" + "noImages": "Šiai kamerai miniatiūrų nerasta", + "unknownLabel": "Išsaugotas Trigerio Paveiksliukas" } } diff --git a/web/public/locales/lt/components/filter.json b/web/public/locales/lt/components/filter.json index f5beaf8d2..0f276efc9 100644 --- a/web/public/locales/lt/components/filter.json +++ b/web/public/locales/lt/components/filter.json @@ -132,5 +132,9 @@ "selectPlatesFromList": "Pasirinkti vieną ar daugiau numerių iš sąrašo.", "selectAll": "Pasirinkti viską", "clearAll": "Išvalyti viską" + }, + "attributes": { + "label": "Klasifikavimo Atributai", + "all": "Visi Atributai" } } diff --git a/web/public/locales/lt/views/classificationModel.json b/web/public/locales/lt/views/classificationModel.json index 9deea3608..df38fe0eb 100644 --- a/web/public/locales/lt/views/classificationModel.json +++ b/web/public/locales/lt/views/classificationModel.json @@ -1,11 +1,14 @@ { - "documentTitle": "Klasifikavimo Modeliai", + "documentTitle": "Klasifikavimo Modeliai - Frigate", "button": { "deleteClassificationAttempts": "Trinti Klasisifikavimo Nuotraukas", "renameCategory": "Pervadinti Klasę", "deleteCategory": "Trinti Klasę", "deleteImages": "Trinti Nuotraukas", - "trainModel": "Treniruoti Modelį" + "trainModel": "Treniruoti Modelį", + "addClassification": "Pridėti Klasifikatorių", + "deleteModels": "Ištrinti Modelius", + "editModel": "Koreguoti Modelį" }, "toast": { "success": { @@ -13,41 +16,53 @@ "deletedImage": "Ištrinti Nuotraukas", "categorizedImage": "Sekmingai Klasifikuotas Nuotrauka", "trainedModel": "Modelis sėkmingai apmokytas.", - "trainingModel": "Sėkmingai pradėtas modelio apmokymas." + "trainingModel": "Sėkmingai pradėtas modelio apmokymas.", + "deletedModel_one": "Sėkmingai ištrintas {{count}} modelis", + "deletedModel_few": "Sėkmingai ištrinti {{count}} modeliai", + "deletedModel_other": "Sėkmingai ištrinta {{count}} modelių", + "updatedModel": "Modelio nustatymai atnaujinti sėkmingai", + "renamedCategory": "Klasifikatorius sėkmingai pervadintas į {{name}}" }, "error": { "deleteImageFailed": "Nepavyko ištrinti:{{errorMessage}}", "deleteCategoryFailed": "Nepavyko ištrinti klasės:{{errorMessage}}", "categorizeFailed": "Nepavyko kategorizuoti nuotraukos:{{errorMessage}}", - "trainingFailed": "Nepavyko pradėti modelio apmokymo:{{errorMessage}}" + "trainingFailed": "Modelio treniravimas nepavyko. Patikrinkite Frigate log'ų detales.", + "deleteModelFailed": "Nepavyko ištrinti modelio: {{errorMessage}}", + "trainingFailedToStart": "Nepavyko pradėti modelio treniravimo: {{errorMessage}}", + "updateModelFailed": "Nepavyko atnaujinti modelio: {{errorMessage}}", + "renameCategoryFailed": "Nepavyko pervadinti klasifikatoriaus: {{errorMessage}}" } }, "deleteCategory": { "title": "Trinti Klasę", - "desc": "Esate įsitikinę, norite ištrinti klasę {{name}}? Tai negrįžtamai ištrins visas susijusias nuotraukas ir reikės iš naujo apmokinti modelį." + "desc": "Esate įsitikinę, norite ištrinti klasę {{name}}? Tai negrįžtamai ištrins visas susijusias nuotraukas ir reikės iš naujo apmokinti modelį.", + "minClassesTitle": "Negalima Ištrinti Klasifikatoriaus", + "minClassesDesc": "Klasifikavimo modelis turi turėti bent 2 klasifikatorius. Pridėkite dar vieną klasifikatoriu prieš ištrinant šį." }, "deleteDatasetImages": { "title": "Ištrinti Imties Nuotraukas", - "desc_one": "Esate įsitikinę norite ištrinti {{count}} nautraukas iš {{dataset}}? Šis veiksmas negrįžtamas ir reikės iš naujo apmokinti modelį.", - "desc_few": "", - "desc_other": "" + "desc_one": "Esate įsitikinę norite ištrinti {{count}} nautrauką iš {{dataset}}? Šis veiksmas negrįžtamas ir reikės iš naujo apmokinti modelį.", + "desc_few": "Esate įsitikinę norite ištrinti {{count}} nautraukas iš {{dataset}}? Šis veiksmas negrįžtamas ir reikės iš naujo apmokinti modelį.", + "desc_other": "Esate įsitikinę norite ištrinti {{count}} nautraukų iš {{dataset}}? Šis veiksmas negrįžtamas ir reikės iš naujo apmokinti modelį." }, "deleteTrainImages": { "title": "Ištrinti Apmokymo Nuotraukas", - "desc_one": "Ar esate įsitikinę, kad norite ištrinti {{count}} nuotraukas? Šis veiksmas negrįžtamas.", - "desc_few": "", - "desc_other": "" + "desc_one": "Ar esate įsitikinę, kad norite ištrinti {{count}} nuotrauką? Šis veiksmas negrįžtamas.", + "desc_few": "Ar esate įsitikinę, kad norite ištrinti {{count}} nuotraukas? Šis veiksmas negrįžtamas.", + "desc_other": "Ar esate įsitikinę, kad norite ištrinti {{count}} nuotraukų? Šis veiksmas negrįžtamas." }, "renameCategory": { "title": "Pervadinti Klasę", - "desc": "Įveskite naują vardą vietoje {{name}}. Jums reikės iš naujo apmokinti modelį, kad vardas įsigaliotų." + "desc": "Įveskite naują vardą vietoje {{name}}. Jums reikės iš naujo apmokinti modelį, kad pavadinimas įsigaliotų." }, "description": { "invalidName": "Netinkamas vardas. Vardas gali būti sudarytas tik iš raidžiū, skaičių, tarpų, apostrofų, pabraukimų ar brūkšnelių." }, "train": { "title": "Pastarosios Klasifikacijos", - "aria": "Pasirinkti Pastarasias Klasifikacijas" + "aria": "Pasirinkti Pastarasias Klasifikacijas", + "titleShort": "Paskutiniai" }, "categories": "Klasės", "createCategory": { @@ -62,7 +77,49 @@ "buttonText": "Sukurti Objekto Modelį" }, "state": { - "title": "Nėra Būklės Klasifikavimo Modelių" + "title": "Nėra Būklės Klasifikavimo Modelių", + "description": "Sukurti individualų modelį sekti ir klasifikuoti būsenų pokyčius konkrečiuose kameros plotuose.", + "buttonText": "Sukurti Būsenos Modelį" } + }, + "details": { + "scoreInfo": "Įvertinimas atspindi vidutinį klasivikavimo pasitikėjimą tarp visų šio objekto atpažinimų.", + "none": "Nėra", + "unknown": "Nežinoma" + }, + "tooltip": { + "trainingInProgress": "Šiuo metu vyksta modelio apmokymas", + "noNewImages": "Nėra naujų paveikslėlių apmokymui. Pradžiai suklasifikuokite daugiau paveikslėlių duomenų rinkinyje.", + "noChanges": "Po paskutinio apmokymo duomenų rinkinyje pakeitimų nėra.", + "modelNotReady": "Modelis neparuoštas apmokymui" + }, + "deleteModel": { + "title": "Ištrinti Klasifikavimo Modelį", + "single": "Ar įsitikinę kad norite trinti {{name}}? Tai negrįžtamai ištrins ir susijusius paveikslėlius bei apmokymo duomenis. Tai negali būti sugražinta.", + "desc_one": "Ar esate įsitikinę kad norite ištrinti {{count}} modelį? Tai negrįžtamai ištrins ir susijusius paveikslėlius bei apmokymo duomenis. Tai negali būti sugražinta.", + "desc_few": "Ar esate įsitikinę kad norite ištrinti {{count}} modelius? Tai negrįžtamai ištrins ir susijusius paveikslėlius bei apmokymo duomenis. Tai negali būti sugražinta.", + "desc_other": "Ar esate įsitikinę kad norite ištrinti {{count}} modelių? Tai negrįžtamai ištrins ir susijusius paveikslėlius bei apmokymo duomenis. Tai negali būti sugražinta." + }, + "edit": { + "title": "Koreguoti Klasifikavimo Modelį", + "descriptionState": "Koreguoti klasifikatorius šiam būklės klasifikavimo modeliui. Pokyčiams reikės išnaujo apmokinti modelį.", + "descriptionObject": "Koreguoti objekto tipą ir klasifikavimo tipą šiam objektų klasifikavimo modeliui.", + "stateClassesInfo": "Pastaba: Keičiant statuso klasifikatorius privaloma iš naujo apmokinti modelį." + }, + "wizard": { + "step3": { + "allImagesRequired_one": "Prašom klasifikuoti visus paveikslėlius. Liko {{count}} paveikslėlis.", + "allImagesRequired_few": "Prašom klasifikuoti visus paveikslėlius. Liko {{count}} paveikslėliai.", + "allImagesRequired_other": "Prašom klasifikuoti visus paveikslėlius. Liko {{count}} paveikslėlių." + }, + "title": "Sukurti Naują Klasifikavimą", + "steps": { + "nameAndDefine": "Pavadinimas ir Apibūdinimas", + "stateArea": "Būsenos Plotas" + } + }, + "menu": { + "objects": "Objektai", + "states": "Būsenos" } } diff --git a/web/public/locales/lt/views/events.json b/web/public/locales/lt/views/events.json index bd4ab2895..c3e670a16 100644 --- a/web/public/locales/lt/views/events.json +++ b/web/public/locales/lt/views/events.json @@ -22,7 +22,11 @@ "empty": { "alert": "Nėra pranešimų peržiūrai", "detection": "Nėra aptikimų peržiūrai", - "motion": "Duomenų apie judesius nėra" + "motion": "Duomenų apie judesius nėra", + "recordingsDisabled": { + "title": "Įrašai privalo būti įjungti", + "description": "Peržiūros gali būti kuriamos tik tada kai kamerai yra aktyvuoti įrašymai." + } }, "documentTitle": "Peržiūros - Frigate", "recordings": { @@ -40,13 +44,24 @@ "detail": { "noDataFound": "Peržiūrai informacijos nėra", "aria": "Perjungti į detalų vaizdą", - "trackedObject_one": "objektas", - "trackedObject_other": "objektai", + "trackedObject_one": "{{count}} objektas", + "trackedObject_other": "{{count}} objektai", "noObjectDetailData": "Nėra objekto detalių duomenų.", - "label": "Detalės" + "label": "Detalės", + "settings": "Vaizdo Nustatymai Detaliau", + "alwaysExpandActive": { + "title": "Visada išskleisti aktyvų", + "desc": "Aktyviai peržiūrimam įrašui visada išskleisti objekto detales jei jos yra." + } }, "objectTrack": { "trackedPoint": "Susektas taškas", "clickToSeek": "Spustelkite perkelti į šį laiką" - } + }, + "zoomIn": "Priartinti", + "zoomOut": "Patolinti", + "select_all": "Viską", + "normalActivity": "Normali veikla", + "needsReview": "Reikalinga peržiūra", + "securityConcern": "Saugumo rūpestis" } diff --git a/web/public/locales/lt/views/explore.json b/web/public/locales/lt/views/explore.json index 0186e7365..b68a3233b 100644 --- a/web/public/locales/lt/views/explore.json +++ b/web/public/locales/lt/views/explore.json @@ -49,7 +49,8 @@ "regenerate": "Gauta nauja užklausa iš {{provider}} naujam aprašymui. Priklausomai nuo jūsų tiekėjo greičio, naują aprašymą sukurti gali užtrukti.", "updatedSublabel": "Sėkmingai atnaujinta sub etiketė.", "updatedLPR": "Sėkmingai atnaujinti registracijos numeriai.", - "audioTranscription": "Sėkmingai užklausta garso aprašymo." + "audioTranscription": "Sėkmingai užklausta garso aprašymo. Priklausomai nuo jūsų Frigate serverio pajėgumų, tai gali užtrukti.", + "updatedAttributes": "Atributai sekmingai užkelti." }, "error": { "regenerate": "Nepavyko pakviesti {{provider}} naujam aprašymui: {{errorMessage}}", @@ -158,7 +159,7 @@ }, "dialog": { "confirmDelete": { - "desc": "Trinant šį sekamą objektą taip pat bus pašalintos momentinės iškarpos, išsaugoti įterpiai, priskirti objekto gyvavimo ciklo įrašai. Šių sekamų objektų įrašyta filmuota medžiaga Istorijos vaizde ištrinta NEBUS.

Ar esate įsitikinę, kad norite tęsti?", + "desc": "Trinant šį sekamą objektą taip pat bus pašalintos momentinės iškarpos, išsaugoti įterpiai ir kitos susios sekimo detalės. Šių sekamų objektų įrašyta filmuota medžiaga Istorijos vaizde ištrinta NEBUS.

Ar esate įsitikinę, kad norite tęsti?", "title": "Patvirtinti Ištrynimą" } }, @@ -167,7 +168,9 @@ "details": "detalės", "snapshot": "momentinės nuotraukos", "video": "vaizdas", - "object_lifecycle": "objekto gyvavimo ciklas" + "object_lifecycle": "objekto gyvavimo ciklas", + "thumbnail": "miniatiūra", + "tracking_details": "sekimo detalės" }, "itemMenu": { "downloadVideo": { @@ -222,5 +225,54 @@ }, "concerns": { "label": "Rūpesčiai" + }, + "trackingDetails": { + "title": "Sekimo Detalės", + "noImageFound": "Šiai miniatiūrai paveikslėlis nerastas.", + "createObjectMask": "Sukurti Objekto Maskavimą", + "adjustAnnotationSettings": "Patikslinti pastabų nustatymus", + "scrollViewTips": "Spustelkite pamatyti svarbius objekto gyvavimo momentus.", + "autoTrackingTips": "Apribojančio stačiakampio pozicijos nebus tikslios kameroms su autosekimu.", + "count": "{{first}} iš {{second}}", + "trackedPoint": "Sekamas Taškas", + "lifecycleItemDesc": { + "visible": "{{label}} aptiktas", + "entered_zone": "{{label}} pateko į {{zones}}", + "active": "{{label}} tapo aktyvus", + "stationary": "{{label}} tapo statinis", + "attribute": { + "faceOrLicense_plate": "{{attribute}} aptiktas etiketei {{label}}", + "other": "{{label}} atpažintas kaip {{attribute}}" + }, + "gone": "{{label}} kairė", + "heard": "{{label}} girdėta", + "external": "{{label}} aptikta", + "header": { + "zones": "Zonos", + "ratio": "Santykis", + "area": "Plotas", + "score": "Balas" + } + }, + "annotationSettings": { + "title": "Anotacijų Nustatymai", + "showAllZones": { + "title": "Rodyti Visas Zonas", + "desc": "Visada rodyti zonas kadruose kur objektas patenka į zoną." + }, + "offset": { + "label": "Anotacijų offset", + "desc": "Šie duomenys gaunami iš kameros aptikimo srauto, tačiau yra užkeliami ant atvaizdo sluoksnio iš įrašymo srauto. Tobulai synchronizuoti du srautai yra mažai tikėtini. Kaip rezultatas, apribojančio stačiakampio ir vaizdo medžiaga tobulai nesusilygiuos. Norėdami geriau sulygiuoti su įrašų medžiaga, jūs galite naudoti šį nustatymą srauto perslinkimui pirmyn arba atgal.", + "millisecondsToOffset": "Aptikimo anotacijų perslinkimas milisekundėmis. Default: 0", + "tips": "Sumažinkite reikšmę jei video įrašas yra pirmesnis nei kvadratai ar kelio taškai, ir padidinkite reikšmė jei video įrašas atsilieka. Ši reikšmė gali būti neigiama.", + "toast": { + "success": "Anotacijų perslinkimas kamerai {{camera}} išsaugotas konfiguracijoje." + } + } + }, + "carousel": { + "previous": "Ankstesnė skaidrė", + "next": "Kita skaidrė" + } } } diff --git a/web/public/locales/lt/views/exports.json b/web/public/locales/lt/views/exports.json index c8b257a54..dbb5483b7 100644 --- a/web/public/locales/lt/views/exports.json +++ b/web/public/locales/lt/views/exports.json @@ -13,5 +13,11 @@ "error": { "renameExportFailed": "Nepavyko pervadinti eksportuojamo įrašo: {{errorMessage}}" } + }, + "tooltip": { + "shareExport": "Pasidalinti įrašu", + "downloadVideo": "Atsisiųsti video", + "editName": "Koreguoti pavadinimą", + "deleteExport": "Ištrinti eksportus" } } diff --git a/web/public/locales/lt/views/faceLibrary.json b/web/public/locales/lt/views/faceLibrary.json index 721e119ce..cd7307a27 100644 --- a/web/public/locales/lt/views/faceLibrary.json +++ b/web/public/locales/lt/views/faceLibrary.json @@ -32,7 +32,7 @@ "addFaceLibrary": "{{name}} vardas buvo sėkmingai pridėtas į Veidų Katalogą!", "renamedFace": "Sėkmingai veidas pervadintas į {{name}}", "trainedFace": "Veidas apmokytas sėkmingai.", - "updatedFaceScore": "Veido balas atnaujintas sėkmingai." + "updatedFaceScore": "Veido balas atnaujintas sėkmingai į {{name}} {{score}}." }, "error": { "uploadingImageFailed": "Nepavyko įkelti nuotraukos: {{errorMessage}}", @@ -71,7 +71,8 @@ "train": { "title": "Pastarieji Atpažinimai", "aria": "Pasirinkti pastaruosius atpažinimus", - "empty": "Pastaruoju metu nebuvo atliktas veidų atpažinimas" + "empty": "Pastaruoju metu nebuvo atliktas veidų atpažinimas", + "titleShort": "Paskutiniai" }, "selectFace": "Pasirinkti Veidą", "renameFace": { diff --git a/web/public/locales/lt/views/search.json b/web/public/locales/lt/views/search.json index 054efd004..eac3b4f55 100644 --- a/web/public/locales/lt/views/search.json +++ b/web/public/locales/lt/views/search.json @@ -26,7 +26,8 @@ "recognized_license_plate": "Atpažinti Registracijos Numeriai", "has_clip": "Turi Klipą", "has_snapshot": "Turi Nuotrauką", - "sub_labels": "Sub Etiketės" + "sub_labels": "Sub Etiketės", + "attributes": "Atributai" }, "searchType": { "thumbnail": "Miniatiūra", diff --git a/web/public/locales/lt/views/settings.json b/web/public/locales/lt/views/settings.json index 4fcd9cb8f..3cad3b210 100644 --- a/web/public/locales/lt/views/settings.json +++ b/web/public/locales/lt/views/settings.json @@ -4,7 +4,7 @@ "authentication": "Autentifikavimo Nustatymai - Frigate", "camera": "Kameros Nustatymai - Frigate", "object": "Debug - Frigate", - "general": "Bendrieji Nustatymai - Frigate", + "general": "Vartotojo Sąsajos Nustatymai - Frigate", "frigatePlus": "Frigate+ Nustatymai - Frigate", "notifications": "Pranešimų Nustatymai - Frigate", "motionTuner": "Judesio Derinimas - Frigate", @@ -39,7 +39,7 @@ "noCamera": "Nėra Kameros" }, "general": { - "title": "Bendri Nustatymai", + "title": "Vartotojo Sąsajos Nustatymai", "liveDashboard": { "title": "Tiesioginės Transliacijos Skydelis", "automaticLiveView": { @@ -49,6 +49,14 @@ "playAlertVideos": { "label": "Leist Įspejimų Vaizdus", "desc": "Pagal nutylėjimą, paskutinieji įspėjimai rodomį kaip maži cikliški vaizdo įrašai. Šią funkciją išjunkite jei norite matyti statinius įspėjimų paveiksliukus šiame įrenginyje/naršyklėje." + }, + "displayCameraNames": { + "label": "Visada Rodyti Kamerų Pavadinimus", + "desc": "Keletos kamerų tiesioginės transliacijos tinklelyje visada rodyti kameros pavadinimą žymoje." + }, + "liveFallbackTimeout": { + "label": "Transliacijos atstatymas neišlauktas", + "desc": "Kai kameros aukštos raiškos transliacija nepasiekiama, persijungti į žemos raiškos rėžimą po tiek tai sekundžių. Default: 3." } }, "storedLayouts": { @@ -234,7 +242,7 @@ "name": { "title": "Pavadinimas", "inputPlaceHolder": "Įveskite pavadinimą …", - "tips": "Pavadinimas privalo būti bent 2 simboliai, privalo turėti bent vieną raidę ir negali būti toks pat kaip kita kamera ar zona." + "tips": "Pavadinimas privalo būti bent 2 simboliai, privalo turėti bent vieną raidę ir negali būti toks pat kaip kita kamera ar kita šios kameros zona." }, "inertia": { "title": "Inercija", @@ -268,7 +276,7 @@ } }, "toast": { - "success": "Zona ({{zoneName}}) buvo išsaugota. Perkrauti Frigate kad įgalinti pokyčius." + "success": "Zona ({{zoneName}}) buvo išsaugota." } }, "motionMasks": { @@ -293,8 +301,8 @@ "clickDrawPolygon": "Spragtelti kad piešti poligoną ant atvaizdo.", "toast": { "success": { - "title": "{{polygonName}} išsaugotas. Perkrauti Frigate, kad pritaikyti pokyčius.", - "noName": "Judesio Maskuotė buvo išsaugota. Perkrauti Frigate, kad pritaikyti pokyčius." + "title": "{{polygonName}} išsaugotas.", + "noName": "Judesio Maskuotė buvo išsaugota." } } }, @@ -319,8 +327,8 @@ }, "toast": { "success": { - "title": "{{polygonName}} buvo išsaugotas. Perkrauti Frigate, kad pritaikyti pokyčius.", - "noName": "Objektų Maskuotė buvo išsaugota. Perkrauti Frigate, kad pritaikyti pokyčius." + "title": "{{polygonName}} buvo išsaugotas.", + "noName": "Objektų Maskuotė buvo išsaugota." } } }, @@ -428,10 +436,10 @@ "objectList": "Objektų sąrašas", "noObjects": "Objektų nėra", "boundingBoxes": { - "title": "Apibrėžiančios dėžutės", - "desc": "Rodyti apibrėžiančias dėžutes aplink sekamus objektus", + "title": "Apribojantys stačiakampiai", + "desc": "Rodyti apribojančius stačiakampius aplink sekamus objektus", "colors": { - "label": "Objektus Apibrėžiančių Dėžučių Spalvos", + "label": "Objektus Apribojančių Stačiakampių Spalvos", "info": "
  • Pradžioje, skirtingos spalvos bus priskirtos kiekvienai objekto etiketei
  • Tamsiai mėlyna plona linija simbolizuoja, kad objektas esamu momentu dar nėra aptiktas
  • Pilka linija nurodo kad objektas yra aptiktas kaip nejudantis
  • Stora linija nurodo kad objektas yra automatiškai sekamas (kai įjungta)
  • " } }, @@ -544,7 +552,7 @@ "desc": "Valdyti šios Frigate aplinkos vartotojų paskyras." }, "addUser": "Pridėti Vartotoją", - "updatePassword": "Atnaujinti Slaptažodį", + "updatePassword": "Atkurti Slaptažodį", "toast": { "success": { "createUser": "Vartotojas {{user}} sėkmingai sukurtas", @@ -565,7 +573,7 @@ "role": "Rolė", "noUsers": "Vartotojų nerasta.", "changeRole": "Pakeisti vartotojo rolę", - "password": "Slaptažodis", + "password": "Atkurti Slaptažodį", "deleteUser": "Ištrinti vartotoją" } }, @@ -586,10 +594,10 @@ "form": { "name": { "title": "Pavadinimas", - "placeholder": "Įvesti trigerio pavadinimą", + "placeholder": "Užvadinkite trigerį", "error": { - "minLength": "Pavadinimas turi būti bent dviejų simbolių ilgio.", - "invalidCharacters": "Pavadinime gali būti tik raidės, skaičiai, pabraukimai ir brūkšnelis.", + "minLength": "Laukelis turi būti bent dviejų simbolių ilgio.", + "invalidCharacters": "Laukelyje gali būti tik raidės, skaičiai, pabraukimai ir brūkšnelis.", "alreadyExists": "Trigeris su tokiu vardu jau yra šiai kamerai." } }, @@ -602,9 +610,9 @@ }, "content": { "title": "Turinys", - "imagePlaceholder": "Pasirinkti paveikslėlį", + "imagePlaceholder": "Parinkti miniatiūrą", "textPlaceholder": "Įvesti teksto turinį", - "imageDesc": "Pasirinkite paveikslėli kad inicijuotumėte veiksmą kai panašus vaizdas bus aptiktas.", + "imageDesc": "Rodoma tik 100 paskutinių miniatiūrų. Jei norimos miniatiūros nerandate, galite ieškoti senesnių įrašų per Paieškų meniu ir tenai kurti trigerį.", "textDesc": "Įveskite tekstą kad inicijuotumėte veiksmą kai panašus sekamo objekto aprašymas bus aptiktas.", "error": { "required": "Turinys privalomas." @@ -619,7 +627,7 @@ }, "actions": { "title": "Veiksmai", - "desc": "Pagal nutylėjimą, Frigate sukuria MQTT žinutę visiem trigeriams. Pasirinkite kokius papildomus veiksmus atlikti kai trigeris suveiks.", + "desc": "Pagal nutylėjimą, Frigate sukuria MQTT žinutę visiem trigeriams. Subetiketės prideda trigerio pavadinimą prie objekto etiketės. Atributai, tai paieškai pasiekiami metaduomenys saugomi atskirai sekamų objektų metaduomenyse.", "error": { "min": "Bent vienas veiksmas privalo būti parinktas." } @@ -633,7 +641,7 @@ }, "documentTitle": "Trigeriai", "management": { - "title": "Trigerių Valdymas", + "title": "Trigeriai", "desc": "Valdykite trigerius kamerai {{camera}}. Naudokite miniatiūros tipą, kad panašios miniatiūros būtų jūsų pasirinkto objekto trigeris, o aprašymo trigerį kad panašūs aprašymai būtų trigeris pagal jūsų parašytą tekstą." }, "addTrigger": "Pridėti Trigerį", @@ -782,9 +790,9 @@ "toast": { "success": { "deleteRole": "Rolė {{role}} sėkmingai pašalinta", - "userRolesUpdated_one": "{{count}} šios rolės vartotojai buvo priskirti rolei 'žiūrovas', kuri turi prieigą prie visų kamerų.", - "userRolesUpdated_few": "", - "userRolesUpdated_other": "", + "userRolesUpdated_one": "{{count}} šios rolės vartotojas buvo priskirti rolei 'žiūrovas', kuri turi prieigą prie visų kamerų.", + "userRolesUpdated_few": "{{count}} šios rolės vartotojai buvo priskirti rolei 'žiūrovas', kuri turi prieigą prie visų kamerų.", + "userRolesUpdated_other": "{{count}} šios rolės vartotojų buvo priskirti rolei 'žiūrovas', kuri turi prieigą prie visų kamerų.", "createRole": "Rolė {{role}} sėkmingai sukurta", "updateCameras": "Atnaujintos kameros rolei {{role}}" }, @@ -854,7 +862,7 @@ "testFailed": "Transliacijos testas nepavyko: {{error}}" }, "step1": { - "description": "Įveskite savo kameros informaciją ir testuokite prisijungimą.", + "description": "Įveskite savo kameros informaciją ir pasirinkite \"probe\" kamerai arba rankiniu būdų pasirinkite gamintoją.", "cameraName": "Kameros Pavadinimas", "cameraNamePlaceholder": "pvz., priekines_durys arba Galinio Kiemo Vaizdas", "host": "Host/IP Adresas", diff --git a/web/public/locales/lt/views/system.json b/web/public/locales/lt/views/system.json index 8918ad32d..f390d9671 100644 --- a/web/public/locales/lt/views/system.json +++ b/web/public/locales/lt/views/system.json @@ -76,7 +76,12 @@ } }, "npuUsage": "NPU Naudojimas", - "npuMemory": "NPU Atmintis" + "npuMemory": "NPU Atmintis", + "intelGpuWarning": { + "title": "Intel GPU statistikų įspėjimas", + "message": "GPU statistika negalima", + "description": "Tai žinoma problema su Intel GPU statistikos raportavimo įrankiu (intel_gpu_top), kai jis stringa ir pakartotinai grąžina GPU vartojimas 0% net tais atvejais kai hardware acceleration ir objektų aptikimas taisiklingai veikia naudojant (i)GPU. Tai nėra Frigate klaida. Laikinai padeda įrenginio perkrovimas, kad įsitikinti teisingu GPU funkcionavimu. Tai neįtakoja spartos." + } }, "otherProcesses": { "title": "Kiti Procesai", From 4188eedf3d9170af8c9dbec7a49c31fd2548456f Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:52 +0100 Subject: [PATCH 08/98] Translated using Weblate (Thai) Currently translated at 23.5% (32 of 136 strings) Translated using Weblate (Thai) Currently translated at 2.4% (3 of 122 strings) Translated using Weblate (Thai) Currently translated at 45.2% (24 of 53 strings) Translated using Weblate (Thai) Currently translated at 60.8% (45 of 74 strings) Co-authored-by: Hosted Weblate Co-authored-by: Kongesque Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/th/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/th/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/th/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/th/ Translation: Frigate NVR/components-filter Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-system --- web/public/locales/th/components/filter.json | 3 +++ web/public/locales/th/views/classificationModel.json | 10 +++++++++- web/public/locales/th/views/faceLibrary.json | 5 +++-- web/public/locales/th/views/system.json | 5 +++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/web/public/locales/th/components/filter.json b/web/public/locales/th/components/filter.json index aea9fc5a7..5f23f3142 100644 --- a/web/public/locales/th/components/filter.json +++ b/web/public/locales/th/components/filter.json @@ -82,5 +82,8 @@ }, "title": "การตั้งค่า" } + }, + "classes": { + "label": "หมวดหมู่" } } diff --git a/web/public/locales/th/views/classificationModel.json b/web/public/locales/th/views/classificationModel.json index 0967ef424..3181c4e9f 100644 --- a/web/public/locales/th/views/classificationModel.json +++ b/web/public/locales/th/views/classificationModel.json @@ -1 +1,9 @@ -{} +{ + "documentTitle": "โมเดลการจำแนกประเภท- Frigate", + "details": { + "scoreInfo": "คะแนน (Score) คือค่าเฉลี่ยของความมั่นใจในการจำแนกประเภท (Classification Confidence) จากการตรวจจับวัตถุชิ้นนี้ในทุกๆ ครั้ง" + }, + "description": { + "invalidName": "ชื่อไม่ถูกต้อง ชื่อสามารถประกอบได้ด้วยตัวอักษร, ตัวเลข, ช่องว่าง, เครื่องหมาย ( ' , _ , - ) เท่านั้น" + } +} diff --git a/web/public/locales/th/views/faceLibrary.json b/web/public/locales/th/views/faceLibrary.json index 4372d09b5..c6ad3e750 100644 --- a/web/public/locales/th/views/faceLibrary.json +++ b/web/public/locales/th/views/faceLibrary.json @@ -43,8 +43,9 @@ }, "collections": "คอลเลกชัน", "description": { - "addFace": "ทำตามวิธีการเพิ่มคอลเลกชันใหม่ไปยังที่เก็บหน้า.", - "placeholder": "ใส่ชื่อสําหรับคอลเลกชันนี้" + "addFace": "เพิ่มคอลเลกชันใหม่ไปยังคลังใบหน้า โดยการอัปโหลดรูปภาพแรก", + "placeholder": "ใส่ชื่อสําหรับคอลเลกชันนี้", + "invalidName": "ชื่อไม่ถูกต้อง ชื่อสามารถประกอบได้ด้วยตัวอักษร, ตัวเลข, ช่องว่าง, เครื่องหมาย ( ' , _ , - ) เท่านั้น" }, "toast": { "success": { diff --git a/web/public/locales/th/views/system.json b/web/public/locales/th/views/system.json index 2084d91a3..fd0010fdd 100644 --- a/web/public/locales/th/views/system.json +++ b/web/public/locales/th/views/system.json @@ -55,5 +55,10 @@ "stats": { "cameraIsOffline": "{{camera}} ออฟไลน์", "detectIsVerySlow": "{{detect}} ช้ามาก ({{speed}} มิลลิวินาที)" + }, + "documentTitle": { + "cameras": "ข้อมูลกล้อง - Frigate", + "storage": "สถิติคลังข้อมูล - Frigate", + "general": "สถิติทั่วไป - Frigate" } } From 8d26d2dca2ee1cbe08ac23bc389cbb238835b293 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:52 +0100 Subject: [PATCH 09/98] Translated using Weblate (Portuguese (Brazil)) Currently translated at 66.2% (433 of 654 strings) Co-authored-by: Cleiton PEres Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/pt_BR/ Translation: Frigate NVR/views-settings --- web/public/locales/pt-BR/views/settings.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/public/locales/pt-BR/views/settings.json b/web/public/locales/pt-BR/views/settings.json index 541fd8bf4..7bbb597d6 100644 --- a/web/public/locales/pt-BR/views/settings.json +++ b/web/public/locales/pt-BR/views/settings.json @@ -49,6 +49,9 @@ "playAlertVideos": { "label": "Reproduzir Alertas de Video", "desc": "Por padrão, alertas recentes no Painel em Tempo Real são reproduzidos como vídeos em loop. Desative essa opção para mostrar apenas a imagens estáticas de alertas recentes nesse dispositivo / navegador." + }, + "displayCameraNames": { + "label": "Sempre mostrar os nomes das câmeras" } }, "storedLayouts": { From c13a47f30bf52c8f5ba6ec88c539d44dc94e81e6 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:52 +0100 Subject: [PATCH 10/98] Translated using Weblate (German) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (German) Currently translated at 98.5% (134 of 136 strings) Translated using Weblate (German) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (German) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (German) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (German) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (German) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (German) Currently translated at 100.0% (122 of 122 strings) Co-authored-by: Hosted Weblate Co-authored-by: Sebastian Sie Co-authored-by: jmtatsch Co-authored-by: zobe123 Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/de/ Translation: Frigate NVR/common Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/de/common.json | 3 +- .../locales/de/views/classificationModel.json | 50 +++++++++---------- web/public/locales/de/views/events.json | 6 ++- web/public/locales/de/views/explore.json | 5 +- web/public/locales/de/views/faceLibrary.json | 2 +- web/public/locales/de/views/settings.json | 2 +- web/public/locales/de/views/system.json | 9 +++- 7 files changed, 46 insertions(+), 31 deletions(-) diff --git a/web/public/locales/de/common.json b/web/public/locales/de/common.json index 532463f55..a9d13566e 100644 --- a/web/public/locales/de/common.json +++ b/web/public/locales/de/common.json @@ -130,7 +130,8 @@ "show": "Zeige {{item}}", "ID": "ID", "none": "Nichts", - "all": "Alle" + "all": "Alle", + "other": "andere" }, "menu": { "configurationEditor": "Konfigurationseditor", diff --git a/web/public/locales/de/views/classificationModel.json b/web/public/locales/de/views/classificationModel.json index 217d9df53..2de77e73e 100644 --- a/web/public/locales/de/views/classificationModel.json +++ b/web/public/locales/de/views/classificationModel.json @@ -1,5 +1,5 @@ { - "documentTitle": "Klassifizierungsmodelle - Fregatte", + "documentTitle": "Klassifikationsmodelle - Frigate", "details": { "scoreInfo": "Die Punktzahl gibt die durchschnittliche Konfidenz aller Erkennungen dieses Objekts wieder.", "none": "Keiner", @@ -11,7 +11,7 @@ "deleteCategory": "Klasse löschen", "deleteImages": "Bilder löschen", "trainModel": "Modell trainieren", - "addClassification": "Klassifizierung hinzufügen", + "addClassification": "Klassifikationsmodell hinzufügen", "deleteModels": "Modell löschen", "editModel": "Modell bearbeiten" }, @@ -58,7 +58,7 @@ }, "edit": { "title": "Klassifikationsmodell bearbeiten", - "descriptionState": "Bearbeite die Klassen für dieses Zustandsklassifikationsmodell. Änderungen erfordern erneutes Trainieren des Modells.", + "descriptionState": "Bearbeite die Klassen für dieses Zustandsklassifikationsmodell. Änderungen erfordern ein erneutes Trainieren des Modells.", "descriptionObject": "Bearbeite den Objekttyp und Klassifizierungstyp für dieses Objektklassifikationsmodell.", "stateClassesInfo": "Hinweis: Die Änderung der Statusklassen erfordert ein erneutes Trainieren des Modells mit den aktualisierten Klassen." }, @@ -97,49 +97,49 @@ "noModels": { "object": { "title": "Keine Objektklassifikationsmodelle", - "description": "Erstelle ein benutzerdefiniertes Modell, um erkannte Objekte zu klassifizieren.", - "buttonText": "Objektmodell erstellen" + "description": "Erstelle ein benutzerdefiniertes Objektklassifikationsmodell, um erkannte Objekte zu klassifizieren.", + "buttonText": "Objektklassifikationsmodell erstellen" }, "state": { - "title": "Keine Statusklassifizierungsmodelle", - "description": "Erstellen Sie ein benutzerdefiniertes Modell, um Zustandsänderungen in bestimmten Kamerabereichen zu überwachen und zu klassifizieren.", - "buttonText": "Zustandsmodell erstellen" + "title": "Keine Zustandsklassifikationsmodelle", + "description": "Erstellen Sie ein benutzerdefiniertes Zustandsklassifikationsmodell, um Zustandsänderungen in bestimmten Kamerabereichen zu überwachen und zu klassifizieren.", + "buttonText": "Zustandsklassifikationsmodell erstellen" } }, "wizard": { - "title": "Neue Klassifizierung erstellen", + "title": "Neues Klassifikationsmodell erstellen", "steps": { "nameAndDefine": "Benennen und definieren", - "stateArea": "Gebiet", + "stateArea": "Überwachungsbereich", "chooseExamples": "Beispiel auswählen" }, "step1": { - "description": "Zustandsmodelle überwachen feste Kamerabereiche auf Veränderungen (z. B. Tür offen/geschlossen). Objektmodelle fügen den erkannten Objekten Klassifizierungen hinzu (z. B. bekannte Tiere, Lieferanten usw.).", + "description": "Zustandsmodelle überwachen fest definierte Kamerabereiche auf Veränderungen (z. B. Tür offen/geschlossen). Objektmodelle klassifizieren erkannte Objekte genauer (z. B. in bekannte Tiere, Lieferanten usw.).", "name": "Name", - "namePlaceholder": "Eingeben Modell Name...", + "namePlaceholder": "Modellname eingeben ...", "type": "Typ", "typeState": "Zustand", "typeObject": "Objekt", - "objectLabel": "Objekt Bezeichnung", + "objectLabel": "Objektbezeichnung", "objectLabelPlaceholder": "Auswahl Objekt Typ...", "classificationType": "Klassifizierungstyp", "classificationTypeTip": "Etwas über Klassifizierungstyp lernen", "classificationTypeDesc": "Unterbezeichnungen fügen dem Objektnamen zusätzlichen Text hinzu (z. B. „Person: UPS“). Attribute sind durchsuchbare Metadaten, die separat in den Objektmetadaten gespeichert sind.", "classificationSubLabel": "Unterlabel", - "classificationAttribute": "Merkmal", - "classes": "Klasse", - "states": "Gebiet", - "classesTip": "Über Klassen lernen", + "classificationAttribute": "Attribut", + "classes": "Klassen", + "states": "Zustände", + "classesTip": "Mehr über Klassen erfahren", "classesStateDesc": "Definieren Sie die verschiedenen Zustände, in denen sich Ihr Kamerabereich befinden kann. Beispiel: „offen” und „geschlossen” für ein Garagentor.", "classesObjectDesc": "Definieren Sie die verschiedenen Kategorien, in die erkannte Objekte klassifiziert werden sollen. Beispiel: „Lieferant“, „Bewohner“, „Fremder“ für die Klassifizierung von Personen.", "classPlaceholder": "Klassenbezeichnung eingeben...", "errors": { - "nameRequired": "Modellname ist erforderlich", + "nameRequired": "Der Modellname ist erforderlich", "nameLength": "Der Modellname darf maximal 64 Zeichen lang sein", "nameOnlyNumbers": "Der Modellname darf nicht nur aus Zahlen bestehen", "classRequired": "Mindestens eine Klasse ist erforderlich", - "classesUnique": "Klassenname muss eindeutig sein", - "stateRequiresTwoClasses": "Gebietsmodelle erfordern mindestens zwei Klassen", + "classesUnique": "Der Klassenname muss eindeutig sein", + "stateRequiresTwoClasses": "Zustandsmodelle erfordern mindestens zwei Klassen", "objectLabelRequired": "Bitte wähle eine Objektbeschriftung", "objectTypeRequired": "Bitte wählen Sie einen Klassifizierungstyp aus", "noneNotAllowed": "Die Klasse „none“ ist nicht zulässig" @@ -149,12 +149,12 @@ "description": "Wählen Sie Kameras aus und legen Sie für jede Kamera den zu überwachenden Bereich fest. Das Modell klassifiziert den Zustand dieser Bereiche.", "cameras": "Kameras", "selectCamera": "Kamera auswählen", - "noCameras": "Klick + zum hinzufügen der Kameras", + "noCameras": "Klicke + zum Hinzufügen von Kameras", "selectCameraPrompt": "Wählen Sie eine Kamera aus der Liste aus, um ihren Überwachungsbereich festzulegen" }, "step3": { - "selectImagesPrompt": "Wählen sie alle Bilder mit: {{className}}", - "selectImagesDescription": "Klicken Sie auf die Bilder, um sie auszuwählen. Klicken Sie auf „Weiter“, wenn Sie mit diesem Kurs fertig sind.", + "selectImagesPrompt": "Wählen Sie alle Bilder mit: {{className}}", + "selectImagesDescription": "Klicken Sie auf die Bilder, um sie auszuwählen. Klicken Sie auf „Weiter“, wenn Sie mit dieser Klasse fertig sind.", "allImagesRequired_one": "Bitte klassifizieren Sie alle Bilder. {{count}} Bild verbleibend.", "allImagesRequired_other": "Bitte klassifizieren Sie alle Bilder. {{count}} Bilder verbleiben.", "generating": { @@ -162,7 +162,7 @@ "description": "Frigate extrahiert repräsentative Bilder aus Ihren Aufnahmen. Dies kann einen Moment dauern..." }, "training": { - "title": "Trainingsmodell", + "title": "Trainiere Modell", "description": "Ihr Modell wird im Hintergrund trainiert. Schließen Sie diesen Dialog, und Ihr Modell wird ausgeführt, sobald das Training abgeschlossen ist." }, "retryGenerate": "Generierung wiederholen", @@ -177,7 +177,7 @@ "classifyFailed": "Bilder konnten nicht klassifiziert werden: {{error}}" }, "generateSuccess": "Erfolgreich generierte Beispielbilder", - "modelCreated": "Modell erfolgreich erstellt. Verwenden Sie die Ansicht „Aktuelle Klassifizierungen“, um Bilder für fehlende Zustände hinzuzufügen, und trainieren Sie dann das Modell.", + "modelCreated": "Modell erfolgreich erstellt. Verwenden Sie die Ansicht „Aktuelle Klassifizierungen“, um Bilder für fehlende Zustände hinzuzufügen und trainieren Sie dann das Modell erneut.", "missingStatesWarning": { "title": "Beispiele für fehlende Zustände", "description": "Es wird empfohlen für alle Zustände Beispiele auszuwählen. Das Modell wird erst trainiert, wenn für alle Zustände Bilder vorhanden sind. Fahren Sie fort und verwenden Sie die Ansicht „Aktuelle Klassifizierungen“, um Bilder für die fehlenden Zustände zu klassifizieren. Trainieren Sie anschließend das Modell." diff --git a/web/public/locales/de/views/events.json b/web/public/locales/de/views/events.json index 1b031af7b..963482073 100644 --- a/web/public/locales/de/views/events.json +++ b/web/public/locales/de/views/events.json @@ -8,7 +8,11 @@ "empty": { "alert": "Es gibt keine zu prüfenden Alarme", "detection": "Es gibt keine zu prüfenden Erkennungen", - "motion": "Keine Bewegungsdaten gefunden" + "motion": "Keine Bewegungsdaten gefunden", + "recordingsDisabled": { + "title": "Aufzeichnungen müssen aktiviert sein", + "description": "Überprüfungselemente können nur für eine Kamera erstellt werden, wenn Aufzeichnungen für diese Kamera aktiviert sind." + } }, "timeline": "Zeitleiste", "timeline.aria": "Zeitleiste auswählen", diff --git a/web/public/locales/de/views/explore.json b/web/public/locales/de/views/explore.json index 87da74008..273c568a2 100644 --- a/web/public/locales/de/views/explore.json +++ b/web/public/locales/de/views/explore.json @@ -79,7 +79,10 @@ "title": "Attribute bearbeiten", "desc": "Wählen Sie Klassifizierungsattribute für dieses {{label}} aus" }, - "attributes": "Klassifizierungsattribute" + "attributes": "Klassifizierungsattribute", + "title": { + "label": "Titel" + } }, "documentTitle": "Erkunde - Frigate", "generativeAI": "Generative KI", diff --git a/web/public/locales/de/views/faceLibrary.json b/web/public/locales/de/views/faceLibrary.json index e69114b50..1c96176e5 100644 --- a/web/public/locales/de/views/faceLibrary.json +++ b/web/public/locales/de/views/faceLibrary.json @@ -1,7 +1,7 @@ { "description": { "placeholder": "Gib einen Name für diese Kollektion ein", - "addFace": "Füge der Gesichtsbibliothek eine neue Sammlung hinzu, indem ein Bild hinzufügst.", + "addFace": "Füge der Gesichtsbibliothek eine neue Sammlung hinzu, indem du ein Bild hochlädst.", "invalidName": "Ungültiger Name. Namen dürfen nur Buchstaben, Zahlen, Leerzeichen, Apostrophe, Unterstriche und Bindestriche enthalten." }, "details": { diff --git a/web/public/locales/de/views/settings.json b/web/public/locales/de/views/settings.json index f577ae774..4f10f2f51 100644 --- a/web/public/locales/de/views/settings.json +++ b/web/public/locales/de/views/settings.json @@ -49,7 +49,7 @@ "desc": "Standardmäßig werden die letzten Warnmeldungen auf dem Live-Dashboard als kurze Videoschleifen abgespielt. Deaktiviere diese Option, um nur ein statisches Bild der letzten Warnungen auf diesem Gerät/Browser anzuzeigen." }, "automaticLiveView": { - "desc": "Wechsle automatisch zur Live Ansicht der Kamera, wenn einen Aktivität erkannt wurde. Wenn du diese Option deaktivierst, werden die statischen Kamerabilder auf der Liveübersicht nur einmal pro Minute aktualisiert.", + "desc": "Zeigt automatisch das Live-Bild einer Kamera an, wenn eine Aktivität erkannt wird. Ist diese Option deaktiviert, werden Kamerabilder im Live-Dashboard nur einmal pro Minute aktualisiert.", "label": "Automatische Live Ansicht" }, "displayCameraNames": { diff --git a/web/public/locales/de/views/system.json b/web/public/locales/de/views/system.json index a7bb342ae..0437c65b1 100644 --- a/web/public/locales/de/views/system.json +++ b/web/public/locales/de/views/system.json @@ -50,7 +50,14 @@ "otherProcesses": { "title": "Andere Prozesse", "processCpuUsage": "CPU Auslastung für Prozess", - "processMemoryUsage": "Prozessspeicherauslastung" + "processMemoryUsage": "Prozessspeicherauslastung", + "series": { + "go2rtc": "go2rtc", + "recording": "Aufnahme", + "audio_detector": "Geräuscherkennung", + "review_segment": "Überprüfungsteil", + "embeddings": "Einbettungen" + } } }, "documentTitle": { From 68fee3ed7bd573a2c7a1910950203684bcaf3bee Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:52 +0100 Subject: [PATCH 11/98] Translated using Weblate (Greek) Currently translated at 2.4% (3 of 122 strings) Co-authored-by: Hosted Weblate Co-authored-by: Thanasis Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/el/ Translation: Frigate NVR/views-classificationmodel --- web/public/locales/el/views/classificationModel.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/public/locales/el/views/classificationModel.json b/web/public/locales/el/views/classificationModel.json index 0967ef424..3f7b88c7c 100644 --- a/web/public/locales/el/views/classificationModel.json +++ b/web/public/locales/el/views/classificationModel.json @@ -1 +1,7 @@ -{} +{ + "documentTitle": "Μοντέλα Ταξινόμησης - Frigate", + "details": { + "scoreInfo": "Η βαθμολογία αντιπροσωπεύει την κατά μέσο όρο ταξινομική εμπιστοσύνη μεταξύ όλων των ανιχνεύσεων αυτού του αντικειμένου.", + "none": "Καμία" + } +} From 1c7f68bf446ef01f67857947607c28ea452a5af1 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:53 +0100 Subject: [PATCH 12/98] Translated using Weblate (Estonian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Estonian) Currently translated at 67.3% (62 of 92 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (25 of 25 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Estonian) Currently translated at 22.9% (115 of 501 strings) Translated using Weblate (Estonian) Currently translated at 26.6% (36 of 135 strings) Translated using Weblate (Estonian) Currently translated at 14.7% (18 of 122 strings) Translated using Weblate (Estonian) Currently translated at 28.3% (15 of 53 strings) Translated using Weblate (Estonian) Currently translated at 26.5% (13 of 49 strings) Translated using Weblate (Estonian) Currently translated at 5.3% (7 of 131 strings) Translated using Weblate (Estonian) Currently translated at 40.0% (10 of 25 strings) Co-authored-by: Hosted Weblate Co-authored-by: Priit Jõerüüt Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-player/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/et/ Translation: Frigate NVR/audio Translation: Frigate NVR/common Translation: Frigate NVR/components-player Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-live Translation: Frigate NVR/views-search Translation: Frigate NVR/views-system --- web/public/locales/et/audio.json | 60 ++++++++++++++++++- web/public/locales/et/common.json | 3 +- web/public/locales/et/components/player.json | 47 ++++++++++++++- .../locales/et/views/classificationModel.json | 15 ++++- web/public/locales/et/views/events.json | 6 +- web/public/locales/et/views/explore.json | 26 ++++++-- web/public/locales/et/views/faceLibrary.json | 4 ++ web/public/locales/et/views/live.json | 11 ++++ web/public/locales/et/views/search.json | 9 ++- web/public/locales/et/views/system.json | 7 ++- 10 files changed, 174 insertions(+), 14 deletions(-) diff --git a/web/public/locales/et/audio.json b/web/public/locales/et/audio.json index 8797c7867..b0dfec660 100644 --- a/web/public/locales/et/audio.json +++ b/web/public/locales/et/audio.json @@ -55,5 +55,63 @@ "toothbrush": "Hambahari", "vehicle": "Sõiduk", "bark": "Puukoor", - "goat": "Kits" + "goat": "Kits", + "snort": "Nuuskamine", + "cough": "Köhimine", + "throat_clearing": "Kurgu puhtaksköhatamine", + "sneeze": "Aevastamine", + "sniff": "Nuuskimine", + "run": "Jooksmine", + "cheering": "Hõiskamine", + "synthetic_singing": "Sünteesitud laulmine", + "rapping": "Räppimine", + "humming": "Ümisemine", + "groan": "Oigamine", + "grunt": "Röhatamine", + "chatter": "Jutuvada", + "shuffle": "Jalgade lohistamine", + "footsteps": "Sammumise heli", + "chewing": "Närimine", + "biting": "Hammustamine", + "gargling": "Kuristamine", + "stomach_rumble": "Kõhukorin", + "burping": "Röhitsemine", + "hiccup": "Luksumine", + "fart": "Peeretamine", + "yip": "Haukumine heleda häälega", + "howl": "Ulgumine", + "bow_wow": "Haukumise imiteerimine", + "growling": "Urisemine", + "whimper_dog": "Koera nuuksumine", + "purr": "Nurrumine", + "meow": "Näugumine", + "hiss": "Sisisemine", + "caterwaul": "Kräunumine", + "livestock": "Kariloomad", + "bleat": "Määgimine", + "dogs": "Koerad", + "rats": "Rotid", + "patter": "Pladin", + "insect": "Putukas", + "cricket": "Ritsikas", + "mosquito": "Sääsk", + "fly": "Kärbes", + "clip_clop": "Kabjaklobin", + "neigh": "Hirnumine", + "cattle": "Loomakari", + "moo": "Ammumine", + "cowbell": "Lehmakell", + "pig": "Siga", + "oink": "Röhkimine", + "fowl": "Kodulinnud", + "chicken": "Kana", + "cluck": "Kanade loksumine", + "cock_a_doodle_doo": "Kukeleegu", + "turkey": "Kalkun", + "gobble": "Kalkuni kulistamine", + "duck": "Part", + "quack": "Prääksumine", + "goose": "Hani", + "honk": "Kaagatamine", + "wild_animals": "Metsloomad" } diff --git a/web/public/locales/et/common.json b/web/public/locales/et/common.json index c092658e0..ae2d13944 100644 --- a/web/public/locales/et/common.json +++ b/web/public/locales/et/common.json @@ -240,7 +240,8 @@ "show": "Näita: {{item}}", "all": "Kõik", "ID": "Tunnus", - "none": "Puudub" + "none": "Puudub", + "other": "Muu" }, "list": { "two": "{{0}} ja {{1}}", diff --git a/web/public/locales/et/components/player.json b/web/public/locales/et/components/player.json index 2906ab642..76d41dd28 100644 --- a/web/public/locales/et/components/player.json +++ b/web/public/locales/et/components/player.json @@ -1,8 +1,51 @@ { - "noRecordingsFoundForThisTime": "Hetkel ei leidu ühtego salvestust", + "noRecordingsFoundForThisTime": "Hetkel ei leidu ühtegi salvestust", "noPreviewFound": "Eelvaadet ei leidu", "noPreviewFoundFor": "{{cameraName}} kaamera eelvaadet ei leidu", "submitFrigatePlus": { - "submit": "Saada" + "submit": "Saada", + "title": "Kas saadad selle kaadri Frigate+ teenusesse?" + }, + "cameraDisabled": "Kaamera on kasutuselt eemaldatud", + "stats": { + "streamType": { + "title": "Voogedastuse tüüp:", + "short": "Tüüp" + }, + "bandwidth": { + "title": "Ribalaius:", + "short": "Ribalaius" + }, + "latency": { + "title": "Latentsus:", + "value": "{{seconds}} sekundit", + "short": { + "title": "Latentsus", + "value": "{{seconds}} sek" + } + }, + "totalFrames": "Kaadreid kokku:", + "droppedFrames": { + "title": "Vahelejäänud kaadreid:", + "short": { + "title": "Vahelejäänud", + "value": "{{droppedFrames}} kaadrit" + } + }, + "decodedFrames": "Dekodeeritud kaadreid:", + "droppedFrameRate": "Vahelejäänud kaadrite sagedus:" + }, + "livePlayerRequiredIOSVersion": "Selle voogedastuse tüübi jaoks on vajalik iOS-i versioon 17.1 või uuem.", + "streamOffline": { + "title": "Voogedastus ei toimi", + "desc": "„{{cameraName}}“ detect-tüüpi voogedastusest pole tulnud ühtegi kaadrit. Täpsemat teavet leiad vealogidest" + }, + "toast": { + "success": { + "submittedFrigatePlus": "Kaadri saatmine Frigate+ teenusesse õnnestus" + }, + "error": { + "submitFrigatePlusFailed": "Kaadri saatmine Frigate+ teenusesse ei õnnestunud" + } } } diff --git a/web/public/locales/et/views/classificationModel.json b/web/public/locales/et/views/classificationModel.json index 2b393998f..93db04cba 100644 --- a/web/public/locales/et/views/classificationModel.json +++ b/web/public/locales/et/views/classificationModel.json @@ -7,10 +7,18 @@ }, "documentTitle": "Klassifitseerimise mudelid - Frigate", "details": { - "scoreInfo": "Skoor näitab selle objekti kõigi tuvastuste keskmist klassifitseerimise usaldusväärsust." + "scoreInfo": "Skoor näitab selle objekti kõigi tuvastuste keskmist klassifitseerimise usaldusväärsust.", + "none": "Puudub", + "unknown": "Pole teada" }, "button": { - "deleteClassificationAttempts": "Kustuta klassifitseerimispildid" + "deleteClassificationAttempts": "Kustuta klassifitseerimispildid", + "renameCategory": "Muuda klassi nimi", + "deleteCategory": "Kustuta klass", + "deleteImages": "Kustuta pildid", + "addClassification": "Lisa klassifikatsioon", + "deleteModels": "Kustuta mudelid", + "editModel": "Muuda mudelit" }, "description": { "invalidName": "Vigane nimi. Nimed võivad sisaldada ainult tähti, numbreid, tühikuid, ülakomasid, alakriipse ja sidekriipse." @@ -32,5 +40,8 @@ "allImagesRequired_one": "Palun klassifitseeri kõik pildid. Jäänud on veel {{count}} pilt.", "allImagesRequired_other": "Palun klassifitseeri kõik pildid. Jäänud on veel {{count}} pilti." } + }, + "tooltip": { + "trainingInProgress": "Mudel on parasjagu õppimas" } } diff --git a/web/public/locales/et/views/events.json b/web/public/locales/et/views/events.json index ef02cf080..75e4a3d5c 100644 --- a/web/public/locales/et/views/events.json +++ b/web/public/locales/et/views/events.json @@ -22,7 +22,11 @@ "empty": { "alert": "Ülevaatamiseks ei leidu ühtegi häiret", "detection": "Ülevaatamiseks ei leidu ühtegi tuvastamist", - "motion": "Liikumise andmeid ei leidu" + "motion": "Liikumise andmeid ei leidu", + "recordingsDisabled": { + "title": "Salvestamine peab olema sisse lülitatud", + "description": "Objekte saad määrata ülevaadatamiseks vaid siis, kui selle kaamera puhul on salvestamine lülitatud sisse." + } }, "select_all": "Kõik", "camera": "Kaamera", diff --git a/web/public/locales/et/views/explore.json b/web/public/locales/et/views/explore.json index e38334056..76592a97d 100644 --- a/web/public/locales/et/views/explore.json +++ b/web/public/locales/et/views/explore.json @@ -22,7 +22,19 @@ "title": "Näita kõiki tsoone", "desc": "Kui objekt on sisenenud tsooni, siis alati näida tsooni märgistust." } - } + }, + "lifecycleItemDesc": { + "attribute": { + "other": "{{label}} on tuvastatud kui {{attribute}}" + }, + "stationary": "{{label}} jäi paigale", + "active": "{{label}} muutus aktiivseks", + "entered_zone": "{{label}} sisenes tsooni {{zones}}", + "visible": "{{label}} on tuvastatud" + }, + "title": "Jälgimise üksikasjad", + "noImageFound": "Selle ajatempli kohta ei leidu pilti.", + "createObjectMask": "Loo objektimask" }, "documentTitle": "Avasta - Frigate", "generativeAI": "Generatiivne tehisaru", @@ -33,13 +45,18 @@ "thumbnailsEmbedded": "Pisipildid on lõimitud: ", "descriptionsEmbedded": "Kirjeldused on lõimitud: ", "trackedObjectsProcessed": "Jälgitud objektid on töödeldud: " - } + }, + "startingUp": "Käivitun…", + "estimatedTime": "Hinnanguliselt jäänud aega:", + "finishingShortly": "Lõpetan õige pea" } }, "type": { "details": "üksikasjad", "thumbnail": "pisipilt", - "snapshot": "hetkvõte" + "snapshot": "hetkvõte", + "video": "video", + "tracking_details": "jälgimise üksikasjad" }, "details": { "item": { @@ -51,6 +68,7 @@ "snapshotScore": { "label": "Hetkvõttete punktiskoor" }, - "regenerateFromSnapshot": "Loo uuesti hetkvõttest" + "regenerateFromSnapshot": "Loo uuesti hetkvõttest", + "timestamp": "Ajatampel" } } diff --git a/web/public/locales/et/views/faceLibrary.json b/web/public/locales/et/views/faceLibrary.json index adebe7788..42c795a06 100644 --- a/web/public/locales/et/views/faceLibrary.json +++ b/web/public/locales/et/views/faceLibrary.json @@ -30,5 +30,9 @@ "deleteFaceAttempts": { "desc_one": "Kas oled kindel, et soovid kustutada {{count}} näo? Seda tegevust ei saa tagasi pöörata.", "desc_other": "Kas oled kindel, et soovid kustutada {{count}} nägu? Seda tegevust ei saa tagasi pöörata." + }, + "details": { + "timestamp": "Ajatampel", + "unknown": "Pole teada" } } diff --git a/web/public/locales/et/views/live.json b/web/public/locales/et/views/live.json index 87a569679..9ba1ba125 100644 --- a/web/public/locales/et/views/live.json +++ b/web/public/locales/et/views/live.json @@ -91,6 +91,10 @@ "available": "Kahepoolne kõneside on selle voogedastuse puhul saadaval", "unavailable": "Kahepoolne kõneside pole selle voogedastuse puhul saadaval", "tips": "Sinu seadme peab seda funktsionaalsust toetama ja WebRTC peab olema kahepoolse kõneside jaoks seadistatud." + }, + "playInBackground": { + "label": "Esita taustal", + "tips": "Selle eelistusega saad määrata, et voogedastus jääb tööle ka siis, kui meesiaesitaja on suletud." } }, "notifications": "Teavitused", @@ -119,5 +123,12 @@ "label": "Esita taustal", "desc": "Kasuta seda valikut, kui tahad voogedastuse jätkumist ka siis, kui pildivaade on peidetud." } + }, + "noCameras": { + "buttonText": "Lisa kaamera", + "restricted": { + "title": "Ühtegi kaamerat pole saadaval", + "description": "Sul pole õigust ühegi selle grupi kaamera vaatamiseks." + } } } diff --git a/web/public/locales/et/views/search.json b/web/public/locales/et/views/search.json index d691c563e..52b917d22 100644 --- a/web/public/locales/et/views/search.json +++ b/web/public/locales/et/views/search.json @@ -8,11 +8,16 @@ "button": { "clear": "Tühjenda otsing", "save": "Salvesta otsing", - "delete": "Kustuta salvestatud otsing" + "delete": "Kustuta salvestatud otsing", + "filterInformation": "Filtri teave" }, "filter": { "label": { - "has_snapshot": "Leidub hetkvõte" + "has_snapshot": "Leidub hetkvõte", + "cameras": "Kaamerad", + "labels": "Sildid", + "zones": "Tsoonid", + "sub_labels": "Alamsildid" } } } diff --git a/web/public/locales/et/views/system.json b/web/public/locales/et/views/system.json index deb38f24b..b3bbb33aa 100644 --- a/web/public/locales/et/views/system.json +++ b/web/public/locales/et/views/system.json @@ -7,6 +7,11 @@ "logs": { "download": { "label": "Laadi logid alla" + }, + "copy": { + "label": "Kopeeri lõikelauale", + "success": "Logid on kopeeritud lõikelauale" } - } + }, + "title": "Süsteem" } From 849677c75835f958c4d775524bf478c09e33d413 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:53 +0100 Subject: [PATCH 13/98] Translated using Weblate (Romanian) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (136 of 136 strings) Co-authored-by: Hosted Weblate Co-authored-by: lukasig Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ro/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/ro/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/ro/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/ro/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/ro/common.json | 3 ++- web/public/locales/ro/views/events.json | 6 +++++- web/public/locales/ro/views/explore.json | 5 ++++- web/public/locales/ro/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/ro/common.json b/web/public/locales/ro/common.json index a70e1c06f..8d5177776 100644 --- a/web/public/locales/ro/common.json +++ b/web/public/locales/ro/common.json @@ -247,7 +247,8 @@ "show": "Afișează {{item}}", "ID": "ID", "none": "Niciuna", - "all": "Toate" + "all": "Toate", + "other": "Altele" }, "selectItem": "Selectează {{item}}", "pagination": { diff --git a/web/public/locales/ro/views/events.json b/web/public/locales/ro/views/events.json index 6a045d1f5..f4f2ef120 100644 --- a/web/public/locales/ro/views/events.json +++ b/web/public/locales/ro/views/events.json @@ -8,7 +8,11 @@ "empty": { "alert": "Nu sunt alerte de revizuit", "detection": "Nu sunt detecții de revizuit", - "motion": "Nu au fost găsite date despre mișcare" + "motion": "Nu au fost găsite date despre mișcare", + "recordingsDisabled": { + "title": "Înregistrările trebuie să fie activate", + "description": "Elementele de revizuire pot fi create doar pentru o cameră atunci când înregistrările sunt activate pentru acea cameră." + } }, "timeline": "Cronologie", "timeline.aria": "Selectează cronologia", diff --git a/web/public/locales/ro/views/explore.json b/web/public/locales/ro/views/explore.json index fa1b228ad..d76f9191d 100644 --- a/web/public/locales/ro/views/explore.json +++ b/web/public/locales/ro/views/explore.json @@ -167,7 +167,10 @@ "title": "Editează atribute", "desc": "Selectează atributele de clasificare pentru acest {{label}}" }, - "attributes": "Atribute de clasificare" + "attributes": "Atribute de clasificare", + "title": { + "label": "Titlu" + } }, "exploreMore": "Explorează mai multe obiecte cu {{label}}", "trackedObjectDetails": "Detalii despre obiectul urmărit", diff --git a/web/public/locales/ro/views/system.json b/web/public/locales/ro/views/system.json index e64990bba..6966f124f 100644 --- a/web/public/locales/ro/views/system.json +++ b/web/public/locales/ro/views/system.json @@ -60,7 +60,14 @@ "otherProcesses": { "title": "Alte Procese", "processCpuUsage": "Utilizare CPU", - "processMemoryUsage": "Utilizare memorie" + "processMemoryUsage": "Utilizare memorie", + "series": { + "go2rtc": "go2rtc", + "recording": "înregistrare", + "review_segment": "segment de revizuire", + "embeddings": "înglobări", + "audio_detector": "detector audio" + } }, "title": "General" }, From 067de0617698347c28e21ce48b1c807f4f71dc5a Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:53 +0100 Subject: [PATCH 14/98] Translated using Weblate (Bulgarian) Currently translated at 100.0% (10 of 10 strings) Translated using Weblate (Bulgarian) Currently translated at 23.2% (10 of 43 strings) Translated using Weblate (Bulgarian) Currently translated at 8.1% (4 of 49 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (10 of 10 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (13 of 13 strings) Translated using Weblate (Bulgarian) Currently translated at 53.2% (267 of 501 strings) Translated using Weblate (Bulgarian) Currently translated at 1.6% (2 of 122 strings) Translated using Weblate (Bulgarian) Currently translated at 45.6% (21 of 46 strings) Translated using Weblate (Bulgarian) Currently translated at 2.9% (4 of 136 strings) Translated using Weblate (Bulgarian) Currently translated at 10.9% (6 of 55 strings) Translated using Weblate (Bulgarian) Currently translated at 11.3% (6 of 53 strings) Translated using Weblate (Bulgarian) Currently translated at 2.9% (4 of 136 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (13 of 13 strings) Co-authored-by: Borislav Co-authored-by: Hosted Weblate Co-authored-by: Jan Ivanov (Telemaniaka) Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-camera/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-configeditor/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/bg/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/bg/ Translation: Frigate NVR/audio Translation: Frigate NVR/components-auth Translation: Frigate NVR/components-camera Translation: Frigate NVR/components-dialog Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-configeditor Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-exports Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-search Translation: Frigate NVR/views-system --- web/public/locales/bg/audio.json | 7 ++++--- web/public/locales/bg/components/auth.json | 12 ++++++++++- web/public/locales/bg/components/camera.json | 2 +- web/public/locales/bg/components/dialog.json | 5 ++++- .../locales/bg/views/classificationModel.json | 5 ++++- web/public/locales/bg/views/configEditor.json | 18 ++++++++++++++-- web/public/locales/bg/views/events.json | 5 ++++- web/public/locales/bg/views/explore.json | 2 +- web/public/locales/bg/views/exports.json | 21 ++++++++++++++++++- web/public/locales/bg/views/faceLibrary.json | 3 ++- web/public/locales/bg/views/search.json | 3 ++- web/public/locales/bg/views/system.json | 3 ++- 12 files changed, 71 insertions(+), 15 deletions(-) diff --git a/web/public/locales/bg/audio.json b/web/public/locales/bg/audio.json index e59baf850..fcc7a3902 100644 --- a/web/public/locales/bg/audio.json +++ b/web/public/locales/bg/audio.json @@ -2,9 +2,9 @@ "babbling": "Бърборене", "whispering": "Шепнене", "laughter": "Смях", - "crying": "Плача", + "crying": "Плач", "sigh": "Въздишка", - "singing": "Подписвам", + "singing": "Пеене", "choir": "Хор", "yodeling": "Йоделинг", "mantra": "Мантра", @@ -264,5 +264,6 @@ "pant": "Здъхване", "stomach_rumble": "Къркорене на стомах", "heartbeat": "Сърцебиене", - "scream": "Вик" + "scream": "Вик", + "snicker": "Хихикане" } diff --git a/web/public/locales/bg/components/auth.json b/web/public/locales/bg/components/auth.json index 56a13f7f0..094cd71a0 100644 --- a/web/public/locales/bg/components/auth.json +++ b/web/public/locales/bg/components/auth.json @@ -1,6 +1,16 @@ { "form": { "user": "Потребителско име", - "password": "Парола" + "password": "Парола", + "login": "Вход", + "firstTimeLogin": "Опитвате да влезете за първи път? Данните за вход са разпечатани в логовете на Frigate.", + "errors": { + "usernameRequired": "Потребителското име е задължително", + "passwordRequired": "Паролата е задължителна", + "rateLimit": "Надхвърлен брой опити. Моля Опитайте по-късно.", + "loginFailed": "Неуспешен вход", + "unknownError": "Неизвестна грешка. Поля проверете логовете.", + "webUnknownError": "Неизвестна грешка. Поля проверете изхода в конзолата." + } } } diff --git a/web/public/locales/bg/components/camera.json b/web/public/locales/bg/components/camera.json index e95016ad9..cad1127a0 100644 --- a/web/public/locales/bg/components/camera.json +++ b/web/public/locales/bg/components/camera.json @@ -7,7 +7,7 @@ "label": "Изтрий група за камери", "confirm": { "title": "Потвърди изтриването", - "desc": "Сигурни ли сте, че искате да изтриете група {{name}}?" + "desc": "Сигурни ли сте, че искате да изтриете група {{name}}?" } }, "name": { diff --git a/web/public/locales/bg/components/dialog.json b/web/public/locales/bg/components/dialog.json index d704890d6..6a2d356b5 100644 --- a/web/public/locales/bg/components/dialog.json +++ b/web/public/locales/bg/components/dialog.json @@ -11,6 +11,9 @@ }, "restart": { "title": "Сигурен ли сте, че искате да рестартирате Frigate?", - "button": "Рестартирай" + "button": "Рестартирай", + "restarting": { + "title": "Frigare се рестартира" + } } } diff --git a/web/public/locales/bg/views/classificationModel.json b/web/public/locales/bg/views/classificationModel.json index 685eefe75..7b8ecb1dd 100644 --- a/web/public/locales/bg/views/classificationModel.json +++ b/web/public/locales/bg/views/classificationModel.json @@ -1,3 +1,6 @@ { - "documentTitle": "Модели за класификация" + "documentTitle": "Модели за класификация - Frigate", + "description": { + "invalidName": "Невалидно име. Имената могат да съдържат единствено: букви, числа, празни места, долни черти и тирета." + } } diff --git a/web/public/locales/bg/views/configEditor.json b/web/public/locales/bg/views/configEditor.json index b2507c3f2..955fb99b7 100644 --- a/web/public/locales/bg/views/configEditor.json +++ b/web/public/locales/bg/views/configEditor.json @@ -1,4 +1,18 @@ { - "documentTitle": "Настройки на конфигурацията - Фригейт", - "configEditor": "Настройки на конфигурацията" + "documentTitle": "Настройки на конфигурацията - Frigate", + "configEditor": "Конфигуратор", + "safeConfigEditor": "Конфигуратор (Safe Mode)", + "safeModeDescription": "Frigate е в режим \"Safe Mode\" тъй като конфигурацията не минава проверките за валидност.", + "copyConfig": "Копирай Конфигурацията", + "saveAndRestart": "Запази и Рестартирай", + "saveOnly": "Запази", + "confirm": "Изход без запис?", + "toast": { + "success": { + "copyToClipboard": "Конфигурацията е копирана." + }, + "error": { + "savingError": "Грешка при запис на конфигурацията" + } + } } diff --git a/web/public/locales/bg/views/events.json b/web/public/locales/bg/views/events.json index 3b8260068..affd0cb52 100644 --- a/web/public/locales/bg/views/events.json +++ b/web/public/locales/bg/views/events.json @@ -11,5 +11,8 @@ }, "allCameras": "Всички камери", "alerts": "Известия", - "detections": "Засичания" + "detections": "Засичания", + "motion": { + "label": "Движение" + } } diff --git a/web/public/locales/bg/views/explore.json b/web/public/locales/bg/views/explore.json index f8964930d..d6c074d4e 100644 --- a/web/public/locales/bg/views/explore.json +++ b/web/public/locales/bg/views/explore.json @@ -10,5 +10,5 @@ "trackedObjectsCount_one": "{{count}} проследен обект ", "trackedObjectsCount_other": "{{count}} проследени обекта ", "documentTitle": "Разгледай - Фригейт", - "generativeAI": "Генериращ Изкъствен Интелект" + "generativeAI": "Генеративен Изкъствен Интелект" } diff --git a/web/public/locales/bg/views/exports.json b/web/public/locales/bg/views/exports.json index ae366d5d2..5454a085d 100644 --- a/web/public/locales/bg/views/exports.json +++ b/web/public/locales/bg/views/exports.json @@ -1,4 +1,23 @@ { "documentTitle": "Експорт - Frigate", - "search": "Търси" + "search": "Търси", + "noExports": "Няма намерени експорти", + "deleteExport": "Изтрий експорт", + "deleteExport.desc": "Сигурни ли сте, че искате да изтриете {{exportName}}?", + "editExport": { + "title": "Преименувай експорт", + "desc": "Въведете ново име за този експорт.", + "saveExport": "Запази експорт" + }, + "tooltip": { + "shareExport": "Сподели експорт", + "downloadVideo": "Свали видео", + "editName": "Редактирай име", + "deleteExport": "Изтрий експорт" + }, + "toast": { + "error": { + "renameExportFailed": "Неуспешно преименуване на експорт: {{errorMessage}}" + } + } } diff --git a/web/public/locales/bg/views/faceLibrary.json b/web/public/locales/bg/views/faceLibrary.json index 4c9b15b16..7d4a82211 100644 --- a/web/public/locales/bg/views/faceLibrary.json +++ b/web/public/locales/bg/views/faceLibrary.json @@ -13,6 +13,7 @@ }, "description": { "addFace": "Добавете нова колекция във библиотеката за лица при качването на първата ви снимка.", - "placeholder": "Напишете име за тази колекция" + "placeholder": "Напишете име за тази колекция", + "invalidName": "Невалидно име. Имената могат да съдържат единствено: букви, числа, празни места, долни черти и тирета." } } diff --git a/web/public/locales/bg/views/search.json b/web/public/locales/bg/views/search.json index e92f48860..924682386 100644 --- a/web/public/locales/bg/views/search.json +++ b/web/public/locales/bg/views/search.json @@ -3,5 +3,6 @@ "save": "Запазване на търсенето" }, "search": "Търси", - "savedSearches": "Запазени търсения" + "savedSearches": "Запазени търсения", + "searchFor": "Търсене за {{inputValue}}" } diff --git a/web/public/locales/bg/views/system.json b/web/public/locales/bg/views/system.json index ec5f0ec6c..be1e23db1 100644 --- a/web/public/locales/bg/views/system.json +++ b/web/public/locales/bg/views/system.json @@ -4,6 +4,7 @@ }, "documentTitle": { "cameras": "Статистики за Камери - Фригейт", - "storage": "Статистика за паметта - Фригейт" + "storage": "Статистика за паметта - Фригейт", + "general": "Обща Статистика - Frigate" } } From 6572fa8a48ab3b4a5fb3ebb6b84d2eb13b136944 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:53 +0100 Subject: [PATCH 15/98] Translated using Weblate (Ukrainian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (136 of 136 strings) Co-authored-by: Hosted Weblate Co-authored-by: Максим Горпиніч Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/uk/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/uk/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/uk/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/uk/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/uk/common.json | 3 ++- web/public/locales/uk/views/events.json | 6 +++++- web/public/locales/uk/views/explore.json | 5 ++++- web/public/locales/uk/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/uk/common.json b/web/public/locales/uk/common.json index b6692bad8..da875f1f8 100644 --- a/web/public/locales/uk/common.json +++ b/web/public/locales/uk/common.json @@ -248,7 +248,8 @@ "show": "Показати {{item}}", "ID": "ID", "none": "Жоден", - "all": "Усі" + "all": "Усі", + "other": "Інше" }, "toast": { "save": { diff --git a/web/public/locales/uk/views/events.json b/web/public/locales/uk/views/events.json index 3cceebda5..5b3c20443 100644 --- a/web/public/locales/uk/views/events.json +++ b/web/public/locales/uk/views/events.json @@ -12,7 +12,11 @@ "empty": { "alert": "Немає попереджень для перегляду", "detection": "Немає ніяких ознак", - "motion": "Даних про рух не знайдено" + "motion": "Даних про рух не знайдено", + "recordingsDisabled": { + "title": "Записи мають бути ввімкнені", + "description": "Елементи рецензування можна створювати для камери, лише якщо для цієї камери ввімкнено запис." + } }, "timeline": "Хронологія", "timeline.aria": "Вибрати хронiку", diff --git a/web/public/locales/uk/views/explore.json b/web/public/locales/uk/views/explore.json index d97e09ab6..0c7863e05 100644 --- a/web/public/locales/uk/views/explore.json +++ b/web/public/locales/uk/views/explore.json @@ -172,7 +172,10 @@ "title": "Редагувати атрибути", "desc": "Виберіть атрибути класифікації для цього {{label}}" }, - "attributes": "Атрибути класифікації" + "attributes": "Атрибути класифікації", + "title": { + "label": "Назва" + } }, "dialog": { "confirmDelete": { diff --git a/web/public/locales/uk/views/system.json b/web/public/locales/uk/views/system.json index 0e2a58511..b65616c60 100644 --- a/web/public/locales/uk/views/system.json +++ b/web/public/locales/uk/views/system.json @@ -115,7 +115,14 @@ "otherProcesses": { "processMemoryUsage": "Використання пам'яті процесу", "processCpuUsage": "Використання процесора процесу", - "title": "Інші процеси" + "title": "Інші процеси", + "series": { + "go2rtc": "go2rtc", + "recording": "запис", + "review_segment": "сегмент огляду", + "embeddings": "вбудовування", + "audio_detector": "аудіодетектор" + } }, "detector": { "temperature": "Температура детектора", From 91f9a01df54bc6bdb8ab22fd550f139b40ea8043 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:54 +0100 Subject: [PATCH 16/98] Translated using Weblate (Japanese) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (501 of 501 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (118 of 118 strings) Co-authored-by: Hosted Weblate Co-authored-by: alpha Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/ja/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/ja/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/ja/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/ja/ Translation: Frigate NVR/audio Translation: Frigate NVR/objects Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore --- web/public/locales/ja/audio.json | 2 +- web/public/locales/ja/objects.json | 2 +- web/public/locales/ja/views/events.json | 6 +++++- web/public/locales/ja/views/explore.json | 5 ++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/web/public/locales/ja/audio.json b/web/public/locales/ja/audio.json index e049b882e..43811ed76 100644 --- a/web/public/locales/ja/audio.json +++ b/web/public/locales/ja/audio.json @@ -57,7 +57,7 @@ "animal": "動物", "pets": "ペット", "dog": "犬", - "bark": "樹皮", + "bark": "吠え声", "yip": "キャンキャン鳴く声", "howl": "遠吠え", "bow_wow": "ワンワン", diff --git a/web/public/locales/ja/objects.json b/web/public/locales/ja/objects.json index c8b24e800..c3e41af3f 100644 --- a/web/public/locales/ja/objects.json +++ b/web/public/locales/ja/objects.json @@ -6,7 +6,7 @@ "airplane": "飛行機", "animal": "動物", "dog": "犬", - "bark": "樹皮", + "bark": "吠え声", "cat": "猫", "horse": "馬", "goat": "ヤギ", diff --git a/web/public/locales/ja/views/events.json b/web/public/locales/ja/views/events.json index b1f85a066..544412974 100644 --- a/web/public/locales/ja/views/events.json +++ b/web/public/locales/ja/views/events.json @@ -8,7 +8,11 @@ "empty": { "detection": "レビューする検出はありません", "alert": "レビューするアラートはありません", - "motion": "モーションデータは見つかりません" + "motion": "モーションデータは見つかりません", + "recordingsDisabled": { + "title": "録画を有効にする必要があります", + "description": "カメラの録画が有効になっている場合にのみ、そのカメラに対してレビューアイテムを作成できます。" + } }, "camera": "カメラ", "allCameras": "全カメラ", diff --git a/web/public/locales/ja/views/explore.json b/web/public/locales/ja/views/explore.json index ccee1d47a..35265cc50 100644 --- a/web/public/locales/ja/views/explore.json +++ b/web/public/locales/ja/views/explore.json @@ -80,7 +80,10 @@ "title": "属性を編集", "desc": "この {{label}} の分類属性を選択してください" }, - "attributes": "分類属性" + "attributes": "分類属性", + "title": { + "label": "タイトル" + } }, "exploreMore": "{{label}} のオブジェクトをさらに探索", "exploreIsUnavailable": { From a326ecdc9f0a5334b0056d57a424ace12728a350 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:54 +0100 Subject: [PATCH 17/98] Translated using Weblate (Catalan) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (136 of 136 strings) Co-authored-by: Eduardo Pastor Fernández <123eduardoneko123@gmail.com> Co-authored-by: Hosted Weblate Co-authored-by: anton garcias Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ca/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/ca/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/ca/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/ca/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/ca/common.json | 3 ++- web/public/locales/ca/views/events.json | 6 +++++- web/public/locales/ca/views/explore.json | 5 ++++- web/public/locales/ca/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/ca/common.json b/web/public/locales/ca/common.json index 03d217ae0..61faabea0 100644 --- a/web/public/locales/ca/common.json +++ b/web/public/locales/ca/common.json @@ -227,7 +227,8 @@ "show": "Mostra {{item}}", "ID": "ID", "none": "Cap", - "all": "Tots" + "all": "Tots", + "other": "Altres" }, "button": { "apply": "Aplicar", diff --git a/web/public/locales/ca/views/events.json b/web/public/locales/ca/views/events.json index 960d6a209..5f3c5ea95 100644 --- a/web/public/locales/ca/views/events.json +++ b/web/public/locales/ca/views/events.json @@ -10,7 +10,11 @@ "empty": { "alert": "Hi ha cap alerta per revisar", "detection": "Hi ha cap detecció per revisar", - "motion": "No s'haan trobat dades de moviment" + "motion": "No s'haan trobat dades de moviment", + "recordingsDisabled": { + "title": "S'han d'activar les gravacions", + "description": "Només es poden revisar temes quan s'han activat les gravacions de la càmera." + } }, "timeline": "Línia de temps", "timeline.aria": "Seleccionar línia de temps", diff --git a/web/public/locales/ca/views/explore.json b/web/public/locales/ca/views/explore.json index 0461ac7c7..2c94e50f5 100644 --- a/web/public/locales/ca/views/explore.json +++ b/web/public/locales/ca/views/explore.json @@ -169,7 +169,10 @@ "title": "Edita els atributs", "desc": "Seleccioneu els atributs de classificació per a aquesta {{label}}" }, - "attributes": "Atributs de classificació" + "attributes": "Atributs de classificació", + "title": { + "label": "Títol" + } }, "searchResult": { "tooltip": "S'ha identificat {{type}} amb una confiança del {{confidence}}%", diff --git a/web/public/locales/ca/views/system.json b/web/public/locales/ca/views/system.json index 662ca7552..312f3c299 100644 --- a/web/public/locales/ca/views/system.json +++ b/web/public/locales/ca/views/system.json @@ -86,7 +86,14 @@ "otherProcesses": { "title": "Altres processos", "processMemoryUsage": "Ús de memòria de procés", - "processCpuUsage": "Ús de la CPU del procés" + "processCpuUsage": "Ús de la CPU del procés", + "series": { + "recording": "gravant", + "review_segment": "segment de revisió", + "embeddings": "incrustacions", + "audio_detector": "detector d'àudio", + "go2rtc": "go2rtc" + } } }, "storage": { From 820fc6e9b59fb6e617f3196a8a83febb4e4c7788 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:54 +0100 Subject: [PATCH 18/98] Translated using Weblate (Portuguese) Currently translated at 100.0% (10 of 10 strings) Translated using Weblate (Portuguese) Currently translated at 27.8% (34 of 122 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Portuguese) Currently translated at 4.9% (6 of 122 strings) Co-authored-by: Hosted Weblate Co-authored-by: Nuno Ponte Co-authored-by: fabiovalverde Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/pt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/pt/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/pt/ Translation: Frigate NVR/common Translation: Frigate NVR/components-auth Translation: Frigate NVR/views-classificationmodel --- web/public/locales/pt/common.json | 48 +++++++++++++---- web/public/locales/pt/components/auth.json | 3 +- .../locales/pt/views/classificationModel.json | 51 ++++++++++++++++++- 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/web/public/locales/pt/common.json b/web/public/locales/pt/common.json index 97d543802..557d6b48d 100644 --- a/web/public/locales/pt/common.json +++ b/web/public/locales/pt/common.json @@ -18,9 +18,9 @@ "year_one": "{{time}} ano", "year_many": "{{time}} de anos", "year_other": "{{time}} anos", - "month_one": "{{time}} mes", + "month_one": "{{time}} mês", "month_many": "{{time}} meses", - "month_other": "", + "month_other": "{{time}} meses", "day_one": "{{time}} dia", "day_many": "{{time}} dias", "day_other": "{{time}} dias", @@ -87,7 +87,10 @@ "formattedTimestampMonthDayYear": { "12hour": "d MMM, yyyy", "24hour": "d MMM, yyyy" - } + }, + "inProgress": "Em andamento", + "invalidStartTime": "Horário de início inválido", + "invalidEndTime": "Horário de término inválido" }, "unit": { "speed": { @@ -97,6 +100,14 @@ "length": { "feet": "pés", "meters": "metros" + }, + "data": { + "kbps": "kB/s", + "mbps": "MB/s", + "gbps": "GB/s", + "kbph": "kB/hora", + "mbph": "MB/hora", + "gbph": "GB/hora" } }, "button": { @@ -108,7 +119,7 @@ "saving": "A guardar…", "apply": "Aplicar", "disable": "Desativar", - "save": "Guardar", + "save": "Salvar", "copy": "Copiar", "cancel": "Cancelar", "close": "Fechar", @@ -134,10 +145,16 @@ "export": "Exportar", "next": "Seguinte", "play": "Tocar", - "pictureInPicture": "Imagem sobre Imagem" + "pictureInPicture": "Imagem sobre Imagem", + "continue": "Continuar" }, "label": { - "back": "Voltar" + "back": "Voltar", + "hide": "Ocultar {{item}}", + "show": "Exibir {{item}}", + "ID": "ID", + "none": "Nenhum", + "all": "Todos" }, "menu": { "user": { @@ -169,7 +186,7 @@ "languages": "Idiomas", "language": { "en": "Inglês (EUA)", - "zhCN": "Chinês (Chinês Simplificado)", + "zhCN": "简体中文 (Chinês Simplificado)", "withSystem": { "label": "Utilizar as definições do sistema para o idioma" }, @@ -239,7 +256,8 @@ "export": "Exportar", "explore": "Explorar", "review": "Rever", - "uiPlayground": "Área de Testes da IU" + "uiPlayground": "Área de Testes da IU", + "classification": "Classificação" }, "pagination": { "previous": { @@ -280,5 +298,17 @@ "title": "404" }, "selectItem": "Selecionar {{item}}", - "readTheDocumentation": "Leia a documentação" + "readTheDocumentation": "Leia a documentação", + "information": { + "pixels": "{{area}}px" + }, + "list": { + "two": "{{0}} e {{1}}", + "many": "{{items}} e {{last}}", + "separatorWithSpace": ", " + }, + "field": { + "optional": "Opcional", + "internalID": "o Frigate utiliza o ID na configuração e no banco de dados" + } } diff --git a/web/public/locales/pt/components/auth.json b/web/public/locales/pt/components/auth.json index fc00399b1..3fa777ba8 100644 --- a/web/public/locales/pt/components/auth.json +++ b/web/public/locales/pt/components/auth.json @@ -10,6 +10,7 @@ "unknownError": "Erro desconhecido. Verifique os registos.", "webUnknownError": "Erro desconhecido. Verifique os registos da consola." }, - "password": "Palavra-passe" + "password": "Palavra-passe", + "firstTimeLogin": "Está tentando fazer login pela primeira vez? As credenciais estão impressas nos registros do Frigate." } } diff --git a/web/public/locales/pt/views/classificationModel.json b/web/public/locales/pt/views/classificationModel.json index 0967ef424..2ab7c1fa8 100644 --- a/web/public/locales/pt/views/classificationModel.json +++ b/web/public/locales/pt/views/classificationModel.json @@ -1 +1,50 @@ -{} +{ + "button": { + "trainModel": "Treinar Modelo", + "addClassification": "Adicionar Classificação", + "deleteModels": "Apagar Modelos", + "editModel": "Editar Modelo", + "deleteClassificationAttempts": "Excluir imagens de classificação", + "renameCategory": "Renomear Classe", + "deleteCategory": "Excluir Classe", + "deleteImages": "Excluir imagens" + }, + "tooltip": { + "trainingInProgress": "Modelo está a ser treinado", + "noNewImages": "Não há novas imagens para treinar. Classifique mais imagens no dataset.", + "noChanges": "Nenhuma alteração foi feita no conjunto de dados desde o último treinamento.", + "modelNotReady": "O modelo não está pronto para treinamento" + }, + "details": { + "scoreInfo": "A pontuação representa a confiança média da classificação em todas as detecções deste objeto.", + "none": "Nenhum", + "unknown": "Desconhecido" + }, + "toast": { + "success": { + "deletedCategory": "Classe excluída", + "deletedImage": "Imagens excluídas", + "categorizedImage": "Imagem classificada com sucesso", + "trainedModel": "Modelo treinado com sucesso.", + "trainingModel": "Treinamento do modelo iniciado com sucesso.", + "updatedModel": "Configuração do modelo atualizada com sucesso", + "renamedCategory": "Classe renomeada com sucesso para {{name}}" + }, + "error": { + "deleteImageFailed": "Falha ao excluir: {{errorMessage}}", + "deleteCategoryFailed": "Falha ao excluir a classe: {{errorMessage}}", + "deleteModelFailed": "Falha ao excluir o modelo: {{errorMessage}}", + "categorizeFailed": "Falha ao categorizar a imagem: {{errorMessage}}", + "trainingFailed": "O treinamento do modelo falhou. Verifique os registros do Frigate para obter detalhes.", + "trainingFailedToStart": "Falha ao iniciar o treinamento do modelo: {{errorMessage}}", + "updateModelFailed": "Falha ao atualizar o modelo: {{errorMessage}}", + "renameCategoryFailed": "Falha ao renomear a classe: {{errorMessage}}" + } + }, + "deleteCategory": { + "title": "Excluir Classe", + "desc": "Tem certeza de que deseja excluir a classe {{name}}? Isso excluirá permanentemente todas as imagens associadas e exigirá o treinamento do modelo novamente.", + "minClassesTitle": "Não é possível excluir a classe", + "minClassesDesc": "Um modelo de classificação deve ter pelo menos duas classes. Adicione outra classe antes de excluir esta." + } +} From cd3d0883bc19f9566ddfceb77a4ff9d1a9eb7af6 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:54 +0100 Subject: [PATCH 19/98] Translated using Weblate (Croatian) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (46 of 46 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (74 of 74 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (55 of 55 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (118 of 118 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (49 of 49 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (501 of 501 strings) Translated using Weblate (Croatian) Currently translated at 46.7% (43 of 92 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (118 of 118 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Croatian) Currently translated at 10.9% (55 of 501 strings) Translated using Weblate (Croatian) Currently translated at 27.8% (34 of 122 strings) Translated using Weblate (Croatian) Currently translated at 15.8% (34 of 215 strings) Translated using Weblate (Croatian) Currently translated at 24.5% (29 of 118 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (13 of 13 strings) Translated using Weblate (Croatian) Currently translated at 67.4% (29 of 43 strings) Translated using Weblate (Croatian) Currently translated at 39.1% (29 of 74 strings) Translated using Weblate (Croatian) Currently translated at 58.4% (31 of 53 strings) Translated using Weblate (Croatian) Currently translated at 22.7% (31 of 136 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (10 of 10 strings) Translated using Weblate (Croatian) Currently translated at 63.0% (29 of 46 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (10 of 10 strings) Translated using Weblate (Croatian) Currently translated at 31.5% (29 of 92 strings) Translated using Weblate (Croatian) Currently translated at 100.0% (25 of 25 strings) Translated using Weblate (Croatian) Currently translated at 59.1% (29 of 49 strings) Translated using Weblate (Croatian) Currently translated at 7.9% (40 of 501 strings) Translated using Weblate (Croatian) Currently translated at 52.7% (29 of 55 strings) Translated using Weblate (Croatian) Currently translated at 5.0% (33 of 654 strings) Translated using Weblate (Croatian) Currently translated at 26.4% (36 of 136 strings) Co-authored-by: Hosted Weblate Co-authored-by: stipe-jurkovic Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-camera/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-player/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-configeditor/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/hr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/hr/ Translation: Frigate NVR/audio Translation: Frigate NVR/common Translation: Frigate NVR/components-auth Translation: Frigate NVR/components-camera Translation: Frigate NVR/components-dialog Translation: Frigate NVR/components-filter Translation: Frigate NVR/components-player Translation: Frigate NVR/objects Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-configeditor Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-exports Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-live Translation: Frigate NVR/views-search Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/hr/audio.json | 487 +++++++++++++++++- web/public/locales/hr/common.json | 282 +++++++++- web/public/locales/hr/components/auth.json | 6 +- web/public/locales/hr/components/camera.json | 48 +- web/public/locales/hr/components/dialog.json | 78 ++- web/public/locales/hr/components/filter.json | 114 +++- web/public/locales/hr/components/player.json | 36 +- web/public/locales/hr/objects.json | 105 +++- .../locales/hr/views/classificationModel.json | 58 ++- web/public/locales/hr/views/configEditor.json | 8 +- web/public/locales/hr/views/events.json | 49 +- web/public/locales/hr/views/explore.json | 47 +- web/public/locales/hr/views/exports.json | 7 +- web/public/locales/hr/views/faceLibrary.json | 64 ++- web/public/locales/hr/views/live.json | 57 +- web/public/locales/hr/views/search.json | 50 +- web/public/locales/hr/views/settings.json | 55 +- web/public/locales/hr/views/system.json | 49 +- 18 files changed, 1551 insertions(+), 49 deletions(-) diff --git a/web/public/locales/hr/audio.json b/web/public/locales/hr/audio.json index d0b8ecaaa..55d1e5fce 100644 --- a/web/public/locales/hr/audio.json +++ b/web/public/locales/hr/audio.json @@ -4,14 +4,14 @@ "bicycle": "Bicikl", "yell": "Vikanje", "car": "Automobil", - "bellow": "Ispod", + "bellow": "Rika", "motorcycle": "Motocikl", "whispering": "Šaptanje", "bus": "Autobus", "laughter": "Smijeh", "train": "Vlak", - "snicker": "Tenisica", - "boat": "Čamac", + "snicker": "Smješkanje", + "boat": "ÄŒamac", "crying": "Plakanje", "singing": "Pjevanje", "choir": "Zbor", @@ -19,8 +19,485 @@ "mantra": "Mantra", "bird": "Ptica", "child_singing": "Dijete pjeva", - "cat": "Mačka", + "cat": "Mačka", "dog": "Pas", "horse": "Konj", - "sheep": "Ovca" + "sheep": "Ovca", + "whoop": "Ups", + "sigh": "Uzdah", + "chant": "Pjevanje", + "synthetic_singing": "Sintetičko pjevanje", + "rapping": "Repanje", + "humming": "Pjevušenje", + "groan": "Jauk", + "grunt": "Mrmljanje", + "whistling": "Zviždanje", + "breathing": "Disanje", + "wheeze": "Piskanje", + "snoring": "Hrkanje", + "gasp": "Izdisaj", + "pant": "Dahćanje", + "snort": "Šmrk", + "cough": "Kašalj", + "skateboard": "Skejtboard", + "door": "Vrata", + "mouse": "Miš", + "keyboard": "Tipkovnica", + "sink": "Sudoper", + "blender": "Blender", + "clock": "Sat", + "scissors": "Škare", + "hair_dryer": "Fen", + "toothbrush": "Četkica za zube", + "vehicle": "Vozilo", + "animal": "Životinja", + "bark": "Kora", + "goat": "Koza", + "camera": "Kamera", + "throat_clearing": "Pročišćavanje grla", + "sneeze": "Kihati", + "sniff": "Njuškanje", + "run": "Trčanje", + "shuffle": "Geganje", + "footsteps": "Koraci", + "chewing": "Žvakanje", + "biting": "Grizenje", + "gargling": "Grgljanje", + "stomach_rumble": "Kruljenje u želucu", + "burping": "Podrigivanje", + "hiccup": "Štucanje", + "fart": "Prdac", + "hands": "Ruke", + "finger_snapping": "Pucketanje prstima", + "clapping": "Pljesak", + "heartbeat": "Otkucaji srca", + "heart_murmur": "Šum na srcu", + "cheering": "Navijanje", + "applause": "Pljesak", + "chatter": "Brbljanje", + "crowd": "Publika", + "children_playing": "Djeca se igraju", + "pets": "Kućni ljubimci", + "yip": "Kevtanje", + "howl": "Zavijanje", + "bow_wow": "Bow Wow", + "growling": "Režanje", + "whimper_dog": "Ps Cvilenje", + "purr": "Purr", + "meow": "Mijau", + "hiss": "Šuštanje", + "caterwaul": "Caterlaul", + "livestock": "Stočarstvo", + "clip_clop": "Clip Clop", + "neigh": "Njiši", + "cattle": "Goveda", + "moo": "Muu", + "cowbell": "Kravlje zvono", + "pig": "Svinja", + "oink": "Oink", + "bleat": "Blejanje", + "fowl": "Perad", + "chicken": "Piletina", + "cluck": "Kljuc", + "cock_a_doodle_doo": "Kukurikurik", + "turkey": "Turska", + "gobble": "Halapljivo jedenje", + "duck": "Patka", + "quack": "Kvak", + "goose": "Guska", + "honk": "Truba", + "wild_animals": "Divlje životinje", + "roaring_cats": "Rikuće mačke", + "roar": "Rika", + "chirp": "Cvrkut", + "squawk": "Krik", + "pigeon": "Golub", + "coo": "Cvrkut", + "crow": "Vrana", + "caw": "Krak", + "owl": "Sova", + "hoot": "Hookanje", + "flapping_wings": "Mahanje krilima", + "dogs": "Psi", + "rats": "Štakori", + "patter": "Patkanje", + "insect": "Insekt", + "cricket": "Kriket", + "mosquito": "Komarac", + "fly": "Leti", + "buzz": "Bzz", + "frog": "Žaba", + "croak": "Krek", + "snake": "Zmija", + "rattle": "Zveckanje", + "whale_vocalization": "Vokalizacija kita", + "music": "Glazba", + "musical_instrument": "Glazbeni instrument", + "plucked_string_instrument": "Trzajući žičani instrument", + "guitar": "Gitara", + "electric_guitar": "Električna gitara", + "bass_guitar": "Bas gitara", + "acoustic_guitar": "Akustična gitara", + "steel_guitar": "Steel gitara", + "tapping": "Tapkanje", + "strum": "Tunganje", + "banjo": "Banjo (Instrument)", + "sitar": "Sitar (Instrument)", + "mandolin": "Mandolina", + "zither": "Cither", + "ukulele": "Ukulele (Instrument)", + "piano": "Klavir", + "electric_piano": "Električni klavir", + "organ": "Orgulje", + "electronic_organ": "Elektroničke orgulje", + "hammond_organ": "Hammond orgulje", + "synthesizer": "Sintesajzer", + "sampler": "Sampler (Instrument)", + "harpsichord": "Čembalo", + "percussion": "Udaraljke", + "drum_kit": "Bubnjarski set", + "drum_machine": "Bubnjarski stroj", + "drum": "Bubanj", + "snare_drum": "Doboš", + "rimshot": "Rimshot (udaranje po rubu bubnja)", + "drum_roll": "Bubnjarski uvod", + "bass_drum": "Bas bubanj", + "timpani": "Timpani bubnjevi", + "tabla": "Tabla", + "cymbal": "Činela", + "hi_hat": "Hi-Hat bubanj", + "wood_block": "Drveni blok", + "tambourine": "Tamburin", + "maraca": "Maraca (Instrument)", + "gong": "Gong (Instrument)", + "tubular_bells": "Tubular Bells (Instrument)", + "mallet_percussion": "Mallet udaraljke", + "marimba": "Marimba (Instrument)", + "glockenspiel": "Glockenspiel (Instrument)", + "vibraphone": "Vibrafon", + "steelpan": "Steelpan (Instrument)", + "orchestra": "Orkestar", + "brass_instrument": "Limeni instrumenti", + "french_horn": "Francuski rog", + "trumpet": "Truba", + "trombone": "Trombon", + "bowed_string_instrument": "Gudački žičani instrument", + "string_section": "Gudačka sekcija", + "violin": "Violina", + "pizzicato": "Pizzicato (Instrument)", + "cello": "Violončelo", + "double_bass": "Kontrabas", + "wind_instrument": "Puhački instrument", + "flute": "Flauta", + "saxophone": "Saksofon", + "clarinet": "Klarinet", + "harp": "Harfa", + "bell": "Zvono", + "church_bell": "Crkveno zvono", + "jingle_bell": "Zvončić", + "bicycle_bell": "Biciklističko zvono", + "tuning_fork": "Vilica za ugađanje", + "chime": "Zvono", + "wind_chime": "Zvono na vjetru", + "harmonica": "Usna harmonika", + "accordion": "Harmonika", + "bagpipes": "Gajde", + "didgeridoo": "Didgeridoo (Instrument)", + "theremin": "Theremin (Instrument)", + "singing_bowl": "Pjevajuća zdjela", + "scratching": "Grebanje", + "pop_music": "Pop glazba", + "hip_hop_music": "Hip-hop glazba", + "beatboxing": "Beatbox", + "rock_music": "Rock glazba", + "heavy_metal": "Heavy Metal (žanr rock glazbe)", + "punk_rock": "Punk Rock (žanr glazbe)", + "grunge": "Grunge (žanr glazbe)", + "progressive_rock": "Progresivni rock", + "rock_and_roll": "Rock and Roll (žanr glazbe)", + "psychedelic_rock": "Psihodelični rock", + "rhythm_and_blues": "Rhythm and Blues (žanr glazbe)", + "soul_music": "Soul glazba", + "reggae": "Reggae (žanr glazbe)", + "country": "Zemlja", + "swing_music": "Swing glazba", + "bluegrass": "Bluegrass (žanr glazbe)", + "funk": "Funk (žanr glazbe)", + "folk_music": "Narodna glazba", + "middle_eastern_music": "Bliskoistočna glazba", + "jazz": "Jazz (žanr glazbe)", + "disco": "Disco (žanr glazbe)", + "classical_music": "Klasična glazba", + "opera": "Opera", + "electronic_music": "Elektronička glazba", + "house_music": "House glazba", + "techno": "Techno (žanr glazbe)", + "dubstep": "Dubstep (žanr glazbe)", + "drum_and_bass": "Drum and Bass (žanr glazbe)", + "electronica": "Elektronika", + "electronic_dance_music": "Elektronička plesna glazba", + "ambient_music": "Ambijentalna glazba", + "trance_music": "Trance glazba", + "music_of_latin_america": "Glazba Latinske Amerike", + "salsa_music": "Salsa glazba", + "flamenco": "Flamenco (žanr glazbe)", + "blues": "Blues (žanr glazbe)", + "music_for_children": "Glazba za djecu", + "new-age_music": "New Age glazba", + "vocal_music": "Vokalna glazba", + "a_capella": "A Capella (Izvedba glazbe bez instrumenata)", + "music_of_africa": "Glazba Afrike", + "afrobeat": "Afrobeat (žanr glazbe)", + "christian_music": "Kršćanska glazba", + "gospel_music": "Gospel glazba", + "music_of_asia": "Glazba Azije", + "carnatic_music": "Karnatska glazba", + "music_of_bollywood": "Glazba Bollywooda", + "ska": "Ska (žanr glazbe)", + "traditional_music": "Tradicionalna glazba", + "independent_music": "Nezavisna glazba", + "song": "Pjesma", + "background_music": "Pozadinska glazba", + "theme_music": "Tematska glazba", + "jingle": "Jingle", + "soundtrack_music": "Glazba za glazbu", + "lullaby": "Uspavanka", + "video_game_music": "Glazba iz videoigara", + "christmas_music": "Božićna glazba", + "dance_music": "Plesna glazba", + "wedding_music": "Svadbena glazba", + "happy_music": "Sretna glazba", + "sad_music": "Tužna glazba", + "tender_music": "Nježna glazba", + "exciting_music": "Uzbudljiva glazba", + "angry_music": "Ljutita glazba", + "scary_music": "Strašna glazba", + "wind": "Vjetar", + "rustling_leaves": "Šuštanje lišća", + "wind_noise": "Buka vjetra", + "thunderstorm": "Grmljavinska oluja", + "thunder": "Grmljavina", + "water": "Voda", + "rain": "Kiša", + "raindrop": "Kap kiše", + "rain_on_surface": "Kiša na površini", + "stream": "Potok", + "waterfall": "Vodopad", + "ocean": "Ocean", + "waves": "Valovi", + "steam": "Parni vlakovi", + "gurgling": "Grgljanje", + "fire": "Požar", + "crackle": "Pucketanje", + "sailboat": "Jedrilica", + "rowboat": "Čamac na vesla", + "motorboat": "Motorni čamac", + "ship": "Brod", + "motor_vehicle": "Motorna vozila", + "toot": "Tut", + "car_alarm": "Automobilski alarm", + "power_windows": "Električni prozori", + "skidding": "Klizanje", + "tire_squeal": "Škripa guma", + "car_passing_by": "Prolazak automobila", + "race_car": "Trkaći automobil", + "truck": "Kamion", + "air_brake": "Zračna kočnica", + "air_horn": "Zračni rog", + "reversing_beeps": "Zvuk unatrag", + "ice_cream_truck": "Kamion za sladoled", + "emergency_vehicle": "Vozilo hitne pomoći", + "police_car": "Policijski automobil", + "ambulance": "Hitna pomoć", + "fire_engine": "Vatrogasno vozilo", + "traffic_noise": "Buka prometa", + "rail_transport": "Željeznički promet", + "train_whistle": "Zviždaljka vlaka", + "train_horn": "Sirena vlaka", + "railroad_car": "Željeznički vagon", + "train_wheels_squealing": "Škripa kotača vlaka", + "subway": "Podzemna željeznica", + "aircraft": "Zrakoplovi", + "aircraft_engine": "Zrakoplovni motor", + "jet_engine": "Mlazni motor", + "propeller": "Propeler", + "helicopter": "Helikopter", + "fixed-wing_aircraft": "Zrakoplovi s fiksnim krilima", + "engine": "Motor", + "light_engine": "Laka lokomotiva", + "dental_drill's_drill": "Dentalna bušilica", + "lawn_mower": "Kosilica za travu", + "chainsaw": "Motorna pila", + "medium_engine": "Srednji motor", + "heavy_engine": "Teški motor", + "engine_knocking": "Kucanje motora", + "engine_starting": "Pokretanje motora", + "idling": "Rad u praznom hodu", + "accelerating": "Ubrzavanje", + "doorbell": "Zvono na vratima", + "ding-dong": "Ding-Dong", + "sliding_door": "Klizna vrata", + "slam": "Slam (žanr glazbe)", + "knock": "Kuc", + "tap": "Tap", + "squeak": "Cvrkut", + "cupboard_open_or_close": "Otvaranje ili zatvaranje ormara", + "drawer_open_or_close": "Otvaranje ili zatvaranje ladice", + "dishes": "Jela", + "cutlery": "Pribor za jelo", + "chopping": "Sjeckanje", + "frying": "Prženje", + "microwave_oven": "Mikrovalna pećnica", + "water_tap": "Vodovodna slavina", + "bathtub": "Kada", + "toilet_flush": "Ispiranje WC-a", + "electric_toothbrush": "Električna četkica za zube", + "vacuum_cleaner": "Usisavač", + "zipper": "Patentni zatvarač", + "keys_jangling": "Zvuk ključeva", + "coin": "Novčić", + "electric_shaver": "Električni brijač", + "shuffling_cards": "Miješanje karata", + "typing": "Tipkanje", + "typewriter": "Pisaća mašina", + "computer_keyboard": "Računalna tipkovnica", + "writing": "Pisanje", + "alarm": "Alarm", + "telephone": "Telefon", + "telephone_bell_ringing": "Zvono telefona zvoni", + "ringtone": "Melodija zvona", + "telephone_dialing": "Telefonsko biranje", + "dial_tone": "Ton biranja", + "busy_signal": "Zauzeti signal", + "alarm_clock": "Budilica", + "siren": "Sirena", + "civil_defense_siren": "Sirena civilne zaštite", + "buzzer": "Buzzer (Uređaj)", + "smoke_detector": "Detektor dima", + "fire_alarm": "Protupožarni alarm", + "foghorn": "Maglenka", + "whistle": "Zviždaljka", + "steam_whistle": "Parna zviždaljka", + "mechanisms": "Mehanizmi", + "ratchet": "Zupčanik sa zaporom (ratchet)", + "tick": "Tik", + "tick-tock": "Tik-tak", + "gears": "Zupčanici", + "pulleys": "Koloture", + "sewing_machine": "Šivaći stroj", + "mechanical_fan": "Mehanički ventilator", + "air_conditioning": "Klima uređaj", + "cash_register": "Blagajna", + "printer": "Pisač", + "single-lens_reflex_camera": "Jednooki refleksni fotoaparat", + "tools": "Alati", + "hammer": "Čekić", + "jackhammer": "Pneumatski čekić", + "sawing": "Piljenje", + "filing": "Podnošenje", + "sanding": "Brušenje", + "power_tool": "Električni alat", + "drill": "Vježba", + "explosion": "Eksplozija", + "gunshot": "Pucanj", + "machine_gun": "Mitraljez", + "fusillade": "Pucnjava", + "artillery_fire": "Topnička paljba", + "cap_gun": "Cap Gun", + "fireworks": "Vatromet", + "firecracker": "Petarda", + "burst": "Prasak", + "eruption": "Erupcija", + "boom": "Bum", + "wood": "Drvo", + "chop": "Brzo.", + "splinter": "Rascijepanje", + "crack": "Pukotina", + "glass": "Staklo", + "chink": "Kinez", + "shatter": "Razbijanje", + "silence": "Tišina", + "sound_effect": "Zvučni efekt", + "environmental_noise": "Okolišna buka", + "static": "Statički", + "white_noise": "Bijeli šum", + "pink_noise": "Ružičasti šum", + "television": "Televizija", + "radio": "Radio", + "field_recording": "Terensko snimanje", + "scream": "Vrisak", + "sodeling": "Sodeling", + "chird": "Chird", + "change_ringing": "Trčanje zvona", + "shofar": "Šofar", + "liquid": "Tekućina", + "splash": "Pljusak", + "slosh": "Pljusak", + "squish": "Zgnječenje", + "drip": "Kapanje", + "pour": "Usipanje", + "trickle": "Kapljanje", + "gush": "Brzo izlijevanje", + "fill": "Napuni", + "spray": "Prskanje", + "pump": "Pumpa", + "stir": "Miješaj", + "boiling": "Kuhanje", + "sonar": "Sonar", + "arrow": "Strijela", + "whoosh": "Whoosh", + "thump": "Tup", + "thunk": "Tup", + "electronic_tuner": "Elektronički tuner", + "effects_unit": "Jedinica za efekte", + "chorus_effect": "Efekt zbora", + "basketball_bounce": "Košarkaški odskok", + "bang": "Bam", + "slap": "Pljusak", + "whack": "Udarac", + "smash": "Slamanje", + "breaking": "Razbijanje", + "bouncing": "Skakanje", + "whip": "Bič", + "flap": "Flop", + "scratch": "Grebanje", + "scrape": "Struganje", + "rub": "Trljanje", + "roll": "Rolanje", + "crushing": "Drobljenje", + "crumpling": "Gužvanje", + "tearing": "Razdiruća", + "beep": "Bip", + "ping": "Ping", + "ding": "Ding", + "clang": "Klang", + "squeal": "Cviljenje", + "creak": "Škripa", + "rustle": "Šuštanje", + "whir": "Šuštanje", + "clatter": "Zveket", + "sizzle": "Crvčanje", + "clicking": "Klikovi", + "clickety_clack": "Klikety klak", + "rumble": "Tutnjanje", + "plop": "Plop", + "hum": "Šum", + "zing": "Cing", + "boing": "Boing", + "crunch": "Krckanje", + "sine_wave": "Sinusni val", + "harmonic": "Harmonik", + "chirp_tone": "Ton cvrkuta", + "pulse": "Puls", + "inside": "Unutra", + "outside": "Izvana", + "reverberation": "Reverberacija", + "echo": "Jeka", + "noise": "Buka", + "mains_hum": "Zujanje glavnih zvučnika", + "distortion": "Izobličenje", + "sidetone": "Bočni Ton", + "cacophony": "Kakofonija", + "throbbing": "Pulsirajuća", + "vibration": "Vibracija" } diff --git a/web/public/locales/hr/common.json b/web/public/locales/hr/common.json index 1e60764bd..1b080afe1 100644 --- a/web/public/locales/hr/common.json +++ b/web/public/locales/hr/common.json @@ -20,6 +20,286 @@ "12hours": "12 sati", "24hours": "24 sata", "pm": "pm", - "am": "am" + "am": "am", + "ago": "prije {{timeAgo}}", + "yr": "{{time}}g.", + "year_one": "{{time}} godina", + "year_few": "{{time}} godine", + "year_other": "{{time}} godina", + "mo": "{{time}}mj.", + "month_one": "{{time}} mjesec", + "month_few": "{{time}} mjeseca", + "month_other": "{{time}} mjeseci", + "day_one": "{{time}} dan", + "day_few": "{{time}} dana", + "day_other": "{{time}} dana", + "h": "{{time}}h", + "hour_one": "{{time}} sat", + "hour_few": "{{time}} sata", + "hour_other": "{{time}} sati", + "minute_one": "{{time}} minuta", + "minute_few": "{{time}} minute", + "minute_other": "{{time}} minuta", + "second_one": "{{time}} sekunda", + "second_few": "{{time}} sekunde", + "second_other": "{{time}} sekundi", + "d": "{{time}}d", + "m": "{{time}}m", + "s": "{{time}}s", + "formattedTimestamp": { + "12hour": "d. MMM, h:mm:ss aaa", + "24hour": "d. MMM, HH:mm:ss" + }, + "formattedTimestamp2": { + "12hour": "dd/MM h:mm:ssa", + "24hour": "d MMM HH:mm:ss" + }, + "formattedTimestampHourMinute": { + "12hour": "h:mm aaa", + "24hour": "HH:mm" + }, + "formattedTimestampHourMinuteSecond": { + "12hour": "h:mm:ss aaa", + "24hour": "HH:mm:ss" + }, + "formattedTimestampMonthDayHourMinute": { + "12hour": "d MMM, h:mm aaa", + "24hour": "d. MMM, HH:mm" + }, + "formattedTimestampMonthDayYear": { + "12hour": "d. MMM, yyyy", + "24hour": "d. MMM, yyyy" + }, + "formattedTimestampMonthDayYearHourMinute": { + "12hour": "d. MMM yyyy, h:mm aaa", + "24hour": "d. MMM yyyy, HH:mm" + }, + "formattedTimestampMonthDay": "d. MMM", + "formattedTimestampFilename": { + "12hour": "dd-MM-yy-h-mm-ss-a", + "24hour": "dd-MM-yy-HH-mm-ss" + }, + "inProgress": "U tijeku", + "invalidStartTime": "Nevažeće vrijeme početka", + "invalidEndTime": "Nevažeće vrijeme završetka" + }, + "menu": { + "live": { + "cameras": { + "count_one": "{{count}} kamera", + "count_few": "{{count}} kamere", + "count_other": "{{count}} kamera", + "title": "Kamere" + }, + "title": "Uživo", + "allCameras": "Sve Kamere" + }, + "system": "Sustav", + "systemMetrics": "Metrike sustava", + "configuration": "Konfiguracija", + "systemLogs": "Zapisnici sustava", + "settings": "Postavke", + "configurationEditor": "Uređivač konfiguracije", + "languages": "Jezici", + "language": { + "en": "Engleski", + "es": "Španjolski", + "zhCN": "简体中文 (Pojednostavljeni Kineski)", + "hi": "हिन्दी (Hindi)", + "fr": "Francuski", + "ar": "العربية (Arapski)", + "pt": "Portugalski", + "ptBR": "Brazilski Portugalski", + "ru": "Ruski", + "de": "Njemački", + "ja": "Japanski", + "tr": "Turski", + "it": "Talijanski", + "nl": "Nizozemski", + "sv": "Švedski", + "cs": "Češki", + "nb": "Norveški bokmål", + "ko": "Korejski", + "vi": "Vietnamski", + "fa": "Perzijski", + "pl": "Poljski", + "uk": "Ukrajinski", + "he": "Hebrejski", + "el": "Grčki", + "ro": "Rumunjski", + "hu": "Mađarski", + "fi": "Finski", + "da": "Danski", + "sk": "Slovački", + "yue": "Kantonščina", + "th": "Tajski", + "ca": "Katalonski", + "sr": "Srpski", + "sl": "Slovenski", + "lt": "Litvanski", + "bg": "Bulgarski", + "gl": "Galicijski", + "id": "Indonezijski", + "ur": "Urdu", + "withSystem": { + "label": "Koristi postavke sustava za jezik" + } + }, + "appearance": "Izgled", + "darkMode": { + "label": "Tamni način", + "light": "Svijetla", + "dark": "Tamna", + "withSystem": { + "label": "Koristi postavke sustava za svijetli ili tamni način rada" + } + }, + "withSystem": "Sustav", + "theme": { + "label": "Tema", + "blue": "Plava", + "green": "Zelena", + "nord": "Nord", + "red": "Crvena", + "highcontrast": "Visoki Kontrast", + "default": "Zadana" + }, + "help": "Pomoć", + "documentation": { + "title": "Dokumentacija", + "label": "Frigate dokumentacija" + }, + "restart": "Ponovno pokreni Frigate", + "review": "Pregled", + "explore": "Istraži", + "export": "Izvezi", + "uiPlayground": "Igralište korisničkog sučelja", + "faceLibrary": "Biblioteka Lica", + "classification": "Klasifikacija", + "user": { + "title": "Korisnik", + "account": "Račun", + "current": "Trenutni Korisnik: {{user}}", + "anonymous": "anonimno", + "logout": "Odjava", + "setPassword": "Postavi Lozinku" + } + }, + "button": { + "save": "Spremi", + "apply": "Primjeni", + "reset": "Resetiraj", + "done": "Gotovo", + "enabled": "Omogućeno", + "enable": "Omogući", + "disabled": "Onemogućeno", + "disable": "Onemogući", + "saving": "Spremanje…", + "cancel": "Odustani", + "close": "Zatvori", + "copy": "Kopiraj", + "back": "Nazad", + "history": "Povijest", + "fullscreen": "Cijeli zaslon", + "exitFullscreen": "Izađi iz cijelog zaslona", + "pictureInPicture": "Slika u Slici", + "twoWayTalk": "Dvosmjerni razgovor", + "cameraAudio": "Kamera Zvuk", + "on": "UKLJUČENO", + "off": "ISKLJUČENO", + "edit": "Uredi", + "copyCoordinates": "Kopiraj koordinate", + "delete": "Izbriši", + "yes": "Da", + "no": "Ne", + "download": "Preuzmi", + "info": "Informacije", + "suspended": "Obustavljeno", + "unsuspended": "Ponovno aktiviraj", + "play": "Reproduciraj", + "unselect": "Odznači", + "export": "Izvezi", + "deleteNow": "Izbriši Sada", + "next": "Sljedeće", + "continue": "Nastavi" + }, + "unit": { + "speed": { + "mph": "mph", + "kph": "km/h" + }, + "length": { + "feet": "stopa", + "meters": "metri" + }, + "data": { + "kbps": "kB/s", + "mbps": "MB/s", + "gbps": "GB/s", + "kbph": "kB/sat", + "mbph": "MB/sat", + "gbph": "GB/sat" + } + }, + "label": { + "back": "Idi nazad", + "hide": "Sakrij {{item}}", + "show": "Prikaži {{item}}", + "ID": "ID", + "none": "Nema", + "all": "Sve", + "other": "Druge" + }, + "list": { + "two": "{{0}} i {{1}}", + "many": "{{items}} i {{last}}", + "separatorWithSpace": ", " + }, + "field": { + "optional": "Opcionalno", + "internalID": "Interni ID koji Frigate koristi u konfiguraciji i bazi podataka" + }, + "toast": { + "copyUrlToClipboard": "Kopiran URL u međuspremnik.", + "save": { + "title": "Spremi", + "error": { + "title": "Neuspješno spremanje promjena konfiguracije: {{errorMessage}}", + "noMessage": "Neuspješno spremanje promjena konfiguracije" + } + } + }, + "role": { + "title": "Uloge", + "admin": "Administrator", + "viewer": "Gledatelj", + "desc": "Administratori imaju potpuni pristup svim značajkama u Frigate korisnickom sučelju. Gledatelji su ograničeni na pregled kamera, pregled stavki i povijesnog snimka u korisničkom sučelju." + }, + "pagination": { + "label": "paginacija", + "previous": { + "title": "Prethodno", + "label": "Idi na prethodnu stranicu" + }, + "next": { + "title": "Sljedeće", + "label": "Idi na sljedeću stranicu" + }, + "more": "Više stranica" + }, + "accessDenied": { + "documentTitle": "Pristup Odbijen - Frigate", + "title": "Pristup Odbijen", + "desc": "Nemaš dopuštenje za pregled ove stranice." + }, + "notFound": { + "documentTitle": "Nije Nađeno - Frigate", + "title": "404", + "desc": "Stranica nije pronađena" + }, + "selectItem": "Odaberi {{item}}", + "readTheDocumentation": "Čitaj dokumentaciju", + "information": { + "pixels": "{{area}}px" } } diff --git a/web/public/locales/hr/components/auth.json b/web/public/locales/hr/components/auth.json index 110ad2c64..74a83d2a4 100644 --- a/web/public/locales/hr/components/auth.json +++ b/web/public/locales/hr/components/auth.json @@ -8,7 +8,9 @@ "passwordRequired": "Lozinka je obavezna", "loginFailed": "Prijava nije uspjela", "unknownError": "Nepoznata greška. Provjeri dnevnik.", - "webUnknownError": "Nepoznata greška. Provjerite logove u konzoli." - } + "webUnknownError": "Nepoznata greška. Provjerite logove u konzoli.", + "rateLimit": "Prekoračeno ograničenje. Pokušaj opet kasnije." + }, + "firstTimeLogin": "Prokušavaš se prijaviti prvi put? Vjerodajnice su ispisane u Frigate logovima." } } diff --git a/web/public/locales/hr/components/camera.json b/web/public/locales/hr/components/camera.json index 271949a85..c973fa3f2 100644 --- a/web/public/locales/hr/components/camera.json +++ b/web/public/locales/hr/components/camera.json @@ -33,8 +33,54 @@ "title": "{{cameraName}} Streaming Postavke", "desc": "Promijenite opcije streamanja uživo za nadzornu ploču ove grupe kamera. Ove postavke su specifične za uređaj/preglednik.", "audioIsAvailable": "Za ovaj prijenos dostupan je zvuk", - "audioIsUnavailable": "Za ovaj prijenos zvuk nije dostupan" + "audioIsUnavailable": "Za ovaj prijenos zvuk nije dostupan", + "audio": { + "tips": { + "title": "Audio mora dolaziti s vaše kamere i biti konfiguriran u go2rtc za ovaj prijenos." + } + }, + "stream": "Prijenos", + "placeholder": "Izaberi prijenos", + "streamMethod": { + "label": "Metoda Prijenosa", + "placeholder": "Odaberi metodu prijenosa", + "method": { + "noStreaming": { + "label": "Nema Prijenosa", + "desc": "Slike s kamere bit će ažurirane samo jednom u minuti, a prijenos uživo neće biti dostupan." + }, + "smartStreaming": { + "desc": "Pametno emitiranje ažurirat će sliku vaše kamere jednom u minuti kada nema prepoznatljive aktivnosti kako bi uštedjelo propusnost i resurse. Kada se detektira aktivnost, slika će se besprijekorno prebaciti na prijenos uživo.", + "label": "Pametno Emitiranje (preporučeno)" + }, + "continuousStreaming": { + "label": "Kontinuirano Emitiranje", + "desc": { + "title": "Slika kamere uvijek će biti prijenos uživo kada je vidljiva na nadzornoj ploči, čak i ako nije detektirana nikakva aktivnost.", + "warning": "Neprekidno emitiranje može uzrokovati visok unos propusnosti i probleme s izvedbom. Koristite s oprezom." + } + } + } + }, + "compatibilityMode": { + "label": "Način kompatibilnosti", + "desc": "Omogućite ovu opciju samo ako vaš prijenos uživo s kamere prikazuje artefakte boje i ima dijagonalnu liniju na desnoj strani slike." + } } } + }, + "debug": { + "options": { + "label": "Postavke", + "title": "Opcije", + "showOptions": "Pokaži Opcije", + "hideOptions": "Sakrij Opcije" + }, + "boundingBox": "Granični okvir", + "timestamp": "Vremenska oznaka", + "zones": "Zone", + "mask": "Maska", + "motion": "Kretnja", + "regions": "Regije" } } diff --git a/web/public/locales/hr/components/dialog.json b/web/public/locales/hr/components/dialog.json index 2f360e1d6..42030519d 100644 --- a/web/public/locales/hr/components/dialog.json +++ b/web/public/locales/hr/components/dialog.json @@ -11,7 +11,8 @@ "explore": { "plus": { "submitToPlus": { - "label": "Pošalji u Frigate+" + "label": "Pošalji u Frigate+", + "desc": "Objekti u lokacijama koje želiš izbjeći nisu lažno pozitivni. Slanjem njih kao lažno pozitivnih će zbuniti model." }, "review": { "question": { @@ -41,7 +42,82 @@ "end": { "title": "Vrijeme kraja", "label": "Odaberi vrijeme kraja" + }, + "fromTimeline": "Izaberi sa vremenske crte", + "custom": "Prilagođeno" + }, + "name": { + "placeholder": "Imenuj Izvoz" + }, + "select": "Odaberi", + "export": "Izvoz", + "selectOrExport": "Odaberi ili Izvezi", + "toast": { + "success": "Izvoz je uspješno pokrenut. Datoteku možete pregledati na stranici za izvoz.", + "view": "Prikaz", + "error": { + "failed": "Nije uspjelo pokretanje izvoza: {{error}}", + "endTimeMustAfterStartTime": "Vrijeme završetka mora biti nakon vremena početka", + "noVaildTimeSelected": "Nema odabranog valjanog vremenskog raspona" + } + }, + "fromTimeline": { + "saveExport": "Spremi Izvoz", + "previewExport": "Pregledaj Izvoz" + } + }, + "streaming": { + "label": "Emitiraj", + "restreaming": { + "disabled": "Ponovno emitiranje nije omogućeno za ovu kameru.", + "desc": { + "title": "Postavi go2rtc za opcije dodatnog prikaza uživo i zvuk za ovu kameru." + } + }, + "showStats": { + "label": "Pokaži statistike emitiranja", + "desc": "Omogući ovu opciju za prikaz statistike emitiranja kao proziran prozor na slici kamere." + }, + "debugView": "Debug Prikaz" + }, + "search": { + "saveSearch": { + "label": "Spremi Pretragu", + "desc": "Dodaj ime za ovu spremljenu pretragu.", + "placeholder": "Unesi ime za svoju pretragu", + "overwrite": "{{searchName}} već postoji. Spremanje će prepisati postojeću vrijednost.", + "success": "Pretraga ({{searchName}}) je spremljena.", + "button": { + "save": { + "label": "Spremi ovu pretragu" + } } } + }, + "recording": { + "confirmDelete": { + "title": "Potvrdi Brisanje", + "desc": { + "selected": "Jeste li sigurni da želite izbrisati sav snimljen video povezan s ovom preglednom stavkom?

    DržiShift tipku za zaobilaženje ove poruke u budućnosti." + }, + "toast": { + "success": "Video snimke povezane s odabranim preglednim stavkama su uspješno izbrisane.", + "error": "Neuspješno brisanje: {{error}}" + } + }, + "button": { + "export": "Izvezi", + "markAsReviewed": "Označi kao pregledano", + "markAsUnreviewed": "Označi kao nepregledano", + "deleteNow": "Izbriši sada" + } + }, + "imagePicker": { + "selectImage": "Odaberi sličicu praćenog objekta", + "unknownLabel": "Spremljena Slika Okinuća", + "search": { + "placeholder": "Traži prema oznaci ili podoznaci..." + }, + "noImages": "Sličica nisu nađene za ovu kameru" } } diff --git a/web/public/locales/hr/components/filter.json b/web/public/locales/hr/components/filter.json index d50119743..deac5b18b 100644 --- a/web/public/locales/hr/components/filter.json +++ b/web/public/locales/hr/components/filter.json @@ -1,7 +1,12 @@ { "filter": "Filter", "classes": { - "label": "Klase" + "label": "Klase", + "all": { + "title": "Sve klase" + }, + "count_one": "{{count}} Klasa", + "count_other": "{{count}} Klase" }, "labels": { "label": "Oznake", @@ -26,5 +31,110 @@ "short": "Datumi" } }, - "more": "Više filtera" + "more": "Više filtera", + "reset": { + "label": "Ponovno postavi filtere na zadane vrijednosti" + }, + "timeRange": "Vremenski Raspon", + "subLabels": { + "label": "Podoznake", + "all": "Sve Podoznake" + }, + "attributes": { + "label": "Klasifikacijski Atributi", + "all": "Svi Atributi" + }, + "score": "Rezultat", + "estimatedSpeed": "Procijenjena Brzina ({{unit}})", + "features": { + "label": "Značajke", + "hasSnapshot": "Ima snimku", + "hasVideoClip": "Ima video isječak", + "submittedToFrigatePlus": { + "label": "Poslano na Frigate+", + "tips": "Prvo moraš filtrirati praćene objekte koji imaju snimku stanja.

    Praćeni objekti bez snimke stanja ne mogu se poslati Frigate+." + } + }, + "sort": { + "label": "Poredaj", + "dateAsc": "Datum (Uzlazno)", + "dateDesc": "Datum (Silazno)", + "scoreAsc": "Ocjena Objekta (Uzlazno)", + "scoreDesc": "Ocjena objekta (uzlazno)", + "speedAsc": "Procijenjena Brzina (Uzlazno)", + "speedDesc": "Procijenjena Brzina (Silazno)", + "relevance": "Značajnost" + }, + "cameras": { + "label": "Filter Kamera", + "all": { + "title": "Sve Kamere", + "short": "Kamere" + } + }, + "review": { + "showReviewed": "Prikaži Pregledano" + }, + "motion": { + "showMotionOnly": "Prikaži Jedino Pokrete" + }, + "explore": { + "settings": { + "title": "Postavke", + "defaultView": { + "title": "Zadani Prikaz", + "summary": "Sažetak", + "unfilteredGrid": "Nefiltrirana mreža", + "desc": "Kada filteri nisu odabrani, prikazan je sažetak najnovijih objekata po oznaci, ili je prikazana nefiltrirana mreža." + }, + "gridColumns": { + "title": "Stupci Mreže", + "desc": "Odaberi broj stupaca u mrežnom prikazu." + }, + "searchSource": { + "label": "Traži Izvor", + "desc": "Odaberi želiš li tražiti sličice ili opise tvojih praćenih objekata.", + "options": { + "thumbnailImage": "Sličica", + "description": "Opis" + } + } + }, + "date": { + "selectDateBy": { + "label": "Odaberi datum za filtriranje" + } + } + }, + "logSettings": { + "label": "Filtriraj stupanj zapisnika", + "filterBySeverity": "Filtriraj zapisnike po ozbiljnosti", + "loading": { + "title": "Učitavanje", + "desc": "Kada je prozor zapisnika listan do dna, novi zapisi se prikazuju automatski nakon stvaranja." + }, + "disableLogStreaming": "Onemogući prijenos zapisa uživo", + "allLogs": "Svi zapisi" + }, + "trackedObjectDelete": { + "title": "Potvrdi Brisanje", + "desc": "Brisanjem ovih praćenih objekata ({{objectLength}}) uklanja se snimak, svi spremljeni ugradbeni elementi i svi povezani unosi životnog ciklusa objekta. Snimljeni materijali ovih praćenih objekata u prikazu povijesti NEĆE biti izbrisani.

    Jeste li sigurni da želite nastaviti?

    Držite tipku Shift da biste u budućnosti zaobišli ovaj dijalog.", + "toast": { + "success": "Praćeni objekti su uspješno izbrisani.", + "error": "Neuspješno brisanje praćenih objekata: {{errorMessage}}" + } + }, + "zoneMask": { + "filterBy": "Filtritaj prema maski zone" + }, + "recognizedLicensePlates": { + "title": "Prepoznate Registracijske Oznake", + "loadFailed": "Neuspješno učitavanje prepoznatih registracijskih oznaka.", + "loading": "Učitavanje prepoznatih registracijskih oznaka…", + "placeholder": "Upiši za traženje registracijskih oznaka…", + "noLicensePlatesFound": "Registracijske oznake nisu nađene.", + "selectPlatesFromList": "Odaberi jednu ili više registracijskih oznaka iz liste.", + "selectAll": "Odaberi sve", + "clearAll": "Očisti sve" + } } diff --git a/web/public/locales/hr/components/player.json b/web/public/locales/hr/components/player.json index f32271904..67a1d91a0 100644 --- a/web/public/locales/hr/components/player.json +++ b/web/public/locales/hr/components/player.json @@ -7,13 +7,45 @@ "cameraDisabled": "Kamera je onemogućena", "stats": { "streamType": { - "short": "Vrsta" + "short": "Vrsta", + "title": "Tip Streama:" }, "latency": { "value": "{{seconds}} sekundi", "short": { - "value": "{{seconds}} sekundi" + "value": "{{seconds}} sekundi", + "title": "Kašnjenje" + }, + "title": "Kašnjenje:" + }, + "bandwidth": { + "title": "Mrežna propusnost:", + "short": "Mrežna propusnost" + }, + "totalFrames": "Ukupni broj kadrova (slika):", + "droppedFrames": { + "title": "Izgubljeni kadrovi:", + "short": { + "title": "Izgubljeno", + "value": "{{droppedFrames}} kadrova" } + }, + "decodedFrames": "Dekodirani kadrovi:", + "droppedFrameRate": "Stopa izgubljenih kadrova:" + }, + "noPreviewFound": "Nije nađen pretpregled", + "noPreviewFoundFor": "Pretpregled nije nađen za {{cameraName}}", + "livePlayerRequiredIOSVersion": "iOS 17.1 ili noviji je potreban za ovu vrstu uživog prijenosa.", + "streamOffline": { + "title": "Stream nije dostupan", + "desc": "Slike nisu primljene sa {{cameraName}} detect stream-a, provjeri logove" + }, + "toast": { + "success": { + "submittedFrigatePlus": "Kadar je uspješno poslan u Frigate+" + }, + "error": { + "submitFrigatePlusFailed": "Neuspješno slanje kadra u Frigate+" } } } diff --git a/web/public/locales/hr/objects.json b/web/public/locales/hr/objects.json index 1a9a74392..955ebe0cd 100644 --- a/web/public/locales/hr/objects.json +++ b/web/public/locales/hr/objects.json @@ -6,16 +6,115 @@ "airplane": "Zrakoplov", "bus": "Autobus", "train": "Vlak", - "boat": "Čamac", + "boat": "ÄŒamac", "traffic_light": "Semafor", "fire_hydrant": "Hidrant", "street_sign": "Prometni znak", "stop_sign": "Znak stop", "bench": "Klupa", "bird": "Ptica", - "cat": "Mačka", + "cat": "Mačka", "dog": "Pas", "horse": "Konj", "sheep": "Ovca", - "cow": "Krava" + "cow": "Krava", + "parking_meter": "Parkirni Automat", + "elephant": "Slon", + "bear": "Medvjed", + "zebra": "Zebra", + "giraffe": "Žirafa", + "hat": "Kapa", + "backpack": "Ruksak", + "umbrella": "Kišobran", + "shoe": "Cipela", + "eye_glasses": "Naočale", + "handbag": "Ručna torba", + "tie": "Kravata", + "suitcase": "Kovčeg", + "frisbee": "Frizbi", + "skis": "Skije", + "snowboard": "Snowboard", + "sports_ball": "Sportska Lopta", + "kite": "Zmaj", + "baseball_bat": "Baseball Palica", + "baseball_glove": "Baseball Rukavica", + "skateboard": "Skejtboard", + "surfboard": "Daska za surfanje", + "tennis_racket": "Teniski reket", + "bottle": "Boca", + "plate": "Tanjur", + "wine_glass": "Vinska Čaša", + "cup": "Šalica", + "fork": "Vilica", + "knife": "Nož", + "spoon": "Žlica", + "bowl": "Zdjela", + "banana": "Banana", + "apple": "Jabuka", + "sandwich": "Sendvič", + "orange": "Naranča", + "broccoli": "Brokula", + "carrot": "Mrkva", + "hot_dog": "Hot Dog", + "pizza": "Pizza", + "donut": "Krafna", + "cake": "Torta", + "chair": "Stolica", + "couch": "Kauč", + "potted_plant": "Biljka u Loncu", + "bed": "Krevet", + "mirror": "Ogledalo", + "dining_table": "Blagovaonski Stol", + "window": "Prozor", + "desk": "Radni Stol", + "toilet": "WC", + "door": "Vrata", + "tv": "TV", + "laptop": "Laptop", + "mouse": "Miš", + "remote": "Daljinski", + "keyboard": "Tipkovnica", + "cell_phone": "Mobilni Telefon", + "microwave": "Mikrovalna", + "oven": "Pećnica", + "toaster": "Toster", + "sink": "Sudoper", + "refrigerator": "Frižider", + "blender": "Blender", + "book": "Knjiga", + "clock": "Sat", + "vase": "Vaza", + "scissors": "Škare", + "teddy_bear": "Plišani Medo", + "hair_dryer": "Fen", + "toothbrush": "Četkica za zube", + "hair_brush": "Četka za kosu", + "vehicle": "Vozilo", + "squirrel": "Vjeverica", + "deer": "Jelen", + "animal": "Životinja", + "bark": "Kora", + "fox": "Lisica", + "goat": "Koza", + "rabbit": "Zec", + "raccoon": "Rakun", + "robot_lawnmower": "Robotska Kosilica", + "waste_bin": "Kanta za smeće", + "on_demand": "Na Zahtjev", + "face": "Lice", + "license_plate": "Registracijska oznaka", + "package": "Paket", + "bbq_grill": "Roštilj", + "amazon": "Amazon", + "usps": "USPS", + "ups": "UPS", + "fedex": "FedEx", + "dhl": "DHL", + "an_post": "An Post", + "purolator": "Purolator", + "postnl": "PostNL", + "nzpost": "NZPost", + "postnord": "PostNord", + "gls": "GLS", + "dpd": "DPD" } diff --git a/web/public/locales/hr/views/classificationModel.json b/web/public/locales/hr/views/classificationModel.json index e3070af27..a588d5607 100644 --- a/web/public/locales/hr/views/classificationModel.json +++ b/web/public/locales/hr/views/classificationModel.json @@ -5,18 +5,68 @@ "trainModel": "Treniraj model", "addClassification": "Dodaj klasifikaciju", "deleteModels": "Obriši modele", - "editModel": "Uredi model" + "editModel": "Uredi model", + "deleteClassificationAttempts": "Izbriši Klasifikacijske Slike", + "renameCategory": "Preimenuj klasu", + "deleteCategory": "Izbriši Klasu" }, "tooltip": { "trainingInProgress": "Model se trenutno trenira", - "modelNotReady": "Model nije spreman za treniranje" + "modelNotReady": "Model nije spreman za treniranje", + "noNewImages": "Nema novih slika za treniranje. Prvo klasificirajte više slika u skupu podataka.", + "noChanges": "Nema promjena u skupu podataka od posljednjeg treniranja." }, "details": { - "unknown": "Nepoznato" + "unknown": "Nepoznato", + "none": "Nijedan", + "scoreInfo": "Rezultat predstavlja prosječnu klasifikacijsku pouzdanost kroz sve detekcije ovog objekta." }, "toast": { "success": { - "deletedImage": "Obrisane slike" + "deletedImage": "Obrisane slike", + "deletedCategory": "Izbrisana Klasa", + "deletedModel_one": "Uspješno izbrisan {{count}} model", + "deletedModel_few": "Uspješno izbrisana {{count}} modela", + "deletedModel_other": "Uspješno izbrisano {{count}} modela", + "categorizedImage": "Uspješno klasificirana slika", + "trainedModel": "Uspješno treniran model.", + "trainingModel": "Uspješno započeto treniranje modela.", + "updatedModel": "Uspješno ažurirana konfiguracija modela", + "renamedCategory": "Uspješno preimenovana klasa na {{name}}" + }, + "error": { + "deleteImageFailed": "Neuspješno brisanje: {{errorMessage}}", + "deleteCategoryFailed": "Neuspješno brisanje klase: {{errorMessage}}", + "deleteModelFailed": "Nije uspjelo brisanje modela: {{errorMessage}}", + "categorizeFailed": "Nije uspjelo kategoriziranje slike: {{errorMessage}}" + } + }, + "description": { + "invalidName": "Nevaljano ime. Ime može samo uključivati slova, brojeve, razmake, navodnike, podcrte i crtice." + }, + "train": { + "titleShort": "Nedavno" + }, + "deleteModel": { + "desc_one": "Jeste li sigurni da želite izbrisati {{count}} model? Ovo će trajno izbrisati sve povezane podatke, uključujući slike i podatke za treniranje. Ova radnja se ne može poništiti.", + "desc_few": "Jeste li sigurni da želite izbrisati {{count}} modela? Ovo će trajno izbrisati sve povezane podatke, uključujući slike i podatke za treniranje. Ova radnja se ne može poništiti.", + "desc_other": "Jeste li sigurni da želite izbrisati {{count}} modela? Ovo će trajno izbrisati sve povezane podatke, uključujući slike i podatke za treniranje. Ova radnja se ne može poništiti." + }, + "deleteDatasetImages": { + "desc_one": "Jeste li sigurni da želite izbrisati {{count}} sliku iz {{dataset}}? Ova radnja se ne može poništiti i zahtijevat će ponovno treniranje modela.", + "desc_few": "Jeste li sigurni da želite izbrisati {{count}} slike iz {{dataset}}? Ova radnja se ne može poništiti i zahtijevat će ponovno treniranje modela.", + "desc_other": "Jeste li sigurni da želite izbrisati {{count}} slika iz {{dataset}}? Ova radnja se ne može poništiti i zahtijevat će ponovno treniranje modela." + }, + "deleteTrainImages": { + "desc_one": "Jeste li sigurni da želite izbrisati {{count}} sliku? Ova radnja se ne može poništiti.", + "desc_few": "Jeste li sigurni da želite izbrisati {{count}} slike? Ova radnja se ne može poništiti.", + "desc_other": "Jeste li sigurni da želite izbrisati {{count}} slika? Ova radnja se ne može poništiti." + }, + "wizard": { + "step3": { + "allImagesRequired_one": "Molimo klasificirajte sve slike. Preostala je {{count}} slika.", + "allImagesRequired_few": "Molimo klasificirajte sve slike. Preostale su {{count}} slike.", + "allImagesRequired_other": "Molimo klasificirajte sve slike. Preostalo je {{count}} slika." } } } diff --git a/web/public/locales/hr/views/configEditor.json b/web/public/locales/hr/views/configEditor.json index fe4011ecc..1a5f2d23e 100644 --- a/web/public/locales/hr/views/configEditor.json +++ b/web/public/locales/hr/views/configEditor.json @@ -7,6 +7,12 @@ "toast": { "error": { "savingError": "Greška pri spremanju konfiguracije" + }, + "success": { + "copyToClipboard": "Konfiguracija je kopirana u međuspremnik." } - } + }, + "configEditor": "Uređivač konfiguracije", + "safeModeDescription": "Frigate je u sigurnom načinu zbog greške u validaciji konfiguracije.", + "safeConfigEditor": "Uređivač konfiguracije (Siguran Način)" } diff --git a/web/public/locales/hr/views/events.json b/web/public/locales/hr/views/events.json index 47c1530f2..3bafeee22 100644 --- a/web/public/locales/hr/views/events.json +++ b/web/public/locales/hr/views/events.json @@ -2,14 +2,18 @@ "alerts": "Upozorenja", "detections": "Detekcije", "motion": { - "label": "Pokret", - "only": "Samo pokret" + "label": "Kretnja", + "only": "Samo kretnje" }, "allCameras": "Sve kamere", "empty": { "alert": "Nema uzbuna za pregledati", "detection": "Nema detekcija za pregled", - "motion": "Nema podataka o pokretu" + "motion": "Nema podataka o pokretu", + "recordingsDisabled": { + "title": "Snimanja moraju biti uključena", + "description": "Stavke za pregled mogu biti stvorene za kameru jedino kada su snimanja uključena za tu kameru." + } }, "timeline": "Vremenska linija", "timeline.aria": "Odaberi vremensku liniju", @@ -21,6 +25,41 @@ }, "zoomIn": "Približi", "detail": { - "label": "Detalji" - } + "label": "Detalji", + "noDataFound": "Nema detaljnih podataka za pregled", + "aria": "Uključi/isključi prikaz detalja", + "trackedObject_one": "{{count}} objekt", + "trackedObject_other": "{{count}} objekta", + "noObjectDetailData": "Nema dostupnih detaljnih podataka o objektu.", + "settings": "Postavke detaljnog prikaza", + "alwaysExpandActive": { + "title": "Uvijek proširi aktivno", + "desc": "Uvijek proširite detalje objekta aktivnog pregledanog stavka kada su dostupni." + } + }, + "objectTrack": { + "trackedPoint": "Praćena točka", + "clickToSeek": "Kliknite za pomicanje na ovo vrijeme" + }, + "documentTitle": "Pregled - Frigate", + "recordings": { + "documentTitle": "Snimke - Frigate" + }, + "calendarFilter": { + "last24Hours": "Zadnja 24 sata" + }, + "markAsReviewed": "Označi kao Pregledano", + "markTheseItemsAsReviewed": "Označi ove stavke kao pregledane", + "newReviewItems": { + "label": "Pogledaj nove stavke za pregled", + "button": "Nove stavke za pregled" + }, + "selected_one": "{{count}} odabran", + "selected_other": "{{count}} odabrano", + "select_all": "Sve", + "camera": "Kamera", + "detected": "detektirano", + "normalActivity": "Normalno", + "needsReview": "Potreban pregled", + "securityConcern": "Sigurnosna zabrinutost" } diff --git a/web/public/locales/hr/views/explore.json b/web/public/locales/hr/views/explore.json index 114e4f893..83a7412b0 100644 --- a/web/public/locales/hr/views/explore.json +++ b/web/public/locales/hr/views/explore.json @@ -6,19 +6,54 @@ "embeddingsReindexing": { "startingUp": "Pokretanje…", "finishingShortly": "Završava uskoro", - "estimatedTime": "Procjenjeno preostalo vrijeme:" + "estimatedTime": "Procjenjeno preostalo vrijeme:", + "context": "Istraživanje se može koristiti nakon što je završeno ponovno indeksiranje ugrađivanja praćenih objekata.", + "step": { + "thumbnailsEmbedded": "Ugrađene sličice: ", + "descriptionsEmbedded": "Ugrađeni opisi: ", + "trackedObjectsProcessed": "Procesirani praćeni objekti: " + } }, "downloadingModels": { "setup": { - "textModel": "Tekstualni model" - } + "textModel": "Tekstualni model", + "visionModel": "Model za vid", + "visionModelFeatureExtractor": "Ekstraktor značajki modela vizije", + "textTokenizer": "Tokenizator teksta" + }, + "context": "Frigate preuzima potrebne modele ugrađivanja (embeddings) kako bi podržao značajku semantičkog pretraživanja. To može potrajati nekoliko minuta, ovisno o brzini vaše mrežne veze.", + "tips": { + "context": "Možda ćete htjeti ponovno indeksirati ugrađivanja (embeddings) svojih praćenih objekata kada se modeli preuzmu." + }, + "error": "Došlo je do pogreške. Provjerite Frigate logove." } }, "details": { - "timestamp": "Vremenska oznaka" + "timestamp": "Vremenska oznaka", + "item": { + "tips": { + "mismatch_one": "{{count}} nedostupan objekt je otkriven i uključen u ovaj pregledni stavak. Ti objekti ili nisu kvalificirani kao upozorenje ili detekcija, ili su već uklonjeni/izbrisani.", + "mismatch_few": "{{count}} nedostupna objekta su otkrivena i uključena u ovaj pregledni stavak. Ti objekti ili nisu kvalificirani kao upozorenje ili detekcija, ili su već uklonjeni/izbrisani.", + "mismatch_other": "{{count}} nedostupnih objekata je otkriveno i uključeno u ovaj pregledni stavak. Ti objekti ili nisu kvalificirani kao upozorenje ili detekcija, ili su već uklonjeni/izbrisani." + } + } }, "trackedObjectDetails": "Detalji praćenog objekta", "type": { - "details": "detalji" - } + "details": "detalji", + "snapshot": "snimka", + "thumbnail": "Sličica", + "video": "video", + "tracking_details": "detalji praćenja" + }, + "exploreMore": "Istraži više {{label}} objekata", + "trackingDetails": { + "title": "Detalji Praćenja", + "noImageFound": "Slika nije nađena za ovaj vremenski zapis.", + "createObjectMask": "Napravi Masku Objekta", + "adjustAnnotationSettings": "Podesi postavke anotacije" + }, + "trackedObjectsCount_one": "{{count}} praćeni objekt ", + "trackedObjectsCount_few": "{{count}} praćena objekta ", + "trackedObjectsCount_other": "{{count}} praćenih objekata " } diff --git a/web/public/locales/hr/views/exports.json b/web/public/locales/hr/views/exports.json index 6a4956e69..0762ed6c7 100644 --- a/web/public/locales/hr/views/exports.json +++ b/web/public/locales/hr/views/exports.json @@ -14,5 +14,10 @@ "deleteExport": "Obriši izvoz" }, "noExports": "Izvozi nisu pronađeni", - "deleteExport": "Obriši izvoz" + "deleteExport": "Obriši izvoz", + "toast": { + "error": { + "renameExportFailed": "Neuspjeh preimenovanja izvoza: {{errorMessage}}" + } + } } diff --git a/web/public/locales/hr/views/faceLibrary.json b/web/public/locales/hr/views/faceLibrary.json index b500f4b90..29883ae67 100644 --- a/web/public/locales/hr/views/faceLibrary.json +++ b/web/public/locales/hr/views/faceLibrary.json @@ -1,7 +1,8 @@ { "description": { "addFace": "Dodaj novu kolekcije u Biblioteku lica učitavanjem prve slike.", - "placeholder": "Unesi ime za ovu kolekciju" + "placeholder": "Unesi ime za ovu kolekciju", + "invalidName": "Nevaljano ime. Ime može samo uključivati slova, brojeve, razmake, navodnike, podcrte i crtice." }, "steps": { "faceName": "Unesi Ime Lica", @@ -14,7 +15,8 @@ "train": { "title": "Nedavna Prepoznavanja", "aria": "Odaberite nedavna prepoznavanja", - "empty": "Nema nedavnih pokušaja prepoznavanja lica" + "empty": "Nema nedavnih pokušaja prepoznavanja lica", + "titleShort": "Nedavno" }, "deleteFaceLibrary": { "title": "Izbriši Ime", @@ -28,14 +30,64 @@ }, "details": { "timestamp": "Vremenska oznaka", - "unknown": "Nepoznato" + "unknown": "Nepoznato", + "scoreInfo": "Rezultat je ponderirani prosjek svih rezultata lica, pri čemu su ponderi određeni veličinom lica na svakoj slici." }, "documentTitle": "Biblioteka lica - Frigate", "uploadFaceImage": { - "title": "Učitaj sliku lica" + "title": "Učitaj sliku lica", + "desc": "Učitaj sliku za skeniranje lica i uključi za {{pageToggle}}" }, "collections": "Kolekcije", "createFaceLibrary": { - "new": "Stvori novo lice" - } + "new": "Stvori novo lice", + "nextSteps": "Kako biste izgradili čvrste temelje:
  • Koristite karticu Nedavna prepoznavanja za odabir i treniranje na slikama za svaku detektiranu osobu.
  • Usredotočite se na slike snimljene direktno ispred lica za najbolje rezultate; izbjegavajte slike za treniranje koje prikazuju lica pod kutom.
  • " + }, + "renameFace": { + "title": "Preimenuj Lice", + "desc": "Unesi novo ime za {{name}}" + }, + "toast": { + "success": { + "deletedFace_one": "Uspješno izbrisano {{count}} lice.", + "deletedFace_few": "Uspješno izbrisana {{count}} lica.", + "deletedFace_other": "Uspješno izbrisano {{count}} lica.", + "deletedName_one": "{{count}} lice je uspješno izbrisano.", + "deletedName_few": "{{count}} lica su uspješno izbrisana.", + "deletedName_other": "{{count}} lica je uspješno izbrisano.", + "uploadedImage": "Uspješno učitana slika.", + "addFaceLibrary": "{{name}} je uspješno dodano u Biblioteku Lica!", + "renamedFace": "Uspješno preimenovano lice na {{name}}", + "trainedFace": "Uspješno trenirano lice.", + "updatedFaceScore": "Uspješno ažurirana ocjena lica na {{name}} ({{score}})." + }, + "error": { + "uploadingImageFailed": "Neuspješno učitavanje slike: {{errorMessage}}", + "addFaceLibraryFailed": "Neuspješno postavljanje imena lica: {{errorMessage}}", + "deleteFaceFailed": "Neuspješno brisanje: {{errorMessage}}", + "deleteNameFailed": "Neuspješno brisanje imena: {{errorMessage}}", + "renameFaceFailed": "Neuspješno preimenovanje lica: {{errorMessage}}", + "trainFailed": "Neuspješno treniranje: {{errorMessage}}", + "updateFaceScoreFailed": "Neuspješno ažuriranje ocjene lica: {{errorMessage}}" + } + }, + "button": { + "deleteFaceAttempts": "Izbriši Lica", + "addFace": "Dodaj Lice", + "renameFace": "Preimenuj Lice", + "deleteFace": "Izbriši Lice", + "uploadImage": "Učitaj Sliku", + "reprocessFace": "Ponovno Procesiraj Lice" + }, + "imageEntry": { + "validation": { + "selectImage": "Molim izaberi datoteku slike." + }, + "dropActive": "Ispusti sliku ovdje…", + "dropInstructions": "Povuci i ispusti ili zalijepi sliku ovdje, ili odaberi klikom", + "maxSize": "Max veličina: {{size}}MB" + }, + "nofaces": "Nema dostupnih lica", + "trainFaceAs": "Treniraj lice kao:", + "trainFace": "Treniraj Lice" } diff --git a/web/public/locales/hr/views/live.json b/web/public/locales/hr/views/live.json index edf847efc..82c150edb 100644 --- a/web/public/locales/hr/views/live.json +++ b/web/public/locales/hr/views/live.json @@ -40,7 +40,62 @@ "focus": { "in": { "label": "Izoštri fokus PTZ kamere" + }, + "out": { + "label": "Fokusirajte PTZ kameru prema van" } - } + }, + "frame": { + "center": { + "label": "Kliknite unutar kadra da centrirate PTZ kameru" + } + }, + "presets": "Unaprijed postavljene pozicije PTZ kamere" + }, + "lowBandwidthMode": "Način niskog bandwidtha", + "camera": { + "enable": "Omogući Kameru", + "disable": "Onemogući Kameru" + }, + "muteCameras": { + "enable": "Isključi zvuk svih kamera", + "disable": "Uključi zvuk svih kamera" + }, + "detect": { + "enable": "Omogući Detekciju", + "disable": "Onemogući detekciju" + }, + "recording": { + "enable": "Omogući Snimanje", + "disable": "Onemogući Snimanje" + }, + "snapshots": { + "enable": "Omogući Snimke", + "disable": "Onemogući snimke slike" + }, + "snapshot": { + "takeSnapshot": "Preuzmi instantnu snimku slike", + "noVideoSource": "Video izvor nije dostupan za snimku slike.", + "captureFailed": "Snimanje slike neuspješno.", + "downloadStarted": "Preuzimanje snimke slike započeto." + }, + "audioDetect": { + "enable": "Omogući Zvučnu Detekciju", + "disable": "Onemogući Zvučnu Detekciju" + }, + "transcription": { + "enable": "Omogući Transkripciju Zvuka Uživo", + "disable": "Onemogući Transkripciju Zvuka Uživo" + }, + "autotracking": { + "enable": "Omogući Automatsko Praćenje", + "disable": "Onemogući Auto Praćenje" + }, + "streamStats": { + "enable": "Prikaži statistike emitiranja", + "disable": "Sakrij statistike emitiranja" + }, + "manualRecording": { + "title": "Na Zahtjev" } } diff --git a/web/public/locales/hr/views/search.json b/web/public/locales/hr/views/search.json index c31ff77c8..984c3f37a 100644 --- a/web/public/locales/hr/views/search.json +++ b/web/public/locales/hr/views/search.json @@ -19,7 +19,55 @@ "attributes": "Atributi", "before": "Prije", "after": "Poslije", - "min_score": "Min ocjena" + "min_score": "Min ocjena", + "sub_labels": "Podoznake", + "max_score": "Maksimalni rezultat", + "min_speed": "Minimalna Brzina", + "max_speed": "Maksimalna Brzina", + "recognized_license_plate": "Prepoznata Registarska Oznaka", + "has_clip": "Ima isječak", + "has_snapshot": "Ima Snimku" + }, + "searchType": { + "thumbnail": "Sličica", + "description": "Opis" + }, + "toast": { + "error": { + "beforeDateBeLaterAfter": "Datum 'prije' mora biti kasniji od datuma 'poslije'.", + "afterDatebeEarlierBefore": "Datum 'poslije' mora biti raniji od datuma 'prije'.", + "minScoreMustBeLessOrEqualMaxScore": "Vrijednost 'min_score' mora biti manja ili jednaka vrijednosti 'max_score'.", + "maxScoreMustBeGreaterOrEqualMinScore": "Vrijednost 'max_score' mora biti veća ili jednaka vrijednosti 'min_score'.", + "minSpeedMustBeLessOrEqualMaxSpeed": "Vrijednost 'min_speed' mora biti manja ili jednaka vrijednosti 'max_speed'.", + "maxSpeedMustBeGreaterOrEqualMinSpeed": "Vrijednost 'max_speed' mora biti veća ili jednaka vrijednosti 'min_speed'." + } + }, + "tips": { + "title": "Kako koristiti text filtere", + "desc": { + "text": "Filtri pomažu suziti rezultate pretraživanja. Evo kako ih koristiti u polju za unos:", + "step1": "Upišite naziv ključa filtra, a zatim dvotočku (npr. 'cameras:').", + "step2": "Odaberite vrijednost iz prijedloga ili unesite svoju.", + "step3": "Koristite više filtera tako da ih dodajete jedan za drugim s razmakom između.", + "step4": "Filteri po datumu (before: i after:) koriste format {{DateFormat}}.", + "step5": "Filter vremenskog raspona koristi format {{exampleTime}}.", + "step6": "Uklonite filtre klikom na 'x' pored njih.", + "exampleLabel": "Primjer:" + } + }, + "header": { + "currentFilterType": "Vrijednosti Filtra", + "noFilters": "Filteri", + "activeFilters": "Aktivni Filteri" } + }, + "trackedObjectId": "ID Praćenog Objekta", + "similaritySearch": { + "title": "Pretraga po sličnosti", + "active": "Pretraživanje po sličnosti aktivno", + "clear": "Deaktiviraj pretraživanje po sličnosti" + }, + "placeholder": { + "search": "Pretraži…" } } diff --git a/web/public/locales/hr/views/settings.json b/web/public/locales/hr/views/settings.json index 500361bf3..df374e02f 100644 --- a/web/public/locales/hr/views/settings.json +++ b/web/public/locales/hr/views/settings.json @@ -7,7 +7,10 @@ "general": "Postavke sučelja - Frigate", "frigatePlus": "Frigate+ postavke - Frigate", "notifications": "Postavke notifikacija - Frigate", - "enrichments": "Postavke obogaćivanja - Frigate" + "enrichments": "Postavke obogaćivanja - Frigate", + "cameraReview": "Postavke Pregleda Kamere - Frigate", + "motionTuner": "Uređivač pokreta - Frigate", + "object": "Debug - Frigate" }, "menu": { "ui": "Sučelje", @@ -15,6 +18,54 @@ "enrichments": "Obogaćenja", "masksAndZones": "Maske / Zone", "triggers": "Okidači", - "users": "Korisnici" + "users": "Korisnici", + "cameraManagement": "Upravljanje", + "motionTuner": "Podešavač pokreta", + "debug": "Debug", + "roles": "Uloga", + "notifications": "Obavijesti", + "frigateplus": "Frigate+" + }, + "dialog": { + "unsavedChanges": { + "title": "Imaš nespremljene promjene.", + "desc": "Želiš li spremiti promjene prije nastavka?" + } + }, + "cameraSetting": { + "camera": "Kamera", + "noCamera": "Nema Kamere" + }, + "masksAndZones": { + "zones": { + "point_one": "{{count}} točka", + "point_few": "{{count}} točke", + "point_other": "{{count}} točaka" + }, + "motionMasks": { + "point_one": "{{count}} točka", + "point_few": "{{count}} točke", + "point_other": "{{count}} točaka" + }, + "objectMasks": { + "point_one": "{{count}} točka", + "point_few": "{{count}} točke", + "point_other": "{{count}} točaka" + } + }, + "roles": { + "toast": { + "success": { + "userRolesUpdated_one": "{{count}} korisnik dodijeljen ovoj ulozi ažuriran je na 'gledatelj', koji ima pristup svim kamerama.", + "userRolesUpdated_few": "{{count}} korisnika dodijeljena ovoj ulozi ažurirana su na 'gledatelj', koji imaju pristup svim kamerama.", + "userRolesUpdated_other": "{{count}} korisnika dodijeljena ovoj ulozi ažurirana su na 'gledatelj', koji imaju pristup svim kamerama." + } + } + }, + "general": { + "title": "Postavke Korisničkog Sučelja", + "liveDashboard": { + "title": "Uživo Nadzorna Ploča" + } } } diff --git a/web/public/locales/hr/views/system.json b/web/public/locales/hr/views/system.json index 417209030..0b4d07df8 100644 --- a/web/public/locales/hr/views/system.json +++ b/web/public/locales/hr/views/system.json @@ -3,9 +3,9 @@ "cameras": "Statistika kamera - Frigate", "general": "Generalne statistike - Frigate", "logs": { - "go2rtc": "Go2RTC dnevnik - Frigate", - "nginx": "Nginx dnevnik - Frigate", - "frigate": "Frigate logovi - Frigate" + "go2rtc": "Go2RTC Zapisnici- Frigate", + "nginx": "Nginx Zapisnici - Frigate", + "frigate": "Frigate Zapisnici - Frigate" }, "storage": "Statistika pohrane - Frigate", "enrichments": "Statistika obogaćivanja - Frigate" @@ -13,13 +13,52 @@ "title": "Sustav", "logs": { "download": { - "label": "Preuzmi dnevnik" + "label": "Preuzmi Zapisnike" }, "type": { - "label": "Vrsta", + "label": "Tip", "timestamp": "Vremenska oznaka", "tag": "Oznaka", "message": "Poruka" + }, + "copy": { + "label": "Kopiraj u Međuspremnik", + "success": "Kopirani zapisnici u međuspremnik", + "error": "Nisam mogao kopirati zapisnike u međuspremnik" + }, + "tips": "Zapisnici se prenose s poslužitelja", + "toast": { + "error": { + "fetchingLogsFailed": "Greška dohvaćanja zapisnika: {{errorMessage}}", + "whileStreamingLogs": "Pogreška tijekom prijenosa zapisnika: {{errorMessage}}" + } + } + }, + "metrics": "Metrike sustava", + "general": { + "title": "Općenito", + "detector": { + "title": "Detektori", + "inferenceSpeed": "Brzina izvođenja detektora", + "temperature": "Temperatura Detektora", + "cpuUsage": "Detektorova iskorištenost CPU-a", + "cpuUsageInformation": "CPU korišten za pripremu ulaznih i izlaznih podataka za modele detekcije. Ova vrijednost ne mjeri korištenje tijekom izvođenja modela, čak ni ako se koristi GPU ili akcelerator.", + "memoryUsage": "Detektorova Iskorištenost Memorije" + }, + "hardwareInfo": { + "title": "Informacije o hardveru", + "gpuUsage": "Iskorištenost GPU-a", + "gpuMemory": "GPU Memorija", + "gpuEncoder": "GPU Enkoder", + "gpuDecoder": "GPU Dekoder", + "gpuInfo": { + "vainfoOutput": { + "title": "Ispis Vainfo", + "returnCode": "Povratni kod: {{code}}", + "processOutput": "Ispis procesa:", + "processError": "Greška procesa:" + } + } } } } From e2353e55f34420e557b6b6aff5213a1e1fe9c340 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:55 +0100 Subject: [PATCH 20/98] Translated using Weblate (Hungarian) Currently translated at 94.3% (50 of 53 strings) Translated using Weblate (Hungarian) Currently translated at 62.0% (406 of 654 strings) Translated using Weblate (Hungarian) Currently translated at 63.4% (26 of 41 strings) Translated using Weblate (Hungarian) Currently translated at 97.9% (48 of 49 strings) Translated using Weblate (Hungarian) Currently translated at 19.6% (24 of 122 strings) Translated using Weblate (Hungarian) Currently translated at 19.6% (24 of 122 strings) Co-authored-by: Hosted Weblate Co-authored-by: ZsoltiHUB Co-authored-by: ugfus1630 Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/hu/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/hu/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/hu/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/hu/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/hu/ Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-events Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-search Translation: Frigate NVR/views-settings --- .../locales/hu/views/classificationModel.json | 35 +++++++++++++++++-- web/public/locales/hu/views/events.json | 3 +- web/public/locales/hu/views/faceLibrary.json | 2 +- web/public/locales/hu/views/search.json | 3 +- web/public/locales/hu/views/settings.json | 2 +- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/web/public/locales/hu/views/classificationModel.json b/web/public/locales/hu/views/classificationModel.json index 5e9d6f58c..75ef202c6 100644 --- a/web/public/locales/hu/views/classificationModel.json +++ b/web/public/locales/hu/views/classificationModel.json @@ -1,18 +1,47 @@ { - "documentTitle": "Osztályozási modellek", + "documentTitle": "Osztályozási modellek - Frigate", "button": { "deleteClassificationAttempts": "Osztályozási képek törlése", "deleteImages": "Képek törlése", "trainModel": "Modell betanítása", "deleteModels": "Modellek törlése", - "editModel": "Modell szerkesztése" + "editModel": "Modell szerkesztése", + "renameCategory": "Osztály átnevezése", + "deleteCategory": "Osztály törlése", + "addClassification": "Osztályozás hozzáadása" }, "toast": { "success": { "deletedImage": "Törölt képek", "deletedModel_one": "Sikeresen törölt {{count}} modellt", "deletedModel_other": "", - "categorizedImage": "A kép sikeresen osztályozva" + "categorizedImage": "A kép sikeresen osztályozva", + "deletedCategory": "Osztály törlése" + }, + "error": { + "deleteImageFailed": "Törlés sikertelen: {{errorMessage}}" } + }, + "details": { + "none": "Nincs", + "unknown": "Ismeretlen", + "scoreInfo": "A pontszám az objektum összes észlelésében mért átlagos osztályozási megbízhatóságot jelöli." + }, + "edit": { + "title": "Osztályozási modell szerkesztése" + }, + "wizard": { + "step1": { + "name": "Név" + }, + "step2": { + "cameras": "Kamerák" + } + }, + "tooltip": { + "trainingInProgress": "A modell betanítás alatt van", + "noNewImages": "Nincsenek új képek a betanításhoz. Először osztályozzon több képet az adathalmazban.", + "noChanges": "Az adathalmazban nem történt változás az utolsó betanítás óta.", + "modelNotReady": "A modell nem áll készen a betanításra" } } diff --git a/web/public/locales/hu/views/events.json b/web/public/locales/hu/views/events.json index abea6b464..313d8e553 100644 --- a/web/public/locales/hu/views/events.json +++ b/web/public/locales/hu/views/events.json @@ -37,5 +37,6 @@ "selected_other": "{{count}} kiválasztva", "suspiciousActivity": "Gyanús Tevékenység", "threateningActivity": "Fenyegető Tevékenység", - "zoomIn": "Nagyítás" + "zoomIn": "Nagyítás", + "zoomOut": "Kicsinyítés" } diff --git a/web/public/locales/hu/views/faceLibrary.json b/web/public/locales/hu/views/faceLibrary.json index 4f9331f87..c7fb67547 100644 --- a/web/public/locales/hu/views/faceLibrary.json +++ b/web/public/locales/hu/views/faceLibrary.json @@ -90,7 +90,7 @@ "nofaces": "Nincs elérhető arc", "documentTitle": "Arc könyvtár - Frigate", "train": { - "title": "Tanít", + "title": "Friss felismerések", "empty": "Nincs friss arcfelismerés", "aria": "Válassza ki a tanítást" }, diff --git a/web/public/locales/hu/views/search.json b/web/public/locales/hu/views/search.json index 185a060e5..488ad43c3 100644 --- a/web/public/locales/hu/views/search.json +++ b/web/public/locales/hu/views/search.json @@ -26,7 +26,8 @@ "max_speed": "Maximális Sebesség", "recognized_license_plate": "Felismert Rendszám", "has_clip": "Van Klip", - "has_snapshot": "Van pillanatképe" + "has_snapshot": "Van pillanatképe", + "attributes": "Tulajdonságok" }, "searchType": { "description": "Leírás", diff --git a/web/public/locales/hu/views/settings.json b/web/public/locales/hu/views/settings.json index c36e9a53f..573342eba 100644 --- a/web/public/locales/hu/views/settings.json +++ b/web/public/locales/hu/views/settings.json @@ -6,7 +6,7 @@ "classification": "Osztályozási beállítások - Frigate", "masksAndZones": "Maszk és zónaszerkesztő - Frigate", "object": "Hibakeresés - Frigate", - "general": "Áltlános Beállítások - Frigate", + "general": "Felhasználói felület beállításai - Frigate", "frigatePlus": "Frigate+ beállítások - Frigate", "notifications": "Értesítések beállítása - Frigate", "motionTuner": "Mozgás Hangoló - Frigate", From 2b345bd3f7801f177379cbbead6cbb279301b793 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:55 +0100 Subject: [PATCH 21/98] Translated using Weblate (Hebrew) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (136 of 136 strings) Co-authored-by: Hosted Weblate Co-authored-by: Ronen Atsil Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/he/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/he/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/he/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/he/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/he/common.json | 3 ++- web/public/locales/he/views/events.json | 6 +++++- web/public/locales/he/views/explore.json | 5 ++++- web/public/locales/he/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/he/common.json b/web/public/locales/he/common.json index 0496941bb..1059ae300 100644 --- a/web/public/locales/he/common.json +++ b/web/public/locales/he/common.json @@ -107,7 +107,8 @@ "show": "הצג {{item}}", "ID": "ID", "none": "ללא", - "all": "הכל" + "all": "הכל", + "other": "אחר" }, "button": { "apply": "החל", diff --git a/web/public/locales/he/views/events.json b/web/public/locales/he/views/events.json index 6abcccd11..636a073b1 100644 --- a/web/public/locales/he/views/events.json +++ b/web/public/locales/he/views/events.json @@ -9,7 +9,11 @@ "empty": { "detection": "אין גילויים לבדיקה", "alert": "אין התראות להצגה", - "motion": "לא נמצאו נתוני תנועה" + "motion": "לא נמצאו נתוני תנועה", + "recordingsDisabled": { + "title": "יש להפעיל הקלטות", + "description": "ניתן ליצור פריטי סקירה עבור מצלמה רק כאשר הקלטות מופעלות עבור אותה מצלמה." + } }, "timeline": "ציר זמן", "timeline.aria": "בחירת ציר זמן", diff --git a/web/public/locales/he/views/explore.json b/web/public/locales/he/views/explore.json index 07be1ceec..6042b4329 100644 --- a/web/public/locales/he/views/explore.json +++ b/web/public/locales/he/views/explore.json @@ -220,7 +220,10 @@ "score": { "label": "ציון" }, - "attributes": "מאפייני סיווג" + "attributes": "מאפייני סיווג", + "title": { + "label": "כותרת" + } }, "dialog": { "confirmDelete": { diff --git a/web/public/locales/he/views/system.json b/web/public/locales/he/views/system.json index 90480a554..fa32918f6 100644 --- a/web/public/locales/he/views/system.json +++ b/web/public/locales/he/views/system.json @@ -97,7 +97,14 @@ "otherProcesses": { "title": "תהליכים אחרים", "processCpuUsage": "ניצול CPU של התהליך", - "processMemoryUsage": "ניצול זיכרון של תהליך" + "processMemoryUsage": "ניצול זיכרון של תהליך", + "series": { + "go2rtc": "go2rtc", + "recording": "מקליט", + "review_segment": "קטע סקירה", + "embeddings": "הטמעות", + "audio_detector": "זיהוי שמע" + } } }, "enrichments": { From ace11730bda1c8db33f2e0fdba223e1133e54c5e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:55 +0100 Subject: [PATCH 22/98] Translated using Weblate (Polish) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Polish) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Polish) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Polish) Currently translated at 100.0% (74 of 74 strings) Translated using Weblate (Polish) Currently translated at 100.0% (55 of 55 strings) Translated using Weblate (Polish) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Polish) Currently translated at 100.0% (501 of 501 strings) Translated using Weblate (Polish) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Polish) Currently translated at 100.0% (131 of 131 strings) Translated using Weblate (Polish) Currently translated at 100.0% (122 of 122 strings) Translated using Weblate (Polish) Currently translated at 95.1% (39 of 41 strings) Translated using Weblate (Polish) Currently translated at 100.0% (49 of 49 strings) Translated using Weblate (Polish) Currently translated at 69.6% (85 of 122 strings) Translated using Weblate (Polish) Currently translated at 84.4% (114 of 135 strings) Translated using Weblate (Polish) Currently translated at 100.0% (53 of 53 strings) Co-authored-by: Hosted Weblate Co-authored-by: J P Co-authored-by: Janusz Poloczek Co-authored-by: przeniek Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/pl/ Translation: Frigate NVR/audio Translation: Frigate NVR/common Translation: Frigate NVR/components-dialog Translation: Frigate NVR/components-filter Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-search Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/pl/audio.json | 82 ++++++++- web/public/locales/pl/common.json | 25 +-- web/public/locales/pl/components/dialog.json | 3 +- web/public/locales/pl/components/filter.json | 3 +- .../locales/pl/views/classificationModel.json | 65 ++++++-- web/public/locales/pl/views/events.json | 10 +- web/public/locales/pl/views/explore.json | 49 +++++- web/public/locales/pl/views/faceLibrary.json | 3 +- web/public/locales/pl/views/search.json | 3 +- web/public/locales/pl/views/settings.json | 157 ++++++++++++++---- web/public/locales/pl/views/system.json | 29 +++- 11 files changed, 353 insertions(+), 76 deletions(-) diff --git a/web/public/locales/pl/audio.json b/web/public/locales/pl/audio.json index 62cd7b465..4d8e1f28d 100644 --- a/web/public/locales/pl/audio.json +++ b/web/public/locales/pl/audio.json @@ -124,7 +124,7 @@ "zither": "Cytra", "ukulele": "Ukulele", "keyboard": "Klawiatura", - "rimshot": "Rimshot", + "rimshot": "Uderzenie w obręcz", "drum_roll": "Werbel (tremolo)", "bass_drum": "Bęben basowy", "timpani": "Kotły", @@ -168,14 +168,14 @@ "didgeridoo": "Didgeridoo", "theremin": "Theremin", "singing_bowl": "Misa dźwiękowa", - "scratching": "Scratching", + "scratching": "Drapanie", "pop_music": "Muzyka pop", "hip_hop_music": "Muzyka hip-hopowa", "beatboxing": "Beatbox", "rock_music": "Muzyka rockowa", "heavy_metal": "Heavy metal", "punk_rock": "Punk rock", - "grunge": "Grunge", + "grunge": "Paskudztwo", "progressive_rock": "Rock progresywny", "rock_and_roll": "Rock and roll", "psychedelic_rock": "Rock psychodeliczny", @@ -425,5 +425,79 @@ "pulleys": "Bloczki", "sanding": "Szlifowanie", "clock": "Zegar", - "tick": "Tykanie" + "tick": "Tykanie", + "sodeling": "Sodeling", + "liquid": "Płyn", + "splash": "Plusk", + "slosh": "Rozchlapywanie", + "squish": "Ściskanie", + "drip": "Kapanie", + "pour": "Wlewanie", + "spray": "Pryskanie", + "pump": "Pompowanie", + "stir": "Mieszanie", + "boiling": "Gotowanie", + "arrow": "Strzała", + "breaking": "Łamanie", + "bouncing": "Odbijanie", + "beep": "Pisk", + "clicking": "Klikanie", + "inside": "Wewnątrz", + "outside": "Na zewnątrz", + "chird": "Child", + "change_ringing": "Zmienny dzwonek", + "shofar": "Shofar", + "trickle": "Trickle", + "gush": "Wylew", + "fill": "Napełnianie", + "sonar": "Sonar", + "whoosh": "Szybki ruch", + "thump": "Uderzenie", + "thunk": "Odgłos uderzenia", + "electronic_tuner": "Tuner elektroniczny", + "effects_unit": "Moduł efektów", + "chorus_effect": "Efekt chóru", + "basketball_bounce": "Odbijanie piłki", + "bang": "Bum", + "slap": "Policzkowanie", + "whack": "Uderzyć", + "smash": "Rozbić", + "whip": "Bicz", + "flap": "Klapa", + "scratch": "Zdrapywanie", + "scrape": "Skrobać", + "rub": "Pocierać", + "roll": "Rolować", + "crushing": "Rozbijać", + "crumpling": "Zgniatanie", + "tearing": "Rozrywanie", + "ping": "Ping", + "ding": "Dzwonienie", + "clang": "Brzdęk", + "squeal": "Piszczenie", + "creak": "Skrzypieć", + "rustle": "Szelest", + "whir": "Świst", + "clatter": "Stukot", + "sizzle": "Sizzle", + "clickety_clack": "Klik-klak", + "rumble": "Grzmot", + "plop": "Plop", + "hum": "Szum", + "zing": "Zing", + "boing": "Odbicie", + "crunch": "Chrupnięcie", + "sine_wave": "Sinusoida", + "harmonic": "Harmoniczna", + "chirp_tone": "Ustawianie tonów", + "pulse": "Puls", + "reverberation": "Pogłos", + "echo": "Echo", + "noise": "Hałas", + "mains_hum": "Szum sieciowy", + "distortion": "Zniekształcenie", + "sidetone": "Sygnał zwrotny", + "throbbing": "Pulsowanie", + "vibration": "Wibracja", + "cacophony": "Kakofonia" } diff --git a/web/public/locales/pl/common.json b/web/public/locales/pl/common.json index 0c68e1813..dbf1576a0 100644 --- a/web/public/locales/pl/common.json +++ b/web/public/locales/pl/common.json @@ -22,18 +22,18 @@ "yesterday": "Wczoraj", "pm": "po południu", "am": "przed południem", - "yr": "{{time}}r.", + "yr": "{{time}}r", "year_one": "{{time}} rok", "year_few": "{{time}} lata", "year_many": "{{time}} lat", - "mo": "{{time}}m.", - "d": "{{time}}d.", + "mo": "{{time}}m", + "d": "{{time}}d", "day_one": "{{time}} dzień", "day_few": "{{time}} dni", "day_many": "{{time}} dni", - "h": "{{time}}godz.", - "m": "{{time}}min.", - "s": "{{time}}s.", + "h": "{{time}}godz", + "m": "{{time}}min", + "s": "{{time}}s", "month_one": "{{time}} miesiąc", "month_few": "{{time}} miesiące", "month_many": "{{time}} miesięcy", @@ -105,9 +105,9 @@ "kbps": "kB/s", "mbps": "MB/s", "gbps": "GB/s", - "kbph": "kB/godz.", - "mbph": "MB/godz.", - "gbph": "GB/godz." + "kbph": "kB/godz", + "mbph": "MB/godz", + "gbph": "GB/godz" } }, "label": { @@ -304,6 +304,11 @@ }, "list": { "two": "{{0}} i {{1}}", - "many": "{{items}}, oraz {{last}}" + "many": "{{items}}, oraz {{last}}", + "separatorWithSpace": "; " + }, + "field": { + "optional": "Opcjonalny", + "internalID": "Wewnętrzny identyfikator używany przez Frigate w konfiguracji i bazie danych" } } diff --git a/web/public/locales/pl/components/dialog.json b/web/public/locales/pl/components/dialog.json index b9a4d9a0f..24842e140 100644 --- a/web/public/locales/pl/components/dialog.json +++ b/web/public/locales/pl/components/dialog.json @@ -130,6 +130,7 @@ "search": { "placeholder": "Wyszukaj po etykiecie (label) lub etykiecie potomnej (sub label)..." }, - "noImages": "Brak miniatur dla tej kamery" + "noImages": "Brak miniatur dla tej kamery", + "unknownLabel": "Zapisany obraz wyzwalacza" } } diff --git a/web/public/locales/pl/components/filter.json b/web/public/locales/pl/components/filter.json index f718061a5..7de30b2dd 100644 --- a/web/public/locales/pl/components/filter.json +++ b/web/public/locales/pl/components/filter.json @@ -134,6 +134,7 @@ "count_other": "{{count}} Klas(y)" }, "attributes": { - "all": "Wszystkie atrybuty" + "all": "Wszystkie atrybuty", + "label": "Atrybuty klasyfikacji" } } diff --git a/web/public/locales/pl/views/classificationModel.json b/web/public/locales/pl/views/classificationModel.json index d2fa9815a..c68baf133 100644 --- a/web/public/locales/pl/views/classificationModel.json +++ b/web/public/locales/pl/views/classificationModel.json @@ -5,7 +5,7 @@ "renameCategory": "Zmień nazwę klasy", "deleteCategory": "Usuń klasyfikację", "deleteImages": "Usuń obrazy", - "trainModel": "Przeszkol model", + "trainModel": "Trenuj model", "addClassification": "Dodaj klasyfikację", "deleteModels": "Usuń modele", "editModel": "Edytuj model" @@ -23,7 +23,7 @@ "deletedModel_few": "Pomyślenie usunięto {{count}} modele", "deletedModel_many": "Pomyślenie usunięto {{count}} modeli", "categorizedImage": "Obraz pomyślnie sklasyfikowany", - "trainedModel": "Model pomyślnie wytrenowany", + "trainedModel": "Model pomyślnie wytrenowany.", "trainingModel": "Pomyślnie uruchomiono trenowanie modelu.", "updatedModel": "Pomyślnie zaktualizowane ustawienia modelu", "renamedCategory": "Pomyślnie zmieniono nazwę klasy na {{name}}" @@ -79,7 +79,7 @@ }, "train": { "title": "Ostatnie Klasyfikacje", - "titleShort": "Najnowsze", + "titleShort": "Ostatnie", "aria": "Wybierz Najnowsze Klasyfikacje" }, "createCategory": { @@ -115,25 +115,47 @@ "title": "Tworzenie nowej klasyfikacji", "steps": { "nameAndDefine": "Nazwij i zdefiniuj", - "stateArea": "Obszar stanu" + "stateArea": "Obszar stanu", + "chooseExamples": "Wybierz przykłady" }, "step1": { "name": "Nazwa", "type": "Typ", "classes": "Klasy", "errors": { - "noneNotAllowed": "Klasa „żadne” jest niedozwolona.", - "stateRequiresTwoClasses": "Modele stanowe wymagają co najmniej dwie klasy.", + "noneNotAllowed": "Klasa 'żadne' jest niedozwolona", + "stateRequiresTwoClasses": "Modele stanowe wymagają co najmniej dwie klasy", "objectLabelRequired": "Proszę wybrać etykietę obiektu", - "objectTypeRequired": "Proszę wybrać typ klasyfikacji" - } + "objectTypeRequired": "Proszę wybrać typ klasyfikacji", + "nameRequired": "Nazwa modelu jest wymagana", + "nameLength": "Nazwa modelu może mieć 64 znaki lub mniej", + "nameOnlyNumbers": "Nazwa modelu nie może być ciągiem cyfr", + "classRequired": "Przynajmniej jedna klasa jest wymagana", + "classesUnique": "Nazwa klasy musi być unikalna" + }, + "classPlaceholder": "Wpisz nazwę klasy...", + "classesObjectDesc": "Zdefiniuj różne kategorie, do których będą klasyfikowane wykryte obiekty. Na przykład: 'dostawca', 'mieszkaniec', 'nieznajomy' w przypadku klasyfikacji osób.", + "description": "Modele stanowe monitorują stałe obszary kamer pod kątem zmian (np. otwarte/zamknięte drzwi). Modele obiektów dodają klasyfikacje do wykrytych obiektów (np. znane zwierzęta, dostawcy itp.).", + "namePlaceholder": "Wprowadź nazwę modelu...", + "typeState": "Stan", + "typeObject": "Obiekt", + "objectLabel": "Etykieta obiektu", + "objectLabelPlaceholder": "Wybierz typ obiektu...", + "classificationType": "Rodzaj klasyfikacji", + "classificationTypeTip": "Dowiedz się więcej o typach klasyfikacji", + "classificationTypeDesc": "Podetykiety dodają dodatkowy tekst do etykiety obiektu (np. 'Osoba: UPS'). Atrybuty to metadane, które można przeszukiwać, przechowywane oddzielnie w metadanych obiektu.", + "classificationSubLabel": "Podetykieta", + "classificationAttribute": "Atrybut", + "states": "Stany", + "classesTip": "Dowiedz się więcej o klasach obiektów", + "classesStateDesc": "Zdefiniuj różne stany, w jakich może znajdować się obszar objęty zasięgiem kamery. Na przykład: 'otwarte' i 'zamknięte' dla bramy garażowej." }, "step2": { "description": "Wybierz kamery i określ obszar monitorowania dla każdej z nich. Model sklasyfikuje stan tych obszarów.", "cameras": "Kamery", "selectCamera": "Wybierz kamerę", "noCameras": "Kliknij +, aby dodać kamery", - "selectCameraPrompt": "Wybierz kamerę z listy, aby zdefiniować jej obszar monitorowania." + "selectCameraPrompt": "Wybierz kamerę z listy, aby zdefiniować jej obszar monitorowania" }, "step3": { "selectImagesPrompt": "Zaznacz wszystkie obrazy z: {{className}}", @@ -142,9 +164,30 @@ "allImagesRequired_few": "Proszę sklasyfikować wszystkie obrazy. Pozostały {{count}} obrazy.", "allImagesRequired_many": "Proszę sklasyfikować wszystkie obrazy. Pozostało {{count}} obrazów.", "generating": { - "title": "Generowanie przykładowych obrazów" + "title": "Generowanie przykładowych obrazów", + "description": "Frigate pobiera reprezentatywne obrazy z Twoich nagrań. Może to chwilę potrwać..." }, - "trainingStarted": "Szkolenie rozpoczęło się pomyślnie" + "trainingStarted": "Szkolenie rozpoczęło się pomyślnie", + "training": { + "title": "Model treningowy", + "description": "Twój model jest szkolony w tle. Zamknij to okno dialogowe, a model zacznie działać zaraz po zakończeniu szkolenia." + }, + "retryGenerate": "Ponowne generowanie", + "noImages": "Nie wygenerowano przykładowych obrazów", + "classifying": "Klasyfikacja i szkolenie...", + "modelCreated": "Model został pomyślnie utworzony. Użyj widoku Ostatnie klasyfikacje, aby dodać obrazy dla brakujących stanów, a następnie wytrenuj model.", + "errors": { + "noCameras": "Brak skonfigurowanych kamer", + "noObjectLabel": "Nie wybrano żadnej etykiety obiektu", + "generateFailed": "Nie udało się wygenerować przykładów: {{error}}", + "generationFailed": "Generowanie nie powiodło się. Spróbuj ponownie.", + "classifyFailed": "Nie udało się sklasyfikować obrazów: {{error}}" + }, + "generateSuccess": "Pomyślnie wygenerowane przykładowe obrazy", + "missingStatesWarning": { + "title": "Przykłady brakujących stanów", + "description": "Aby uzyskać najlepsze wyniki, zaleca się wybranie przykładów dla wszystkich stanów. Można kontynuować bez wybierania wszystkich stanów, ale model nie zostanie wytrenowany, dopóki wszystkie stany nie będą miały obrazów. Po kontynuowaniu należy użyć widoku Ostatnie klasyfikacje, aby sklasyfikować obrazy dla brakujących stanów, a następnie wytrenować model." + } } } } diff --git a/web/public/locales/pl/views/events.json b/web/public/locales/pl/views/events.json index cc7b258c6..0ffc5419f 100644 --- a/web/public/locales/pl/views/events.json +++ b/web/public/locales/pl/views/events.json @@ -10,7 +10,11 @@ "empty": { "alert": "Brak alertów do przejrzenia", "detection": "Brak detekcji do przejrzenia", - "motion": "Nie znaleziono danych o ruchu" + "motion": "Nie znaleziono danych o ruchu", + "recordingsDisabled": { + "title": "Nagrywanie musi być włączone", + "description": "Elementy przeglądu można tworzyć dla kamery tylko wtedy, gdy dla tej kamery włączono nagrywanie." + } }, "timeline": "Oś czasu", "timeline.aria": "Wybierz oś czasu", @@ -57,5 +61,7 @@ "clickToSeek": "Kliknij aby przewinąć do tego miejsca" }, "needsReview": "Wymaga manualnego sprawdzenia", - "normalActivity": "Normalne" + "normalActivity": "Normalne", + "select_all": "Wszystko", + "securityConcern": "Kwestie bezpieczeństwa" } diff --git a/web/public/locales/pl/views/explore.json b/web/public/locales/pl/views/explore.json index cceb1a162..d18d065b8 100644 --- a/web/public/locales/pl/views/explore.json +++ b/web/public/locales/pl/views/explore.json @@ -77,6 +77,14 @@ }, "score": { "label": "Wynik" + }, + "editAttributes": { + "title": "Edytuj atrybuty", + "desc": "Wybierz atrybuty klasyfikacji dla tego {{label}}" + }, + "attributes": "Atrybuty klasyfikacji", + "title": { + "label": "Tytuł" } }, "objectLifecycle": { @@ -200,6 +208,20 @@ "audioTranscription": { "label": "Rozpisz", "aria": "Poproś o audiotranskrypcję" + }, + "downloadCleanSnapshot": { + "label": "Pobierz czysty snapshot", + "aria": "Pobierz czysty snapshot" + }, + "viewTrackingDetails": { + "label": "Wyświetl szczegóły śledzenia", + "aria": "Pokaż szczegóły śledzenia" + }, + "showObjectDetails": { + "label": "Pokaż ścieżkę obiektu" + }, + "hideObjectDetails": { + "label": "Ukryj ścieżkę obiektu" } }, "trackedObjectsCount_one": "{{count}} śledzony obiekt ", @@ -208,7 +230,7 @@ "noTrackedObjects": "Nie znaleziono śledzonych obiektów", "dialog": { "confirmDelete": { - "desc": "Usunięcie tego śledzonego obiektu usuwa zrzut ekranu, wszelkie zapisane osadzenia i wszystkie powiązane wpisy cyklu życia obiektu. Nagrany materiał tego śledzonego obiektu w widoku Historii NIE zostanie usunięty.

    Czy na pewno chcesz kontynuować?", + "desc": "Usunięcie tego śledzonego obiektu usuwa zrzut ekranu, wszelkie zapisane osadzenia i wszystkie powiązane wpisy śledzenia obiektu. Nagrany materiał tego śledzonego obiektu w widoku Historii NIE zostanie usunięty.

    Czy na pewno chcesz kontynuować?", "title": "Potwierdź usunięcie" } }, @@ -220,7 +242,9 @@ "error": "Nie udało się usunąć śledzonego obiektu: {{errorMessage}}" } }, - "tooltip": "Pasuje do {{type}} z pewnością {{confidence}}%" + "tooltip": "Pasuje do {{type}} z pewnością {{confidence}}%", + "previousTrackedObject": "Poprzednio śledzony obiekt", + "nextTrackedObject": "Następny śledzony obiekt" }, "exploreMore": "Odkryj więcej obiektów typu {{label}}", "aiAnalysis": { @@ -251,16 +275,31 @@ "header": { "zones": "Strefy", "area": "Powierzchnia", - "score": "Wynik" - } + "score": "Wynik", + "ratio": "Proporcje" + }, + "heard": "{{label}} słyszałem" }, "annotationSettings": { "title": "Ustawienia adnotacji", "showAllZones": { "title": "Pokaż wszystkie strefy", "desc": "Pokazuj linie stref w momencie wejścia obiektu w strefę." + }, + "offset": { + "label": "Przesunięcie adnotacji", + "desc": "Dane te pochodzą z kanału wykrywania kamery, ale są nakładane na obrazy z kanału nagrywania. Jest mało prawdopodobne, aby oba strumienie były idealnie zsynchronizowane. W rezultacie ramka ograniczająca i materiał filmowy nie będą idealnie dopasowane. Można użyć tego ustawienia, aby przesunąć adnotacje do przodu lub do tyłu w czasie, aby lepiej dopasować je do nagranego materiału filmowego.", + "millisecondsToOffset": "Milisekundy, po których wykrywane są adnotacje. Domyślnie: 0", + "tips": "Zmniejsz wartość, jeśli odtwarzanie wideo wyprzedza pola i punkty ścieżki, i zwiększ wartość, jeśli odtwarzanie wideo pozostaje w tyle. Wartość ta może być ujemna.", + "toast": { + "success": "Przesunięcie adnotacji dla {{camera}} zostało zapisane w pliku konfiguracyjnym." + } } }, - "trackedPoint": "Śledzony Punkt" + "trackedPoint": "Śledzony Punkt", + "carousel": { + "previous": "Poprzedni slajd", + "next": "Następny slajd" + } } } diff --git a/web/public/locales/pl/views/faceLibrary.json b/web/public/locales/pl/views/faceLibrary.json index 5edfcba70..4bd3944f8 100644 --- a/web/public/locales/pl/views/faceLibrary.json +++ b/web/public/locales/pl/views/faceLibrary.json @@ -29,7 +29,8 @@ "train": { "aria": "Wybierz ostatnio rozpoznane", "title": "Ostatnie rozpoznania", - "empty": "Nie podjęto ostatnio żadnych prób rozpoznawania twarzy" + "empty": "Nie podjęto ostatnio żadnych prób rozpoznawania twarzy", + "titleShort": "Ostatnie" }, "selectFace": "Wybierz twarz", "deleteFaceLibrary": { diff --git a/web/public/locales/pl/views/search.json b/web/public/locales/pl/views/search.json index 175b42a80..9de364f59 100644 --- a/web/public/locales/pl/views/search.json +++ b/web/public/locales/pl/views/search.json @@ -26,7 +26,8 @@ "after": "Po", "search_type": "Typ wyszukiwania", "time_range": "Zakres czasu", - "before": "Przed" + "before": "Przed", + "attributes": "Właściwości" }, "searchType": { "thumbnail": "Miniatura", diff --git a/web/public/locales/pl/views/settings.json b/web/public/locales/pl/views/settings.json index 956eb5f02..dfc74b7dc 100644 --- a/web/public/locales/pl/views/settings.json +++ b/web/public/locales/pl/views/settings.json @@ -242,7 +242,8 @@ "mustNotBeSameWithCamera": "Nazwa strefy nie może być taka sama jak nazwa kamery.", "alreadyExists": "Strefa z tą nazwą już istnieje dla tej kamery.", "hasIllegalCharacter": "Nazwa strefy zawiera niedozwolone znaki.", - "mustNotContainPeriod": "Nazwa strefy nie może zawierać kropki." + "mustNotContainPeriod": "Nazwa strefy nie może zawierać kropki.", + "mustHaveAtLeastOneLetter": "Nazwa strefy musi zawierać co najmniej jedną literę." } }, "distance": { @@ -298,7 +299,7 @@ "name": { "title": "Nazwa", "inputPlaceHolder": "Wprowadź nazwę…", - "tips": "Nazwa musi mieć co najmniej 2 znaki i nie może być taka sama jak nazwa kamery lub innej strefy." + "tips": "Nazwa musi mieć co najmniej 1 znak i nie może być taka sama jak nazwa kamery lub innej strefy." }, "objects": { "title": "Obiekty", @@ -336,7 +337,7 @@ "lineDDistance": "Odległość linii D ({{unit}})" }, "toast": { - "success": "Strefa ({{zoneName}}) została zapisana. Uruchom ponownie Frigate, aby zastosować zmiany." + "success": "Strefa ({{zoneName}}) została zapisana." } }, "motionMasks": { @@ -357,8 +358,8 @@ }, "toast": { "success": { - "title": "{{polygonName}} został zapisany. Uruchom ponownie Frigate, aby zastosować zmiany.", - "noName": "Maska Ruchu została zapisana. Uruchom ponownie Frigate, aby zastosować zmiany." + "title": "{{polygonName}} został zapisany.", + "noName": "Maska Ruchu została zapisana." } }, "label": "Maska ruchu", @@ -371,8 +372,8 @@ "objectMasks": { "toast": { "success": { - "title": "{{polygonName}} został zapisany. Uruchom ponownie Frigate aby wprowadzić zmiany.", - "noName": "Maska Obiektu została zapisana. Uruchom ponownie Frigate, aby zastosować zmiany." + "title": "{{polygonName}} został zapisany.", + "noName": "Maska Obiektu została zapisana." } }, "objects": { @@ -491,7 +492,7 @@ }, "users": { "addUser": "Dodaj Użytkownika", - "updatePassword": "Aktualizuj Hasło", + "updatePassword": "Resetuj Hasło", "toast": { "success": { "createUser": "Użytkownik {{user}} został utworzony pomyślnie", @@ -512,7 +513,7 @@ "role": "Rola", "noUsers": "Nie znaleziono użytkowników.", "changeRole": "Zmień rolę użytkownika", - "password": "Hasło", + "password": "Resetuj hasło", "deleteUser": "Usuń użytkownika" }, "dialog": { @@ -537,7 +538,16 @@ }, "title": "Hasło", "placeholder": "Wprowadź hasło", - "notMatch": "Hasła nie pasują" + "notMatch": "Hasła nie pasują", + "show": "Pokaż hasło", + "hide": "Ukryj hasło", + "requirements": { + "title": "Wymagania hasła:", + "length": "Co najmniej 8 znaków", + "uppercase": "Co najmniej jedna duża litera", + "digit": "Co najmniej jedna cyfra", + "special": "Co najmniej jeden znak specjalny (!@#$%^&*(),.?\":{}|<>)" + } }, "newPassword": { "placeholder": "Wprowadź nowe hasło", @@ -547,7 +557,11 @@ } }, "usernameIsRequired": "Nazwa użytkownika jest wymagana", - "passwordIsRequired": "Hasło jest wymagane" + "passwordIsRequired": "Hasło jest wymagane", + "currentPassword": { + "title": "Aktualne hasło", + "placeholder": "Wprowadź aktualne hasło" + } }, "changeRole": { "desc": "Aktualizuj uprawnienia dla {{username}}", @@ -578,7 +592,12 @@ "setPassword": "Ustaw hasło", "desc": "Utwórz silne hasło, aby zabezpieczyć to konto.", "cannotBeEmpty": "Hasło nie może być puste", - "doNotMatch": "Hasła nie pasują do siebie" + "doNotMatch": "Hasła nie pasują do siebie", + "currentPasswordRequired": "Wymagane jest aktualne hasło", + "incorrectCurrentPassword": "Aktualne hasło jest nieprawidłowe", + "passwordVerificationFailed": "Nie udało się zweryfikować hasła", + "multiDeviceWarning": "Wszystkie inne urządzenia, na których jesteś zalogowany, będą wymagały ponownego zalogowania się w ciągu {{refresh_time}}.", + "multiDeviceAdmin": "Możesz również wymusić natychmiastowe ponowne uwierzytelnienie wszystkich użytkowników poprzez zmianę sekretu JWT." } }, "management": { @@ -814,7 +833,7 @@ "triggers": { "documentTitle": "Wyzwalacze", "management": { - "title": "Zarządzanie wyzwalaczami", + "title": "Wyzwalacze", "desc": "Zarządzaj wyzwalaczami dla kamery {{camera}}. Użyj typu miniatury, aby aktywować miniatury podobne do wybranego śledzonego obiektu, i typu opisu, aby aktywować opisy podobne do określonego tekstu." }, "addTrigger": "Dodaj wyzwalacz", @@ -835,7 +854,9 @@ }, "actions": { "alert": "Oznacz jako alarm", - "notification": "Wyślij powiadomienie" + "notification": "Wyślij powiadomienie", + "sub_label": "Dodaj podetykietę", + "attribute": "Dodaj atrybut" }, "dialog": { "createTrigger": { @@ -855,23 +876,26 @@ "title": "Nazwa", "placeholder": "Wprowadź nazwę wyzwalacza", "error": { - "minLength": "Nazwa musi mieć co najmniej 2 znaki.", - "invalidCharacters": "Nazwa może zawierać jedynie litery, liczby, podkreślenie i myślniki.", + "minLength": "Pole musi mieć co najmniej 2 znaki.", + "invalidCharacters": "Pole może zawierać jedynie litery, liczby, podkreślenie i myślniki.", "alreadyExists": "Wyzwalacz o tej nazwie istnieje już dla tej kamery." - } + }, + "description": "Wprowadź unikalną nazwę lub opis, aby zidentyfikować ten wyzwalacz" }, "enabled": { "description": "Włącz lub wyłącz ten wyzwalacz" }, "type": { "title": "Typ", - "placeholder": "Wybierz typ wyzwalacza" + "placeholder": "Wybierz typ wyzwalacza", + "description": "Uruchom, gdy wykryty zostanie podobny opis śledzonego obiektu", + "thumbnail": "Uruchom, gdy wykryta zostanie podobna miniatura śledzonego obiektu" }, "content": { "title": "Zawartość", - "imagePlaceholder": "Wybierz obraz", + "imagePlaceholder": "Wybierz miniaturkę", "textPlaceholder": "Wprowadź treść", - "imageDesc": "Wybierz obraz, aby uruchomić tę akcję po wykryciu podobnego obrazu.", + "imageDesc": "Wyświetlane jest tylko 100 najnowszych miniatur. Jeśli nie możesz znaleźć żądanej miniatury, przejrzyj wcześniejsze obiekty w sekcji Eksploruj i skonfiguruj wyzwalacz z menu w tym miejscu.", "textDesc": "Wprowadź tekst, który spowoduje uruchomienie tej akcji po wykryciu podobnego opisu śledzonego obiektu.", "error": { "required": "Zawartość jest wymagana." @@ -882,11 +906,12 @@ "error": { "min": "Próg musi wynosić co najmniej 0", "max": "Próg nie może być większy niż 1" - } + }, + "desc": "Ustaw próg podobieństwa dla tego wyzwalacza. Wyższy próg oznacza, że do uruchomienia wyzwalacza wymagane jest większe dopasowanie." }, "actions": { "title": "Akcje", - "desc": "Domyślnie Frigate wysyła wiadomość MQTT dla wszystkich wyzwalaczy. Wybierz dodatkową akcję, która ma zostać wykonana po uruchomieniu tego wyzwalacza.", + "desc": "Domyślnie Frigate wysyła komunikat MQTT dla wszystkich wyzwalaczy. Podetykiety dodają nazwę wyzwalacza do etykiety obiektu. Atrybuty to metadane, które można przeszukiwać, przechowywane oddzielnie w metadanych śledzonego obiektu.", "error": { "min": "Musisz wybrać co najmniej jedną akcję." } @@ -913,6 +938,23 @@ "semanticSearch": { "title": "Wyszukiwanie semantyczne jest zablokowane", "desc": "Wyszukiwanie semantyczne musi być włączone, aby korzystać z triggerów." + }, + "wizard": { + "title": "Utwórz wyzwalacz", + "step1": { + "description": "Skonfiguruj podstawowe ustawienia wyzwalacza." + }, + "step2": { + "description": "Skonfiguruj treść, która uruchomi tę akcję." + }, + "step3": { + "description": "Skonfiguruj próg i działania dla tego wyzwalacza." + }, + "steps": { + "nameAndType": "Nazwa i typ", + "configureData": "Skonfiguruj dane", + "thresholdAndActions": "Próg i akcje" + } } }, "cameraWizard": { @@ -1002,7 +1044,15 @@ "probeSuccessful": "Wykrywanie udane", "probeError": "Błąd wykrywania", "probeNoSuccess": "Niepowodzenie wykrywania", - "presets": "Ustawienia wstępne" + "presets": "Ustawienia wstępne", + "rtspCandidates": "Kandydaci RTSP", + "rtspCandidatesDescription": "W wyniku sprawdzania kamery znaleziono następujące adresy URL RTSP. Przetestuj połączenie, aby wyświetlić metadane strumienia.", + "noRtspCandidates": "Nie znaleziono adresów URL RTSP z kamery. Twoje dane uwierzytelniające mogą być nieprawidłowe lub kamera może nie obsługiwać protokołu ONVIF lub metody używanej do pobierania adresów URL RTSP. Wróć i wprowadź adres URL RTSP ręcznie.", + "candidateStreamTitle": "Kandydat {{number}}", + "useCandidate": "Użyj", + "toggleUriView": "Kliknij, aby przełączyć widok pełnego adresu URI", + "connected": "Połączony", + "notConnected": "Niepołączony" }, "step3": { "streamTitle": "Strumień numer: {{number}}", @@ -1032,11 +1082,19 @@ "detectRoleWarning": "Przynajmniej jeden strumień musi mieć rolę \"detect\".", "rolesPopover": { "title": "Role strumienia", - "detect": "Główny strumień służący do wykrywania obiektów." + "detect": "Główny strumień służący do wykrywania obiektów.", + "record": "Zapisuje fragmenty strumienia wideo zgodnie z ustawieniami konfiguracyjnymi.", + "audio": "Kanał do wykrywania opartego na dźwięku." }, "featuresPopover": { - "title": "Funkcje strumienia" - } + "title": "Funkcje strumienia", + "description": "Użyj funkcji ponownego przesyłania strumienia go2rtc, aby zmniejszyć liczbę połączeń z kamerą." + }, + "description": "Skonfiguruj role strumieni i dodaj dodatkowe strumienie dla swojej kamery.", + "streamsTitle": "Strumienie kamery", + "addStream": "Dodaj strumień", + "addAnotherStream": "Dodaj kolejny strumień", + "searchCandidates": "Szukaj kandydatów..." }, "step4": { "description": "Końcowa walidacja i analiza przed zapisaniem ustawień nowej kamery. Połącz się z każdym strumieniem przed zapisaniem.", @@ -1053,7 +1111,7 @@ "ffmpegModuleDescription": "Jeżeli po kilku próbach strumień nadal nie ładuje się, uruchom ten tryb. Gdy włączony jest ten tryb Frigate będzie używać modułu ffmpeg z go2rtc. Może to zapewnić lepszą kompatybilność z niektórymi typami strumieniów.", "none": "Brak", "error": "Błąd", - "streamValidated": "Strumień numer: {{number}} przeszedł test pozytywnie.", + "streamValidated": "Strumień numer: {{number}} przeszedł test pozytywnie", "streamValidationFailed": "Strumień numer: {{number}} test nieudany", "saveAndApply": "Zapisz nową kamerę", "saveError": "Nieprawidłowa konfiguracja. Sprawdź ustawienia.", @@ -1065,11 +1123,26 @@ "noAudioWarning": "Nie wykryto dźwięku dla tego strumienia, nagrania również nie będą zawierać dźwięku.", "audioCodecRecordError": "Kodek AAC jest wymagany aby uwzględnić dźwięk w nagraniach.", "audioCodecRequired": "Strumień audio jest wymagany aby umożliwić wykrywanie dźwięku.", - "restreamingWarning": "Ograniczenie ilości połączeń do strumienia nagrań może delikatnie zwiększyć użycie procesora", + "restreamingWarning": "Ograniczenie ilości połączeń do strumienia nagrań może delikatnie zwiększyć użycie procesora.", "brands": { - "reolink-rtsp": "Strumień RTSP dla kamer firmy Reolink nie jest rekomendowany. Uruchom strumień HTTP w oprogramowaniu kamery i uruchom kreator jeszcze raz." + "reolink-rtsp": "Strumień RTSP dla kamer firmy Reolink nie jest rekomendowany. Uruchom strumień HTTP w oprogramowaniu kamery i uruchom kreator jeszcze raz.", + "reolink-http": "Strumienie HTTP Reolink powinny korzystać z FFmpeg w celu zapewnienia lepszej kompatybilności. Włącz opcję 'Użyj trybu kompatybilności strumienia' dla tego strumienia." + }, + "videoCodecGood": "Kodek wideo to {{codec}}.", + "dahua": { + "substreamWarning": "Podstrumień 1 jest zablokowany na niskiej rozdzielczości. Wiele kamer Dahua / Amcrest / EmpireTech obsługuje dodatkowe podstrumienie, które należy włączyć w ustawieniach kamery. Zaleca się sprawdzenie i wykorzystanie tych strumieni, jeśli są dostępne." + }, + "hikvision": { + "substreamWarning": "Podstrumień 1 jest zablokowany na niskiej rozdzielczości. Wiele kamer Hikvision obsługuje dodatkowe podstrumienie, które należy włączyć w ustawieniach kamery. Zaleca się sprawdzenie i wykorzystanie tych strumieni, jeśli są dostępne." } - } + }, + "connectAllStreams": "Podłącz wszystkie strumienie", + "reconnectionPartial": "Niektóre strumienie nie zostały ponownie połączone.", + "reload": "Przeładuj", + "failed": "Nie powiodło się", + "notTested": "Nietestowane", + "connectStream": "Połącz", + "ffmpegModule": "Użyj trybu zgodności strumienia" }, "description": "Wykonaj poniższe kroki aby dodać nową kamerę do Frigate." }, @@ -1080,7 +1153,8 @@ "selectCamera": "Wybierz kamerę", "backToSettings": "Powrót do ustawień kamery", "streams": { - "title": "Włącz / Wyłącz kamery" + "title": "Włącz / Wyłącz kamery", + "desc": "Tymczasowo wyłącz kamerę do momentu ponownego uruchomienia Frigate. Wyłączenie kamery całkowicie zatrzymuje przetwarzanie strumieni z tej kamery przez program Frigate. Funkcje detekcji, nagrywania i debugowania będą niedostępne.
    Uwaga: nie powoduje to wyłączenia strumieni go2rtc." }, "cameraConfig": { "add": "Dodaj kamerę", @@ -1115,7 +1189,9 @@ "cameraReview": { "review": { "alerts": "Alerty ", - "detections": "Wykrycia " + "detections": "Wykrycia ", + "title": "Recenzja", + "desc": "Tymczasowo włącz/wyłącz alerty i wykrywania dla tej kamery do momentu ponownego uruchomienia programu Frigate. Po wyłączeniu nie będą generowane żadne nowe elementy do przeglądu. " }, "reviewClassification": { "title": "Przegląd klasyfikacji", @@ -1129,7 +1205,22 @@ "unsavedChanges": "Niezapisane ustawienia klasyfikacji przeglądu dla kamery {{camera}}", "selectAlertsZones": "Wybierz strefę dla Alertów", "selectDetectionsZones": "Wybierz strefę dla Wykryć", - "limitDetections": "Ogranicz detekcje do konkretnych stref" + "limitDetections": "Ogranicz detekcje do konkretnych stref", + "desc": "Frigate dzieli elementy do przeglądu na alarmy i detekcje. Domyślnie wszystkie obiekty typu osoba i samochód są traktowane jako alerty. Możesz doprecyzować kategoryzację elementów do przeglądu, konfigurując dla nich wymagane strefy.", + "objectAlertsTips": "Wszystkie obiekty {{alertsLabels}} w {{cameraName}} będą wyświetlane jako alarmy.", + "zoneObjectAlertsTips": "Wszystkie obiekty {{alertsLabels}} wykryte w {{zone}} na {{cameraName}} zostaną wyświetlone jako alarmy.", + "toast": { + "success": "Konfiguracja klasyfikacji została zapisana. Uruchom ponownie program Frigate, aby zastosować zmiany." + } + }, + "title": "Ustawienia przeglądu kamery", + "object_descriptions": { + "title": "Generatywne opisy obiektów AI", + "desc": "Tymczasowo włącz/wyłącz generatywne opisy obiektów AI dla tej kamery. Po wyłączeniu funkcja nie będzie generować opisów AI dla obiektów śledzonych przez tę kamerę." + }, + "review_descriptions": { + "title": "Opisy generatywnej sztucznej inteligencji", + "desc": "Tymczasowo włącz/wyłącz generatywne opisy AI dla tej kamery. Po wyłączeniu opisy generowane przez AI nie będą wymagane dla elementów przeglądu w tej kamerze." } } } diff --git a/web/public/locales/pl/views/system.json b/web/public/locales/pl/views/system.json index d6fe5ea89..ebcc11463 100644 --- a/web/public/locales/pl/views/system.json +++ b/web/public/locales/pl/views/system.json @@ -45,7 +45,8 @@ "npuMemory": "Pamięć NPU", "intelGpuWarning": { "message": "Statystyki układu graficznego niedostępne", - "description": "W narzędziach telemetrii i statystyki układów graficznych firmy Intel (intel_gpu_top) znajduje się znany błąd powodujący raportowanie użycia układu graficznego wynoszące 0%, nawet gdy akceleracja sprzętowa i wykrywanie obiektów działa prawidłowo korzystając ze zintegrowanego układu graficznego. To nie jest błąd oprogramowania Frigate. Restart hosta może chwilowo rozwiązać problem i pozwolić na weryfikację działania układu graficznego. Ten bład nie wpływa na wydajność systemu," + "description": "W narzędziach telemetrii i statystyki układów graficznych firmy Intel (intel_gpu_top) znajduje się znany błąd powodujący raportowanie użycia układu graficznego wynoszące 0%, nawet gdy akceleracja sprzętowa i wykrywanie obiektów działa prawidłowo korzystając ze zintegrowanego układu graficznego. To nie jest błąd oprogramowania Frigate. Restart hosta może chwilowo rozwiązać problem i pozwolić na weryfikację działania układu graficznego. Ten bład nie wpływa na wydajność systemu.", + "title": "Ostrzeżenie dotyczące statystyk Intel GPU" } }, "title": "Ogólne", @@ -60,13 +61,20 @@ "otherProcesses": { "title": "Inne procesy", "processCpuUsage": "Użycie CPU przez proces", - "processMemoryUsage": "Użycie pamięci przez proces" + "processMemoryUsage": "Użycie pamięci przez proces", + "series": { + "audio_detector": "detektor dźwięku", + "go2rtc": "go2rtc", + "recording": "nagranie", + "review_segment": "przejrzyj fragment", + "embeddings": "osadzone opisy" + } } }, "cameras": { "info": { "stream": "Strumień {{idx}}", - "cameraProbeInfo": "{{camera}} Informacje o sondowaniu kamery", + "cameraProbeInfo": "{{camera}} Informacje o ustawieniach kamery", "streamDataFromFFPROBE": "Dane strumienia są pozyskiwane za pomocą ffprobe.", "video": "Wideo:", "codec": "Kodek:", @@ -117,12 +125,12 @@ }, "title": "Magazyn kamery", "camera": "Kamera", - "storageUsed": "Wykorzystany magazyn", + "storageUsed": "Wykorzystana przestrzeń", "percentageOfTotalUsed": "Procent całości", "bandwidth": "Przepustowość", "unusedStorageInformation": "Informacja o niewykorzystanym magazynie" }, - "title": "Magazyn", + "title": "Przestrzeń dyskowa", "overview": "Przegląd", "recordings": { "title": "Nagrania", @@ -187,7 +195,14 @@ "face_recognition": "Rozpoznawanie twarzy", "classification_events_per_second": "{{name}} Klasyfikacja zdarzeń na sekundę", "classification_speed": "{{name}} Szybkość klasyfikacji", - "classification": "{{name}} Klasyfikacja" - } + "classification": "{{name}} Klasyfikacja", + "review_description": "Opis recenzji", + "review_description_speed": "Szybkość opisu recenzji", + "review_description_events_per_second": "Opis recenzji", + "object_description": "Opis obiektu", + "object_description_speed": "Szybkość opisu obiektu", + "object_description_events_per_second": "Opis obiektu" + }, + "averageInf": "Średni czas wnioskowania" } } From 311549536c1d9dd7ae74c925a309cf204973a37c Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:55 +0100 Subject: [PATCH 23/98] Translated using Weblate (Italian) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Italian) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Italian) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Italian) Currently translated at 100.0% (43 of 43 strings) Co-authored-by: Gringo Co-authored-by: Hosted Weblate Co-authored-by: Nton Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/it/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/it/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/it/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/it/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/it/common.json | 3 ++- web/public/locales/it/views/events.json | 6 +++++- web/public/locales/it/views/explore.json | 5 ++++- web/public/locales/it/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/it/common.json b/web/public/locales/it/common.json index 7fc7fc2bf..7967311bd 100644 --- a/web/public/locales/it/common.json +++ b/web/public/locales/it/common.json @@ -154,7 +154,8 @@ "show": "Mostra {{item}}", "ID": "ID", "none": "Nessuna", - "all": "Tutte" + "all": "Tutte", + "other": "Altro" }, "menu": { "configuration": "Configurazione", diff --git a/web/public/locales/it/views/events.json b/web/public/locales/it/views/events.json index 623fb1dee..f1a9255f7 100644 --- a/web/public/locales/it/views/events.json +++ b/web/public/locales/it/views/events.json @@ -8,7 +8,11 @@ "empty": { "alert": "Non ci sono avvisi da rivedere", "detection": "Non ci sono rilevamenti da rivedere", - "motion": "Nessun dato di movimento trovato" + "motion": "Nessun dato di movimento trovato", + "recordingsDisabled": { + "description": "Gli elementi di revisione possono essere creati per una telecamera solo quando le registrazioni sono abilitate per quella telecamera.", + "title": "Le registrazioni devono essere abilitate" + } }, "newReviewItems": { "label": "Visualizza i nuovi elementi da rivedere", diff --git a/web/public/locales/it/views/explore.json b/web/public/locales/it/views/explore.json index 2ec1f4614..498e09465 100644 --- a/web/public/locales/it/views/explore.json +++ b/web/public/locales/it/views/explore.json @@ -110,7 +110,10 @@ "title": "Modifica attributi", "desc": "Seleziona gli attributi di classificazione per questa {{label}}" }, - "attributes": "Attributi di classificazione" + "attributes": "Attributi di classificazione", + "title": { + "label": "Titolo" + } }, "objectLifecycle": { "annotationSettings": { diff --git a/web/public/locales/it/views/system.json b/web/public/locales/it/views/system.json index c4f4b9677..d5e92543b 100644 --- a/web/public/locales/it/views/system.json +++ b/web/public/locales/it/views/system.json @@ -84,7 +84,14 @@ "otherProcesses": { "title": "Altri processi", "processCpuUsage": "Utilizzo CPU processo", - "processMemoryUsage": "Utilizzo memoria processo" + "processMemoryUsage": "Utilizzo memoria processo", + "series": { + "go2rtc": "go2rtc", + "recording": "registrazione", + "review_segment": "segmento di revisione", + "embeddings": "incorporamenti", + "audio_detector": "rilevatore audio" + } } }, "enrichments": { From d1a184d4ac606ad26cd51ded694c307a7b1f3d3c Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:56 +0100 Subject: [PATCH 24/98] Translated using Weblate (Arabic) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Arabic) Currently translated at 0.8% (1 of 122 strings) Co-authored-by: Hosted Weblate Co-authored-by: Med Taha Ben Brahim Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/ar/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/ar/ Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-facelibrary --- .../locales/ar/views/classificationModel.json | 6 +- web/public/locales/ar/views/faceLibrary.json | 86 ++++++++++++++++++- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/web/public/locales/ar/views/classificationModel.json b/web/public/locales/ar/views/classificationModel.json index 0967ef424..bc814e6f5 100644 --- a/web/public/locales/ar/views/classificationModel.json +++ b/web/public/locales/ar/views/classificationModel.json @@ -1 +1,5 @@ -{} +{ + "train": { + "titleShort": "الأخيرة" + } +} diff --git a/web/public/locales/ar/views/faceLibrary.json b/web/public/locales/ar/views/faceLibrary.json index c6c2c394e..5a40c8c59 100644 --- a/web/public/locales/ar/views/faceLibrary.json +++ b/web/public/locales/ar/views/faceLibrary.json @@ -1,6 +1,6 @@ { "description": { - "addFace": "قم بإضافة مجموعة جديدة لمكتبة الأوجه.", + "addFace": "أضف مجموعة جديدة إلى مكتبة الوجوه عن طريق رفع صورتك الأولى.", "invalidName": "أسم غير صالح. يجب أن يشمل الأسم فقط على الحروف، الأرقام، المسافات، الفاصلة العليا، الشرطة التحتية، والشرطة الواصلة.", "placeholder": "أدخل أسم لهذه المجموعة" }, @@ -21,6 +21,88 @@ "collections": "المجموعات", "createFaceLibrary": { "title": "إنشاء المجاميع", - "desc": "إنشاء مجموعة جديدة" + "desc": "إنشاء مجموعة جديدة", + "new": "إضافة وجه جديد", + "nextSteps": "لبناء أساس قوي:
  • استخدم علامة التبويب \"التعرّفات الأخيرة\" لاختيار الصور والتدريب عليها لكل شخص تم اكتشافه.
  • ركّز على الصور الأمامية المباشرة للحصول على أفضل النتائج؛ وتجنّب صور التدريب التي تُظهر الوجوه بزاوية.
  • " + }, + "steps": { + "faceName": "ادخل اسم للوجه", + "uploadFace": "ارفع صورة للوجه", + "nextSteps": "الخطوة التالية", + "description": { + "uploadFace": "قم برفع صورة لـ {{name}} تُظهر وجهه من زاوية أمامية مباشرة. لا يلزم أن تكون الصورة مقتصرة على الوجه فقط." + } + }, + "train": { + "title": "التعرّفات الأخيرة", + "titleShort": "الأخيرة", + "aria": "اختر التعرّفات الأخيرة", + "empty": "لا توجد أي محاولات حديثة للتعرّف على الوجوه" + }, + "deleteFaceLibrary": { + "title": "احذف الاسم", + "desc": "هل أنت متأكد أنك تريد حذف المجموعة {{name}}؟ سيؤدي هذا إلى حذف جميع الوجوه المرتبطة بها نهائيًا." + }, + "deleteFaceAttempts": { + "title": "احذف الوجوه", + "desc_zero": "وجه", + "desc_one": "وجه", + "desc_two": "وجهان", + "desc_few": "وجوه", + "desc_many": "وجهًا", + "desc_other": "وجه" + }, + "renameFace": { + "title": "اعادة تسمية الوجه", + "desc": "ادخل اسم جديد لـ{{name}}" + }, + "button": { + "deleteFaceAttempts": "احذف الوجوه", + "addFace": "اظف وجهًا", + "renameFace": "اعد تسمية وجه", + "deleteFace": "احذف وجهًا", + "uploadImage": "ارفع صورة", + "reprocessFace": "إعادة معالجة الوجه" + }, + "imageEntry": { + "validation": { + "selectImage": "يرجى اختيار ملف صورة." + }, + "dropActive": "اسحب الصورة إلى هنا…", + "dropInstructions": "اسحب وأفلت أو الصق صورة هنا، أو انقر للاختيار", + "maxSize": "الحجم الأقصى: {{size}} ميغابايت" + }, + "nofaces": "لا توجد وجوه متاحة", + "trainFaceAs": "درّب الوجه كـ:", + "trainFace": "درّب الوجه", + "toast": { + "success": { + "uploadedImage": "تم رفع الصورة بنجاح.", + "addFaceLibrary": "تمت إضافة {{name}} بنجاح إلى مكتبة الوجوه!", + "deletedFace_zero": "وجه", + "deletedFace_one": "وجه", + "deletedFace_two": "وجهين", + "deletedFace_few": "وجوه", + "deletedFace_many": "وجهًا", + "deletedFace_other": "وجه", + "deletedName_zero": "وجه", + "deletedName_one": "وجه", + "deletedName_two": "وجهين", + "deletedName_few": "وجوه", + "deletedName_many": "وجهًا", + "deletedName_other": "وجه", + "renamedFace": "تمت إعادة تسمية الوجه بنجاح إلى {{name}}", + "trainedFace": "تم تدريب الوجه بنجاح.", + "updatedFaceScore": "تم تحديث درجة الوجه بنجاح إلى {{name}} ({{score}})." + }, + "error": { + "uploadingImageFailed": "فشل في رفع الصورة: {{errorMessage}}", + "addFaceLibraryFailed": "فشل في تعيين اسم الوجه: {{errorMessage}}", + "deleteFaceFailed": "فشل الحذف: {{errorMessage}}", + "deleteNameFailed": "فشل في حذف الاسم: {{errorMessage}}", + "renameFaceFailed": "فشل في إعادة تسمية الوجه: {{errorMessage}}", + "trainFailed": "فشل التدريب: {{errorMessage}}", + "updateFaceScoreFailed": "فشل في تحديث درجة الوجه: {{errorMessage}}" + } } } From 0a24e3ce67603e28cc3eb8576e9c1f2dd28a19d2 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:56 +0100 Subject: [PATCH 25/98] Translated using Weblate (Dutch) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (131 of 131 strings) Co-authored-by: Hosted Weblate Co-authored-by: Marijn <168113859+Marijn0@users.noreply.github.com> Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/nl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/nl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/nl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/nl/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/nl/common.json | 3 ++- web/public/locales/nl/views/events.json | 6 +++++- web/public/locales/nl/views/explore.json | 5 ++++- web/public/locales/nl/views/system.json | 14 ++++++++++++-- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/web/public/locales/nl/common.json b/web/public/locales/nl/common.json index 17d91279c..045ce5199 100644 --- a/web/public/locales/nl/common.json +++ b/web/public/locales/nl/common.json @@ -148,7 +148,8 @@ "show": "Toon {{item}}", "ID": "ID", "none": "Geen", - "all": "Alle" + "all": "Alle", + "other": "Overige" }, "menu": { "system": "Systeem", diff --git a/web/public/locales/nl/views/events.json b/web/public/locales/nl/views/events.json index 308637378..b4be69aef 100644 --- a/web/public/locales/nl/views/events.json +++ b/web/public/locales/nl/views/events.json @@ -13,7 +13,11 @@ "empty": { "alert": "Er zijn geen meldingen om te beoordelen", "detection": "Er zijn geen detecties om te beoordelen", - "motion": "Geen bewegingsgegevens gevonden" + "motion": "Geen bewegingsgegevens gevonden", + "recordingsDisabled": { + "title": "Opnames moeten zijn ingeschakeld", + "description": "Beoordelingsitems kunnen alleen voor een camera worden aangemaakt als opnames voor die camera zijn ingeschakeld." + } }, "events": { "aria": "Selecteer activiteiten", diff --git a/web/public/locales/nl/views/explore.json b/web/public/locales/nl/views/explore.json index 7372925d7..dcef557f0 100644 --- a/web/public/locales/nl/views/explore.json +++ b/web/public/locales/nl/views/explore.json @@ -167,7 +167,10 @@ "title": "Bewerk attributen", "desc": "Selecteer classificatiekenmerken voor dit {{label}}" }, - "attributes": "Classificatie-kenmerken" + "attributes": "Classificatie-kenmerken", + "title": { + "label": "Titel" + } }, "itemMenu": { "downloadVideo": { diff --git a/web/public/locales/nl/views/system.json b/web/public/locales/nl/views/system.json index 94797952c..73ba194d0 100644 --- a/web/public/locales/nl/views/system.json +++ b/web/public/locales/nl/views/system.json @@ -85,7 +85,14 @@ "otherProcesses": { "processMemoryUsage": "Process Geheugen Gebruik", "processCpuUsage": "Process CPU-verbruik", - "title": "Verdere Processen" + "title": "Verdere Processen", + "series": { + "go2rtc": "go2rtc", + "recording": "opname", + "review_segment": "beoordelingssegment", + "embeddings": "inbeddingen", + "audio_detector": "Geluidsdetector" + } }, "title": "Algemeen" }, @@ -192,7 +199,10 @@ "review_description_events_per_second": "Beoordelingsbeschrijving", "object_description": "Objectbeschrijving", "object_description_speed": "Objectbeschrijvingssnelheid", - "object_description_events_per_second": "Objectbeschrijving" + "object_description_events_per_second": "Objectbeschrijving", + "classification": "{{name}} Classificatie", + "classification_speed": "{{name}} Classificatiesnelheid", + "classification_events_per_second": "{{name}} Classificatie gebeurtenissen per seconde" }, "averageInf": "Gemiddelde inferentietijd" } From 53a592322a5e3087e44995df382838e6754b7107 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:56 +0100 Subject: [PATCH 26/98] Translated using Weblate (Spanish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 98.5% (134 of 136 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (118 of 118 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (131 of 131 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (49 of 49 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (501 of 501 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (122 of 122 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (122 of 122 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (74 of 74 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (55 of 55 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (92 of 92 strings) Co-authored-by: Ancor Trujillo Co-authored-by: Hosted Weblate Co-authored-by: José María Díaz Co-authored-by: klakiti Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/es/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/es/ Translation: Frigate NVR/audio Translation: Frigate NVR/common Translation: Frigate NVR/components-dialog Translation: Frigate NVR/components-filter Translation: Frigate NVR/objects Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-live Translation: Frigate NVR/views-search Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/es/audio.json | 88 ++++- web/public/locales/es/common.json | 35 +- web/public/locales/es/components/dialog.json | 10 +- web/public/locales/es/components/filter.json | 4 + web/public/locales/es/objects.json | 2 +- .../locales/es/views/classificationModel.json | 147 ++++++- web/public/locales/es/views/events.json | 12 +- web/public/locales/es/views/explore.json | 74 +++- web/public/locales/es/views/faceLibrary.json | 13 +- web/public/locales/es/views/live.json | 16 +- web/public/locales/es/views/search.json | 3 +- web/public/locales/es/views/settings.json | 370 ++++++++++++++++-- web/public/locales/es/views/system.json | 28 +- 13 files changed, 731 insertions(+), 71 deletions(-) diff --git a/web/public/locales/es/audio.json b/web/public/locales/es/audio.json index 16288b261..2641cb561 100644 --- a/web/public/locales/es/audio.json +++ b/web/public/locales/es/audio.json @@ -31,7 +31,7 @@ "crying": "Llanto", "synthetic_singing": "Canto sintético", "rapping": "Rap", - "humming": "Tarareo", + "humming": "Zumbido leve", "groan": "Gemido", "grunt": "Gruñido", "whistling": "Silbido", @@ -129,7 +129,7 @@ "sitar": "Sitar", "mandolin": "Mandolina", "zither": "Cítara", - "ukulele": "Ukulele", + "ukulele": "Ukelele", "piano": "Piano", "organ": "Órgano", "electronic_organ": "Órgano electrónico", @@ -153,7 +153,7 @@ "mallet_percussion": "Percusión con mazas", "marimba": "Marimba", "glockenspiel": "Glockenspiel", - "steelpan": "Steelpan", + "steelpan": "SarténAcero", "orchestra": "Orquesta", "trumpet": "Trompeta", "string_section": "Sección de cuerdas", @@ -183,13 +183,13 @@ "psychedelic_rock": "Rock psicodélico", "rhythm_and_blues": "Rhythm and blues", "soul_music": "Música soul", - "country": "Country", + "country": "País", "swing_music": "Música swing", "disco": "Disco", "house_music": "Música House", "dubstep": "Dubstep", "drum_and_bass": "Drum and Bass", - "electronica": "Electronica", + "electronica": "Electrónica", "electronic_dance_music": "Música Dance Electronica", "music_of_latin_america": "Música de América Latina", "salsa_music": "Música Salsa", @@ -207,7 +207,7 @@ "song": "Canción", "background_music": "Música Background", "soundtrack_music": "Música de Pelicula", - "lullaby": "Lullaby", + "lullaby": "Cancion de cuna", "video_game_music": "Música de Videojuego", "christmas_music": "Música Navideña", "sad_music": "Música triste", @@ -425,5 +425,79 @@ "radio": "Radio", "gunshot": "Disparo", "fusillade": "Descarga de Fusilería", - "pink_noise": "Ruido Rosa" + "pink_noise": "Ruido Rosa", + "shofar": "Shofar", + "liquid": "Líquido", + "splash": "Chapoteo", + "slosh": "líquido_en_movimiento", + "squish": "Chapotear", + "drip": "Goteo", + "pour": "Derramar", + "trickle": "Chorrito", + "gush": "Chorro", + "fill": "Llenar", + "spray": "Pulverizar", + "pump": "Bombear", + "stir": "Remover", + "boiling": "Hirviendo", + "sonar": "Sonar", + "arrow": "Flecha", + "whoosh": "Zas", + "thump": "Golpear", + "thunk": "Golpe_sordo", + "electronic_tuner": "Afinador_electrónico", + "effects_unit": "Unidades de efecto", + "chorus_effect": "Efecto Coral", + "basketball_bounce": "Bote baloncesto", + "bang": "Bang", + "slap": "Bofeteada", + "whack": "Aporreo", + "smash": "Aplastar", + "breaking": "Romper", + "bouncing": "Botar", + "whip": "Latigazo", + "flap": "Aleteo", + "scratch": "Arañazo", + "scrape": "Arañar", + "rub": "Frotar", + "roll": "Roll", + "crushing": "aplastar", + "crumpling": "Arrugar", + "tearing": "Rasgar", + "beep": "Bip", + "ping": "Ping", + "ding": "Ding", + "clang": "Sonido metálico", + "squeal": "Chillido", + "creak": "Crujido", + "rustle": "Crujir", + "whir": "Zumbido de ventilador", + "clatter": "Estrépito", + "sizzle": "Chisporroteo", + "clicking": "Click", + "clickety_clack": "Clic-clac", + "rumble": "Retumbar", + "plop": "Plaf", + "hum": "Murmullo", + "zing": "silbido", + "boing": "Bote", + "crunch": "Crujido", + "sine_wave": "Onda Sinusoidal", + "harmonic": "Harmonica", + "chirp_tone": "Tono de chirrido", + "pulse": "Pulso", + "inside": "Dentro", + "outside": "Afuera", + "reverberation": "Reverberación", + "echo": "Eco", + "noise": "Ruido", + "mains_hum": "Zumbido de red", + "distortion": "Distorsión", + "sidetone": "Tono lateral", + "cacophony": "Cacofonía", + "throbbing": "Palpitación", + "vibration": "Vibración", + "sodeling": "Sodeling", + "chird": "Chird", + "change_ringing": "Cambio timbre" } diff --git a/web/public/locales/es/common.json b/web/public/locales/es/common.json index 9f35ee958..13d094ac2 100644 --- a/web/public/locales/es/common.json +++ b/web/public/locales/es/common.json @@ -87,7 +87,10 @@ "formattedTimestampMonthDayYear": { "12hour": "MMM d, yyyy", "24hour": "MMM d, yyyy" - } + }, + "inProgress": "En progreso", + "invalidStartTime": "Hora de inicio no válida", + "invalidEndTime": "Hora de finalización no válida" }, "menu": { "settings": "Ajustes", @@ -189,7 +192,8 @@ "review": "Revisar", "explore": "Explorar", "uiPlayground": "Zona de pruebas de la interfaz de usuario", - "faceLibrary": "Biblioteca de rostros" + "faceLibrary": "Biblioteca de rostros", + "classification": "Clasificación" }, "unit": { "speed": { @@ -199,6 +203,14 @@ "length": { "meters": "Metros", "feet": "Pies" + }, + "data": { + "kbps": "kB/s", + "mbps": "MB/s", + "gbps": "GB/s", + "kbph": "kB/hora", + "mbph": "MB/hora", + "gbph": "GB/hora" } }, "button": { @@ -236,7 +248,8 @@ "enabled": "Habilitado", "saving": "Guardando…", "exitFullscreen": "Salir de pantalla completa", - "on": "ENCENDIDO" + "on": "ENCENDIDO", + "continue": "Continuar" }, "toast": { "save": { @@ -249,7 +262,12 @@ "copyUrlToClipboard": "URL copiada al portapapeles." }, "label": { - "back": "Volver atrás" + "back": "Volver atrás", + "hide": "Ocultar {{item}}", + "show": "Mostrar {{item}}", + "ID": "ID", + "none": "Ninguno", + "all": "Todas" }, "role": { "title": "Rol", @@ -283,5 +301,14 @@ "readTheDocumentation": "Leer la documentación", "information": { "pixels": "{{area}}px" + }, + "list": { + "two": "{{0}} y {{1}}", + "many": "{{items}}, y {{last}}", + "separatorWithSpace": ", " + }, + "field": { + "optional": "Opcional", + "internalID": "La ID interna que usa Frigate en la configuración y en la base de datos" } } diff --git a/web/public/locales/es/components/dialog.json b/web/public/locales/es/components/dialog.json index e200c388d..98c96528f 100644 --- a/web/public/locales/es/components/dialog.json +++ b/web/public/locales/es/components/dialog.json @@ -66,10 +66,11 @@ "toast": { "error": { "failed": "No se pudo iniciar la exportación: {{error}}", - "noVaildTimeSelected": "No se seleccionó un rango de tiempo válido.", - "endTimeMustAfterStartTime": "La hora de finalización debe ser posterior a la hora de inicio." + "noVaildTimeSelected": "No se seleccionó un rango de tiempo válido", + "endTimeMustAfterStartTime": "La hora de finalización debe ser posterior a la hora de inicio" }, - "success": "Exportación iniciada con éxito. Ver el archivo en la página exportaciones." + "success": "Exportación iniciada con éxito. Ver el archivo en la página exportaciones.", + "view": "Ver" }, "fromTimeline": { "saveExport": "Guardar exportación", @@ -129,6 +130,7 @@ "search": { "placeholder": "Búsqueda por etiqueta o sub-etiqueta..." }, - "noImages": "No se encontraron miniaturas para esta cámara" + "noImages": "No se encontraron miniaturas para esta cámara", + "unknownLabel": "Imagen de activación guardada" } } diff --git a/web/public/locales/es/components/filter.json b/web/public/locales/es/components/filter.json index 3625030f9..d9d77d6f9 100644 --- a/web/public/locales/es/components/filter.json +++ b/web/public/locales/es/components/filter.json @@ -133,5 +133,9 @@ }, "count_one": "{{count}} Clase", "count_other": "{{count}} Clases" + }, + "attributes": { + "label": "Clasificación de Atributos", + "all": "Todos los Atributos" } } diff --git a/web/public/locales/es/objects.json b/web/public/locales/es/objects.json index 0e972102c..0fd02208a 100644 --- a/web/public/locales/es/objects.json +++ b/web/public/locales/es/objects.json @@ -102,7 +102,7 @@ "baseball_bat": "Bate de béisbol", "oven": "Horno", "waste_bin": "Papelera", - "snowboard": "Snowboard", + "snowboard": "Tabla de Snow", "sandwich": "Sandwich", "fox": "Zorro", "nzpost": "NZPost", diff --git a/web/public/locales/es/views/classificationModel.json b/web/public/locales/es/views/classificationModel.json index 4890ed058..8d6087a8d 100644 --- a/web/public/locales/es/views/classificationModel.json +++ b/web/public/locales/es/views/classificationModel.json @@ -1,7 +1,7 @@ { - "documentTitle": "Modelos de Clasificación", + "documentTitle": "Modelos de Clasificación - Frigate", "button": { - "deleteClassificationAttempts": "Borrar Imágenes de Clasificación.", + "deleteClassificationAttempts": "Borrar Imágenes de Clasificación", "renameCategory": "Renombrar Clase", "deleteCategory": "Borrar Clase", "deleteImages": "Borrar Imágenes", @@ -30,12 +30,15 @@ "categorizeFailed": "Fallo al categorizar imagen: {{errorMessage}}", "trainingFailed": "El entrenamiento del modelo ha fallado. Revisa los registros de Frigate para más detalles.", "updateModelFailed": "Fallo al actualizar modelo: {{errorMessage}}", - "trainingFailedToStart": "No se pudo iniciar el entrenamiento del modelo: {{errorMessage}}" + "trainingFailedToStart": "No se pudo iniciar el entrenamiento del modelo: {{errorMessage}}", + "renameCategoryFailed": "Falló el renombrado de la clase: {{errorMessage}}" } }, "deleteCategory": { "title": "Borrar Clase", - "desc": "¿Esta seguro de que quiere borrar la clase {{name}}? Esto borrará permanentemente todas las imágenes asociadas y requerirá reentrenar el modelo." + "desc": "¿Esta seguro de que quiere borrar la clase {{name}}? Esto borrará permanentemente todas las imágenes asociadas y requerirá reentrenar el modelo.", + "minClassesTitle": "No se puede Borrar la Clase", + "minClassesDesc": "Un modelo de clasificación debe tener al menos 2 clases. Añade otra clase antes de borrar esta." }, "deleteModel": { "title": "Borrar Modelo de Clasificación", @@ -45,15 +48,145 @@ "desc_other": "¿Estas seguro de que quiere borrar {{count}} modelos? Esto borrara permanentemente todos los datos asociados, incluyendo imágenes y datos de entrenamiento. Esta acción no puede ser desehecha." }, "edit": { - "title": "Editar modelo de clasificación" + "title": "Editar modelo de clasificación", + "descriptionState": "Edita las clases para este modelo de clasificación de estados. Los cambios requerirán un reentrenamiento de modelo.", + "descriptionObject": "Edita el tipo de objeto y el tipo de clasificación para este modelo de clasificación de objetos.", + "stateClassesInfo": "Nota: El cambio de las clases de estado requiere reentrenar el modelo con las clases actualizadas." }, "tooltip": { "noChanges": "No se han realizado cambios en el conjunto de datos desde el último entrenamiento.", "modelNotReady": "El modelo no está listo para el entrenamiento", - "trainingInProgress": "El modelo está entrenándose actualmente.", + "trainingInProgress": "El modelo está entrenándose actualmente", "noNewImages": "No hay imágenes nuevas para entrenar. Clasifica antes más imágenes del conjunto de datos." }, "details": { - "scoreInfo": "La puntuación representa la confianza media de clasificación en todas las detecciones de este objeto." + "scoreInfo": "La puntuación representa la confianza media de clasificación en todas las detecciones de este objeto.", + "unknown": "Desconocido", + "none": "Nada" + }, + "categorizeImage": "Clasificar Imagen", + "menu": { + "objects": "Objetos", + "states": "Estados" + }, + "wizard": { + "steps": { + "chooseExamples": "Seleccionar Ejemplos", + "nameAndDefine": "Nombrar y definir", + "stateArea": "Área de estado" + }, + "step1": { + "name": "Nombre", + "namePlaceholder": "Introducir nombre del modelo...", + "type": "Tipo", + "typeState": "Estado", + "typeObject": "Objeto", + "objectLabel": "Etiqueta de Objeto", + "objectLabelPlaceholder": "Seleccionar tipo de objeto...", + "classificationAttribute": "Atributo", + "classes": "Clases", + "states": "Estados", + "classPlaceholder": "Introducir nombre de la clase...", + "errors": { + "nameRequired": "Se requiere nombre del modelo", + "nameLength": "El nombre del modelo debe tener 64 caracteres o menos", + "nameOnlyNumbers": "El nombre del modelo no puede contener solo números", + "classRequired": "Al menos se requiere una clase", + "classesUnique": "Los nombres de clase deben ser únicos", + "noneNotAllowed": "La clase 'none' no esta permitida", + "stateRequiresTwoClasses": "Los modelos de estado requieren al menos 2 clases", + "objectLabelRequired": "Por favor seleccione una etiqueta de objeto", + "objectTypeRequired": "Por favor seleccione un tipo de clasificación" + }, + "description": "Los modelos de estado monitorean las áreas fijas de la cámara para detectar cambios (p. ej., puerta abierta/cerrada). Los modelos de objetos clasifican los objetos detectados (p. ej., animales conocidos, repartidores, etc.).", + "classificationType": "Tipo de clasificación", + "classificationTypeTip": "Conozca más sobre los tipos de clasificación", + "classificationTypeDesc": "Las subetiquetas añaden texto adicional a la etiqueta del objeto (p. ej., «Persona: UPS»). Los atributos son metadatos que permiten búsquedas y se almacenan por separado en los metadatos del objeto.", + "classificationSubLabel": "Sub etiqueta", + "classesTip": "Aprenda más sobre clases", + "classesStateDesc": "Define los diferentes estados en los que puede estar el área de tu cámara. Por ejemplo: \"abierta\" y \"cerrada\" para una puerta de garaje.", + "classesObjectDesc": "Define las diferentes categorías para clasificar los objetos detectados. Por ejemplo: \"persona de reparto\", \"residente\" y \"desconocido\" para la clasificación de personas." + }, + "step2": { + "description": "Seleccione las cámaras y defina el area a monitorizar por cada cámara. El modelo clasificará el estado de estas cámaras.", + "cameras": "Camaras", + "selectCamera": "Selecciones Cámara", + "noCameras": "Haga clic en + para añadir cámaras", + "selectCameraPrompt": "Seleccione una cámara de la lista para definir su área de monitorización" + }, + "step3": { + "selectImagesPrompt": "Seleccione todas las imágenes de: {{className}}", + "selectImagesDescription": "Haga clic en las imágenes para seleccionarlas. Haga clic en Continuar cuando esté listo para esta clase.", + "generating": { + "title": "Generando Imágenes de Ejemplo", + "description": "Frigate está seleccionando imágenes representativas de sus grabaciones. Esto puede llevar un tiempo..." + }, + "training": { + "title": "Modelo de Entrenamiento", + "description": "Tu modelo se está entrenando en segundo plano. Cierra este cuadro de diálogo y tu modelo comenzará a ejecutarse en cuanto finalice el entrenamiento." + }, + "retryGenerate": "Reintentar Generación", + "noImages": "No se han generado imágenes de ejemplo", + "classifying": "Clasificando y Entrenando...", + "trainingStarted": "Entrenamiento iniciado con éxito", + "modelCreated": "Modelo creado con éxito. Use la vista de Clasificaciones Recientes para añadir imágenes para los estados que falten, después entrene el modelo.", + "errors": { + "noCameras": "No hay cámaras configuradas", + "noObjectLabel": "No se ha seleccionado etiqueta de objeto", + "generateFailed": "Falló la generación de ejemplos: {{error}}", + "generationFailed": "Generación fallida. Por favor pruebe otra vez.", + "classifyFailed": "Falló la clasificación de imágenes: {{error}}" + }, + "generateSuccess": "Imágenes de ejemplo generadas correctamente", + "missingStatesWarning": { + "title": "Faltan Ejemplos de Estado", + "description": "Se recomienda seleccionar ejemplos para todos los estados para obtener mejores resultados. Puede continuar sin seleccionar todos los estados, pero el modelo no se entrenará hasta que todos los estados tengan imágenes. Después de continuar, use la vista \"Clasificaciones recientes\" para clasificar las imágenes de los estados faltantes y luego entrene el modelo." + }, + "allImagesRequired_one": "Por favor clasifique todas las imágenes. Queda {{count}} imagen.", + "allImagesRequired_many": "Por favor clasifique todas las imágenes. Quedan {{count}} imágenes.", + "allImagesRequired_other": "Por favor clasifique todas las imágenes. Quedan {{count}} imágenes." + }, + "title": "Crear nueva Clasificación" + }, + "deleteDatasetImages": { + "title": "Borrar Conjunto de Imágenes", + "desc_one": "¿Está seguro de que quiere eliminar {{count}} imagen de {{dataset}}? Esta acción no puede ser deshecha y requerirá reentrenar el modelo.", + "desc_many": "¿Está seguro de que quiere eliminar {{count}} imágenes de {{dataset}}? Esta acción no puede ser deshecha y requerirá reentrenar el modelo.", + "desc_other": "¿Está seguro de que quiere eliminar {{count}} imágenes de {{dataset}}? Esta acción no puede ser deshecha y requerirá reentrenar el modelo." + }, + "deleteTrainImages": { + "title": "Borrar Imágenes de Entrenamiento", + "desc_one": "¿Está seguro de que quiere eliminar {{count}} imagen? Esta acción no puede ser deshecha.", + "desc_many": "¿Está seguro de que quiere eliminar {{count}} imágenes? Esta acción no puede ser deshecha.", + "desc_other": "¿Está seguro de que quiere eliminar {{count}} imágenes? Esta acción no puede ser deshecha." + }, + "renameCategory": { + "title": "Renombrar Clase", + "desc": "Introduzca un nuevo nombre para {{name}}. Se requerirá que reentrene el modelo para que el cambio de nombre tenga efecto." + }, + "description": { + "invalidName": "Nombre incorrecto. Los nombres solo pueden incluir letras, números, espacios, apóstrofes, guiones bajos, y guiones." + }, + "train": { + "title": "Clasificaciones Recientes", + "titleShort": "Reciente", + "aria": "Seleccione Clasificaciones Recientes" + }, + "categories": "Clases", + "createCategory": { + "new": "Crear Nueva Clase" + }, + "categorizeImageAs": "Clasificar Imagen Como:", + "noModels": { + "object": { + "title": "No hay Modelos de Clasificación de Objetos", + "description": "Crear modelo a medida para clasificar los objetos detectados.", + "buttonText": "Crear Modelo de Objetos" + }, + "state": { + "title": "No hay Modelos de Clasificación de Estados", + "description": "Cree un modelo personalizado para monitorear y clasificar los cambios de estado en áreas específicas de la cámara.", + "buttonText": "Crear modelo de estado" + } } } diff --git a/web/public/locales/es/views/events.json b/web/public/locales/es/views/events.json index b2b4001ba..d13daff60 100644 --- a/web/public/locales/es/views/events.json +++ b/web/public/locales/es/views/events.json @@ -9,7 +9,11 @@ "empty": { "alert": "No hay alertas para revisar", "detection": "No hay detecciones para revisar", - "motion": "No se encontraron datos de movimiento" + "motion": "No se encontraron datos de movimiento", + "recordingsDisabled": { + "title": "Las grabaciones deben estar habilitadas", + "description": "Solo se pueden crear elementos de revisión para una cámara cuando las grabaciones están habilitadas para esa cámara." + } }, "timeline": "Línea de tiempo", "timeline.aria": "Seleccionar línea de tiempo", @@ -56,5 +60,9 @@ "objectTrack": { "clickToSeek": "Clic para ir a este momento", "trackedPoint": "Puntro trazado" - } + }, + "select_all": "Todas", + "normalActivity": "Normal", + "needsReview": "Necesita revisión", + "securityConcern": "Aviso de seguridad" } diff --git a/web/public/locales/es/views/explore.json b/web/public/locales/es/views/explore.json index 7fcd50fb0..f8f61ce83 100644 --- a/web/public/locales/es/views/explore.json +++ b/web/public/locales/es/views/explore.json @@ -42,13 +42,15 @@ "updatedSublabel": "Subetiqueta actualizada con éxito.", "regenerate": "Se ha solicitado una nueva descripción a {{provider}}. Dependiendo de la velocidad de tu proveedor, la nueva descripción puede tardar algún tiempo en regenerarse.", "updatedLPR": "Matrícula actualizada con éxito.", - "audioTranscription": "Transcripción de audio solicitada con éxito." + "audioTranscription": "Se solicitó correctamente la transcripción de audio. Dependiendo de la velocidad de su servidor Frigate, la transcripción puede tardar un tiempo.", + "updatedAttributes": "Atributos actualizados correctamente." }, "error": { "regenerate": "No se pudo llamar a {{provider}} para una nueva descripción: {{errorMessage}}", "updatedSublabelFailed": "No se pudo actualizar la subetiqueta: {{errorMessage}}", "updatedLPRFailed": "No se pudo actualizar la matrícula: {{errorMessage}}", - "audioTranscription": "Transcripción de audio solicitada falló: {{errorMessage}}" + "audioTranscription": "Transcripción de audio solicitada falló: {{errorMessage}}", + "updatedAttributesFailed": "No se pudieron actualizar los atributos: {{errorMessage}}" } }, "tips": { @@ -102,6 +104,14 @@ }, "score": { "label": "Puntuación" + }, + "editAttributes": { + "title": "Editar atributos", + "desc": "Seleccione atributos de clasificación para esta {{label}}" + }, + "attributes": "Atributos de clasificación", + "title": { + "label": "Título" } }, "documentTitle": "Explorar - Frigate", @@ -198,12 +208,26 @@ "addTrigger": { "label": "Añadir disparador", "aria": "Añadir disparador para el objeto seguido" + }, + "downloadCleanSnapshot": { + "label": "Descargue instantánea limpia", + "aria": "Descargue instantánea limpia" + }, + "viewTrackingDetails": { + "label": "Ver detalles de seguimiento", + "aria": "Ver detalles de seguimiento" + }, + "showObjectDetails": { + "label": "Mostrar la ruta del objeto" + }, + "hideObjectDetails": { + "label": "Ocultar la ruta del objeto" } }, "dialog": { "confirmDelete": { "title": "Confirmar eliminación", - "desc": "Eliminar este objeto rastreado elimina la captura de pantalla, cualquier incrustación guardada y cualquier entrada asociada al ciclo de vida del objeto. Las grabaciones de este objeto rastreado en la vista de Historial NO se eliminarán.

    ¿Estás seguro de que quieres proceder?" + "desc": "Al eliminar este objeto rastreado, se eliminan la instantánea, las incrustaciones guardadas y las entradas de detalles de seguimiento asociadas. Las grabaciones de este objeto rastreado en la vista Historial NO se eliminarán.

    ¿Seguro que desea continuar?" } }, "noTrackedObjects": "No se encontraron objetos rastreados", @@ -215,7 +239,9 @@ "error": "No se pudo eliminar el objeto rastreado: {{errorMessage}}" } }, - "tooltip": "Coincidencia con {{type}} al {{confidence}}%" + "tooltip": "Coincidencia con {{type}} al {{confidence}}%", + "previousTrackedObject": "Objeto rastreado previo", + "nextTrackedObject": "Objeto rastreado siguiente" }, "trackedObjectsCount_one": "{{count}} objeto rastreado ", "trackedObjectsCount_many": "{{count}} objetos rastreados ", @@ -235,7 +261,45 @@ "scrollViewTips": "Haz clic para ver los momentos relevantes del ciclo de vida de este objeto.", "count": "{{first}} de {{second}}", "lifecycleItemDesc": { - "visible": "{{label}} detectado" + "visible": "{{label}} detectado", + "active": "{{label}} ha sido activado/a", + "stationary": "{{label}} se volvió estacionaria", + "attribute": { + "faceOrLicense_plate": "{{attribute}} detectado para {{label}}", + "other": "{{label}} reconocido como {{attribute}}" + }, + "gone": "{{label}} ha salido", + "heard": "{{label}} escuchado/a", + "external": "{{label}} detectado", + "header": { + "zones": "Zonas", + "area": "Área", + "score": "Puntuación", + "ratio": "Ratio(proporción)" + }, + "entered_zone": "{{label}} ha entrado en {{zones}}" + }, + "trackedPoint": "Punto rastreado", + "annotationSettings": { + "title": "Configuración de anotaciones", + "showAllZones": { + "title": "Mostrar todas las Zonas", + "desc": "Mostrar siempre zonas en los marcos donde los objetos han entrado en una zona." + }, + "offset": { + "label": "Desplazamiento de anotación", + "desc": "Estos datos provienen de la señal de detección de la cámara, pero se superponen a las imágenes de la señal de grabación. Es poco probable que ambas transmisiones estén perfectamente sincronizadas. Por lo tanto, el cuadro delimitador y el metraje no se alinearán perfectamente. Puede usar esta configuración para desplazar las anotaciones hacia adelante o hacia atrás en el tiempo para que se alineen mejor con el metraje grabado.", + "millisecondsToOffset": "Milisegundos para compensar la detección de anotaciones. Predeterminado: 0", + "tips": "Disminuya el valor si la reproducción de vídeo se produce antes de los cuadros y los puntos de ruta, y auméntelo si se produce después de ellos. Este valor puede ser negativo.", + "toast": { + "success": "El desplazamiento de anotación para {{camera}} se ha guardado en el archivo de configuración." + } + } + }, + "autoTrackingTips": "Las posiciones del cuadro delimitador serán inexactas para las cámaras con seguimiento automático.", + "carousel": { + "previous": "Vista anterior", + "next": "Vista siguiente" } } } diff --git a/web/public/locales/es/views/faceLibrary.json b/web/public/locales/es/views/faceLibrary.json index 25fa983e7..44e1eba01 100644 --- a/web/public/locales/es/views/faceLibrary.json +++ b/web/public/locales/es/views/faceLibrary.json @@ -2,7 +2,7 @@ "description": { "addFace": "Agregar una nueva colección a la Biblioteca de Rostros subiendo tu primera imagen.", "placeholder": "Introduce un nombre para esta colección", - "invalidName": "Nombre inválido. Los nombres solo pueden incluir letras, números, espacios, apóstrofes, guiones bajos y guiones." + "invalidName": "Nombre incorrecto. Los nombres solo pueden incluir letras, números, espacios, apóstrofes, guiones bajos, y guiones." }, "details": { "person": "Persona", @@ -28,7 +28,8 @@ "train": { "title": "Reconocimientos Recientes", "aria": "Seleccionar reconocimientos recientes", - "empty": "No hay intentos recientes de reconocimiento facial" + "empty": "No hay intentos recientes de reconocimiento facial", + "titleShort": "Reciente" }, "selectItem": "Seleccionar {{item}}", "selectFace": "Seleccionar rostro", @@ -59,10 +60,10 @@ "deletedName_one": "{{count}} rostro ha sido eliminado con éxito.", "deletedName_many": "{{count}} rostros han sido eliminados con éxito.", "deletedName_other": "{{count}} rostros han sido eliminados con éxito.", - "updatedFaceScore": "Puntuación del rostro actualizada con éxito.", - "deletedFace_one": "{{count}} rostro eliminado con éxito", - "deletedFace_many": "{{count}} rostros eliminados con éxito", - "deletedFace_other": "{{count}} rostros eliminados con éxito", + "updatedFaceScore": "Puntuación del rostro actualizada con éxito a {{name}} ({{score}}).", + "deletedFace_one": "{{count}} rostro eliminado con éxito.", + "deletedFace_many": "{{count}} rostros eliminados con éxito.", + "deletedFace_other": "{{count}} rostros eliminados con éxito.", "uploadedImage": "Imagen subida con éxito.", "renamedFace": "Rostro renombrado con éxito a {{name}}" }, diff --git a/web/public/locales/es/views/live.json b/web/public/locales/es/views/live.json index 3d8c0b0be..664f7abec 100644 --- a/web/public/locales/es/views/live.json +++ b/web/public/locales/es/views/live.json @@ -86,7 +86,7 @@ }, "manualRecording": { "title": "Bajo demanda", - "tips": "Iniciar un evento manual basado en la configuración de retención de grabaciones de esta cámara.", + "tips": "Descargar una instantánea o Iniciar un evento manual basado en la configuración de retención de grabaciones de esta cámara.", "playInBackground": { "label": "Reproducir en segundo plano", "desc": "Habilitar esta opción para continuar transmitiendo cuando el reproductor esté oculto." @@ -173,7 +173,17 @@ }, "noCameras": { "title": "No hay cámaras configuradas", - "description": "Comienza conectando una cámara.", - "buttonText": "Añade Cámara" + "description": "Comienza conectando una cámara a Frigate.", + "buttonText": "Añade Cámara", + "restricted": { + "title": "No hay cámaras disponibles", + "description": "No tiene permiso para ver ninguna cámara en este grupo." + } + }, + "snapshot": { + "takeSnapshot": "Descarga captura instantánea", + "noVideoSource": "No hay ninguna fuente de video disponible para la instantánea.", + "captureFailed": "Fallo al capturar la instantánea.", + "downloadStarted": "La descarga de la instantánea ha comenzado." } } diff --git a/web/public/locales/es/views/search.json b/web/public/locales/es/views/search.json index 7458c491d..547b17f4e 100644 --- a/web/public/locales/es/views/search.json +++ b/web/public/locales/es/views/search.json @@ -26,7 +26,8 @@ "max_speed": "Velocidad Máxima", "recognized_license_plate": "Matrícula Reconocida", "has_clip": "Tiene Clip", - "has_snapshot": "Tiene Instantánea" + "has_snapshot": "Tiene Instantánea", + "attributes": "Atributos" }, "searchType": { "thumbnail": "Miniatura", diff --git a/web/public/locales/es/views/settings.json b/web/public/locales/es/views/settings.json index 7fe10b3ff..e9745c4f7 100644 --- a/web/public/locales/es/views/settings.json +++ b/web/public/locales/es/views/settings.json @@ -50,7 +50,15 @@ "label": "Reproducir vídeos de alertas", "desc": "De forma predeterminada, las alertas recientes en el panel en directo se reproducen como pequeños vídeos en bucle. Desactiva esta opción para mostrar solo una imagen estática de las alertas recientes en este dispositivo/navegador." }, - "title": "Panel en directo" + "title": "Panel en directo", + "displayCameraNames": { + "label": "Siempre mostrar nombres de las Camaras", + "desc": "Siempre mostrar nombres de cámaras en la vista en vivo multi-cámara." + }, + "liveFallbackTimeout": { + "label": "Tiempo de espera de respaldo del reproductor en vivo", + "desc": "Cuando la reproducción en vivo de alta calidad de la cámara no está disponible, se usará el modo de ancho de banda bajo después de este número de segundos. Por defecto: 3." + } }, "cameraGroupStreaming": { "desc": "La configuración de transmisión de cada grupo de cámaras se guarda en el almacenamiento local de tu navegador.", @@ -232,7 +240,8 @@ "mustNotBeSameWithCamera": "El nombre de la zona no debe ser el mismo que el nombre de la cámara.", "hasIllegalCharacter": "El nombre de la zona contiene caracteres no permitidos.", "mustBeAtLeastTwoCharacters": "El nombre de la zona debe tener al menos 2 caracteres.", - "mustNotContainPeriod": "El nombre de la zona no debe contener puntos." + "mustNotContainPeriod": "El nombre de la zona no debe contener puntos.", + "mustHaveAtLeastOneLetter": "El nombre de la Zona debe contener al menos una letra." } }, "distance": { @@ -298,7 +307,7 @@ "name": { "title": "Nombre", "inputPlaceHolder": "Introduce un nombre…", - "tips": "El nombre debe tener al menos 2 caracteres y no debe ser el nombre de una cámara ni de otra zona." + "tips": "El nombre debe tener al menos 2 caracteres, al menos 1 letra y no debe coincidir con el nombre de una cámara ni de otra zona." }, "documentTitle": "Editar Zona - Frigate", "clickDrawPolygon": "Haz clic para dibujar un polígono en la imagen.", @@ -326,7 +335,7 @@ "point_other": "{{count}} puntos", "allObjects": "Todos los objetos", "toast": { - "success": "La zona ({{zoneName}}) ha sido guardada. Reinicia Frigate para aplicar los cambios." + "success": "La zona ({{zoneName}}) ha sido guardada." } }, "toast": { @@ -360,8 +369,8 @@ }, "toast": { "success": { - "noName": "La máscara de movimiento ha sido guardada. Reinicia Frigate para aplicar los cambios.", - "title": "{{polygonName}} ha sido guardado. Reinicia Frigate para aplicar los cambios." + "noName": "La máscara de movimiento ha sido guardada.", + "title": "{{polygonName}} ha sido guardado." } }, "documentTitle": "Editar Máscara de Movimiento - Frigate", @@ -386,8 +395,8 @@ }, "toast": { "success": { - "noName": "La máscara de objetos ha sido guardada. Reinicia Frigate para aplicar los cambios.", - "title": "{{polygonName}} ha sido guardado. Reinicia Frigate para aplicar los cambios." + "noName": "La máscara de objetos ha sido guardada.", + "title": "{{polygonName}} ha sido guardado." } }, "point_one": "{{count}} punto", @@ -509,7 +518,7 @@ "role": "Rol", "noUsers": "No se encontraron usuarios.", "changeRole": "Cambiar el rol del usuario", - "password": "Contraseña", + "password": "Restablecer Contraseña", "deleteUser": "Eliminar usuario" }, "dialog": { @@ -534,7 +543,16 @@ "veryStrong": "Muy fuerte" }, "match": "Las contraseñas coinciden", - "notMatch": "Las contraseñas no coinciden" + "notMatch": "Las contraseñas no coinciden", + "show": "Mostrar contraseña", + "hide": "Ocultar contraseña", + "requirements": { + "title": "Requisitos de contraseña:", + "length": "Al menos 8 caracteres", + "uppercase": "Al menos una mayúscula", + "digit": "Al menos un número", + "special": "Al menos un caracter especial (!@#$%^&*(),.?\":{}|<>)" + } }, "newPassword": { "title": "Nueva contraseña", @@ -544,14 +562,23 @@ } }, "usernameIsRequired": "Se requiere el nombre de usuario", - "passwordIsRequired": "Se requiere contraseña" + "passwordIsRequired": "Se requiere contraseña", + "currentPassword": { + "title": "Contraseña actual", + "placeholder": "Introduzca su contraseña actual" + } }, "passwordSetting": { "updatePassword": "Actualizar contraseña para {{username}}", "setPassword": "Establecer contraseña", "desc": "Crear una contraseña fuerte para asegurar esta cuenta.", "cannotBeEmpty": "La contraseña no puede estar vacía", - "doNotMatch": "Las contraseñas no coinciden" + "doNotMatch": "Las contraseñas no coinciden", + "currentPasswordRequired": "Se requiere la contraseña actual", + "incorrectCurrentPassword": "La contraseña actual es incorrecta", + "passwordVerificationFailed": "Fallo al verificar la contraseña", + "multiDeviceWarning": "Cualquier otro dispositivo en el que haya iniciado sesión deberá iniciar sesión nuevamente con {{refresh_time}}.", + "multiDeviceAdmin": "También puede obligar a todos los usuarios a volver a autenticarse inmediatamente rotando su secreto JWT." }, "createUser": { "desc": "Añadir una nueva cuenta de usuario y especificar un rol para el acceso a áreas de la interfaz de usuario de Frigate.", @@ -578,7 +605,7 @@ "desc": "Esta acción no se puede deshacer. Esto eliminará permanentemente la cuenta de usuario y eliminará todos los datos asociados." } }, - "updatePassword": "Actualizar contraseña" + "updatePassword": "Restablecer contraseña" }, "notification": { "title": "Notificaciones", @@ -745,7 +772,7 @@ "triggers": { "documentTitle": "Disparadores", "management": { - "title": "Gestión de disparadores", + "title": "Disparadores", "desc": "Gestionar disparadores para {{camera}}. Usa el tipo de miniatura para activar en miniaturas similares al objeto rastreado seleccionado, y el tipo de descripción para activar en descripciones similares al texto que especifiques." }, "addTrigger": "Añadir Disparador", @@ -766,7 +793,9 @@ }, "actions": { "alert": "Marcar como Alerta", - "notification": "Enviar Notificación" + "notification": "Enviar Notificación", + "sub_label": "Añadir una subetiqueta", + "attribute": "Añadir atributo" }, "dialog": { "createTrigger": { @@ -784,19 +813,22 @@ "form": { "name": { "title": "Nombre", - "placeholder": "Entre nombre de disparador", + "placeholder": "Asigne nombre a este disparador", "error": { - "minLength": "El nombre debe tener al menos 2 caracteres.", - "invalidCharacters": "El nombre sólo puede contener letras, números, guiones bajos, y guiones.", + "minLength": "El campo debe tener al menos 2 caracteres.", + "invalidCharacters": "El campo sólo puede contener letras, números, guiones bajos, y guiones.", "alreadyExists": "Un disparador con este nombre ya existe para esta cámara." - } + }, + "description": "Ingrese un nombre o descripción únicos para identificar este disparador" }, "enabled": { "description": "Activa o desactiva este disparador" }, "type": { "title": "Tipo", - "placeholder": "Seleccione tipo de disparador" + "placeholder": "Seleccione tipo de disparador", + "description": "Se dispara cuando se detecta una descripción de objeto rastreado similar", + "thumbnail": "Se dispara cuando se detecta una miniatura de un objeto rastreado similar" }, "friendly_name": { "title": "Nombre amigable", @@ -805,12 +837,12 @@ }, "content": { "title": "Contenido", - "imagePlaceholder": "Seleccione una imágen", + "imagePlaceholder": "Seleccione una imagen", "textPlaceholder": "Entre contenido de texto", "error": { "required": "El contenido es requrido." }, - "imageDesc": "Seleccione una imágen para iniciar esta acción cuando una imágen similar es detectada.", + "imageDesc": "Solo se muestran las 100 miniaturas más recientes. Si no encuentra la miniatura que busca, revise los objetos anteriores en Explorar y configure un disparador desde el menú.", "textDesc": "Entre texto para iniciar esta acción cuando la descripción de un objecto seguido similar es detectado." }, "threshold": { @@ -818,14 +850,15 @@ "error": { "min": "El umbral debe ser al menos 0", "max": "El umbral debe ser al menos 1" - } + }, + "desc": "Establezca el umbral de similitud para este disparador. Un umbral más alto significa que se requiere una coincidencia más cercana para activar el disparador." }, "actions": { "title": "Acciones", "error": { "min": "Al menos una acción debe ser seleccionada." }, - "desc": "Por defecto, Frigate manda un mensaje MQTT por todos los disparadores. Seleccione una acción adicional que se realizará cuando este disparador se accione." + "desc": "Por defecto, Frigate manda un mensaje MQTT para todos los disparadores. Las subetiquetas añaden el nombre del disparador a la etiqueta del objeto. Los atributos son metadatos de búsqueda que se almacenan por separado en los metadatos del objeto rastreado." } } }, @@ -844,6 +877,23 @@ "updateTriggerFailed": "Fallo al actualizar el disparador: {{errorMessage}}", "deleteTriggerFailed": "Fallo al eliminar el disparador: {{errorMessage}}" } + }, + "wizard": { + "title": "Crear disparador", + "step1": { + "description": "Configure los ajustes básicos para su disparador." + }, + "step2": { + "description": "Configure el contenido que activará esta acción." + }, + "step3": { + "description": "Configure el umbral y las acciones para este disparador." + }, + "steps": { + "nameAndType": "Nombre y tipo", + "configureData": "Configurar datos", + "thresholdAndActions": "Umbral y acciones" + } } }, "roles": { @@ -865,9 +915,9 @@ "createRole": "Rol {{role}} creado exitosamente", "updateCameras": "Cámara actualizada para el rol {{role}}", "deleteRole": "Rol {{role}} eliminado exitosamente", - "userRolesUpdated_one": "{{count}} usuarios asignados a este rol han sido actualizados a 'visor', que tiene acceso a todas las cámaras.", - "userRolesUpdated_many": "", - "userRolesUpdated_other": "" + "userRolesUpdated_one": "{{count}} usuario asignado a este rol ha sido actualizado a 'revisor', que tiene acceso a todas las cámaras.", + "userRolesUpdated_many": "{{count}} usuarios asignados a este rol han sido actualizado a 'revisor', que tienen acceso a todas las cámaras.", + "userRolesUpdated_other": "{{count}} usuarios asignados a este rol han sido actualizado a 'revisor', que tienen acceso a todas las cámaras." }, "error": { "createRoleFailed": "Creación de rol fallida: {{errorMessage}}", @@ -907,5 +957,271 @@ } } } + }, + "cameraWizard": { + "step1": { + "errors": { + "nameRequired": "El nombre de la cámara es un campo obligatorio", + "nameLength": "El nombre de la cámara debe tener 64 caracteres o menos", + "invalidCharacters": "El nombre de la cámara contiene caracteres no válidos", + "nameExists": "El nombre de la cámara ya existe", + "customUrlRtspRequired": "Las URL personalizadas deben comenzar con \"rtsp://\". Se requiere configuración manual para transmisiones de cámara sin RTSP.", + "brandOrCustomUrlRequired": "Seleccione una marca de cámara con host/IP o elija \"Otro\" con una URL personalizada" + }, + "description": "Ingrese los detalles de su cámara y elija probar la cámara o seleccionar manualmente la marca.", + "cameraName": "Nombre de la Cámara", + "cameraNamePlaceholder": "Ejempo: puerta_principal o Vista del Patio trasero", + "host": "Nombre Host / Dirección IP", + "port": "Puerto", + "username": "Nombre de usuario", + "usernamePlaceholder": "Opcional", + "password": "Contraseña", + "passwordPlaceholder": "Opcional", + "selectTransport": "Seleccionar protocolo de transporte", + "cameraBrand": "Marca de la cámara", + "selectBrand": "Seleccione la marca de la cámara para la plantilla de URL", + "customUrl": "URL de transmisión personalizada", + "brandInformation": "Información de la Marca", + "brandUrlFormat": "Para cámaras con formato de URL RTSP como: {{exampleUrl}}", + "customUrlPlaceholder": "rtsp://usuario:contraseña@hostname:puerto/ruta", + "connectionSettings": "Ajustes de conexión", + "detectionMethod": "Método de detección de transmisión", + "onvifPort": "Puerto ONVIF", + "probeMode": "Cámara de sonda", + "manualMode": "Selección manual", + "detectionMethodDescription": "Pruebe la cámara con ONVIF (si es compatible) para encontrar las URL de transmisión o seleccione manualmente la marca de la cámara para usar las URL predefinidas. Para introducir una URL RTSP personalizada, elija el método manual y seleccione \"Otro\".", + "onvifPortDescription": "Para las cámaras compatibles con ONVIF, normalmente es 80 o 8080.", + "useDigestAuth": "Use autenticación digest", + "useDigestAuthDescription": "Utilice la autenticación HTTP digest para ONVIF. Algunas cámaras pueden requerir un nombre de usuario y contraseña ONVIF específicos en lugar del usuario administrador estándar." + }, + "step2": { + "description": "Pruebe la cámara para detectar transmisiones disponibles o configure ajustes manuales según el método de detección seleccionado.", + "testSuccess": "Test de conexión satisfactorio!", + "testFailed": "Test de conexión fallido. Revise la informacion proporcionada e inténtelo de nuevo.", + "testFailedTitle": "Test fallido", + "streamDetails": "Detalles de la transmisión", + "probing": "Probando la cámara...", + "retry": "Re-intentar", + "testing": { + "probingMetadata": "Probando metadatos de la cámara...", + "fetchingSnapshot": "Obteniendo una instantánea de la cámara..." + }, + "probeFailed": "No se pudo alcanzar la cámara: {{error}}", + "probingDevice": "Probando el dispositivo...", + "probeSuccessful": "Prueba satisfactoria", + "probeError": "Error durante la prueba", + "probeNoSuccess": "Prueba fallida", + "deviceInfo": "Información de Dispositivo", + "manufacturer": "Fabricante", + "model": "Modelo", + "firmware": "Firmware", + "profiles": "Perfiles", + "ptzSupport": "Soporte PTZ", + "autotrackingSupport": "Soporte auto-seguimiento", + "presets": "Preestablecidos", + "rtspCandidates": "Candidatos RTSP", + "rtspCandidatesDescription": "Se encontraron las siguientes URL RTSP durante el sondeo de la cámara. Pruebe la conexión para ver los metadatos de la transmisión.", + "noRtspCandidates": "No se encontraron URL RTSP de la cámara. Es posible que sus credenciales sean incorrectas o que la cámara no sea compatible con ONVIF o el método utilizado para obtener las URL RTSP. Vuelva atrás e introduzca la URL RTSP manualmente.", + "candidateStreamTitle": "Candidato {{number}}", + "useCandidate": "Uso", + "uriCopy": "Copiar", + "uriCopied": "URI copiada al portapapeles", + "testConnection": "Probar conexión", + "toggleUriView": "Haga clic para alternar la vista completa de URI", + "connected": "Conectada", + "notConnected": "No conectada", + "errors": { + "hostRequired": "nombre host/dirección IP requeridos" + } + }, + "step3": { + "description": "Configure los roles de transmisión y agregue transmisiones adicionales para su cámara.", + "streamsTitle": "Transmisiones de cámara", + "addStream": "Añadir ruta de transmisión", + "addAnotherStream": "Añadir otra ruta de transmisión", + "streamTitle": "Transmisión {{number}}", + "streamUrl": "URL de transmisión", + "streamUrlPlaceholder": "rtsp://usuario:contraseña@nombrehost:puerto/ruta", + "selectStream": "Seleccione una transmisión", + "searchCandidates": "Búsqueda de candidatos...", + "noStreamFound": "No se ha encontrado transmisión", + "url": "URL", + "resolution": "Resolución", + "selectResolution": "Seleccione resolución", + "quality": "Calidad", + "selectQuality": "Seleccione calidad", + "roles": "Roles", + "roleLabels": { + "detect": "Detección de objetos", + "record": "Grabando", + "audio": "Audio" + }, + "testStream": "Pruebe la conexión", + "testSuccess": "Test de transmisión satisfactorio!", + "testFailed": "Test de transmisión fallido", + "testFailedTitle": "Prueba falló", + "connected": "Conectado", + "notConnected": "No conectado", + "featuresTitle": "Características", + "go2rtc": "Reduzca conexiones hacia la cámara", + "detectRoleWarning": "al menos una transmisión debe tener el roll de detección para continuar.", + "rolesPopover": { + "title": "Roles de transmisión", + "record": "Guarda segmentos de la transmisión de video según la configuración.", + "detect": "Hilo principal para detección de objetos.", + "audio": "Hilo para detección basada en audio." + }, + "featuresPopover": { + "title": "Características de transmisión", + "description": "Utilice la retransmisión go2rtc para reducir las conexiones a su cámara." + } + }, + "step4": { + "description": "Validación y análisis finales antes de guardar la nueva cámara. Conecte cada transmisión antes de guardar.", + "validationTitle": "Validacion de transmisión", + "connectAllStreams": "Conectar todas las transmisiones", + "reconnectionSuccess": "Reconexión satisfactoria.", + "reconnectionPartial": "Algunas transmisiones no pudieron reconectarse.", + "streamUnavailable": "Vista previa de transmisión no disponible", + "reload": "Recargar", + "connecting": "Conectando...", + "streamTitle": "Transmisión {{number}}", + "valid": "Válido", + "failed": "Falló", + "notTested": "No probado", + "connectStream": "Conectar", + "connectingStream": "Conectando", + "disconnectStream": "Desconectar", + "estimatedBandwidth": "Ancho de banda estimado", + "roles": "Roles", + "ffmpegModule": "Utilice el modo de compatibilidad de transmisión", + "ffmpegModuleDescription": "Si la transmisión no carga después de varios intentos, intenta activar esta opción. Al activarla, Frigate usará el módulo ffmpeg con go2rtc. Esto puede mejorar la compatibilidad con algunas transmisiones de cámara.", + "none": "Ninguna", + "error": "Error", + "streamValidated": "Transmisión {{number}} validada correctamente", + "streamValidationFailed": "Stream {{number}} falló la validación", + "saveAndApply": "Guardar nueva cámara", + "saveError": "Configuración inválida. Revise la configuración.", + "issues": { + "title": "Validación de transmisión", + "videoCodecGood": "El codec de video es {{codec}}.", + "audioCodecGood": "El codec de audio es {{codec}}.", + "resolutionHigh": "Una resolución de {{resolution}} puede provocar un mayor uso de recursos.", + "resolutionLow": "Una resolución de {{resolution}} puede ser demasiado baja para una detección confiable de objetos pequeños.", + "noAudioWarning": "No se detectó audio para esta transmisión, las grabaciones no tendrán audio.", + "audioCodecRecordError": "El códec de audio AAC es necesario para admitir audio en grabaciones.", + "audioCodecRequired": "Se requiere una transmisión de audio para admitir la detección de audio.", + "restreamingWarning": "Reducir las conexiones a la cámara para la transmisión de grabación puede aumentar ligeramente el uso de la CPU.", + "brands": { + "reolink-rtsp": "No se recomienda usar Reolink RTSP. Active HTTP en la configuración del firmware de la cámara y reinicie el asistente.", + "reolink-http": "Las transmisiones HTTP de Reolink deberían usar FFmpeg para una mejor compatibilidad. Active \"Usar modo de compatibilidad de transmisiones\" para esta transmisión." + }, + "dahua": { + "substreamWarning": "La subtransmisión 1 está limitada a una resolución baja. Muchas cámaras Dahua/Amcrest/EmpireTech admiten subtransmisiones adicionales que deben habilitarse en la configuración de la cámara. Se recomienda comprobar y utilizar dichas transmisiones si están disponibles." + }, + "hikvision": { + "substreamWarning": "La subtransmisión 1 está limitada a una resolución baja. Muchas cámaras Hikvision admiten subtransmisiones adicionales que deben habilitarse en la configuración de la cámara. Se recomienda comprobar y utilizar dichas transmisiones si están disponibles." + } + } + }, + "title": "Añadir cámara", + "description": "Siga los siguientes pasos para agregar una nueva cámara a su instalación de Frigate.", + "steps": { + "nameAndConnection": "Nombre y conexión", + "probeOrSnapshot": "Sonda de prueba o hacer instantánea", + "streamConfiguration": "Configuración de transmisión", + "validationAndTesting": "Validación y pruebas" + }, + "save": { + "success": "La nueva cámara {{cameraName}} se guardó correctamente.", + "failure": "Error al guardar {{cameraName}}." + }, + "testResultLabels": { + "resolution": "Resolución", + "video": "Video", + "audio": "Audio", + "fps": "FPS" + }, + "commonErrors": { + "noUrl": "Proporcione una URL de transmisión válida", + "testFailed": "Prueba de transmisión fallida: {{error}}" + } + }, + "cameraManagement": { + "title": "Administrar cámaras", + "addCamera": "Añadir nueva cámara", + "editCamera": "Editar cámara:", + "selectCamera": "Seleccione una cámara", + "backToSettings": "Volver a configuración de la cámara", + "streams": { + "title": "Habilitar/deshabilitar cámaras", + "desc": "Desactiva temporalmente una cámara hasta que Frigate se reinicie. Desactivar una cámara detiene por completo el procesamiento de las transmisiones de Frigate. La detección, la grabación y la depuración no estarán disponibles.
    Nota: Esto no desactiva las retransmisiones de go2rtc." + }, + "cameraConfig": { + "add": "Añadir cámara", + "edit": "Editar cámara", + "description": "Configure los ajustes de la cámara, incluidas las entradas de transmisión y los roles.", + "name": "Nombre de la cámara", + "nameRequired": "El nombre de la cámara es obligatorio", + "nameLength": "El nombre de la cámara debe ser inferior a 64 caracteres.", + "namePlaceholder": "Ejemplo: puerta_principal o Vista general de patio trasero", + "enabled": "Habilitada", + "ffmpeg": { + "inputs": "Transmisiones entrantes", + "path": "Ruta de transmisión", + "pathRequired": "La ruta de transmisión es requerida", + "pathPlaceholder": "rtsp://...", + "roles": "Roles", + "rolesRequired": "Al menos un rol es requerido", + "rolesUnique": "Cada rol (audio, detección, grabación) puede únicamente asignarse a una transmisión", + "addInput": "Añadir transmision entrante", + "removeInput": "Elimine transmisión entrante", + "inputsRequired": "Se requiere al menos una transmisión entrante" + }, + "go2rtcStreams": "Transmisiones go2rtc", + "streamUrls": "URLs de transmisión", + "addUrl": "Añadir URL", + "addGo2rtcStream": "Añadir transmisión go2rtc", + "toast": { + "success": "Cámara {{cameraName}} guardada correctamente" + } + } + }, + "cameraReview": { + "title": "Configuración de revisión de la cámara", + "object_descriptions": { + "title": "Descripciones de objetos de IA generativa", + "desc": "Habilite o deshabilite temporalmente las descripciones de objetos generadas por IA para esta cámara. Al deshabilitarlas, no se solicitarán descripciones generadas por IA para los objetos rastreados en esta cámara." + }, + "review_descriptions": { + "title": "Revisión de descripciones de IA generativa", + "desc": "Habilita o deshabilita temporalmente las revisión de descripciones generadas por IA para esta cámara. Al deshabilitarlas, no se solicitarán descripciones generadas por IA para los elementos de revisión de esta cámara." + }, + "review": { + "title": "Revisar", + "desc": "Habilite o deshabilite temporalmente las alertas y detecciones de esta cámara hasta que Frigate se reinicie. Al deshabilitarlas, no se generarán nuevas revisiones. ", + "alerts": "Alertas ", + "detections": "Detecciones " + }, + "reviewClassification": { + "title": "Clasificación de la revisión", + "desc": "Frigate clasifica los elementos de revisión como Alertas y Detecciones. De forma predeterminada, todos los objetos de persona y coche se consideran Alertas. Puede refinar la categorización de sus elementos de revisión configurando las zonas requeridas para ellos.", + "noDefinedZones": "No hay Zonas definidas para esta cámara.", + "objectAlertsTips": "Todos los objetos {{alertsLabels}} en {{cameraName}} se mostrarán como alertas.", + "zoneObjectAlertsTips": "Todos los objetos {{alertsLabels}} detectados en {{zone}} en {{cameraName}} se mostrarán como alertas.", + "objectDetectionsTips": "Todos los objetos {{detectionsLabels}} no categorizados en {{cameraName}} se mostrarán como Detecciones independientemente de la zona en la que se encuentren.", + "zoneObjectDetectionsTips": { + "text": "Todos los objetos {{detectionsLabels}} no categorizados en {{zone}} en {{cameraName}} se mostrarán como Detecciones.", + "notSelectDetections": "Todos los objetos {{detectionsLabels}} detectados en {{zone}} en {{cameraName}} que no estén categorizados como Alertas se mostrarán como Detecciones independientemente de la zona en la que se encuentren.", + "regardlessOfZoneObjectDetectionsTips": "Todos los objetos {{detectionsLabels}} no categorizados en {{cameraName}} se mostrarán como Detecciones independientemente de la zona en la que se encuentren." + }, + "unsavedChanges": "Configuración de clasificación de revisión no guardadas para {{camera}}", + "selectAlertsZones": "Seleccione Zonas para Alertas", + "selectDetectionsZones": "Seleccione Zonas para la Detección", + "limitDetections": "Limite la detección a zonas específicas", + "toast": { + "success": "Se ha guardado la configuración de la clasificación de revisión. Reinicie Frigate para aplicar los cambios." + } + } } } diff --git a/web/public/locales/es/views/system.json b/web/public/locales/es/views/system.json index e54a7802b..0b441592e 100644 --- a/web/public/locales/es/views/system.json +++ b/web/public/locales/es/views/system.json @@ -76,12 +76,22 @@ }, "gpuMemory": "Memoria de GPU", "npuMemory": "Memoria de NPU", - "npuUsage": "Uso de NPU" + "npuUsage": "Uso de NPU", + "intelGpuWarning": { + "title": "Aviso de estadísticas Intel GPU", + "message": "Estadísticas de GPU no disponibles", + "description": "Este es un error conocido en las herramientas de informes de estadísticas de GPU de Intel (intel_gpu_top). El error se produce y muestra repetidamente un uso de GPU del 0 %, incluso cuando la aceleración de hardware y la detección de objetos se ejecutan correctamente en la (i)GPU. No se trata de un error de Frigate. Puede reiniciar el host para solucionar el problema temporalmente y confirmar que la GPU funciona correctamente. Esto no afecta al rendimiento." + } }, "otherProcesses": { "title": "Otros Procesos", "processCpuUsage": "Uso de CPU del Proceso", - "processMemoryUsage": "Uso de Memoria del Proceso" + "processMemoryUsage": "Uso de Memoria del Proceso", + "series": { + "go2rtc": "go2rtc", + "recording": "grabación", + "review_segment": "revisar segmento" + } } }, "storage": { @@ -169,9 +179,19 @@ "plate_recognition": "Reconocimiento de Matrículas", "yolov9_plate_detection": "Detección de Matrículas YOLOv9", "image_embedding": "Incrustación de Imágenes", - "yolov9_plate_detection_speed": "Velocidad de Detección de Matrículas YOLOv9" + "yolov9_plate_detection_speed": "Velocidad de Detección de Matrículas YOLOv9", + "review_description": "Revisión de descripción", + "review_description_speed": "Velocidad de revisión de la descripción", + "review_description_events_per_second": "Revisión de la descripción", + "object_description": "Descripción de Objeto", + "object_description_speed": "Velocidad de descripción de objeto", + "object_description_events_per_second": "Descripción de objeto", + "classification": "Clasificación de {{name}}", + "classification_speed": "Velocidad de clasificación de {{name}}", + "classification_events_per_second": "Clasificacion de eventos por segundo de {{name}}" }, - "title": "Enriquecimientos" + "title": "Enriquecimientos", + "averageInf": "Tiempo promedio de inferencia" }, "stats": { "ffmpegHighCpuUsage": "{{camera}} tiene un uso elevado de CPU por FFmpeg ({{ffmpegAvg}}%)", From 85bc988c76b021f64ea73e93120358b262111f4f Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:56 +0100 Subject: [PATCH 27/98] Translated using Weblate (French) Currently translated at 97.7% (133 of 136 strings) Translated using Weblate (French) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (French) Currently translated at 100.0% (43 of 43 strings) Co-authored-by: Apocoloquintose Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/fr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/fr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/fr/ Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/fr/views/events.json | 6 +++++- web/public/locales/fr/views/explore.json | 5 ++++- web/public/locales/fr/views/system.json | 6 +++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/web/public/locales/fr/views/events.json b/web/public/locales/fr/views/events.json index 833dc4b2a..6baaf9b93 100644 --- a/web/public/locales/fr/views/events.json +++ b/web/public/locales/fr/views/events.json @@ -9,7 +9,11 @@ "empty": { "alert": "Aucune alerte à traiter", "detection": "Aucune détection à traiter", - "motion": "Aucune donnée de mouvement trouvée" + "motion": "Aucune donnée de mouvement trouvée", + "recordingsDisabled": { + "title": "Les enregistrements doivent être activés.", + "description": "Les activités ne peuvent être générées pour une caméra que si l'enregistrement est activé pour celle-ci." + } }, "timeline": "Chronologie", "events": { diff --git a/web/public/locales/fr/views/explore.json b/web/public/locales/fr/views/explore.json index 652c8bf56..637936450 100644 --- a/web/public/locales/fr/views/explore.json +++ b/web/public/locales/fr/views/explore.json @@ -110,7 +110,10 @@ "title": "Modifier les attributs", "desc": "Sélectionnez les attributs de classification pour : {{label}}" }, - "attributes": "Attributs de classification" + "attributes": "Attributs de classification", + "title": { + "label": "Titre" + } }, "type": { "details": "détails", diff --git a/web/public/locales/fr/views/system.json b/web/public/locales/fr/views/system.json index f261fa996..fde436292 100644 --- a/web/public/locales/fr/views/system.json +++ b/web/public/locales/fr/views/system.json @@ -86,7 +86,11 @@ "otherProcesses": { "title": "Autres processus", "processCpuUsage": "Utilisation CPU du processus", - "processMemoryUsage": "Utilisation mémoire du processus" + "processMemoryUsage": "Utilisation mémoire du processus", + "series": { + "go2rtc": "go2rtc", + "recording": "enregistrement" + } } }, "storage": { From da75481443da477e69e8ac96749987e107142170 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:57 +0100 Subject: [PATCH 28/98] Translated using Weblate (Swedish) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (136 of 136 strings) Co-authored-by: Hosted Weblate Co-authored-by: bittin1ddc447d824349b2 Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/sv/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/sv/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/sv/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/sv/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/sv/common.json | 3 ++- web/public/locales/sv/views/events.json | 6 +++++- web/public/locales/sv/views/explore.json | 5 ++++- web/public/locales/sv/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/sv/common.json b/web/public/locales/sv/common.json index a1ad12bb0..6c9143c9d 100644 --- a/web/public/locales/sv/common.json +++ b/web/public/locales/sv/common.json @@ -260,7 +260,8 @@ "show": "Visa {{item}}", "ID": "ID", "none": "Ingen", - "all": "Alla" + "all": "Alla", + "other": "Annat" }, "unit": { "speed": { diff --git a/web/public/locales/sv/views/events.json b/web/public/locales/sv/views/events.json index f19596e7a..f849a43a2 100644 --- a/web/public/locales/sv/views/events.json +++ b/web/public/locales/sv/views/events.json @@ -9,7 +9,11 @@ "empty": { "alert": "Det finns inga varningar att granska", "detection": "Det finns inga detekteringar att granska", - "motion": "Ingen rörelsedata hittad" + "motion": "Ingen rörelsedata hittad", + "recordingsDisabled": { + "title": "Inspelningar måste vara aktiverat", + "description": "Granskningsobjekt kan bara skapas för en kamera när inspelningar är aktiverat för den kameran." + } }, "documentTitle": "Granska - Frigate", "timeline": "Tidslinje", diff --git a/web/public/locales/sv/views/explore.json b/web/public/locales/sv/views/explore.json index 95e7b5b05..b6355ea2c 100644 --- a/web/public/locales/sv/views/explore.json +++ b/web/public/locales/sv/views/explore.json @@ -109,7 +109,10 @@ "title": "Redigera attribut", "desc": "Välj klassificeringsattribut för denna {{label}}" }, - "attributes": "Klassificeringsattribut" + "attributes": "Klassificeringsattribut", + "title": { + "label": "Titel" + } }, "exploreMore": "Utforska fler {{label}} objekt", "type": { diff --git a/web/public/locales/sv/views/system.json b/web/public/locales/sv/views/system.json index 55d757cc1..27eb9b844 100644 --- a/web/public/locales/sv/views/system.json +++ b/web/public/locales/sv/views/system.json @@ -86,7 +86,14 @@ "otherProcesses": { "title": "Övriga processer", "processCpuUsage": "Process CPU-användning", - "processMemoryUsage": "Processminnesanvändning" + "processMemoryUsage": "Processminnesanvändning", + "series": { + "go2rtc": "go2rtc", + "recording": "inspelning", + "review_segment": "granskningssegment", + "embeddings": "inbäddningar", + "audio_detector": "ljuddetektor" + } } }, "storage": { From 7d02220ec5b1e3b2d026fdaa507acea2dda14a72 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:57 +0100 Subject: [PATCH 29/98] Translated using Weblate (Persian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Persian) Currently translated at 100.0% (49 of 49 strings) Translated using Weblate (Persian) Currently translated at 100.0% (122 of 122 strings) Translated using Weblate (Persian) Currently translated at 100.0% (131 of 131 strings) Translated using Weblate (Persian) Currently translated at 100.0% (6 of 6 strings) Translated using Weblate (Persian) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Persian) Currently translated at 100.0% (46 of 46 strings) Translated using Weblate (Persian) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Persian) Currently translated at 100.0% (92 of 92 strings) Translated using Weblate (Persian) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Persian) Currently translated at 100.0% (55 of 55 strings) Translated using Weblate (Persian) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Persian) Currently translated at 100.0% (13 of 13 strings) Translated using Weblate (Persian) Currently translated at 100.0% (501 of 501 strings) Translated using Weblate (Persian) Currently translated at 100.0% (118 of 118 strings) Translated using Weblate (Persian) Currently translated at 100.0% (10 of 10 strings) Translated using Weblate (Persian) Currently translated at 100.0% (131 of 131 strings) Translated using Weblate (Persian) Currently translated at 100.0% (55 of 55 strings) Translated using Weblate (Persian) Currently translated at 100.0% (41 of 41 strings) Translated using Weblate (Persian) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Persian) Currently translated at 99.6% (652 of 654 strings) Translated using Weblate (Persian) Currently translated at 98.9% (91 of 92 strings) Translated using Weblate (Persian) Currently translated at 100.0% (122 of 122 strings) Translated using Weblate (Persian) Currently translated at 84.6% (11 of 13 strings) Translated using Weblate (Persian) Currently translated at 100.0% (74 of 74 strings) Translated using Weblate (Persian) Currently translated at 100.0% (118 of 118 strings) Translated using Weblate (Persian) Currently translated at 100.0% (135 of 135 strings) Translated using Weblate (Persian) Currently translated at 95.6% (44 of 46 strings) Translated using Weblate (Persian) Currently translated at 66.6% (4 of 6 strings) Translated using Weblate (Persian) Currently translated at 100.0% (10 of 10 strings) Translated using Weblate (Persian) Currently translated at 92.0% (23 of 25 strings) Translated using Weblate (Persian) Currently translated at 100.0% (501 of 501 strings) Translated using Weblate (Persian) Currently translated at 100.0% (2 of 2 strings) Translated using Weblate (Persian) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Persian) Currently translated at 97.9% (48 of 49 strings) Co-authored-by: Hosted Weblate Co-authored-by: حمید ملک محمدی Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-auth/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-camera/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-icons/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-player/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-configeditor/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-exports/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-recording/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/fa/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/fa/ Translation: Frigate NVR/audio Translation: Frigate NVR/common Translation: Frigate NVR/components-auth Translation: Frigate NVR/components-camera Translation: Frigate NVR/components-dialog Translation: Frigate NVR/components-filter Translation: Frigate NVR/components-icons Translation: Frigate NVR/components-player Translation: Frigate NVR/objects Translation: Frigate NVR/views-classificationmodel Translation: Frigate NVR/views-configeditor Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-exports Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-live Translation: Frigate NVR/views-recording Translation: Frigate NVR/views-search Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/fa/audio.json | 478 +++++++- web/public/locales/fa/common.json | 290 ++++- web/public/locales/fa/components/auth.json | 10 +- web/public/locales/fa/components/camera.json | 78 +- web/public/locales/fa/components/dialog.json | 113 +- web/public/locales/fa/components/filter.json | 132 +- web/public/locales/fa/components/icons.json | 2 +- web/public/locales/fa/components/player.json | 47 +- web/public/locales/fa/objects.json | 102 +- .../locales/fa/views/classificationModel.json | 166 ++- web/public/locales/fa/views/configEditor.json | 13 +- web/public/locales/fa/views/events.json | 59 +- web/public/locales/fa/views/explore.json | 242 +++- web/public/locales/fa/views/exports.json | 21 +- web/public/locales/fa/views/faceLibrary.json | 81 +- web/public/locales/fa/views/live.json | 179 ++- web/public/locales/fa/views/recording.json | 12 +- web/public/locales/fa/views/search.json | 70 +- web/public/locales/fa/views/settings.json | 1061 ++++++++++++++++- web/public/locales/fa/views/system.json | 194 ++- 20 files changed, 3315 insertions(+), 35 deletions(-) diff --git a/web/public/locales/fa/audio.json b/web/public/locales/fa/audio.json index 965460f7f..b3e547006 100644 --- a/web/public/locales/fa/audio.json +++ b/web/public/locales/fa/audio.json @@ -23,5 +23,481 @@ "bus": "اتوبوس", "motorcycle": "موتور سیکلت", "train": "قطار", - "bicycle": "دوچرخه" + "bicycle": "دوچرخه", + "child_singing": "آواز خواندن کودک", + "snort": "خرناس", + "cough": "سرفه", + "throat_clearing": "صاف کردن گلو", + "sneeze": "عطسه", + "sniff": "بو کشیدن", + "run": "دویدن", + "synthetic_singing": "آواز مصنوعی", + "rapping": "رپ‌خوانی", + "humming": "هوم‌خوانی", + "sheep": "گوسفند", + "groan": "ناله", + "grunt": "غرغر", + "whistling": "سوت زدن", + "breathing": "تنفس", + "wheeze": "خِس‌خِس", + "snoring": "خروپف", + "gasp": "به نفس‌نفس افتادن", + "pant": "نفس‌نفس‌زدن", + "shuffle": "پخش تصادفی", + "footsteps": "صدای قدم‌ها", + "chewing": "جویدن", + "biting": "گاز گرفتن", + "camera": "دوربین", + "gargling": "غرغره کردنغرغره کردن", + "stomach_rumble": "قاروقور شکم", + "burping": "آروغ زدن", + "skateboard": "اسکیت‌بورد", + "yip": "ییپ", + "howl": "زوزه", + "growling": "درحال غرغر", + "meow": "میو", + "caterwaul": "جیغ‌وداد", + "livestock": "دام", + "clip_clop": "تق‌تق", + "cattle": "گوساله", + "cowbell": "زنگولهٔ گاو", + "mouse": "موش", + "oink": "خِرخِر", + "keyboard": "صفحه‌کلید", + "goat": "بز", + "sink": "سینک", + "cluck": "قُدقُد", + "turkey": "بوقلمون", + "quack": "قاقا", + "scissors": "قیچی", + "honk": "بوق", + "hair_dryer": "سشوار", + "roar": "غرش", + "vehicle": "وسیلهٔ نقلیه", + "chirp": "جیک‌جیک", + "squawk": "جیغ زدن", + "coo": "قوقو", + "crow": "کلاغ", + "owl": "جغد", + "dogs": "سگ‌ها", + "patter": "شرشر", + "mosquito": "پشه", + "buzz": "وزوز", + "frog": "قورباغه", + "snake": "مار", + "rattle": "جغجغه کردن", + "music": "موسیقی", + "musical_instrument": "ساز موسیقی", + "guitar": "گیتار", + "electric_guitar": "گیتار برقی", + "acoustic_guitar": "گیتار آکوستیک", + "steel_guitar": "گیتار استیل", + "banjo": "بانجو", + "sitar": "سیتار", + "hiccup": "سکسکه", + "fart": "باد معده", + "finger_snapping": "بشکن زدن", + "clapping": "دست زدن", + "heartbeat": "ضربان قلب", + "heart_murmur": "سوفل قلبی", + "applause": "تشویق", + "chatter": "وراجی", + "crowd": "جمعیت", + "children_playing": "بازی کردن کودکان", + "animal": "حیوان", + "pets": "حیوانات خانگی", + "bark": "پارس", + "bow_wow": "هاپ‌هاپ", + "whimper_dog": "نالیدن سگ", + "purr": "خرخر", + "hiss": "هیس", + "neigh": "شیهه", + "door": "در", + "moo": "ماغ", + "pig": "خوک", + "bleat": "بع‌بع", + "fowl": "ماکیان", + "cock_a_doodle_doo": "قدقدی‌قدقد", + "blender": "مخلوط‌کن", + "chicken": "مرغ", + "gobble": "قورت دادن", + "clock": "ساعت", + "duck": "اردک", + "goose": "غاز", + "wild_animals": "حیوانات وحشی", + "toothbrush": "مسواک", + "roaring_cats": "غرش گربه‌ها", + "pigeon": "کبوتر", + "hoot": "هوهو", + "flapping_wings": "بال‌بال زدن", + "rats": "موش‌ها", + "insect": "حشره", + "cricket": "جیرجیرک", + "fly": "مگس", + "croak": "قارقار", + "whale_vocalization": "آواز نهنگ", + "plucked_string_instrument": "ساز زهی زخمه‌ای", + "bass_guitar": "گیتار باس", + "tapping": "ضربه‌زدن", + "strum": "زخمه‌زدن", + "mandolin": "ماندولین", + "zither": "زیتر", + "ukulele": "یوکللی", + "piano": "پیانو", + "electric_piano": "پیانوی الکتریکی", + "organ": "ارگ", + "electronic_organ": "ارگ الکترونیکی", + "hammond_organ": "ارگ هموند", + "synthesizer": "سینتی‌سایزر", + "sampler": "سمپلر", + "harpsichord": "هارپسیکورد", + "percussion": "سازهای کوبه‌ای", + "drum_kit": "ست درام", + "drum_machine": "درام ماشین", + "drum": "درام", + "snare_drum": "درام اسنیر", + "rimshot": "ریم‌شات", + "drum_roll": "درام رول", + "bass_drum": "درام باس", + "timpani": "تیمپانی", + "tabla": "طبلا", + "cymbal": "سنج", + "hi_hat": "های‌هت", + "wood_block": "بلوک چوبی", + "tambourine": "تامبورین", + "maraca": "ماراکا", + "gong": "گونگ", + "tubular_bells": "ناقوس‌های لوله‌ای", + "mallet_percussion": "سازهای کوبه‌ای مالت", + "marimba": "ماریمبا", + "glockenspiel": "گلوکن‌اشپیل", + "vibraphone": "ویبرافون", + "steelpan": "استیل‌پن", + "orchestra": "ارکستر", + "brass_instrument": "ساز بادی برنجی", + "french_horn": "هورن فرانسوی", + "trumpet": "ترومپت", + "trombone": "ترومبون", + "bowed_string_instrument": "ساز زهی آرشه‌ای", + "string_section": "بخش سازهای زهی", + "violin": "ویولن", + "pizzicato": "پیتزیکاتو", + "cello": "ویولنسل", + "double_bass": "کنترباس", + "wind_instrument": "ساز بادی", + "flute": "فلوت", + "saxophone": "ساکسوفون", + "clarinet": "کلارینت", + "harp": "چنگ", + "bell": "ناقوس", + "church_bell": "ناقوس کلیسا", + "jingle_bell": "زنگوله", + "bicycle_bell": "زنگ دوچرخه", + "tuning_fork": "دیاپازون", + "chime": "زنگ", + "wind_chime": "زنگ باد", + "harmonica": "سازدهنی", + "accordion": "آکاردئون", + "bagpipes": "نی‌انبان", + "didgeridoo": "دیجریدو", + "theremin": "ترمین", + "singing_bowl": "کاسهٔ آوازخوان", + "scratching": "خراشیدن", + "pop_music": "موسیقی پاپ", + "hip_hop_music": "موسیقی هیپ‌هاپ", + "beatboxing": "بیت‌باکس", + "rock_music": "موسیقی راک", + "heavy_metal": "هوی متال", + "punk_rock": "پانک راک", + "grunge": "گرانج", + "progressive_rock": "راک پراگرسیو", + "rock_and_roll": "راک اند رول", + "psychedelic_rock": "راک روان‌گردان", + "rhythm_and_blues": "ریتم اند بلوز", + "soul_music": "موسیقی سول", + "reggae": "رگی", + "country": "کانتری", + "swing_music": "موسیقی سوئینگ", + "bluegrass": "بلوگرس", + "funk": "فانک", + "folk_music": "موسیقی فولک", + "jazz": "جاز", + "disco": "دیسکو", + "classical_music": "موسیقی کلاسیک", + "opera": "اپرا", + "electronic_music": "موسیقی الکترونیک", + "house_music": "موسیقی هاوس", + "techno": "تکنو", + "dubstep": "داب‌استپ", + "drum_and_bass": "درام اند بیس", + "electronica": "الکترونیکا", + "electronic_dance_music": "موسیقی رقص الکترونیک", + "ambient_music": "موسیقی امبینت", + "trance_music": "موسیقی ترنس", + "music_of_latin_america": "موسیقی آمریکای لاتین", + "salsa_music": "موسیقی سالسا", + "flamenco": "فلامنکو", + "blues": "بلوز", + "music_for_children": "موسیقی برای کودکان", + "new-age_music": "موسیقی نیو ایج", + "vocal_music": "موسیقی آوازی", + "a_capella": "آکاپلا", + "music_of_africa": "موسیقی آفریقا", + "afrobeat": "آفروبیت", + "christian_music": "موسیقی مسیحی", + "gospel_music": "موسیقی گاسپل", + "music_of_asia": "موسیقی آسیا", + "carnatic_music": "موسیقی کارناتیک", + "music_of_bollywood": "موسیقی بالیوود", + "ska": "اسکا", + "traditional_music": "موسیقی سنتی", + "independent_music": "موسیقی مستقل", + "song": "آهنگ", + "background_music": "موسیقی پس‌زمینه", + "theme_music": "موسیقی تم", + "soundtrack_music": "موسیقی متن", + "lullaby": "لالایی", + "video_game_music": "موسیقی بازی‌های ویدیویی", + "christmas_music": "موسیقی کریسمس", + "dance_music": "موسیقی رقص", + "wedding_music": "موسیقی عروسی", + "happy_music": "موسیقی شاد", + "sad_music": "موسیقی غمگین", + "tender_music": "موسیقی لطیف", + "angry_music": "موسیقی خشمگین", + "exciting_music": "موسیقی هیجان‌انگیز", + "scary_music": "موسیقی ترسناک", + "wind": "باد", + "rustling_leaves": "خش‌خش برگ‌ها", + "wind_noise": "صدای باد", + "thunderstorm": "طوفان تندری", + "thunder": "رعد", + "water": "آب", + "rain": "باران", + "raindrop": "قطرهٔ باران", + "rain_on_surface": "باران روی سطح", + "waterfall": "آبشار", + "ocean": "اقیانوس", + "waves": "امواج", + "steam": "بخار", + "gurgling": "قل‌قل", + "motorboat": "قایق موتوری", + "ship": "کشتی", + "motor_vehicle": "وسیلهٔ نقلیهٔ موتوری", + "toot": "توت", + "car_alarm": "دزدگیر خودرو", + "truck": "کامیون", + "air_brake": "ترمز بادی", + "air_horn": "بوق بادی", + "reversing_beeps": "بوق دنده‌عقب", + "ice_cream_truck": "کامیون بستنی‌فروشی", + "traffic_noise": "صدای ترافیک", + "rail_transport": "حمل‌ونقل ریلی", + "train_whistle": "سوت قطار", + "train_horn": "بوق قطار", + "jet_engine": "موتور جت", + "propeller": "ملخ", + "helicopter": "بالگرد", + "fixed-wing_aircraft": "هواپیمای بال‌ثابت", + "medium_engine": "موتور متوسط", + "heavy_engine": "موتور سنگین", + "engine_knocking": "تق‌تق موتور", + "engine_starting": "روشن شدن موتور", + "idling": "درجا کار کردن", + "slam": "محکم کوبیدن", + "knock": "در زدن", + "tap": "ضربهٔ آرام", + "squeak": "جیرجیر", + "cupboard_open_or_close": "باز یا بسته شدن کمد", + "microwave_oven": "مایکروفر", + "water_tap": "شیر آب", + "bathtub": "وان حمام", + "toilet_flush": "سیفون توالت", + "keys_jangling": "جرینگ‌جرینگ کلیدها", + "coin": "سکه", + "electric_shaver": "ریش‌تراش برقی", + "shuffling_cards": "بر زدنِ کارت‌ها", + "telephone_bell_ringing": "زنگ خوردن تلفن", + "ringtone": "زنگ تماس", + "telephone_dialing": "شماره‌گیری تلفن", + "dial_tone": "بوق آزاد", + "busy_signal": "بوق اشغال", + "alarm_clock": "ساعت زنگ‌دار", + "fire_alarm": "هشدار آتش‌سوزی", + "foghorn": "بوق مه", + "whistle": "سوت", + "steam_whistle": "سوت بخار", + "mechanisms": "سازوکارها", + "pulleys": "قرقره‌ها", + "sewing_machine": "چرخ خیاطی", + "mechanical_fan": "پنکهٔ مکانیکی", + "air_conditioning": "تهویهٔ مطبوع", + "cash_register": "صندوق فروش", + "jackhammer": "چکش بادی", + "sawing": "اره‌کردن", + "drill": "دریل", + "sanding": "سنباده‌کاری", + "power_tool": "ابزار برقی", + "filing": "سوهان‌کاری", + "artillery_fire": "آتش توپخانه", + "cap_gun": "تفنگ ترقه‌ای", + "fireworks": "آتش‌بازی", + "firecracker": "ترقه", + "burst": "ترکیدن", + "crack": "ترک", + "glass": "شیشه", + "chink": "جرینگ", + "shatter": "خُرد شدن", + "silence": "سکوت", + "television": "تلویزیون", + "radio": "رادیو", + "field_recording": "ضبط میدانی", + "scream": "جیغ", + "chird": "جیرجیر", + "change_ringing": "زنگ خوردن پول خرد", + "shofar": "شوفار", + "liquid": "مایع", + "splash": "پاشیدن", + "gush": "فوران", + "fill": "پر کردن", + "spray": "اسپری", + "pump": "پمپ", + "stir": "هم زدن", + "thunk": "صدای افتادن", + "electronic_tuner": "تیونر الکترونیکی", + "effects_unit": "واحد افکت‌ها", + "chorus_effect": "افکت کُر", + "basketball_bounce": "پرش توپ بسکتبال", + "bouncing": "پرش", + "whip": "شلاق", + "flap": "بال‌بال زدن", + "scratch": "خراشیدن", + "scrape": "ساییدن", + "beep": "بیپ", + "ping": "پینگ", + "ding": "دینگ", + "clang": "تق", + "squeal": "جیغ", + "clicking": "کلیک‌کردن", + "clickety_clack": "تَق‌تَق", + "rumble": "غرّش", + "plop": "پَت", + "chirp_tone": "صدای جیک", + "pulse": "پالس", + "inside": "داخل", + "outside": "بیرون", + "reverberation": "پژواک", + "cacophony": "همهمه", + "throbbing": "تپش", + "vibration": "لرزش", + "hands": "دست‌ها", + "cheering": "تشویق کردن", + "caw": "قارقار", + "jingle": "جینگل", + "middle_eastern_music": "موسیقی خاورمیانه‌ای", + "stream": "جریان", + "fire": "آتش", + "crackle": "ترق‌تروق", + "sailboat": "قایق بادبانی", + "rowboat": "قایق پارویی", + "power_windows": "شیشه‌بالابر برقی", + "skidding": "سرخوردن", + "tire_squeal": "جیغ لاستیک", + "car_passing_by": "عبور خودرو", + "race_car": "خودروی مسابقه", + "emergency_vehicle": "خودروی امدادی", + "police_car": "خودروی پلیس", + "vacuum_cleaner": "جاروبرقی", + "zipper": "زیپ", + "typing": "تایپ کردن", + "typewriter": "ماشین تحریر", + "computer_keyboard": "صفحه‌کلید رایانه", + "writing": "نوشتن", + "alarm": "هشدار", + "telephone": "تلفن", + "siren": "آژیر", + "civil_defense_siren": "آژیر دفاع مدنی", + "buzzer": "بیزر", + "smoke_detector": "آشکارساز دود", + "ratchet": "جغجغه", + "tick-tock": "تیک‌تاک", + "gears": "چرخ‌دنده‌ها", + "printer": "چاپگر", + "single-lens_reflex_camera": "دوربین تک‌لنزی بازتابی", + "tools": "ابزارها", + "hammer": "چکش", + "explosion": "انفجار", + "gunshot": "شلیک", + "machine_gun": "مسلسل", + "fusillade": "رگبار", + "eruption": "فوران", + "boom": "بوم", + "wood": "چوب", + "sound_effect": "جلوهٔ صوتی", + "splinter": "تراشه", + "environmental_noise": "نویز محیطی", + "static": "ساکن", + "white_noise": "نویز سفید", + "squish": "فشردن", + "drip": "چکه", + "pour": "ریختن", + "trickle": "چکیدن", + "boiling": "جوشیدن", + "thump": "کوبیدن", + "bang": "بنگ", + "slap": "سیلی", + "whack": "ضربه", + "smash": "خرد کردن", + "roll": "غلتیدن", + "crushing": "خرد کردن", + "crumpling": "چروک شدن", + "tearing": "پاره کردن", + "creak": "جیرجیر", + "clatter": "قارقار", + "sizzle": "جوشیدن", + "hum": "زمزمه", + "zing": "زنگ", + "boing": "بویینگ", + "crunch": "خرد کردن", + "noise": "نویز", + "mains_hum": "زمزمهٔ برق", + "distortion": "اعوجاج", + "sidetone": "صدای گوشی", + "ambulance": "آمبولانس", + "fire_engine": "خودروی آتش‌نشانی", + "railroad_car": "واگن راه‌آهن", + "train_wheels_squealing": "جیرجیر چرخ‌های قطار", + "subway": "مترو", + "aircraft": "هوانورد", + "aircraft_engine": "موتور هواپیما", + "engine": "موتور", + "light_engine": "موتور سبک", + "dental_drill's_drill": "متهٔ دندانپزشکی", + "lawn_mower": "چمن‌زن", + "chainsaw": "ارهٔ زنجیری", + "accelerating": "شتاب‌گیری", + "doorbell": "زنگ در", + "ding-dong": "دینگ‌دونگ", + "sliding_door": "در کشویی", + "drawer_open_or_close": "باز یا بسته شدن کشو", + "dishes": "ظروف", + "cutlery": "قاشق و چنگال", + "chopping": "خرد کردن", + "frying": "سرخ کردن", + "electric_toothbrush": "مسواک برقی", + "tick": "تیک", + "chop": "خرد کردن", + "pink_noise": "نویز صورتی", + "sodeling": "سودلینگ", + "slosh": "پاشیدن", + "sonar": "سونار", + "arrow": "پیکان", + "whoosh": "ووش", + "breaking": "شکستن", + "rub": "مالیدن", + "rustle": "خش‌خش", + "whir": "وزوز", + "sine_wave": "موج سینوسی", + "harmonic": "هارمونیک", + "echo": "پژواک" } diff --git a/web/public/locales/fa/common.json b/web/public/locales/fa/common.json index 2bb9555cb..3b9e02617 100644 --- a/web/public/locales/fa/common.json +++ b/web/public/locales/fa/common.json @@ -4,6 +4,294 @@ "untilForRestart": "تا زمانی که فریگیت دوباره شروع به کار کند.", "untilRestart": "تا زمان ری‌استارت", "ago": "{{timeAgo}} قبل", - "justNow": "هم اکنون" + "justNow": "هم اکنون", + "today": "امروز", + "yesterday": "دیروز", + "last7": "۷ روز گذشته", + "last14": "۱۴ روز گذشته", + "last30": "۳۰ روز گذشته", + "thisWeek": "این هفته", + "lastWeek": "هفتهٔ گذشته", + "thisMonth": "این ماه", + "lastMonth": "ماه گذشته", + "5minutes": "۵ دقیقه", + "10minutes": "۱۰ دقیقه", + "day_one": "{{time}} روز", + "day_other": "{{time}} روز", + "h": "{{time}}س", + "hour_one": "{{time}} ساعت", + "hour_other": "{{time}} ساعت", + "m": "{{time}} دقیقه", + "minute_one": "{{time}} دقیقه", + "minute_other": "{{time}} دقیقه", + "s": "{{time}}ث", + "30minutes": "۳۰ دقیقه", + "1hour": "۱ ساعت", + "12hours": "۱۲ ساعت", + "24hours": "۲۴ ساعت", + "pm": "ب.ظ.", + "am": "ق.ظ.", + "yr": "{{time}} سال", + "year_one": "{{time}} سال", + "year_other": "{{time}} سال", + "mo": "{{time}} ماه", + "month_one": "{{time}} ماه", + "month_other": "{{time}} ماه", + "d": "{{time}} روز", + "second_one": "{{time}} ثانیه", + "second_other": "‏{{time}} ثانیه", + "formattedTimestamp": { + "12hour": "MMM d، h:mm:ss aaa", + "24hour": "MMM d، HH:mm:ss" + }, + "formattedTimestamp2": { + "12hour": "MM/dd h:mm:ssa", + "24hour": "d MMM HH:mm:ssd MMM، HH:mm:ss" + }, + "formattedTimestampHourMinute": { + "12hour": "h:mm aaa", + "24hour": "HH:mm" + }, + "formattedTimestampHourMinuteSecond": { + "12hour": "h:mm:ss aaa", + "24hour": "HH:mm:ss" + }, + "formattedTimestampMonthDayHourMinute": { + "12hour": "d MMM, h:mm aaa", + "24hour": "d MMM, HH:mm" + }, + "formattedTimestampMonthDayYear": { + "12hour": "d MMM, yyyy", + "24hour": "d MMM, yyyy" + }, + "formattedTimestampMonthDayYearHourMinute": { + "12hour": "d MMM yyyy, h:mm aaa", + "24hour": "yyyy MMM d, HH:mm" + }, + "formattedTimestampMonthDay": "d MMM", + "formattedTimestampFilename": { + "12hour": "MM-dd-yy-h-mm-ss-a", + "24hour": "MM-dd-yy-HH-mm-ss" + }, + "inProgress": "در حال انجام", + "invalidStartTime": "زمان شروع نامعتبر است", + "invalidEndTime": "زمان پایان نامعتبر است" + }, + "unit": { + "length": { + "feet": "فوت", + "meters": "متر" + }, + "data": { + "kbps": "kB/s", + "gbps": "GB/s", + "mbph": "مگابایت/ساعت", + "gbph": "گیگابایت/ساعت", + "mbps": "مگابایت/ثانیه", + "kbph": "کیلوبایت/ساعت" + }, + "speed": { + "mph": "مایل/ساعت", + "kph": "کیلومتر/ساعت" + } + }, + "label": { + "hide": "پنهان کردن {{item}}", + "ID": "شناسه", + "all": "همه", + "back": "برگشت به قبل", + "show": "نمایش {{item}}", + "none": "هیچ‌کدام" + }, + "list": { + "many": "{{items}}، و {{last}}", + "two": "{{0}} و {{1}}", + "separatorWithSpace": ", · " + }, + "field": { + "internalID": "شناسهٔ داخلی‌ای که Frigate در پیکربندی و پایگاه‌داده استفاده می‌کند", + "optional": "اختیاری" + }, + "button": { + "apply": "اعمال", + "done": "انجام شد", + "enable": "فعال کردن", + "disabled": "غیرفعال", + "cancel": "لغو", + "close": "بستن", + "back": "بازگشت", + "fullscreen": "تمام‌صفحه", + "exitFullscreen": "خروج از حالت تمام‌صفحه", + "twoWayTalk": "مکالمهٔ دوطرفه", + "cameraAudio": "صدای دوربین", + "off": "خاموش", + "delete": "حذف", + "download": "دانلود", + "unsuspended": "برداشتن تعلیق", + "unselect": "لغو انتخاب", + "export": "خروجی گرفتن", + "next": "بعدی", + "reset": "بازنشانی", + "enabled": "فعال", + "disable": "غیرفعال کردن", + "save": "ذخیره", + "saving": "در حال ذخیره…", + "copy": "کپی", + "history": "تاریخچه", + "pictureInPicture": "تصویر در تصویر", + "copyCoordinates": "کپی مختصات", + "yes": "بله", + "no": "خیر", + "info": "اطلاعات", + "play": "پخش", + "deleteNow": "حذف فوری", + "continue": "ادامه", + "on": "روشن", + "edit": "ویرایش", + "suspended": "تعلیق‌شده" + }, + "menu": { + "systemMetrics": "شاخص‌های سیستم", + "configuration": "پیکربندی", + "settings": "تنظیمات", + "language": { + "en": "انگلیسی (English)", + "hi": "هندی (Hindi)", + "fr": "فرانسوی (French)", + "ptBR": "پرتغالیِ برزیل (Brazilian Portuguese)", + "ru": "روسی (Russian)", + "es": "اسپانیایی (زبان اسپانیایی)", + "zhCN": "چینی ساده‌شده (چینی ساده)", + "ar": "عربی (زبان عربی)", + "pt": "پرتغالی (زبان پرتغالی)", + "de": "آلمانی (زبان آلمانی)", + "ja": "ژاپنی (زبان ژاپنی)", + "tr": "ترکی (زبان ترکی)", + "it": "ایتالیایی (زبان ایتالیایی)", + "nl": "هلندی (زبان هلندی)", + "sv": "سوئدی (زبان سوئدی)", + "cs": "چکی (زبان چکی)", + "nb": "بوکمل نروژیایی (بوکمل نروژی)", + "ko": "کره‌ای (زبان کره‌ای)", + "vi": "ویتنامی (زبان ویتنامی)", + "fa": "فارسی (زبان فارسی)", + "pl": "لهستانی (زبان لهستانی)", + "uk": "اوکراینی (زبان اوکراینی)", + "he": "عبری (زبان عبری)", + "el": "یونانی (زبان یونانی)", + "ro": "رومانیایی (زبان رومانیایی)", + "hu": "مجاری (زبان مجاری)", + "fi": "فنلاندی (زبان فنلاندی)", + "da": "دانمارکی (زبان دانمارکی)", + "sk": "اسلواکی (زبان اسلواکی)", + "yue": "کانتونی (زبان کانتونی)", + "th": "تایلندی (زبان تایلندی)", + "ca": "کاتالانی (زبان کاتالانی)", + "sr": "صربی (زبان صربی)", + "sl": "اسلوونیایی (زبان اسلوونیایی)", + "lt": "لیتوانیایی (زبان لیتوانیایی)", + "bg": "بلغاری (زبان بلغاری)", + "gl": "گالیسیایی (زبان گالیسیایی)", + "id": "اندونزیایی (زبان اندونزیایی)", + "ur": "اردو (زبان اردو)", + "withSystem": { + "label": "برای زبان از تنظیمات سامانه استفاده کنید" + } + }, + "system": "سامانه", + "systemLogs": "لاگ‌های سامانه", + "configurationEditor": "ویرایشگر پیکربندی", + "languages": "زبان‌ها", + "appearance": "ظاهر", + "darkMode": { + "label": "حالت تاریک", + "light": "روشنایی", + "dark": "تاریک", + "withSystem": { + "label": "برای حالت روشن یا تاریک از تنظیمات سامانه استفاده کنید" + } + }, + "withSystem": "سامانه", + "theme": { + "label": "پوسته", + "blue": "آبی", + "green": "سبز", + "nord": "نورد", + "red": "قرمز", + "highcontrast": "کنتراست بالا", + "default": "پیش‌فرض" + }, + "help": "راهنما", + "documentation": { + "title": "مستندات", + "label": "مستندات Frigate" + }, + "restart": "راه‌اندازی مجدد Frigate", + "live": { + "title": "زنده", + "allCameras": "همهٔ دوربین‌ها", + "cameras": { + "title": "دوربین‌ها", + "count_one": "{{count}} دوربین", + "count_other": "{{count}} دوربین" + } + }, + "review": "بازبینی", + "explore": "کاوش", + "export": "خروجی گرفتن", + "uiPlayground": "محیط آزمایشی UI", + "faceLibrary": "کتابخانهٔ چهره", + "classification": "طبقه‌بندی", + "user": { + "title": "کاربر", + "account": "حساب کاربری", + "current": "کاربر فعلی: {{user}}", + "anonymous": "ناشناس", + "logout": "خروج", + "setPassword": "تنظیم گذرواژه" + } + }, + "toast": { + "copyUrlToClipboard": "نشانی اینترنتی در کلیپ‌بورد کپی شد.", + "save": { + "title": "ذخیره", + "error": { + "title": "ذخیرهٔ تغییرات پیکربندی ناموفق بود: {{errorMessage}}", + "noMessage": "ذخیرهٔ تغییرات پیکربندی ناموفق بود" + } + } + }, + "role": { + "title": "نقش", + "admin": "مدیر", + "viewer": "بیننده", + "desc": "مدیران به همهٔ ویژگی‌ها در رابط کاربری Frigate دسترسی کامل دارند. بیننده‌ها فقط می‌توانند دوربین‌ها، موارد بازبینی و ویدیوهای تاریخی را در رابط کاربری مشاهده کنند." + }, + "pagination": { + "label": "صفحه‌بندی", + "previous": { + "title": "قبلی", + "label": "رفتن به صفحهٔ قبلی" + }, + "next": { + "title": "بعدی", + "label": "رفتن به صفحهٔ بعدی" + }, + "more": "صفحه‌های بیشتر" + }, + "accessDenied": { + "documentTitle": "دسترسی ممنوع - Frigate", + "title": "دسترسی ممنوع", + "desc": "شما اجازهٔ مشاهدهٔ این صفحه را ندارید." + }, + "notFound": { + "documentTitle": "یافت نشد - Frigate", + "title": "۴۰۴", + "desc": "صفحه پیدا نشد" + }, + "selectItem": "انتخاب {{item}}", + "readTheDocumentation": "مستندات را بخوانید", + "information": { + "pixels": "{{area}}px" } } diff --git a/web/public/locales/fa/components/auth.json b/web/public/locales/fa/components/auth.json index 6b87e7257..3c4e021b2 100644 --- a/web/public/locales/fa/components/auth.json +++ b/web/public/locales/fa/components/auth.json @@ -3,6 +3,14 @@ "user": "نام کاربری", "password": "رمز عبور", "login": "ورود", - "firstTimeLogin": "اولین باز است وارد می شود؟ اطلاعات هویتی در ثبت رخداد های فریگیت چاپ خواهد شد." + "firstTimeLogin": "اولین باز است وارد می شود؟ اطلاعات هویتی در ثبت رخداد های فریگیت چاپ خواهد شد.", + "errors": { + "usernameRequired": "وارد کردن نام کاربری الزامی است", + "passwordRequired": "وارد کردن رمز عبور الزامی است", + "loginFailed": "ورود ناموفق بود", + "unknownError": "خطای ناشناخته. گزارش‌ها را بررسی کنید.", + "webUnknownError": "خطای ناشناخته. گزارش‌های کنسول را بررسی کنید.", + "rateLimit": "از حد مجاز درخواست‌ها فراتر رفت. بعداً دوباره تلاش کنید." + } } } diff --git a/web/public/locales/fa/components/camera.json b/web/public/locales/fa/components/camera.json index ee4d1d172..35f7ec517 100644 --- a/web/public/locales/fa/components/camera.json +++ b/web/public/locales/fa/components/camera.json @@ -4,7 +4,83 @@ "add": "افزودن گروه دوربین", "edit": "ویرایش گروه دوربین", "delete": { - "label": "حذف گروه دوربین ها" + "label": "حذف گروه دوربین ها", + "confirm": { + "title": "تأیید حذف", + "desc": "آیا مطمئن هستید که می‌خواهید گروه دوربین «{{name}}» را حذف کنید؟" + } + }, + "name": { + "label": "نام", + "placeholder": "یک نام وارد کنید…", + "errorMessage": { + "mustLeastCharacters": "نام گروه دوربین باید حداقل ۲ کاراکتر باشد.", + "exists": "نام گروه دوربین از قبل وجود دارد.", + "nameMustNotPeriod": "نام گروه دوربین نباید شامل نقطه باشد.", + "invalid": "نام گروه دوربین نامعتبر است." + } + }, + "cameras": { + "desc": "دوربین‌های این گروه را انتخاب کنید.", + "label": "دوربین‌ها" + }, + "icon": "آیکون", + "success": "گروه دوربین ({{name}}) ذخیره شد.", + "camera": { + "setting": { + "streamMethod": { + "method": { + "noStreaming": { + "label": "بدون پخش", + "desc": "تصاویر دوربین فقط هر یک دقیقه یک‌بار به‌روزرسانی می‌شوند و هیچ پخش زنده‌ای انجام نخواهد شد." + }, + "smartStreaming": { + "label": "پخش هوشمند (پیشنهادی)", + "desc": "پخش هوشمند زمانی که فعالیت قابل تشخیصی وجود ندارد برای صرفه‌جویی در پهنای باند و منابع، تصویر دوربین شما را هر یک دقیقه یک‌بار به‌روزرسانی می‌کند. وقتی فعالیت تشخیص داده شود، تصویر به‌طور یکپارچه به پخش زنده تغییر می‌کند." + }, + "continuousStreaming": { + "label": "پخش پیوسته", + "desc": { + "title": "تصویر دوربین وقتی در داشبورد قابل مشاهده باشد همیشه پخش زنده خواهد بود، حتی اگر هیچ فعالیتی تشخیص داده نشود.", + "warning": "پخش پیوسته ممکن است باعث مصرف بالای پهنای‌باند و مشکلات عملکردی شود. با احتیاط استفاده کنید." + } + } + }, + "label": "روش پخش", + "placeholder": "یک روش پخش را انتخاب کنید" + }, + "label": "تنظیمات پخش دوربین", + "title": "تنظیمات پخش {{cameraName}}", + "audioIsAvailable": "صدا برای این پخش در دسترس است", + "audioIsUnavailable": "صدا برای این پخش در دسترس نیست", + "audio": { + "tips": { + "title": "برای این پخش، صدا باید از دوربین شما خروجی گرفته شود و در go2rtc پیکربندی شده باشد." + } + }, + "stream": "جریان", + "placeholder": "یک جریان را برگزینید", + "compatibilityMode": { + "label": "حالت سازگاری", + "desc": "این گزینه را فقط زمانی فعال کنید که پخش زندهٔ دوربین شما دچار آثار رنگی (artifact) است و در سمت راست تصویر یک خط مورب دیده می‌شود." + }, + "desc": "گزینه‌های پخش زنده را برای داشبورد این گروه دوربین تغییر دهید. این تنظیمات مخصوص دستگاه/مرورگر هستند. " + }, + "birdseye": "نمای پرنده" } + }, + "debug": { + "options": { + "label": "تنظیمات", + "title": "گزینه‌ها", + "showOptions": "نمایش گزینه‌ها", + "hideOptions": "پنهان کردن گزینه‌ها" + }, + "boundingBox": "کادر محدوده", + "timestamp": "مهر زمانی", + "zones": "ناحیه‌ها", + "mask": "ماسک", + "motion": "حرکت", + "regions": "مناطق" } } diff --git a/web/public/locales/fa/components/dialog.json b/web/public/locales/fa/components/dialog.json index 121a73224..99095fc9d 100644 --- a/web/public/locales/fa/components/dialog.json +++ b/web/public/locales/fa/components/dialog.json @@ -1,11 +1,122 @@ { "restart": { - "title": "آیا از ری‌استارت فریگیت اطمینان دارید؟", + "title": "آیا برای راه اندازی مجدد Frigate مطمئن هستید؟", "button": "ری‌استارت", "restarting": { "title": "فریگیت در حال ری‌استارت شدن", "content": "صفحه تا {{countdown}} ثانیه دیگر مجددا بارگزاری خواهد شد.", "button": "بارگزاری مجدد هم اکنون اجرا شود" } + }, + "explore": { + "plus": { + "submitToPlus": { + "label": "ارسال به Frigate+", + "desc": "اشیایی که در مکان‌هایی هستند که می‌خواهید از آن‌ها اجتناب کنید، «مثبت کاذب» محسوب نمی‌شوند. ارسال آن‌ها به‌عنوان مثبت کاذب باعث می‌شود مدل دچار سردرگمی شود." + }, + "review": { + "question": { + "label": "این برچسب را برای Frigate Plus تأیید کنید", + "ask_a": "آیا این شیء {{label}} است؟", + "ask_an": "آیا این شیء یک {{label}} است؟", + "ask_full": "آیا این شیء یک {{untranslatedLabel}} ({{translatedLabel}}) است؟" + }, + "state": { + "submitted": "ارسال شد" + } + } + }, + "video": { + "viewInHistory": "مشاهده در تاریخچه" + } + }, + "export": { + "time": { + "fromTimeline": "انتخاب از خط زمانی", + "lastHour_one": "ساعت گذشته", + "lastHour_other": "آخرین {{count}} ساعت", + "custom": "سفارشی", + "start": { + "title": "زمان شروع", + "label": "زمان شروع را انتخاب کنید" + }, + "end": { + "title": "زمان پایان", + "label": "زمان پایان را انتخاب کنید" + } + }, + "toast": { + "error": { + "endTimeMustAfterStartTime": "زمان پایان باید بعد از زمان شروع باشد", + "noVaildTimeSelected": "بازهٔ زمانی معتبر انتخاب نشده است", + "failed": "شروع خروجی‌گیری ناموفق بود: {{error}}" + }, + "success": "ساخت خروجی با موفقیت آغاز شد. فایل را در صفحه خروجی‌ها مشاهده کنید.", + "view": "مشاهده" + }, + "fromTimeline": { + "saveExport": "ذخیرهٔ خروجی", + "previewExport": "پیش‌نمایش خروجی" + }, + "name": { + "placeholder": "برای خروجی نام بگذارید" + }, + "select": "انتخاب", + "export": "خروجی", + "selectOrExport": "انتخاب یا خروجی" + }, + "streaming": { + "label": "جریان", + "restreaming": { + "disabled": "بازپخش برای این دوربین فعال نیست.", + "desc": { + "title": "برای گزینه‌های بیشتر نمایش زنده و صدا برای این دوربین، go2rtc را تنظیم کنید." + } + }, + "showStats": { + "label": "نمایش آمار جریان", + "desc": "این گزینه را فعال کنید تا آمار جریان به‌صورت پوششی روی تصویر دوربین نمایش داده شود." + }, + "debugView": "نمای اشکال‌زدایی" + }, + "search": { + "saveSearch": { + "label": "ذخیره جست‌وجو", + "desc": "برای این جست‌وجوی ذخیره‌شده یک نام وارد کنید.", + "placeholder": "برای جستجوی خود یک نام وارد کنید", + "success": "جستجو ({{searchName}}) ذخیره شد.", + "button": { + "save": { + "label": "ذخیرهٔ این جستجو" + } + }, + "overwrite": "{{searchName}} موجود است. ذخیره سازی منجر به بازنویسی مقدار موجود خواهد شد." + } + }, + "recording": { + "confirmDelete": { + "title": "تأیید حذف", + "desc": { + "selected": "آیا مطمئن هستید که می‌خواهید همهٔ ویدیوهای ضبط‌شدهٔ مرتبط با این مورد بازبینی را حذف کنید؟

    برای رد کردن این پنجره در آینده، کلید Shift را نگه دارید." + }, + "toast": { + "success": "ویدیوهای مرتبط با موارد بازبینیِ انتخاب‌شده با موفقیت حذف شد.", + "error": "حذف ناموفق بود: {{error}}" + } + }, + "button": { + "export": "خروجی گرفتن", + "markAsReviewed": "علامت‌گذاری به‌عنوان بازبینی‌شده", + "markAsUnreviewed": "علامت‌گذاری به‌عنوان بازبینی‌نشده", + "deleteNow": "حذف فوری" + } + }, + "imagePicker": { + "selectImage": "یک بندانگشتیِ شیء ردیابی‌شده را انتخاب کنید", + "unknownLabel": "تصویر محرک ذخیره شد", + "search": { + "placeholder": "جستجو بر اساس برچسب یا زیر‌برچسب…" + }, + "noImages": "برای این دوربین بندانگشتی‌ای یافت نشد" } } diff --git a/web/public/locales/fa/components/filter.json b/web/public/locales/fa/components/filter.json index ad7827e25..a742be9f8 100644 --- a/web/public/locales/fa/components/filter.json +++ b/web/public/locales/fa/components/filter.json @@ -5,6 +5,136 @@ "all": { "title": "تمامی کلاس ها" }, - "count_one": "{{count}} کلاس" + "count_one": "{{count}} کلاس", + "count_other": "{{count}} کلاس‌ها" + }, + "labels": { + "label": "برچسب‌ها", + "all": { + "title": "همه برچسب‌ها", + "short": "برچسب‌ها" + }, + "count_one": "{{count}} برچسب", + "count_other": "{{count}} برچسب‌ها" + }, + "zones": { + "label": "ناحیه‌ها", + "all": { + "title": "همهٔ ناحیه‌ها", + "short": "ناحیه‌ها" + } + }, + "dates": { + "selectPreset": "یک پیش‌تنظیم را انتخاب کنید…", + "all": { + "title": "همهٔ تاریخ‌ها", + "short": "تاریخ‌ها" + } + }, + "features": { + "hasVideoClip": "دارای کلیپ ویدئویی است", + "submittedToFrigatePlus": { + "label": "ارسال‌شده به Frigate+", + "tips": "ابتدا باید روی اشیای ردیابی‌شده‌ای که عکس فوری دارند فیلتر کنید.

    اشیای ردیابی‌شده بدون عکس فوری نمی‌توانند به Frigate+ ارسال شوند." + }, + "label": "قابلیت‌ها", + "hasSnapshot": "دارای یک عکس فوری" + }, + "sort": { + "label": "مرتب‌سازی", + "dateAsc": "تاریخ (صعودی)", + "dateDesc": "تاریخ (نزولی)", + "scoreAsc": "امتیاز شیء (صعودی)", + "scoreDesc": "امتیاز شیء (نزولی)", + "speedAsc": "سرعت تخمینی (صعودی)", + "speedDesc": "سرعت تخمینی (نزولی)", + "relevance": "آموزش چهره به‌عنوان:ارتباط" + }, + "more": "فیلترهای بیشتر", + "reset": { + "label": "بازنشانی فیلترها به مقادیر پیش‌فرض" + }, + "timeRange": "بازهٔ زمانی", + "subLabels": { + "label": "زیربرچسب‌ها", + "all": "همهٔ زیر برچسب‌ها" + }, + "attributes": { + "label": "ویژگی‌های طبقه‌بندی", + "all": "همهٔ ویژگی‌ها" + }, + "score": "امتیاز", + "estimatedSpeed": "سرعت تخمینی ( {{unit}})", + "cameras": { + "label": "فیلتر دوربین‌ها", + "all": { + "title": "همهٔ دوربین‌ها", + "short": "دوربین‌ها" + } + }, + "logSettings": { + "filterBySeverity": "فیلتر کردن لاگ‌ها بر اساس شدت", + "loading": { + "desc": "وقتی پنل لاگ تا پایین‌ترین نقطه اسکرول شود، لاگ‌های جدید هنگام اضافه‌شدن به‌صورت خودکار نمایش داده می‌شوند.", + "title": "در حال بارگذاری" + }, + "label": "فیلتر سطح لاگ", + "disableLogStreaming": "غیرفعال کردن پخش زندهٔ لاگ", + "allLogs": "همهٔ لاگ‌ها" + }, + "trackedObjectDelete": { + "title": "تأیید حذف", + "toast": { + "success": "اشیای ردیابی‌شده با موفقیت حذف شدند.", + "error": "حذف اشیای ردیابی‌شده ناموفق بود: {{errorMessage}}" + }, + "desc": "حذف این {{objectLength}} شیء ردیابی‌شده باعث حذف عکس فوری، هرگونه امبدینگِ ذخیره‌شده و همهٔ ورودی‌های مرتبط با چرخهٔ عمر شیء می‌شود. ویدیوهای ضبط‌شدهٔ این اشیای ردیابی‌شده در نمای تاریخچه حذف نخواهند شد.

    آیا مطمئن هستید که می‌خواهید ادامه دهید؟

    برای رد کردن این پنجره در آینده، کلید Shift را نگه دارید." + }, + "zoneMask": { + "filterBy": "فیلتر بر اساس ماسک ناحیه" + }, + "recognizedLicensePlates": { + "loadFailed": "بارگذاری پلاک‌های شناسایی‌شده ناموفق بود.", + "loading": "در حال بارگذاری پلاک‌های شناسایی‌شده…", + "noLicensePlatesFound": "هیچ پلاکی پیدا نشد.", + "selectAll": "انتخاب همه", + "title": "پلاک‌های شناسایی‌شده", + "placeholder": "برای جستجوی پلاک‌ها تایپ کنید…", + "selectPlatesFromList": "یک یا چند پلاک را از فهرست انتخاب کنید.", + "clearAll": "پاک کردن همه" + }, + "review": { + "showReviewed": "نمایش بازبینی‌شده‌ها" + }, + "motion": { + "showMotionOnly": "فقط نمایش حرکت" + }, + "explore": { + "settings": { + "title": "تنظیمات", + "defaultView": { + "title": "نمای پیش‌فرض", + "summary": "خلاصه", + "unfilteredGrid": "شبکهٔ بدون فیلتر", + "desc": "هنگامی که هیچ فیلتری انتخاب نشده باشد، خلاصه ای از آخرین اشیاء ردیابی شده در هر برچسب یا یک شبکه فیلتر نشده نمایش داده خواهد شد." + }, + "gridColumns": { + "title": "ستون‌های شبکه", + "desc": "تعداد ستون‌ها را در نمای شبکه انتخاب کنید." + }, + "searchSource": { + "label": "منبع جستجو", + "desc": "انتخاب کنید که در بندانگشتی‌ها جستجو شود یا در توضیحات اشیای ردیابی‌شده.", + "options": { + "thumbnailImage": "تصویر پیش‌نمایش", + "description": "توضیحات" + } + } + }, + "date": { + "selectDateBy": { + "label": "یک تاریخ را برای فیلتر کردن انتخاب کنید" + } + } } } diff --git a/web/public/locales/fa/components/icons.json b/web/public/locales/fa/components/icons.json index 20111cbaa..0fa7bec26 100644 --- a/web/public/locales/fa/components/icons.json +++ b/web/public/locales/fa/components/icons.json @@ -2,7 +2,7 @@ "iconPicker": { "selectIcon": "انتخاب آیکون", "search": { - "placeholder": "جستجو برای آیکون" + "placeholder": "جستجو برای آیکون…" } } } diff --git a/web/public/locales/fa/components/player.json b/web/public/locales/fa/components/player.json index d82c22d9b..38e543fb1 100644 --- a/web/public/locales/fa/components/player.json +++ b/web/public/locales/fa/components/player.json @@ -1,8 +1,51 @@ { "noRecordingsFoundForThisTime": "ویدیویی برای این زمان وجود ندارد", "noPreviewFound": "پیش‌نمایش پیدا نشد", - "noPreviewFoundFor": "هیچ پیش‌نمایشی برای {{cameraName}} پیدا نشد", + "noPreviewFoundFor": "هیچ پیش‌نمایشی برای {{cameraName}} پیدا نشد", "submitFrigatePlus": { - "title": "این فریم به فریگیت+ ارسال شود؟" + "title": "این فریم به فریگیت+ ارسال شود؟", + "submit": "ارسال" + }, + "livePlayerRequiredIOSVersion": "برای این نوع پخش زنده، iOS 17.1 یا بالاتر لازم است.", + "streamOffline": { + "title": "جریان آفلاین", + "desc": "هیچ فریمی از جریان detect دوربین {{cameraName}} دریافت نشده است، گزارش‌های خطا را بررسی کنید" + }, + "cameraDisabled": "دوربین غیرفعال است", + "stats": { + "streamType": { + "title": "نوع جریان:", + "short": "نوع" + }, + "bandwidth": { + "title": "پهنای باند:", + "short": "پهنای باند" + }, + "latency": { + "title": "تأخیر:", + "value": "{{seconds}} ثانیه‌ها", + "short": { + "title": "تأخیر", + "value": "{{seconds}} ثانیه" + } + }, + "totalFrames": "مجموع فریم‌ها:", + "droppedFrames": { + "title": "فریم‌های از دست‌رفته:", + "short": { + "title": "از دست‌رفته", + "value": "{{droppedFrames}} فریم" + } + }, + "decodedFrames": "فریم‌های رمزگشایی‌شده:", + "droppedFrameRate": "نرخ فریم‌های از دست‌رفته:" + }, + "toast": { + "success": { + "submittedFrigatePlus": "فریم با موفقیت به Frigate+ ارسال شد" + }, + "error": { + "submitFrigatePlusFailed": "ارسال فریم به Frigate+ ناموفق بود" + } } } diff --git a/web/public/locales/fa/objects.json b/web/public/locales/fa/objects.json index 278086db2..c2ce4e4cf 100644 --- a/web/public/locales/fa/objects.json +++ b/web/public/locales/fa/objects.json @@ -16,5 +16,105 @@ "bird": "پرنده", "cat": "گربه", "dog": "سگ", - "horse": "اسب" + "horse": "اسب", + "shoe": "کفش", + "eye_glasses": "عینک", + "handbag": "کیف دستی", + "tie": "کراوات", + "suitcase": "چمدان", + "frisbee": "فریزبی", + "sheep": "گوسفند", + "cow": "گاو", + "elephant": "فیل", + "bear": "خرس", + "zebra": "گورخر", + "giraffe": "زرافه", + "hat": "کلاه", + "umbrella": "چتر", + "skis": "اسکی", + "snowboard": "اسنوبورد", + "sports_ball": "توپ ورزشی", + "kite": "بادبادک", + "baseball_bat": "برای استفاده از چند فیلتر، آن‌ها را یکی پس از دیگری با یک فاصله از هم اضافه کنید.چوب بیسبال", + "baseball_glove": "دستکش بیسبال", + "skateboard": "اسکیت‌بورد", + "hot_dog": "هات‌داگ", + "cake": "کیک", + "couch": "مبل", + "bed": "تخت", + "dining_table": "میز ناهارخوری", + "toilet": "توالت", + "tv": "تلویزیون", + "mouse": "موش", + "keyboard": "صفحه‌کلید", + "goat": "بز", + "oven": "فر", + "sink": "سینک", + "refrigerator": "یخچال", + "book": "کتاب", + "vase": "گلدان", + "scissors": "قیچی", + "hair_dryer": "سشوار", + "hair_brush": "برس مو", + "vehicle": "وسیلهٔ نقلیه", + "deer": "گوزن", + "fox": "روباه", + "raccoon": "راکون", + "on_demand": "در صورت نیاز", + "license_plate": "پلاک خودرو", + "package": "بسته", + "amazon": "آمازون", + "usps": "USPS", + "fedex": "FedEx", + "dhl": "DHL", + "purolator": "پرولاتور", + "postnord": "PostNord", + "backpack": "کوله‌پشتی", + "tennis_racket": "راکت تنیس", + "bottle": "بطری", + "plate": "پلاک", + "wine_glass": "جام شراب", + "cup": "فنجان", + "fork": "چنگال", + "knife": "چاقو", + "spoon": "قاشق", + "bowl": "کاسه", + "banana": "موز", + "apple": "سیب", + "animal": "حیوان", + "sandwich": "ساندویچ", + "orange": "پرتقال", + "broccoli": "بروکلی", + "bark": "پارس", + "carrot": "هویج", + "pizza": "پیتزا", + "donut": "دونات", + "chair": "صندلی", + "potted_plant": "گیاه گلدانی", + "mirror": "آینه", + "window": "پنجره", + "desk": "میز", + "door": "در", + "laptop": "لپ‌تاپ", + "remote": "ریموت", + "cell_phone": "گوشی موبایل", + "microwave": "مایکروویو", + "toaster": "توستر", + "blender": "مخلوط‌کن", + "clock": "ساعت", + "teddy_bear": "خرس عروسکی", + "toothbrush": "مسواک", + "squirrel": "سنجاب", + "rabbit": "خرگوش", + "robot_lawnmower": "چمن‌زن رباتی", + "waste_bin": "سطل زباله", + "face": "چهره", + "bbq_grill": "گریل کباب", + "ups": "یو‌پی‌اس", + "an_post": "آن پُست", + "postnl": "پست‌اِن‌اِل", + "nzpost": "اِن‌زد پُست", + "gls": "جی‌اِل‌اِس", + "dpd": "دی‌پی‌دی", + "surfboard": "تخته موج سواری" } diff --git a/web/public/locales/fa/views/classificationModel.json b/web/public/locales/fa/views/classificationModel.json index 7369674e5..b61d55e4d 100644 --- a/web/public/locales/fa/views/classificationModel.json +++ b/web/public/locales/fa/views/classificationModel.json @@ -4,7 +4,10 @@ "renameCategory": "تغییر نام کلاس", "deleteCategory": "حذف کردن کلاس", "deleteImages": "حذف کردن عکس ها", - "trainModel": "مدل آموزش" + "trainModel": "مدل آموزش", + "addClassification": "افزودن دسته‌بندی", + "deleteModels": "حذف مدل‌ها", + "editModel": "ویرایش مدل" }, "toast": { "success": { @@ -12,11 +15,21 @@ "deletedImage": "عکس های حذف شده", "categorizedImage": "تصویر طبقه بندی شده", "trainedModel": "مدل آموزش دیده شده.", - "trainingModel": "آموزش دادن مدل با موفقیت شروع شد." + "trainingModel": "آموزش دادن مدل با موفقیت شروع شد.", + "deletedModel_one": "{{count}} مدل با موفقیت حذف شد", + "deletedModel_other": "{{count}} مدل با موفقیت حذف شدند", + "updatedModel": "پیکربندی مدل با موفقیت به‌روزرسانی شد", + "renamedCategory": "نام کلاس با موفقیت به {{name}} تغییر یافت" }, "error": { - "deleteImageFailed": "حذف نشد:{{پیغام خطا}}", - "deleteCategoryFailed": "کلاس حذف نشد:{{پیغام خطا}}" + "deleteImageFailed": "حذف نشد: {{errorMessage}}", + "deleteCategoryFailed": "کلاس حذف نشد: {{errorMessage}}", + "deleteModelFailed": "حذف مدل ناموفق بود: {{errorMessage}}", + "categorizeFailed": "دسته‌بندی تصویر ناموفق بود: {{errorMessage}}", + "trainingFailed": "آموزش مدل ناموفق بود. برای جزئیات، گزارش‌های Frigate را بررسی کنید.", + "trainingFailedToStart": "شروع آموزش مدل ناموفق بود: {{errorMessage}}", + "updateModelFailed": "به‌روزرسانی مدل ناموفق بود: {{errorMessage}}", + "renameCategoryFailed": "تغییر نام کلاس ناموفق بود: {{errorMessage}}" } }, "documentTitle": "دسته بندی مدل ها - فریگیت", @@ -27,5 +40,148 @@ "none": "هیچکدام", "scoreInfo": "امتیاز، نشان دهنده میانگین دقت در تشخیص و دسته بندی این شیء در بین تمام تشخیص‌هاست.", "unknown": "ناشناخته" - } + }, + "tooltip": { + "trainingInProgress": "مدل در حال آموزش است", + "noNewImages": "هیچ تصویر جدیدی برای آموزش وجود ندارد. ابتدا تصاویر بیشتری را در مجموعه‌داده دسته‌بندی کنید.", + "noChanges": "از آخرین آموزش، هیچ تغییری در مجموعه‌داده ایجاد نشده است.", + "modelNotReady": "مدل برای آموزش آماده نیست" + }, + "deleteCategory": { + "title": "(pending)", + "desc": "آیا مطمئن هستید که می‌خواهید کلاس {{name}} را حذف کنید؟ این کار همهٔ تصاویر مرتبط را برای همیشه حذف می‌کند و نیاز به آموزش مجدد مدل دارد.", + "minClassesTitle": "امکان حذف کلاس وجود ندارد", + "minClassesDesc": "یک مدل دسته‌بندی باید دست‌کم ۲ کلاس داشته باشد. پیش از حذف این مورد، یک کلاس دیگر اضافه کنید." + }, + "train": { + "titleShort": "اخیر", + "title": "طبقه‌بندی‌های اخیر", + "aria": "انتخاب طبقه‌بندی‌های اخیر" + }, + "deleteModel": { + "title": "حذف مدل دسته‌بندی", + "single": "آیا مطمئن هستید که می‌خواهید {{name}} را حذف کنید؟ این کار همهٔ داده‌های مرتبط از جمله تصاویر و داده‌های آموزش را برای همیشه حذف می‌کند. این عمل قابل بازگشت نیست.", + "desc_one": "آیا مطمئن هستید که می‌خواهید این {{count}} مدل را حذف کنید؟ این کار همهٔ داده‌های مرتبط از جمله تصاویر و داده‌های آموزشی را برای همیشه حذف می‌کند. این عمل قابل بازگشت نیست.", + "desc_other": "آیا مطمئن هستید که می‌خواهید {{count}} مدل را حذف کنید؟ این کار همهٔ داده‌های مرتبط از جمله تصاویر و داده‌های آموزشی را برای همیشه حذف می‌کند. این عمل قابل بازگشت نیست." + }, + "categorizeImage": "طبقه‌بندی تصویر", + "menu": { + "states": "حالت‌ها", + "objects": "اشیاء" + }, + "noModels": { + "object": { + "description": "یک مدل سفارشی ایجاد کنید تا اشیای شناسایی‌شده را طبقه‌بندی کند.", + "title": "هیچ مدل طبقه‌بندی شیء وجود ندارد", + "buttonText": "ایجاد مدل شیء" + }, + "state": { + "title": "هیچ مدل طبقه‌بندی حالت وجود ندارد", + "description": "یک مدل سفارشی ایجاد کنید تا تغییرات وضعیت را در نواحی مشخصِ دوربین پایش و طبقه‌بندی کند.", + "buttonText": "ایجاد مدل وضعیت" + } + }, + "wizard": { + "title": "ایجاد طبقه‌بندی جدید", + "steps": { + "stateArea": "ناحیهٔ حالت", + "nameAndDefine": "نام‌گذاری و تعریف", + "chooseExamples": "انتخاب نمونه‌ها" + }, + "step1": { + "description": "مدل‌های حالت نواحی ثابت دوربین را برای تغییرات پایش می‌کنند (مثلاً درِ باز/بسته). مدل‌های شیء به اشیای شناسایی‌شده طبقه‌بندی اضافه می‌کنند (مثلاً حیوانات شناخته‌شده، مأموران تحویل، و غیره).", + "namePlaceholder": "نام مدل را وارد کنید...", + "type": "نوع", + "typeObject": "شیء", + "objectLabelPlaceholder": "نوع شیء را انتخاب کنید...", + "classificationTypeDesc": "زیر‌برچسب‌ها متن اضافی به برچسب شیء اضافه می‌کنند (مثلاً «Person: UPS»). ویژگی‌ها فرادادهٔ قابل جست‌وجو هستند که جداگانه در فرادادهٔ شیء ذخیره می‌شوند.", + "classificationAttribute": "ویژگی", + "classes": "کلاس‌ها", + "classesTip": "دربارهٔ کلاس‌ها بیشتر بدانید", + "classesObjectDesc": "دسته‌بندی‌های مختلف را برای طبقه‌بندی اشیای شناسایی‌شده تعریف کنید. برای نمونه: «delivery_person»، «resident»، «stranger» برای طبقه‌بندی افراد.", + "errors": { + "nameLength": "نام مدل باید ۶۴ نویسه یا کم‌تر باشد", + "classesUnique": "نام کلاس‌ها باید یکتا باشند", + "stateRequiresTwoClasses": "مدل‌های حالت دست‌کم به ۲ کلاس نیاز دارند", + "objectLabelRequired": "لطفاً یک برچسب شیء را انتخاب کنید", + "nameRequired": "نام مدل الزامی است", + "nameOnlyNumbers": "نام مدل نمی‌تواند فقط شامل عدد باشد", + "noneNotAllowed": "کلاس «none» مجاز نیست", + "classRequired": "حداقل ۱ کلاس لازم است", + "objectTypeRequired": "لطفاً یک نوع طبقه‌بندی را انتخاب کنید" + }, + "name": "نام", + "typeState": "وضعیت", + "objectLabel": "برچسب شیء", + "classificationType": "نوع طبقه‌بندی", + "classificationSubLabel": "زیر‌برچسب", + "classificationTypeTip": "دربارهٔ انواع طبقه‌بندی بیشتر بدانید", + "states": "وضعیت‌ها", + "classesStateDesc": "حالت‌های مختلفی را که ناحیهٔ دوربین شما می‌تواند در آن باشد تعریف کنید. برای مثال: «باز» و «بسته» برای یک درِ گاراژ.", + "classPlaceholder": "نام کلاس را وارد کنید…" + }, + "step2": { + "description": "دوربین‌ها را انتخاب کنید و ناحیه‌ای را که باید برای هر دوربین پایش شود تعریف کنید. مدل، وضعیت این ناحیه‌ها را طبقه‌بندی می‌کند.", + "cameras": "دوربین‌ها", + "noCameras": "برای افزودن دوربین‌ها روی + کلیک کنید", + "selectCamera": "انتخاب دوربین", + "selectCameraPrompt": "برای تعریف ناحیهٔ پایش، یک دوربین را از فهرست انتخاب کنید" + }, + "step3": { + "selectImagesDescription": "برای انتخاب، روی تصاویر کلیک کنید. وقتی کارتان با این کلاس تمام شد روی «ادامه» کلیک کنید.", + "generating": { + "description": "Frigate در حال استخراج تصاویر نماینده از ضبط‌های شماست. ممکن است کمی زمان ببرد…", + "title": "در حال تولید تصاویر نمونه" + }, + "retryGenerate": "تلاش دوباره برای تولید", + "classifying": "در حال طبقه‌بندی و آموزش…", + "trainingStarted": "آموزش با موفقیت شروع شد", + "errors": { + "noCameras": "هیچ دوربینی پیکربندی نشده است", + "noObjectLabel": "هیچ برچسب شیئی انتخاب نشده است", + "generationFailed": "تولید ناموفق بود. لطفاً دوباره تلاش کنید.", + "classifyFailed": "طبقه‌بندی تصاویر ناموفق بود: {{error}}", + "generateFailed": "تولید نمونه‌ها ناموفق بود: {{error}}" + }, + "missingStatesWarning": { + "title": "نمونه‌های وضعیتِ جاافتاده", + "description": "برای بهترین نتیجه، توصیه می‌شود برای همهٔ حالت‌ها نمونه انتخاب کنید. می‌توانید بدون انتخاب همهٔ حالت‌ها ادامه دهید، اما تا زمانی که همهٔ حالت‌ها تصویر نداشته باشند مدل آموزش داده نمی‌شود. پس از ادامه، از نمای «طبقه‌بندی‌های اخیر» برای طبقه‌بندی تصاویرِ حالت‌های جاافتاده استفاده کنید، سپس مدل را آموزش دهید." + }, + "allImagesRequired_one": "لطفاً همهٔ تصاویر را طبقه‌بندی کنید. {{count}} تصویر باقی مانده است.", + "allImagesRequired_other": "لطفاً همهٔ تصاویر را طبقه‌بندی کنید. {{count}} تصویر باقی مانده است.", + "training": { + "title": "در حال آموزش مدل", + "description": "مدل شما در پس‌زمینه در حال آموزش است. این پنجره را ببندید؛ به‌محض تکمیل آموزش، مدل شما شروع به اجرا می‌کند." + }, + "noImages": "هیچ تصویر نمونه‌ای تولید نشد", + "modelCreated": "مدل با موفقیت ایجاد شد. از نمای «طبقه‌بندی‌های اخیر» برای افزودن تصاویرِ وضعیت‌هایِ جاافتاده استفاده کنید، سپس مدل را آموزش دهید.", + "generateSuccess": "تصاویر نمونه با موفقیت تولید شد", + "selectImagesPrompt": "همهٔ تصاویر با {{className}} را انتخاب کنید" + } + }, + "edit": { + "title": "ویرایش مدل طبقه‌بندی", + "descriptionState": "کلاس‌های این مدل طبقه‌بندی حالت را ویرایش کنید. اعمال تغییرات نیاز به بازآموزی مدل دارد.", + "descriptionObject": "نوع شیء و نوع طبقه‌بندی را برای این مدل طبقه‌بندی شیء ویرایش کنید.", + "stateClassesInfo": "توجه: تغییر کلاس‌های وضعیت نیازمند بازآموزی مدل با کلاس‌های به‌روزرسانی‌شده است." + }, + "deleteDatasetImages": { + "title": "حذف تصاویر مجموعه‌داده", + "desc_one": "آیا مطمئن هستید که می‌خواهید این {{count}} تصویر را از {{dataset}} حذف کنید؟ این عمل قابل بازگشت نیست و نیاز به بازآموزی مدل دارد.", + "desc_other": "آیا مطمئن هستید که می‌خواهید {{count}} تصویر را از {{dataset}} حذف کنید؟ این عمل قابل بازگشت نیست و نیاز به بازآموزی مدل دارد." + }, + "deleteTrainImages": { + "title": "حذف تصاویر آموزش", + "desc_one": "آیا مطمئن هستید که می‌خواهید این {{count}} تصویر را حذف کنید؟ این عمل قابل بازگشت نیست.", + "desc_other": "آیا مطمئن هستید که می‌خواهید {{count}} تصویر را حذف کنید؟ این عمل قابل بازگشت نیست." + }, + "renameCategory": { + "title": "تغییر نام کلاس", + "desc": "یک نام جدید برای {{name}} وارد کنید. برای اعمال تغییر نام، لازم است مدل را بازآموزی کنید." + }, + "categories": "کلاس‌ها", + "createCategory": { + "new": "ایجاد کلاس جدید" + }, + "categorizeImageAs": "طبقه‌بندی تصویر به‌عنوان:" } diff --git a/web/public/locales/fa/views/configEditor.json b/web/public/locales/fa/views/configEditor.json index 0c97e3f62..c43489dbb 100644 --- a/web/public/locales/fa/views/configEditor.json +++ b/web/public/locales/fa/views/configEditor.json @@ -3,5 +3,16 @@ "configEditor": "ویرایشگر کانفیگ", "safeConfigEditor": "ویرایشگر تنظیمات (حالت امن)", "safeModeDescription": "فریگیت به دلیل خطا در صحت سنجی پیکربندی، در حالت امن می باشد.", - "copyConfig": "کپی پیکربندی" + "copyConfig": "کپی پیکربندی", + "saveAndRestart": "ذخیره و راه‌اندازی مجدد", + "saveOnly": "فقط ذخیره", + "confirm": "بدون ذخیره خارج می‌شوید؟", + "toast": { + "success": { + "copyToClipboard": "پیکربندی در کلیپ‌بورد کپی شد." + }, + "error": { + "savingError": "خطا در ذخیره‌سازی پیکربندی" + } + } } diff --git a/web/public/locales/fa/views/events.json b/web/public/locales/fa/views/events.json index a56694712..cf3ca7871 100644 --- a/web/public/locales/fa/views/events.json +++ b/web/public/locales/fa/views/events.json @@ -4,5 +4,62 @@ "motion": { "label": "حرکت", "only": "فقط حرکتی" - } + }, + "allCameras": "همه دوربین‌ها", + "empty": { + "alert": "هیچ هشداری برای بازبینی وجود ندارد", + "detection": "هیچ تشخیصی برای بازبینی وجود ندارد", + "motion": "هیچ داده‌ای از حرکت پیدا نشد", + "recordingsDisabled": { + "title": "ضبط‌ها بایستی فعال باشند", + "description": "موارد بازبینی برای یک دوربین تنها درصورتی امکان ساخت دارند که ضبط‌ها برای آن دورین فعال باشد." + } + }, + "timeline": "خط زمانی", + "timeline.aria": "انتخاب خط زمانی", + "zoomIn": "بزرگ‌نمایی", + "zoomOut": "کوچک‌نمایی", + "events": { + "aria": "انتخاب رویدادها", + "noFoundForTimePeriod": "برای این بازهٔ زمانی هیچ رویدادی یافت نشد.", + "label": "رویدادها" + }, + "recordings": { + "documentTitle": "ضبط‌ها - فریگیت" + }, + "calendarFilter": { + "last24Hours": "۲۴ ساعت گذشته" + }, + "markAsReviewed": "علامت‌گذاری به‌عنوان بازبینی‌شده", + "markTheseItemsAsReviewed": "این موارد را به‌عنوان بازبینی‌شده علامت‌گذاری کنید", + "newReviewItems": { + "label": "مشاهدهٔ موارد جدید برای بازبینی", + "button": "موارد جدید برای بازبینی" + }, + "detail": { + "label": "جزئیات", + "noDataFound": "داده‌ای برای بازبینیِ جزئیات وجود ندارد", + "aria": "تغییر وضعیتِ نمای جزئیات", + "trackedObject_one": "{{count}} شیء", + "trackedObject_other": "{{count}} اشیاء", + "noObjectDetailData": "دادهٔ جزئیات شیء در دسترس نیست.", + "settings": "تنظیمات نمای جزئیات", + "alwaysExpandActive": { + "title": "همیشه فعال را باز کنید", + "desc": "در صورت امکان، همیشه جزئیات شیء مربوط به موردِ بازبینیِ فعال را باز کنید." + } + }, + "objectTrack": { + "trackedPoint": "نقطهٔ ردیابی‌شده", + "clickToSeek": "برای رفتن به این زمان کلیک کنید" + }, + "documentTitle": "بازبینی - Frigate", + "selected_one": "{{count}} انتخاب شد", + "selected_other": "{{count}} انتخاب شدند", + "select_all": "همه", + "camera": "دوربین", + "detected": "گزینه‌هاشناسایی شد", + "normalActivity": "عادی", + "needsReview": "نیاز به بازبینی", + "securityConcern": "نگرانی امنیتی" } diff --git a/web/public/locales/fa/views/explore.json b/web/public/locales/fa/views/explore.json index 7ee77df16..d532878c4 100644 --- a/web/public/locales/fa/views/explore.json +++ b/web/public/locales/fa/views/explore.json @@ -1,14 +1,248 @@ { "generativeAI": "هوش مصنوعی تولید کننده", - "documentTitle": "کاوش کردن - فرایگیت", + "documentTitle": "کاوش - فریگیت", "exploreMore": "نمایش اشیا {{label}} بیشتر", "details": { - "timestamp": "زمان دقیق" + "timestamp": "زمان دقیق", + "item": { + "desc": "بررسی جزئیات مورد", + "button": { + "viewInExplore": "مشاهده در کاوش", + "share": "اشتراک‌گذاری این مورد بازبینی" + }, + "tips": { + "hasMissingObjects": "اگر می‌خواهید Frigate اشیای ردیابی‌شده را برای برچسب‌های زیر ذخیره کند، پیکربندی خود را تنظیم کنید: {{objects}} ", + "mismatch_one": "{{count}} شیء غیرقابلدسترس شناسایی شد و در این مورد بازبینی گنجانده شد. این اشیا یا شرایط لازم برای هشدار یا تشخیص را نداشتند یا قبلاً پاکسازی/حذف شدهاند.", + "mismatch_other": "{{count}} شیء غیرقابلدسترس شناسایی شدند و در این مورد بازبینی گنجانده شدند. این اشیا یا شرایط لازم برای هشدار یا تشخیص را نداشتند یا قبلاً پاکسازی/حذف شدهاند." + }, + "toast": { + "success": { + "regenerate": "یک توضیح جدید از {{provider}} درخواست شد. بسته به سرعت ارائه‌دهندهٔ شما، بازتولیدِ توضیح جدید ممکن است کمی زمان ببرد.", + "updatedLPR": "پلاک با موفقیت به‌روزرسانی شد.", + "audioTranscription": "درخواست تبدیل گفتارِ صوت با موفقیت ثبت شد. بسته به سرعت سرور Frigate شما، تکمیل تبدیل گفتار ممکن است کمی زمان ببرد.", + "updatedSublabel": "زیر برچسب با موفقیت به‌روزرسانی شد.", + "updatedAttributes": "ویژگی‌ها با موفقیت به‌روزرسانی شد." + }, + "error": { + "updatedSublabelFailed": "به‌روزرسانی زیر‌برچسب ناموفق بود: {{errorMessage}}", + "updatedAttributesFailed": "به‌روزرسانی ویژگی‌ها ناموفق بود: {{errorMessage}}", + "regenerate": "فراخوانی {{provider}} برای توضیح جدید ناموفق بود: {{errorMessage}}", + "updatedLPRFailed": "به‌روزرسانی پلاک ناموفق بود: {{errorMessage}}", + "audioTranscription": "درخواست رونویسی صدا ناموفق بود: {{errorMessage}}" + } + }, + "title": "جزئیات مورد بازبینی" + }, + "editSubLabel": { + "title": "ویرایش زیر‌برچسب", + "descNoLabel": "برای این شیء ردیابی‌شده یک زیر‌برچسب جدید وارد کنید", + "desc": "برای این {{label}} یک زیر‌برچسب جدید وارد کنید" + }, + "editLPR": { + "desc": "برای {{label}} یک مقدار جدید برای پلاک وارد کنید", + "descNoLabel": "برای این شیء ردیابی‌شده یک مقدار جدید برای پلاک وارد کنید", + "title": "ویرایش پلاک" + }, + "editAttributes": { + "desc": "ویژگی‌های طبقه‌بندی را برای {{label}} انتخاب کنید", + "title": "ویرایش ویژگی‌ها" + }, + "topScore": { + "label": "بالاترین امتیاز", + "info": "بالاترین امتیاز، بالاترین امتیاز میانه برای شیء ردیابی‌شده است؛ بنابراین ممکن است با امتیازی که روی تصویر بندانگشتیِ نتیجهٔ جست‌وجو نمایش داده می‌شود متفاوت باشد." + }, + "recognizedLicensePlate": "پلاک شناسایی‌شده", + "estimatedSpeed": "سرعت تخمینی", + "objects": "اشیا", + "zones": "ناحیه‌ها", + "button": { + "regenerate": { + "title": "بازتولید", + "label": "بازسازی توضیح شیء ردیابی‌شده" + }, + "findSimilar": "یافتن مشابه" + }, + "description": { + "placeholder": "توضیحِ شیء ردیابی‌شده", + "label": "توضیحات", + "aiTips": "Frigate تا زمانی که چرخهٔ عمر شیء ردیابی‌شده پایان نیابد، از ارائه‌دهندهٔ هوش مصنوعی مولد شما درخواست توضیح نمی‌کند." + }, + "expandRegenerationMenu": "باز کردن منوی بازتولید", + "regenerateFromSnapshot": "بازتولید از اسنپ‌شات", + "tips": { + "descriptionSaved": "توضیح با موفقیت ذخیره شد", + "saveDescriptionFailed": "به‌روزرسانی توضیح ناموفق بود: {{errorMessage}}" + }, + "label": "برچسب", + "snapshotScore": { + "label": "امتیاز عکس فوری" + }, + "score": { + "label": "امتیاز" + }, + "attributes": "ویژگی‌های طبقه‌بندی", + "camera": "دوربین", + "regenerateFromThumbnails": "بازسازی از تصاویر بندانگشتی", + "title": { + "label": "عنوان" + } }, "exploreIsUnavailable": { - "title": "نمایش کلی موجود نمی باشد", + "title": "کاوش کردن در دسترس نیست", "embeddingsReindexing": { - "startingUp": "درحال شروع…" + "startingUp": "درحال شروع…", + "context": "پس از اینکه جاسازی‌های شیء ردیابی‌شده، نمایه‌سازی مجدد را به پایان رساندند، می‌توان از کاوش استفاده کرد.", + "estimatedTime": "زمان تخمینی باقی‌مانده:", + "finishingShortly": "به‌زودی تمام می‌شود", + "step": { + "thumbnailsEmbedded": "تصاویر بندانگشتی جاسازی‌شده: ", + "descriptionsEmbedded": "توضیحات جاسازی‌شده: ", + "trackedObjectsProcessed": "اشیای ردیابی‌شدهٔ پردازش‌شده: " + } + }, + "downloadingModels": { + "context": "Frigate در حال دانلود مدل‌های بردارسازی لازم برای پشتیبانی از قابلیت «جست‌وجوی معنایی» است. بسته به سرعت اتصال شبکه شما، این کار ممکن است چند دقیقه طول بکشد.", + "setup": { + "visionModel": "مدل بینایی", + "visionModelFeatureExtractor": "استخراج‌کنندهٔ ویژگی‌های مدل بینایی", + "textModel": "مدل متنی", + "textTokenizer": "توکن‌ساز متن" + }, + "tips": { + "context": "ممکن است بخواهید پس از دانلود مدل‌ها، تعبیه‌های اشیای ردیابی‌شدهٔ خود را دوباره ایندکس کنید." + }, + "error": "خطایی رخ داده است. گزارش‌های Frigate را بررسی کنید." } + }, + "trackingDetails": { + "adjustAnnotationSettings": "تنظیمات حاشیه‌نویسی را تنظیم کنید", + "scrollViewTips": "برای مشاهدهٔ لحظه‌های مهم چرخهٔ زندگی این شیء کلیک کنید.", + "autoTrackingTips": "موقعیت کادرها برای دوربین‌های ردیابی خودکار دقیق نخواهد بود.", + "count": "{{first}} از {{second}}", + "trackedPoint": "نقطهٔ ردیابی‌شده", + "lifecycleItemDesc": { + "visible": "{{label}} شناسایی شد", + "entered_zone": "{{label}} وارد {{zones}} شد", + "active": "{{label}} فعال شد", + "stationary": "{{label}} ساکن شد", + "attribute": { + "faceOrLicense_plate": "{{attribute}} برای {{label}} شناسایی شد", + "other": "{{label}} به‌عنوان {{attribute}} شناسایی شد" + }, + "gone": "{{label}} خارج شد", + "heard": "{{label}} شنیده شد", + "external": "{{label}} شناسایی شد", + "header": { + "zones": "ناحیه‌ها", + "ratio": "نسبت", + "area": "مساحت", + "score": "امتیاز" + } + }, + "title": "جزئیات ردیابی", + "noImageFound": "برای این برچسب زمانی هیچ تصویری یافت نشد.", + "createObjectMask": "ایجاد ماسک شیء", + "annotationSettings": { + "title": "تنظیمات حاشیه‌نویسی", + "showAllZones": { + "title": "نمایش همهٔ مناطق", + "desc": "همیشه مناطق را روی فریم‌هایی که اشیا وارد یک منطقه شده‌اند نمایش دهید." + }, + "offset": { + "toast": { + "success": "افست حاشیه‌نویسی برای {{camera}} در فایل پیکربندی ذخیره شد." + }, + "label": "افست حاشیه‌نویسی", + "desc": "این داده از فید تشخیص دوربین شما می‌آید، اما روی تصاویر فید ضبط‌شده قرار می‌گیرد. بعید است این دو جریان کاملاً هم‌زمان باشند. در نتیجه، کادر محدوده و ویدیو دقیقاً روی هم منطبق نخواهند بود. می‌توانید با این تنظیمات، حاشیه‌نویسی‌ها را در زمان به جلو یا عقب جابه‌جا کنید تا با ویدئوی ضبط‌شده بهتر هم‌تراز شوند.", + "millisecondsToOffset": "میلی‌ثانیه برای جابه‌جایی حاشیه‌نویسی‌های تشخیص. پیش‌فرض: 0 ", + "tips": "اگر پخش ویدیو جلوتر از کادرها و نقاط مسیر است مقدار را کمتر کنید و اگر پخش ویدیو عقب‌تر از آن‌هاست مقدار را بیشتر کنید. این مقدار می‌تواند منفی باشد." + } + }, + "carousel": { + "previous": "اسلاید قبلی", + "next": "اسلاید بعدی" + } + }, + "trackedObjectDetails": "جزئیات شیء ردیابی‌شده", + "type": { + "details": "جزئیات‌ها", + "snapshot": "عکس فوری", + "thumbnail": "پیش‌نمایش", + "video": "ویدیو", + "tracking_details": "جزئیات ردیابی" + }, + "itemMenu": { + "downloadVideo": { + "aria": "دانلود ویدئو", + "label": "دانلود ویدیو" + }, + "downloadSnapshot": { + "label": "دانلود اسنپ‌شات", + "aria": "دانلود عکس" + }, + "downloadCleanSnapshot": { + "label": "دانلود اسنپ‌شاتِ بدون کادر", + "aria": "دانلود عکس فوری بدون کادر" + }, + "viewTrackingDetails": { + "aria": "نمایش جزئیات ردیابی", + "label": "مشاهدهٔ جزئیات ردیابی" + }, + "findSimilar": { + "label": "یافتن مشابه", + "aria": "یافتن اشیای ردیابی‌شدهٔ مشابه" + }, + "addTrigger": { + "label": "افزودن تریگر", + "aria": "افزودن تریگر برای این شیء ردیابی‌شده" + }, + "audioTranscription": { + "aria": "درخواست رونویسیِ صوتی", + "label": "رونویسی" + }, + "submitToPlus": { + "aria": "ارسال به Frigate Plus", + "label": "ارسال به Frigate+" + }, + "viewInHistory": { + "label": "مشاهده در تاریخچه", + "aria": "مشاهده در تاریخچه" + }, + "showObjectDetails": { + "label": "نمایش مسیر شیء" + }, + "hideObjectDetails": { + "label": "پنهان کردن مسیر شیء" + }, + "deleteTrackedObject": { + "label": "حذف این شیء ردیابی‌شده" + } + }, + "noTrackedObjects": "هیچ شیء ردیابی‌شده‌ای پیدا نشد", + "fetchingTrackedObjectsFailed": "خطا در دریافت اشیای ردیابی‌شده: {{errorMessage}}", + "trackedObjectsCount_one": "{{count}} شیء ردیابیشده ", + "trackedObjectsCount_other": "{{count}} اشیای ردیابیشده ", + "dialog": { + "confirmDelete": { + "title": "تأیید حذف", + "desc": "حذف این شیء ردیابی‌شده عکس فوری، هرگونه امبدینگ ذخیره‌شده و هر ورودی مرتبط با جزئیات ردیابی را حذف می‌کند. فیلم ضبط‌شدهٔ این شیء ردیابی‌شده در نمای تاریخ حذف نخواهد شد.

    آیا مطمئنید می‌خواهید ادامه دهید؟" + } + }, + "searchResult": { + "tooltip": "{{type}} با {{confidence}}٪ مطابقت داشت", + "previousTrackedObject": "شیء ردیابی‌شدهٔ قبلی", + "nextTrackedObject": "شیء ردیابی‌شدهٔ بعدی", + "deleteTrackedObject": { + "toast": { + "success": "شیء ردیابی‌شده با موفقیت حذف شد.", + "error": "حذف شیء ردیابی‌شده ناموفق بود: {{errorMessage}}" + } + } + }, + "aiAnalysis": { + "title": "تحلیل هوش مصنوعی" + }, + "concerns": { + "label": "نگرانی‌ها" } } diff --git a/web/public/locales/fa/views/exports.json b/web/public/locales/fa/views/exports.json index 30532619c..46aec6287 100644 --- a/web/public/locales/fa/views/exports.json +++ b/web/public/locales/fa/views/exports.json @@ -1,6 +1,23 @@ { - "search": "جستجو", + "search": "یافتن", "documentTitle": "گرفتن خروجی - فریگیت", "noExports": "هیچ خروجی یافت نشد", - "deleteExport": "حذف خروجی" + "deleteExport": "حذف خروجی", + "deleteExport.desc": "آیا مطمئن هستید که می‌خواهید {{exportName}} را حذف کنید؟", + "editExport": { + "title": "تغییر نام خروجی", + "desc": "یک نام جدید برای این خروجی وارد کنید.", + "saveExport": "ذخیرهٔ خروجی" + }, + "tooltip": { + "shareExport": "اشتراک‌گذاری خروجی", + "downloadVideo": "دانلود ویدئو", + "editName": "ویرایش نام", + "deleteExport": "حذف خروجی" + }, + "toast": { + "error": { + "renameExportFailed": "تغییر نام خروجی ناموفق بود: {{errorMessage}}" + } + } } diff --git a/web/public/locales/fa/views/faceLibrary.json b/web/public/locales/fa/views/faceLibrary.json index fa2595f8e..4cf24c268 100644 --- a/web/public/locales/fa/views/faceLibrary.json +++ b/web/public/locales/fa/views/faceLibrary.json @@ -6,6 +6,85 @@ }, "details": { "timestamp": "زمان دقیق", - "unknown": "ناشناخته" + "unknown": "ناشناخته", + "scoreInfo": "امتیاز، میانگینِ وزن‌دارِ امتیاز همهٔ چهره‌هاست که وزن آن براساس اندازهٔ چهره در هر تصویر تعیین می‌شود." + }, + "documentTitle": "کتابخانه چهره - Frigate", + "uploadFaceImage": { + "title": "بارگذاری تصویر چهره", + "desc": "یک تصویر بارگذاری کنید تا چهره‌ها اسکن شوند و برای {{pageToggle}} در نظر گرفته شود" + }, + "collections": "مجموعه‌ها", + "createFaceLibrary": { + "new": "ایجاد چهرهٔ جدید", + "nextSteps": "برای ایجاد یک پایهٔ محکم:
  • از تب «تشخیص‌های اخیر» برای انتخاب و آموزش با تصاویر هر شخصِ شناسایی‌شده استفاده کنید.
  • برای بهترین نتیجه روی تصاویر روبه‌رو تمرکز کنید؛ از آموزش با تصاویری که چهره را از زاویه نشان می‌دهند خودداری کنید.
  • " + }, + "steps": { + "faceName": "نام چهره را وارد کنید", + "uploadFace": "بارگذاری تصویر چهره", + "nextSteps": "مراحل بعدی", + "description": { + "uploadFace": "تصویری از {{name}} بارگذاری کنید که چهرهٔ او را از زاویهٔ روبه‌رو نشان دهد. لازم نیست تصویر فقط به چهرهٔ او برش داده شود." + } + }, + "button": { + "addFace": "افزودن چهره", + "renameFace": "تغییر نام چهره", + "deleteFace": "حذف چهره", + "uploadImage": "بارگذاری تصویر", + "reprocessFace": "پردازش مجدد چهره", + "deleteFaceAttempts": "حذف چهره‌ها" + }, + "imageEntry": { + "validation": { + "selectImage": "لطفاً یک فایل تصویر انتخاب کنید." + }, + "dropActive": "تصویر را اینجا رها کنید…", + "dropInstructions": "یک تصویر را اینجا بکشید و رها کنید یا جای‌گذاری کنید، یا برای انتخاب کلیک کنید", + "maxSize": "حداکثر اندازه: {{size}}MB" + }, + "train": { + "title": "تشخیص‌های اخیر", + "titleShort": "اخیر", + "aria": "تشخیص‌های اخیر را انتخاب کنید", + "empty": "تلاشِ اخیر برای تشخیص چهره وجود ندارد" + }, + "deleteFaceLibrary": { + "title": "حذف نام", + "desc": "آیا مطمئن هستید می‌خواهید مجموعهٔ {{name}} را حذف کنید؟ این کار همهٔ چهره‌های مرتبط را برای همیشه حذف می‌کند." + }, + "deleteFaceAttempts": { + "title": "حذف چهره‌ها", + "desc_one": "آیا مطمئن هستید که می‌خواهید {{count}} چهره را حذف کنید؟ این عمل قابل بازگشت نیست.", + "desc_other": "آیا مطمئن هستید که می‌خواهید {{count}} چهره را حذف کنید؟ این عمل قابل بازگشت نیست." + }, + "renameFace": { + "title": "تغییر نام چهره", + "desc": "یک نام جدید برای {{name}} وارد کنید" + }, + "nofaces": "هیچ چهره‌ای موجود نیست", + "trainFaceAs": "شناسایی شدآموزش چهره به‌عنوان:", + "trainFace": "آموزش چهره", + "toast": { + "success": { + "uploadedImage": "تصویر با موفقیت بارگذاری شد.", + "addFaceLibrary": "{{name}} با موفقیت به کتابخانهٔ چهره اضافه شد!", + "deletedFace_one": "حذف این {{count}} چهره با موفقیت انجام شد.", + "deletedFace_other": "حذف {{count}} چهره با موفقیت انجام شد.", + "deletedName_one": "{{count}} چهره با موفقیت حذف شد.", + "deletedName_other": "{{count}} چهره با موفقیت حذف شدند.", + "renamedFace": "نام چهره با موفقیت به {{name}} تغییر یافت", + "trainedFace": "آموزش چهره با موفقیت انجام شد.", + "updatedFaceScore": "امتیاز چهره با موفقیت به {{name}} ( {{score}}) به‌روزرسانی شد." + }, + "error": { + "uploadingImageFailed": "آپلود تصویر ناموفق بود: {{errorMessage}}", + "addFaceLibraryFailed": "تنظیم نام چهره ناموفق بود: {{errorMessage}}", + "deleteFaceFailed": "حذف ناموفق بود: {{errorMessage}}", + "deleteNameFailed": "حذف نام ناموفق بود: {{errorMessage}}", + "renameFaceFailed": "تغییر نام چهره ناموفق بود: {{errorMessage}}", + "trainFailed": "آموزش ناموفق بود: {{errorMessage}}", + "updateFaceScoreFailed": "به‌روزرسانی امتیاز چهره ناموفق بود: {{errorMessage}}" + } } } diff --git a/web/public/locales/fa/views/live.json b/web/public/locales/fa/views/live.json index 97faeda8b..383da433c 100644 --- a/web/public/locales/fa/views/live.json +++ b/web/public/locales/fa/views/live.json @@ -3,9 +3,184 @@ "documentTitle.withCamera": "{{camera}} - زنده - فریگیت", "lowBandwidthMode": "حالت کاهش مصرف پهنای باند", "twoWayTalk": { - "enable": "فعال سازی مکالمه دوطرفه" + "enable": "فعال سازی مکالمه دوطرفه", + "disable": "غیرفعال کردن گفتگوی دوطرفه" }, "cameraAudio": { - "enable": "فعالسازی صدای دوربین" + "enable": "فعالسازی صدای دوربین", + "disable": "غیرفعال کردن صدای دوربین" + }, + "ptz": { + "move": { + "clickMove": { + "label": "برای قرار دادن دوربین در مرکز، در کادر کلیک کنید", + "enable": "فعال‌سازی کلیک برای جابه‌جایی", + "disable": "غیرفعال‌سازی کلیک برای جابه‌جایی" + }, + "left": { + "label": "دوربین PTZ را به چپ حرکت دهید" + }, + "up": { + "label": "دوربین PTZ را به بالا حرکت دهید" + }, + "right": { + "label": "دوربین PTZ را به راست حرکت دهید" + }, + "down": { + "label": "دوربین PTZ را به پایین حرکت دهید" + } + }, + "zoom": { + "in": { + "label": "روی دوربین PTZ بزرگ‌نمایی کنید" + }, + "out": { + "label": "روی دوربین PTZ کوچک‌نمایی کنید" + } + }, + "focus": { + "in": { + "label": "فوکوس دوربین PTZ را به داخل ببرید" + }, + "out": { + "label": "فوکوس دوربین PTZ را به بیرون ببرید" + } + }, + "frame": { + "center": { + "label": "برای قرار دادن دوربین PTZ در مرکز، داخل کادر کلیک کنید" + } + }, + "presets": "پیش‌تنظیم‌های دوربین PTZ" + }, + "recording": { + "disable": "غیرفعال کردن ضبط", + "enable": "فعال‌سازی ضبط" + }, + "snapshots": { + "enable": "فعال کردن عکس‌های فوری", + "disable": "غیرفعال کردن عکس‌های فوری" + }, + "snapshot": { + "takeSnapshot": "دانلود عکس فوری", + "noVideoSource": "منبع ویدیویی برای عکس فوری در دسترس نیست.", + "captureFailed": "گرفتن عکس فوری ناموفق بود.", + "downloadStarted": "دانلود عکس فوری آغاز شد." + }, + "camera": { + "enable": "فعال کردن دوربین", + "disable": "غیرفعال کردن دوربین" + }, + "muteCameras": { + "enable": "بی‌صدا کردن همهٔ دوربین‌ها", + "disable": "قطع بی‌صدا برای همهٔ دوربین‌ها" + }, + "detect": { + "enable": "فعال‌سازی تشخیص", + "disable": "غیرفعال‌سازی تشخیص" + }, + "audioDetect": { + "enable": "فعال‌سازی تشخیص صدا", + "disable": "غیرفعال‌سازی تشخیص صدا" + }, + "transcription": { + "enable": "فعال‌سازی رونوشت‌برداری زندهٔ صدا", + "disable": "غیرفعال‌سازی رونوشت‌برداری زندهٔ صدا" + }, + "autotracking": { + "enable": "فعال‌سازی ردیابی خودکار", + "disable": "غیرفعال کردن ردیابی خودکار" + }, + "streamingSettings": "تنظیمات استریم", + "audio": "صدا", + "stream": { + "title": "جریان", + "audio": { + "tips": { + "title": "برای این استریم، صدا باید از دوربین شما خروجی داده شود و در go2rtc پیکربندی شده باشد." + }, + "unavailable": "صدا برای این استریم در دسترس نیست", + "available": "برای این جریان صدا در دسترس است" + }, + "twoWayTalk": { + "tips": "دستگاه شما باید از این قابلیت پشتیبانی کند و WebRTC برای مکالمهٔ دوطرفه پیکربندی شده باشد.", + "unavailable": "مکالمهٔ دوطرفه برای این استریم در دسترس نیست", + "available": "گفت‌وگوی دوطرفه برای این جریان در دسترس است" + }, + "playInBackground": { + "label": "پخش در پس‌زمینه", + "tips": "این گزینه را فعال کنید تا هنگام پنهان بودن پخش‌کننده، پخش زنده ادامه یابد." + }, + "debug": { + "picker": "انتخاب جریان در حالت اشکال‌زدایی در دسترس نیست. نمای اشکال‌زدایی همیشه از جریانی استفاده می‌کند که نقش detect به آن اختصاص داده شده است." + }, + "lowBandwidth": { + "tips": "به‌دلیل بافر شدن یا خطاهای جریان، نمای زنده در حالت کم‌پهنای‌باند است.", + "resetStream": "بازنشانی جریان" + } + }, + "cameraSettings": { + "title": "تنظیمات {{camera}}", + "objectDetection": "تشخیص شیء", + "snapshots": "اسنپ‌شات‌ها", + "audioDetection": "تشخیص صدا", + "autotracking": "ردیابی خودکار", + "cameraEnabled": "دوربین فعال", + "recording": "ضبط", + "transcription": "رونویسی صوتی" + }, + "effectiveRetainMode": { + "modes": { + "motion": "حرکت", + "all": "همه", + "active_objects": "اشیای فعال" + } + }, + "editLayout": { + "label": "ویرایش چیدمان", + "group": { + "label": "ویرایش گروه دوربین" + }, + "exitEdit": "خروج از حالت ویرایش" + }, + "noCameras": { + "title": "هیچ دوربینی پیکربندی نشده است", + "buttonText": "افزودن دوربین", + "restricted": { + "description": "شما اجازهٔ مشاهدهٔ هیچ دوربینی را در این گروه ندارید.", + "title": "هیچ دوربینی در دسترس نیست" + }, + "description": "برای شروع، یک دوربین را به Frigate متصل کنید." + }, + "streamStats": { + "enable": "نمایش آمار پخش", + "disable": "پنهان کردن آمار پخش" + }, + "manualRecording": { + "tips": "بر اساس تنظیمات نگهداری ضبطِ این دوربین، یک عکس فوری دانلود کنید یا یک رویداد دستی را شروع کنید.", + "playInBackground": { + "label": "پخش در پس‌زمینه", + "desc": "این گزینه را فعال کنید تا هنگام پنهان بودن پخش‌کننده، پخش زنده ادامه یابد." + }, + "showStats": { + "label": "نمایش آمار", + "desc": "این گزینه را فعال کنید تا آمار پخش به‌صورت هم‌پوشان روی تصویر دوربین نمایش داده شود." + }, + "debugView": "نمای اشکال‌زدایی", + "start": "شروع ضبط درخواستی", + "started": "ضبط دستیِ درخواستی شروع شد.", + "failedToStart": "شروع ضبط دستیِ درخواستی ناموفق بود.", + "recordDisabledTips": "از آن‌جا که ضبط برای این دوربین در تنظیمات غیرفعال یا محدود شده است، فقط یک عکس فوری ذخیره می‌شود.", + "end": "پایان ضبط درخواستی", + "ended": "ضبط دستیِ درخواستی پایان یافت.", + "failedToEnd": "پایان دادنِ ضبط دستیِ درخواستی ناموفق بود.", + "title": "بر حسب تقاضا" + }, + "notifications": "اعلان‌ها", + "suspend": { + "forTime": "تعلیق به مدت: " + }, + "history": { + "label": "نمایش ویدیوهای تاریخی" } } diff --git a/web/public/locales/fa/views/recording.json b/web/public/locales/fa/views/recording.json index 664f93ef6..a7a9a133c 100644 --- a/web/public/locales/fa/views/recording.json +++ b/web/public/locales/fa/views/recording.json @@ -1,6 +1,12 @@ { "filter": "فیلتر", - "export": "گرفتن خروجی", - "calendar": "تفویم", - "filters": "فیلترها" + "export": "خروجی گرفتن", + "calendar": "تقویم", + "filters": "فیلترها", + "toast": { + "error": { + "noValidTimeSelected": "بازهٔ زمانی معتبری انتخاب نشده است", + "endTimeMustAfterStartTime": "زمان پایان باید بعد از زمان شروع باشد" + } + } } diff --git a/web/public/locales/fa/views/search.json b/web/public/locales/fa/views/search.json index 092c45f82..007abe106 100644 --- a/web/public/locales/fa/views/search.json +++ b/web/public/locales/fa/views/search.json @@ -1,9 +1,73 @@ { - "search": "جستجو", + "search": "یافتن", "savedSearches": "جستجوهای ذخیره شده", - "searchFor": "جستجو برای {{inputValue}}", + "searchFor": "جستجو برای {{inputValue}}", "button": { "clear": "پاک کردن جستجو", - "save": "ذخیره جستجو" + "save": "ذخیره جست‌وجو", + "delete": "حذف جستجوی ذخیره‌شده", + "filterInformation": "اطلاعات فیلتر", + "filterActive": "فیلترها فعال‌اند" + }, + "trackedObjectId": "شناسهٔ شیء ردیابی‌شده", + "filter": { + "label": { + "cameras": "دوربین‌ها", + "labels": "برچسب‌ها", + "sub_labels": "زیر‌برچسب‌ها", + "attributes": "صفت‌ها", + "search_type": "نوع جستجو", + "time_range": "بازهٔ زمانی", + "zones": "ناحیه‌ها", + "before": "قبل از", + "after": "بعد از", + "min_score": "حداقل امتیاز", + "max_score": "حداکثر امتیاز", + "min_speed": "حداقل سرعت", + "max_speed": "حداکثر سرعت", + "recognized_license_plate": "پلاک شناسایی‌شده", + "has_clip": "دارای کلیپ", + "has_snapshot": "دارای عکس فوری" + }, + "toast": { + "error": { + "beforeDateBeLaterAfter": "تاریخ 'قبل از' باید بعد از تاریخ 'بعد از' باشد.", + "afterDatebeEarlierBefore": "تاریخ 'بعد از' باید قبل از تاریخ 'قبل از' باشد.", + "minScoreMustBeLessOrEqualMaxScore": "'min_score' باید کمتر یا مساوی 'max_score' باشد.", + "maxScoreMustBeGreaterOrEqualMinScore": "'max_score' باید بزرگ‌تر یا مساوی 'min_score' باشد.", + "minSpeedMustBeLessOrEqualMaxSpeed": "'min_speed' باید کمتر یا مساوی 'max_speed' باشد.", + "maxSpeedMustBeGreaterOrEqualMinSpeed": "'max_speed' باید بزرگ‌تر یا مساوی 'min_speed' باشد." + } + }, + "searchType": { + "thumbnail": "پیش‌نمایش", + "description": "توضیحات" + }, + "tips": { + "title": "نحوهٔ استفاده از فیلترهای متنی", + "desc": { + "text": "فیلترها به شما کمک می‌کنند نتایج جست‌وجوی خود را محدودتر کنید. در اینجا نحوهٔ استفاده از آن‌ها در فیلد ورودی آمده است:", + "step1": "نام کلید فیلتر را بنویسید و بعد از آن دونقطه بگذارید (مثلاً \"cameras:\").", + "step2": "از پیشنهادها یک مقدار را انتخاب کنید یا مقدار دلخواه خود را تایپ کنید.", + "step3": "برای استفاده از چند فیلتر، آن‌ها را یکی پس از دیگری با یک فاصله از هم اضافه کنید.", + "step4": "فیلترهای تاریخ (before: و after:) از قالب {{DateFormat}} استفاده می‌کنند.", + "step5": "فیلتر بازهٔ زمانی از قالب {{exampleTime}} استفاده می‌کند.", + "exampleLabel": "مثال:", + "step6": "فیلترها را با کلیک بر روی 'x' کنار آنها حذف کنید." + } + }, + "header": { + "currentFilterType": "مقادیر فیلتر", + "noFilters": "فیلترها", + "activeFilters": "فیلترهای فعال" + } + }, + "similaritySearch": { + "title": "جستجوی مشابهت", + "active": "جستجوی مشابهت فعال است", + "clear": "پاک کردن جستجوی مشابهت" + }, + "placeholder": { + "search": "جستجو…" } } diff --git a/web/public/locales/fa/views/settings.json b/web/public/locales/fa/views/settings.json index 4861489d3..d2f7ce17b 100644 --- a/web/public/locales/fa/views/settings.json +++ b/web/public/locales/fa/views/settings.json @@ -5,6 +5,1065 @@ "camera": "تنظیمات دوربین - فریگیت", "cameraManagement": "مدیریت دوربین ها - فریگیت", "cameraReview": "بازبینی تنظیمات دوربین - فریگیت", - "masksAndZones": "ویرایشگر ماسک و منطقه - فریگیت" + "masksAndZones": "ویرایشگر ماسک و منطقه - فریگیت", + "enrichments": "تنظیمات غنی‌سازی‌ها - Frigate", + "motionTuner": "تنظیم‌کنندهٔ حرکت - Frigate", + "object": "اشکال‌زدایی - Frigate", + "general": "تنظیمات رابط کاربری - فریگیت", + "frigatePlus": "تنظیمات Frigate+ - Frigate", + "notifications": "تنظیمات اعلان‌ها - Frigate" + }, + "menu": { + "ui": "رابط کاربری", + "enrichments": "غنی‌سازی‌ها", + "cameraManagement": "مدیریت", + "cameraReview": "بازبینی", + "masksAndZones": "ماسک‌ها / ناحیه‌ها", + "motionTuner": "تنظیم‌کنندهٔ حرکت", + "triggers": "محرک‌ها", + "debug": "اشکال‌زدایی", + "users": "کاربران", + "roles": "نقش‌ها", + "notifications": "اعلان‌ها", + "frigateplus": "فریگیت+" + }, + "general": { + "title": "تنظیمات رابط کاربری", + "liveDashboard": { + "title": "داشبورد زنده", + "automaticLiveView": { + "label": "نمای زندهٔ خودکار", + "desc": "وقتی فعالیت تشخیص داده شود، به‌طور خودکار به نمای زندهٔ دوربین جابه‌جا شوید. غیرفعال کردن این گزینه باعث می‌شود تصاویر ثابت دوربین در داشبورد زنده فقط هر یک دقیقه یک‌بار به‌روزرسانی شوند." + }, + "playAlertVideos": { + "label": "پخش ویدیوهای هشدار", + "desc": "به‌طور پیش‌فرض، هشدارهای اخیر در داشبورد زنده به‌صورت ویدیوهای کوچکِ حلقه‌ای پخش می‌شوند. این گزینه را غیرفعال کنید تا فقط یک تصویر ثابت از هشدارهای اخیر در این دستگاه/مرورگر نمایش داده شود." + }, + "displayCameraNames": { + "label": "نمایش همیشهٔ نام دوربین‌ها", + "desc": "نام دوربین‌ها را همیشه به‌صورت یک برچسب در داشبورد نمای زندهٔ چند دوربینه نشان بده." + }, + "liveFallbackTimeout": { + "label": "مهلت بازگشت پخش زنده", + "desc": "وقتی پخش زندهٔ باکیفیتِ دوربین در دسترس نیست، پس از این تعداد ثانیه به حالت کم‌پهنای‌باند برگردد. پیش‌فرض: ۳." + } + }, + "storedLayouts": { + "title": "چیدمان‌های ذخیره‌شده", + "desc": "چیدمان دوربین‌ها در یک گروه دوربین قابل کشیدن و تغییر اندازه است. موقعیت‌ها در فضای ذخیره‌سازی محلی مرورگر شما ذخیره می‌شوند.", + "clearAll": "پاک کردن همهٔ چیدمان‌ها" + }, + "cameraGroupStreaming": { + "title": "تنظیمات پخش گروه دوربین", + "desc": "تنظیمات پخش برای هر گروه دوربین در فضای ذخیره‌سازی محلی مرورگر شما ذخیره می‌شود.", + "clearAll": "پاک کردن همهٔ تنظیمات پخش" + }, + "recordingsViewer": { + "title": "نمایشگر ضبط‌ها", + "defaultPlaybackRate": { + "label": "نرخ پخش پیش‌فرض", + "desc": "نرخ پخش پیش‌فرض برای پخش ضبط‌ها." + } + }, + "calendar": { + "title": "تقویم", + "firstWeekday": { + "label": "اولین روز هفته", + "desc": "روزی که هفته‌های تقویمِ بازبینی از آن آغاز می‌شوند.", + "sunday": "یکشنبه", + "monday": "دوشنبه" + } + }, + "toast": { + "success": { + "clearStoredLayout": "چیدمان ذخیره‌شده برای {{cameraName}} پاک شد", + "clearStreamingSettings": "تنظیمات پخش برای همهٔ گروه‌های دوربین پاک شد." + }, + "error": { + "clearStoredLayoutFailed": "پاک کردن چیدمان ذخیره‌شده ناموفق بود: {{errorMessage}}", + "clearStreamingSettingsFailed": "پاک کردن تنظیمات پخش ناموفق بود: {{errorMessage}}" + } + } + }, + "dialog": { + "unsavedChanges": { + "title": "تغییرات ذخیره‌نشده دارید.", + "desc": "آیا می‌خواهید پیش از ادامه، تغییرات خود را ذخیره کنید؟" + } + }, + "cameraSetting": { + "camera": "دوربین", + "noCamera": "بدون دوربین" + }, + "enrichments": { + "unsavedChanges": "تغییرات ذخیره‌نشدهٔ تنظیمات غنی‌سازی", + "birdClassification": { + "desc": "طبقه‌بندی پرندگان با استفاده از یک مدل Tensorflow کوانتیزه‌شده، پرندگان شناخته‌شده را شناسایی می‌کند. وقتی یک پرندهٔ شناخته‌شده شناسایی شود، نام رایج آن به‌عنوان sub_label اضافه می‌شود. این اطلاعات در رابط کاربری، فیلترها و همچنین در اعلان‌ها گنجانده می‌شود.", + "title": "طبقه‌بندی پرندگان" + }, + "semanticSearch": { + "desc": "جست‌وجوی معنایی در Frigate به شما اجازه می‌دهد اشیای ردیابی‌شده را در آیتم‌های بازبینی، با استفاده از خودِ تصویر، یک توضیح متنیِ تعریف‌شده توسط کاربر، یا یک توضیحِ تولیدشدهٔ خودکار پیدا کنید.", + "reindexNow": { + "confirmTitle": "تأیید بازنمایه‌سازی", + "confirmButton": "بازنمایه‌سازی", + "alreadyInProgress": "بازنمایه‌سازی از قبل در حال انجام است.", + "label": "بازنمایه‌سازی اکنون", + "desc": "بازنمایه‌سازی، امبدینگ‌ها را برای همهٔ اشیای ردیابی‌شده دوباره تولید می‌کند. این فرایند در پس‌زمینه اجرا می‌شود و بسته به تعداد اشیای ردیابی‌شده‌ای که دارید، ممکن است CPU شما را به سقف برساند و زمان قابل‌توجهی طول بکشد.", + "confirmDesc": "آیا مطمئن هستید که می‌خواهید همهٔ امبدینگ‌های اشیای ردیابی‌شده را بازنمایه‌سازی کنید؟ این فرایند در پس‌زمینه اجرا می‌شود، اما ممکن است CPU شما را به سقف برساند و زمان قابل‌توجهی طول بکشد. می‌توانید پیشرفت را در صفحهٔ Explore مشاهده کنید.", + "success": "بازنمایه‌سازی با موفقیت شروع شد.", + "error": "شروع بازنمایه‌سازی ناموفق بود: {{errorMessage}}" + }, + "modelSize": { + "label": "اندازهٔ مدل", + "desc": "اندازهٔ مدلی که برای بردارهای جست‌وجوی معنایی استفاده می‌شود.", + "small": { + "desc": "استفاده از small از نسخهٔ کوانتیزهٔ مدل استفاده می‌کند که RAM کم‌تری مصرف می‌کند و روی CPU سریع‌تر اجرا می‌شود، با تفاوت بسیار ناچیز در کیفیت embedding.", + "title": "کوچک" + }, + "large": { + "desc": "استفاده از large از مدل کامل Jina استفاده می‌کند و در صورت امکان به‌طور خودکار روی GPU اجرا می‌شود.", + "title": "بزرگ" + } + }, + "title": "جستجوی معنایی" + }, + "faceRecognition": { + "desc": "تشخیص چهره امکان می‌دهد برای افراد نام تعیین شود و وقتی چهرهٔ آن‌ها شناسایی شود، Frigate نام فرد را به‌عنوان زیر‌برچسب اختصاص می‌دهد. این اطلاعات در رابط کاربری، فیلترها و همچنین در اعلان‌ها گنجانده می‌شود.", + "modelSize": { + "label": "اندازهٔ مدل", + "small": { + "title": "کوچک", + "desc": "استفاده از کوچک یک مدل امبدینگ چهرهٔ FaceNet را به‌کار می‌گیرد که روی بیشتر CPUها به‌صورت بهینه اجرا می‌شود." + }, + "large": { + "title": "بزرگ", + "desc": "استفاده از large از مدل embedding چهرهٔ ArcFace استفاده می‌کند و در صورت امکان به‌طور خودکار روی GPU اجرا می‌شود." + }, + "desc": "اندازه مدل مورد استفاده برای تشخیص چهره." + }, + "title": "شناسایی چهره" + }, + "licensePlateRecognition": { + "desc": "Frigate می‌تواند پلاک خودروها را تشخیص دهد و نویسه‌های شناسایی‌شده را به‌طور خودکار به فیلد recognized_license_plate اضافه کند، یا یک نام شناخته‌شده را به‌عنوان sub_label به اشیایی که از نوع car هستند اضافه کند. یک کاربرد رایج می‌تواند خواندن پلاک خودروهایی باشد که وارد پارکینگ/حیاط می‌شوند یا خودروهایی که از خیابان عبور می‌کنند.", + "title": "شناسایی پلاک خودرو" + }, + "toast": { + "success": "تنظیمات غنی‌سازی ذخیره شد. برای اعمال تغییرات، Frigate را دوباره راه‌اندازی کنید.", + "error": "ذخیرهٔ تغییرات پیکربندی ناموفق بود: {{errorMessage}}" + }, + "title": "تنظیمات غنی‌سازی‌ها", + "restart_required": "نیاز به راه‌اندازی مجدد (تنظیمات غنی‌سازی‌ها تغییر کرد)" + }, + "cameraWizard": { + "description": "برای افزودن یک دوربین جدید به نصب Frigate خود، مراحل زیر را دنبال کنید.", + "steps": { + "streamConfiguration": "پیکربندی استریم", + "nameAndConnection": "نام و اتصال", + "probeOrSnapshot": "پروب یا اسنپ‌شات", + "validationAndTesting": "اعتبارسنجی و آزمون" + }, + "save": { + "success": "دوربین جدید {{cameraName}} با موفقیت ذخیره شد.", + "failure": "خطا در ذخیرهٔ {{cameraName}}." + }, + "testResultLabels": { + "video": "ویدئو", + "audio": "صدا", + "fps": "FPS", + "resolution": "وضوح" + }, + "commonErrors": { + "noUrl": "لطفاً یک URL معتبر برای استریم ارائه کنید", + "testFailed": "آزمون استریم ناموفق بود: {{error}}" + }, + "step1": { + "cameraName": "نام دوربین", + "port": "پورت", + "password": "گذرواژه", + "cameraBrand": "برند دوربین", + "customUrl": "URL سفارشی استریم", + "brandInformation": "اطلاعات برند", + "customUrlPlaceholder": "rtsp://نام‌کاربری:رمز@سرور:پورت/مسیر", + "connectionSettings": "تنظیمات اتصال", + "probeMode": "پروبِ دوربین", + "onvifPortDescription": "برای دوربین‌هایی که از ONVIF پشتیبانی می‌کنند، معمولاً ۸۰ یا ۸۰۸۰ است.", + "useDigestAuth": "استفاده از احراز هویت Digest", + "description": "جزئیات دوربین خود را وارد کنید و انتخاب کنید دوربین بررسی شود یا برند را به‌صورت دستی انتخاب کنید.", + "cameraNamePlaceholder": "مثلاً front_door یا Back Yard Overview", + "host": "میزبان/آدرس IP", + "username": "نام کاربری", + "usernamePlaceholder": "اختیاری", + "passwordPlaceholder": "اختیاری", + "selectTransport": "انتخاب پروتکل انتقال", + "selectBrand": "برند دوربین را برای قالب URL انتخاب کنید", + "brandUrlFormat": "برای دوربین‌هایی با قالب URL ‏RTSP به‌شکل: {{exampleUrl}}", + "detectionMethod": "روش تشخیص جریان", + "onvifPort": "پورت ONVIF", + "manualMode": "انتخاب دستی", + "detectionMethodDescription": "دوربین را با ONVIF (در صورت پشتیبانی) بررسی کنید تا URLهای جریان دوربین پیدا شوند، یا برند دوربین را به‌صورت دستی انتخاب کنید تا از URLهای ازپیش‌تعریف‌شده استفاده شود. برای وارد کردن یک URL سفارشی RTSP، روش دستی را انتخاب کنید و «Other» را برگزینید.", + "useDigestAuthDescription": "برای ONVIF از احراز هویت Digest‏ HTTP استفاده کنید. برخی دوربین‌ها ممکن است به‌جای کاربر مدیر استاندارد، به یک نام‌کاربری/گذرواژهٔ اختصاصی ONVIF نیاز داشته باشند.", + "errors": { + "brandOrCustomUrlRequired": "یا یک برند دوربین را همراه با میزبان/آدرس IP انتخاب کنید یا «Other» را با یک URL سفارشی برگزینید", + "nameRequired": "نام دوربین الزامی است", + "nameLength": "نام دوربین باید ۶۴ کاراکتر یا کمتر باشد", + "invalidCharacters": "نام دوربین شامل نویسه‌های نامعتبر است", + "nameExists": "نام دوربین از قبل وجود دارد", + "customUrlRtspRequired": "URLهای سفارشی باید با «rtsp://» شروع شوند. برای جریان‌های دوربینِ غیر RTSP پیکربندی دستی لازم است." + } + }, + "title": "افزودن دوربین", + "step2": { + "description": "دوربین را برای جریان‌های در دسترس بررسی کنید یا بر اساس روش تشخیصِ انتخاب‌شده، تنظیمات دستی را پیکربندی کنید.", + "testSuccess": "آزمون اتصال با موفقیت انجام شد!", + "testFailed": "آزمون اتصال ناموفق بود. لطفاً ورودی‌های خود را بررسی کنید و دوباره تلاش کنید.", + "testFailedTitle": "آزمون ناموفق", + "streamDetails": "جزئیات جریان", + "probing": "در حال بررسی دوربین…", + "retry": "تلاش مجدد", + "testing": { + "probingMetadata": "در حال بررسی فرادادهٔ دوربین…", + "fetchingSnapshot": "در حال دریافت عکس فوریِ دوربین…" + }, + "probeFailed": "بررسی دوربین ناموفق بود: {{error}}", + "probingDevice": "در حال بررسی دستگاه…", + "probeSuccessful": "بررسی موفق", + "probeError": "خطای بررسی", + "probeNoSuccess": "بررسی ناموفق", + "deviceInfo": "اطلاعات دستگاه", + "manufacturer": "سازنده", + "model": "مدل", + "firmware": "فرم‌ور", + "profiles": "پروفایل‌ها", + "ptzSupport": "پشتیبانی PTZ", + "autotrackingSupport": "پشتیبانی از ردیابی خودکار", + "presets": "پیش‌تنظیم‌ها", + "rtspCandidates": "کاندیداهای RTSP", + "rtspCandidatesDescription": "URLهای RTSP زیر از بررسی دوربین به‌دست آمد. برای مشاهدهٔ فرادادهٔ جریان، اتصال را آزمایش کنید.", + "noRtspCandidates": "هیچ URL ‏RTSPای از دوربین پیدا نشد. ممکن است اطلاعات کاربری شما نادرست باشد، یا دوربین از ONVIF یا روشِ استفاده‌شده برای بازیابی URLهای RTSP پشتیبانی نکند. برگردید و URL ‏RTSP را به‌صورت دستی وارد کنید.", + "candidateStreamTitle": "کاندیدا {{number}}", + "useCandidate": "استفاده", + "uriCopy": "کپی", + "uriCopied": "نشانی URI در کلیپ‌بورد کپی شد", + "testConnection": "آزمون اتصال", + "toggleUriView": "برای تغییر به نمایش کامل URI کلیک کنید", + "connected": "متصل", + "notConnected": "متصل نیست", + "errors": { + "hostRequired": "میزبان/آدرس IP الزامی است" + } + }, + "step3": { + "description": "نقش‌های جریان را پیکربندی کنید و برای دوربین خود جریان‌های بیشتری اضافه کنید.", + "streamsTitle": "جریان‌های دوربین", + "addStream": "افزودن جریان", + "addAnotherStream": "افزودن جریان دیگر", + "streamTitle": "جریان {{number}}", + "streamUrl": "نشانی جریان", + "streamUrlPlaceholder": "rtsp://نام‌کاربری:رمز@سرور:پورت/مسیر", + "selectStream": "یک جریان را انتخاب کنید", + "searchCandidates": "جستجوی گزینه‌ها…", + "noStreamFound": "هیچ جریانی پیدا نشد", + "url": "نشانی URL", + "resolution": "وضوح", + "selectResolution": "انتخاب وضوح", + "quality": "کیفیت", + "selectQuality": "انتخاب کیفیت", + "roles": "نقش‌ها", + "roleLabels": { + "detect": "تشخیص شیء", + "record": "ضبط", + "audio": "صدا" + }, + "testStream": "آزمون اتصال", + "testSuccess": "آزمون جریان با موفقیت انجام شد!", + "testFailed": "آزمون جریان ناموفق بود", + "testFailedTitle": "آزمون ناموفق بود", + "connected": "متصل", + "notConnected": "متصل نیست", + "featuresTitle": "ویژگی‌ها", + "go2rtc": "کاهش تعداد اتصال‌ها به دوربین", + "detectRoleWarning": "برای ادامه، حداقل یک جریان باید نقش «detect» داشته باشد.", + "rolesPopover": { + "title": "نقش‌های جریان", + "detect": "فید اصلی برای تشخیص شیء.", + "record": "بر اساس تنظیمات پیکربندی، بخش‌هایی از فید ویدیو را ذخیره می‌کند.", + "audio": "فید برای تشخیص مبتنی بر صدا." + }, + "featuresPopover": { + "title": "ویژگی‌های جریان", + "description": "برای کاهش تعداد اتصال‌ها به دوربین خود از بازپخش go2rtc استفاده کنید." + } + }, + "step4": { + "validationTitle": "اعتبارسنجی جریان", + "connectAllStreams": "اتصال همهٔ جریان‌ها", + "reconnectionSuccess": "اتصال مجدد با موفقیت انجام شد.", + "reconnectionPartial": "اتصال مجدد برخی جریان‌ها ناموفق بود.", + "streamUnavailable": "پیش‌نمایش جریان در دسترس نیست", + "reload": "بارگذاری مجدد", + "streamTitle": "جریان {{number}}", + "valid": "معتبر", + "failed": "ناموفق", + "notTested": "آزمون نشده", + "connectStream": "اتصال", + "connectingStream": "در حال اتصال", + "disconnectStream": "قطع اتصال", + "estimatedBandwidth": "پهنای باند تخمینی", + "roles": "نقش‌ها", + "ffmpegModule": "استفاده از حالت سازگاری جریان", + "ffmpegModuleDescription": "اگر جریان پس از چند تلاش بارگذاری نشد، فعال‌کردن این گزینه را امتحان کنید. وقتی فعال باشد، Frigate از ماژول ffmpeg همراه با go2rtc استفاده می‌کند. این کار ممکن است با برخی جریان‌های دوربین سازگاری بهتری فراهم کند.", + "none": "هیچ‌کدام", + "error": "خطا", + "streamValidated": "اعتبارسنجی جریان {{number}} با موفقیت انجام شد", + "streamValidationFailed": "اعتبارسنجی جریان {{number}} ناموفق بود", + "saveAndApply": "ذخیرهٔ دوربین جدید", + "saveError": "پیکربندی نامعتبر است. لطفاً تنظیمات خود را بررسی کنید.", + "issues": { + "title": "اعتبارسنجی جریان", + "videoCodecGood": "کدک ویدیو {{codec}} است.", + "audioCodecGood": "کدک صدا {{codec}} است.", + "resolutionHigh": "وضوح {{resolution}} ممکن است باعث افزایش مصرف منابع شود.", + "resolutionLow": "وضوح {{resolution}} ممکن است برای تشخیص قابل‌اعتماد اشیای کوچک بیش از حد پایین باشد.", + "noAudioWarning": "برای این جریان صدایی شناسایی نشد؛ ضبط‌ها صدا نخواهند داشت.", + "audioCodecRecordError": "برای پشتیبانی از صدا در ضبط‌ها، کدک صوتی AAC لازم است.", + "audioCodecRequired": "برای پشتیبانی از تشخیص صدا، یک جریان صوتی لازم است.", + "restreamingWarning": "کاهش تعداد اتصال‌ها به دوربین برای جریان ضبط ممکن است کمی مصرف CPU را افزایش دهد.", + "brands": { + "reolink-rtsp": "RTSP در Reolink توصیه نمی‌شود. در تنظیمات میان‌افزار دوربین، HTTP را فعال کنید و جادوگر را دوباره اجرا کنید.", + "reolink-http": "جریان‌های HTTP در Reolink برای سازگاری بهتر باید از FFmpeg استفاده کنند. برای این جریان، «استفاده از حالت سازگاری جریان» را فعال کنید." + }, + "dahua": { + "substreamWarning": "زیرجریان ۱ روی وضوح پایین قفل شده است. بسیاری از دوربین‌های Dahua / Amcrest / EmpireTech از زیرجریان‌های اضافی پشتیبانی می‌کنند که باید در تنظیمات دوربین فعال شوند. توصیه می‌شود در صورت وجود، آن جریان‌ها را بررسی کرده و استفاده کنید." + }, + "hikvision": { + "substreamWarning": "زیرجریان ۱ روی وضوح پایین قفل شده است. بسیاری از دوربین‌های Hikvision از زیرجریان‌های اضافی پشتیبانی می‌کنند که باید در تنظیمات دوربین فعال شوند. توصیه می‌شود در صورت وجود، آن جریان‌ها را بررسی کرده و استفاده کنید." + } + }, + "connecting": "در حال اتصال...", + "description": "پیش از ذخیره کردن دوربین جدیدتان، اعتبارسنجی و تحلیل نهایی انجام می‌شود. پیش از ذخیره، هر استریم را متصل کنید." + } + }, + "cameraManagement": { + "title": "مدیریت دوربین‌ها", + "addCamera": "افزودن دوربین جدید", + "selectCamera": "یک دوربین را انتخاب کنید", + "backToSettings": "بازگشت به تنظیمات دوربین", + "streams": { + "title": "فعال‌سازی / غیرفعال‌سازی دوربین‌ها", + "desc": "یک دوربین را تا زمانی که Frigate دوباره راه‌اندازی شود، موقتاً غیرفعال کنید. غیرفعال‌کردن یک دوربین باعث می‌شود پردازش جریان‌های این دوربین توسط Frigate کاملاً متوقف شود. تشخیص، ضبط و اشکال‌زدایی در دسترس نخواهد بود.
    نکته: این کار بازپخش‌های go2rtc را غیرفعال نمی‌کند." + }, + "cameraConfig": { + "add": "افزودن دوربین", + "edit": "ویرایش دوربین", + "description": "تنظیمات دوربین از جمله ورودی‌های جریان و نقش‌ها را پیکربندی کنید.", + "name": "نام دوربین", + "nameLength": "نام دوربین باید کمتر از ۶۴ کاراکتر باشد.", + "nameRequired": "نام دوربین الزامی است", + "namePlaceholder": "مثلاً front_door یا Back Yard Overview", + "enabled": "فعال", + "ffmpeg": { + "inputs": "جریان‌های ورودی", + "path": "مسیر جریان", + "pathRequired": "مسیر جریان الزامی است", + "pathPlaceholder": "rtsp://...", + "roles": "نقش‌ها", + "rolesRequired": "حداقل یک نقش لازم است", + "rolesUnique": "هر نقش (audio، detect، record) فقط می‌تواند به یک جریان اختصاص داده شود", + "addInput": "افزودن جریان ورودی", + "removeInput": "حذف جریان ورودی", + "inputsRequired": "حداقل یک جریان ورودی لازم است" + }, + "go2rtcStreams": "جریان‌های go2rtc", + "streamUrls": "نشانی‌های جریان", + "addGo2rtcStream": "افزودن جریان go2rtc", + "toast": { + "success": "دوربین {{cameraName}} با موفقیت ذخیره شد" + }, + "addUrl": "افزودن نشانی" + }, + "editCamera": "ویرایش دوربین:" + }, + "cameraReview": { + "title": "تنظیمات بازبینی دوربین", + "object_descriptions": { + "title": "توضیحات شیء با هوش مصنوعی مولد", + "desc": "موقتاً توضیحات اشیای هوش مصنوعی مولد را برای این دوربین فعال/غیرفعال کنید. وقتی غیرفعال باشد، برای اشیای ردیابی‌شده در این دوربین، توضیحات تولیدشده با هوش مصنوعی درخواست نخواهد شد." + }, + "reviewClassification": { + "title": "طبقه‌بندی بازبینی", + "desc": "Frigate موارد بازبینی را به‌عنوان اعلان‌ها و تشخیص‌ها دسته‌بندی می‌کند. به‌طور پیش‌فرض، همهٔ اشیای person و car به‌عنوان اعلان در نظر گرفته می‌شوند. می‌توانید با پیکربندی نواحی لازم برای آن‌ها، طبقه‌بندی موارد بازبینی خود را دقیق‌تر کنید.", + "noDefinedZones": "هیچ ناحیه‌ای برای این دوربین تعریف نشده است.", + "objectAlertsTips": "همهٔ اشیای {{alertsLabels}} در {{cameraName}} به‌صورت اعلان نمایش داده می‌شوند.", + "zoneObjectAlertsTips": "همهٔ اشیای {{alertsLabels}} که در {{zone}} روی {{cameraName}} تشخیص داده می‌شوند، به‌صورت اعلان نمایش داده خواهند شد.", + "selectAlertsZones": "ناحیه‌ها را برای اعلان‌ها انتخاب کنید", + "selectDetectionsZones": "ناحیه‌ها را برای تشخیص‌ها انتخاب کنید", + "limitDetections": "تشخیص‌ها را به نواحی مشخص محدود کنید", + "toast": { + "success": "پیکربندی طبقه‌بندی بازبینی ذخیره شد. برای اعمال تغییرات، Frigate را راه‌اندازی مجدد کنید." + }, + "objectDetectionsTips": "همهٔ اشیای {{detectionsLabels}} که در {{cameraName}} دسته‌بندی نشده‌اند، صرف‌نظر از اینکه در کدام ناحیه هستند، به‌صورت «تشخیص‌ها» نمایش داده می‌شوند.", + "zoneObjectDetectionsTips": { + "text": "همهٔ اشیای {{detectionsLabels}} که در {{zone}} برای {{cameraName}} دسته‌بندی نشده‌اند، به‌صورت «تشخیص‌ها» نمایش داده می‌شوند.", + "notSelectDetections": "همهٔ اشیای {{detectionsLabels}} که در {{zone}} روی {{cameraName}} شناسایی شده‌اند و به‌عنوان «هشدار» دسته‌بندی نشده‌اند، صرف‌نظر از اینکه در کدام ناحیه هستند، به‌صورت «تشخیص‌ها» نمایش داده می‌شوند.", + "regardlessOfZoneObjectDetectionsTips": "همهٔ اشیای {{detectionsLabels}} که در {{cameraName}} دسته‌بندی نشده‌اند، بدون توجه به این‌که در کدام ناحیه هستند، به‌صورت «تشخیص‌ها» نمایش داده خواهند شد." + }, + "unsavedChanges": "تنظیمات ذخیره‌نشدهٔ طبقه‌بندی بازبینی برای {{camera}}" + }, + "review_descriptions": { + "title": "توضیحات بازبینیِ هوش مصنوعی مولد", + "desc": "توضیحات بازبینیِ هوش مصنوعی مولد را برای این دوربین به‌طور موقت فعال/غیرفعال کنید. وقتی غیرفعال باشد، برای موارد بازبینی این دوربین، توضیحات تولیدشده توسط هوش مصنوعی درخواست نخواهد شد." + }, + "review": { + "title": "بازبینی", + "desc": "هشدارها و تشخیص‌ها را برای این دوربین تا زمان راه‌اندازی مجدد Frigate به‌طور موقت فعال/غیرفعال کنید. وقتی غیرفعال باشد، هیچ مورد بازبینی جدیدی ایجاد نخواهد شد. ", + "alerts": "هشدارها ", + "detections": "تشخیص‌ها " + } + }, + "masksAndZones": { + "filter": { + "all": "همهٔ ماسک‌ها و ناحیه‌ها" + }, + "form": { + "zoneName": { + "error": { + "mustNotBeSameWithCamera": "نام ناحیه نباید با نام دوربین یکسان باشد.", + "alreadyExists": "ناحیه‌ای با این نام از قبل برای این دوربین وجود دارد.", + "mustNotContainPeriod": "نام ناحیه نباید شامل نقطه باشد.", + "hasIllegalCharacter": "نام ناحیه شامل نویسه‌های غیرمجاز است.", + "mustHaveAtLeastOneLetter": "نام ناحیه باید حداقل یک حرف داشته باشد.", + "mustBeAtLeastTwoCharacters": "نام ناحیه باید حداقل ۲ کاراکتر باشد." + } + }, + "distance": { + "error": { + "text": "فاصله باید بزرگ‌تر یا مساوی 0.1 باشد.", + "mustBeFilled": "همهٔ فیلدهای فاصله باید پر شوند تا بتوان از تخمین سرعت استفاده کرد." + } + }, + "polygonDrawing": { + "reset": { + "label": "پاک کردن همهٔ نقاط" + }, + "snapPoints": { + "true": "چسباندن به نقاط", + "false": "چسباندن به نقاط انجام نشود" + }, + "delete": { + "title": "تأیید حذف", + "desc": "آیا مطمئن هستید که می‌خواهید {{type}} {{name}} را حذف کنید؟", + "success": "{{name}} حذف شد." + }, + "removeLastPoint": "حذف آخرین نقطه", + "error": { + "mustBeFinished": "رسم چندضلعی باید قبل از ذخیره کامل شود." + } + }, + "inertia": { + "error": { + "mustBeAboveZero": "لختی باید بیشتر از ۰ باشد." + } + }, + "loiteringTime": { + "error": { + "mustBeGreaterOrEqualZero": "زمان توقف باید بیشتر از یا مساوی ۰ باشد." + } + }, + "speed": { + "error": { + "mustBeGreaterOrEqualTo": "آستانهٔ سرعت باید بیشتر از یا مساوی ۰.۱ باشد." + } + } + }, + "zones": { + "add": "افزودن ناحیه", + "edit": "ویرایش ناحیه", + "point_one": "{{count}} نقطه", + "point_other": "{{count}} نقطه", + "clickDrawPolygon": "برای رسم یک چندضلعی روی تصویر کلیک کنید.", + "loiteringTime": { + "desc": "یک حداقل زمان (به ثانیه) تعیین می‌کند که شیء باید در ناحیه باشد تا فعال شود. پیش‌فرض: 0 ", + "title": "زمان توقف" + }, + "objects": { + "title": "اشیا", + "desc": "فهرست اشیایی که برای این ناحیه اعمال می‌شوند." + }, + "allObjects": "همهٔ اشیا", + "speedEstimation": { + "title": "تخمین سرعت", + "desc": "فعال‌سازی تخمین سرعت برای اشیا در این ناحیه. ناحیه باید دقیقاً ۴ نقطه داشته باشد.", + "lineADistance": "فاصلهٔ خط A ( {{unit}})", + "lineBDistance": "فاصلهٔ خط B ( {{unit}})", + "lineCDistance": "فاصلهٔ خط C ( {{unit}})", + "lineDDistance": "فاصلهٔ خط D ( {{unit}})" + }, + "speedThreshold": { + "title": "آستانهٔ سرعت ( {{unit}})", + "desc": "حداقل سرعتی را مشخص می‌کند تا اشیا در این ناحیه در نظر گرفته شوند.", + "toast": { + "error": { + "pointLengthError": "تخمین سرعت برای این ناحیه غیرفعال شد. ناحیه‌هایی که تخمین سرعت دارند باید دقیقاً ۴ نقطه داشته باشند.", + "loiteringTimeError": "ناحیه‌هایی با زمان پرسه‌زنیِ بیشتر از ۰ نباید با تخمین سرعت استفاده شوند." + } + } + }, + "toast": { + "success": "ناحیه ( {{zoneName}}) ذخیره شد." + }, + "label": "ناحیه‌ها", + "documentTitle": "ویرایش ناحیه - Frigate", + "desc": { + "title": "ناحیه‌ها به شما امکان تعریف یک ناحیهٔ مشخص از فریم را می‌دهند تا بتوانید تعیین کنید که آیا یک شیء در یک ناحیهٔ خاص قرار دارد یا خیر.", + "documentation": "مستندات" + }, + "name": { + "title": "نام", + "inputPlaceHolder": "یک نام وارد کنید…", + "tips": "نام باید حداقل ۲ کاراکتر باشد، باید حداقل یک حرف داشته باشد، و نباید نام یک دوربین یا ناحیهٔ دیگری در این دوربین باشد." + }, + "inertia": { + "title": "لختی", + "desc": "تعداد فریم‌هایی را مشخص می‌کند که یک شیء باید در یک ناحیه باشد تا در آن ناحیه محسوب شود. پیش‌فرض: ۳" + } + }, + "motionMasks": { + "label": "ماسک حرکت", + "context": { + "title": "ماسک‌های حرکت برای جلوگیری از این‌که انواع ناخواستهٔ حرکت باعث فعال‌شدن تشخیص شوند استفاده می‌شوند (مثلاً شاخه‌های درخت، مهر زمانیِ دوربین). ماسک‌های حرکت باید با نهایت صرفه‌جویی استفاده شوند؛ ماسک‌گذاریِ بیش‌ازحد باعث می‌شود ردیابی اشیا دشوارتر شود." + }, + "point_one": "{{count}} نقطه", + "point_other": "{{count}} نقطه", + "clickDrawPolygon": "برای رسم یک چندضلعی روی تصویر کلیک کنید.", + "polygonAreaTooLarge": { + "title": "ماسک حرکت {{polygonArea}}٪ از قاب دوربین را پوشش می‌دهد. ماسک‌های حرکتِ بزرگ توصیه نمی‌شوند.", + "tips": "ماسک‌های حرکت مانعِ تشخیص اشیا نمی‌شوند. به‌جای آن باید از «ناحیهٔ الزامی» استفاده کنید." + }, + "add": "ماسک حرکت جدید", + "edit": "ویرایش ماسک حرکت", + "toast": { + "success": { + "title": "{{polygonName}} ذخیره شد.", + "noName": "ماسک حرکت ذخیره شد." + } + }, + "documentTitle": "ویرایش ماسک حرکت - Frigate", + "desc": { + "title": "ماسک‌های حرکت برای جلوگیری از فعال‌سازی تشخیص توسط انواع ناخواستهٔ حرکت استفاده می‌شوند. ماسک‌گذاری بیش‌ازحد ردیابی اشیا را دشوارتر می‌کند.", + "documentation": "مستندات" + } + }, + "objectMasks": { + "desc": { + "documentation": "مستندات", + "title": "ماسک‌های فیلترِ اشیا برای فیلتر کردن مثبت‌های کاذبِ یک نوع شیء مشخص بر اساس موقعیت استفاده می‌شوند." + }, + "add": "افزودن ماسک شیء", + "edit": "ویرایش ماسک شیء", + "context": "ماسک‌های فیلترِ شیء برای فیلتر کردن مثبت‌های کاذب برای یک نوع شیء مشخص بر اساس موقعیت استفاده می‌شوند.", + "point_one": "{{count}} نقطه", + "point_other": "{{count}} نقطه", + "clickDrawPolygon": "برای رسم یک چندضلعی روی تصویر کلیک کنید.", + "toast": { + "success": { + "noName": "ماسک شیء ذخیره شد.", + "title": "{{polygonName}} ذخیره شد." + } + }, + "label": "ماسک‌های شیء", + "documentTitle": "ویرایش ماسک شیء - Frigate", + "objects": { + "title": "اشیا", + "desc": "نوع شیئی که به این ماسک شیء مربوط می‌شود.", + "allObjectTypes": "همهٔ انواع شیء" + } + }, + "restart_required": "نیاز به راه‌اندازی مجدد (ماسک‌ها/ناحیه‌ها تغییر کرده‌اند)", + "toast": { + "success": { + "copyCoordinates": "مختصات {{polyName}} در کلیپ‌بورد کپی شد." + }, + "error": { + "copyCoordinatesFailed": "امکان کپی کردن مختصات در کلیپ‌بورد نبود." + } + }, + "motionMaskLabel": "ماسک حرکت {{number}}", + "objectMaskLabel": "ماسک شیء {{number}} ( {{label}})" + }, + "motionDetectionTuner": { + "title": "تنظیم‌گر تشخیص حرکت", + "unsavedChanges": "تغییرات ذخیره‌نشدهٔ تنظیم‌گر تشخیص حرکت ( {{camera}})", + "desc": { + "title": "Frigate از تشخیص حرکت به‌عنوان نخستین بررسی استفاده می‌کند تا ببیند آیا در قاب چیزی رخ می‌دهد که ارزش بررسی با تشخیص شیء را داشته باشد یا نه.", + "documentation": "راهنمای تنظیم تشخیص حرکت را بخوانید" + }, + "improveContrast": { + "desc": "بهبود کنتراست برای صحنه‌های تاریک‌تر. پیش‌فرض: روشن ", + "title": "بهبود کنتراست" + }, + "toast": { + "success": "تنظیمات حرکت ذخیره شد." + }, + "Threshold": { + "title": "آستانه", + "desc": "مقدار آستانه تعیین می‌کند برای اینکه تغییر روشناییِ یک پیکسل «حرکت» محسوب شود، چه میزان تغییر لازم است. پیش‌فرض: 30" + }, + "contourArea": { + "title": "مساحت کانتور", + "desc": "مقدار مساحت کانتور برای تعیین اینکه کدام گروه‌های پیکسل‌های تغییر‌یافته به‌عنوان حرکت محسوب می‌شوند استفاده می‌شود. پیش‌فرض: ۱۰" + } + }, + "debug": { + "title": "اشکال‌زدایی", + "detectorDesc": "Frigate از آشکارسازهای شما ( {{detectors}}) برای تشخیص اشیا در جریان ویدیوی دوربین شما استفاده می‌کند.", + "desc": "نمای اشکال‌زدایی، نمایی بلادرنگ از اشیای ردیابی‌شده و آمار آن‌ها را نشان می‌دهد. فهرست اشیا یک خلاصهٔ با تأخیر زمانی از اشیای تشخیص‌داده‌شده را نمایش می‌دهد.", + "audio": { + "score": "امتیاز", + "currentRMS": "RMS فعلی", + "currentdbFS": "dbFS فعلی", + "title": "صدا", + "noAudioDetections": "هیچ تشخیص صدایی وجود ندارد" + }, + "boundingBoxes": { + "title": "کادرهای محدوده", + "desc": "نمایش جعبه‌های مرزی دور اشیای ردیابی‌شده", + "colors": { + "label": "رنگ‌های جعبهٔ مرزی شیء", + "info": "
  • در زمان راه‌اندازی، رنگ‌های مختلف به هر برچسب شیء اختصاص داده می‌شود
  • یک خط نازک آبی تیره نشان می‌دهد که شیء در این لحظه تشخیص داده نشده است
  • یک خط نازک خاکستری نشان می‌دهد که شیء به‌عنوان ساکن تشخیص داده شده است
  • یک خط ضخیم نشان می‌دهد که شیء موضوع ردیابی خودکار است (وقتی فعال باشد)
  • " + } + }, + "zones": { + "desc": "یک طرح کلی از هر ناحیهٔ تعریف‌شده را نمایش می‌دهد", + "title": "ناحیه‌ها" + }, + "mask": { + "title": "ماسک‌های حرکت", + "desc": "چندضلعی‌های ماسک حرکت را نشان می‌دهد" + }, + "motion": { + "title": "کادرهای حرکت", + "desc": "کادرهایی را پیرامون نواحی‌ای که در آن‌ها حرکت تشخیص داده می‌شود نشان می‌دهد", + "tips": "

    جعبه‌های حرکت


    جعبه‌های قرمز روی نواحی فریمی که در حال حاضر حرکت در آن‌ها تشخیص داده می‌شود نمایش داده می‌شوند

    " + }, + "paths": { + "desc": "نقاط مهم مسیر شیء ردیابی‌شده را نشان می‌دهد", + "tips": "

    مسیرها


    خط‌ها و دایره‌ها نقاط مهمی را که شیء ردیابی‌شده در طول چرخهٔ عمر خود طی کرده است نشان می‌دهند.

    ", + "title": "مسیرها" + }, + "objectShapeFilterDrawing": { + "title": "رسم فیلتر شکل شیء", + "desc": "برای مشاهدهٔ جزئیات مساحت و نسبت، روی تصویر یک مستطیل رسم کنید", + "tips": "این گزینه را فعال کنید تا بتوانید روی تصویر دوربین یک مستطیل رسم کنید و مساحت و نسبت آن را ببینید. سپس می‌توان از این مقادیر برای تنظیم پارامترهای فیلتر شکل شیء در پیکربندی شما استفاده کرد.", + "score": "امتیاز", + "ratio": "نسبت", + "area": "مساحت" + }, + "openCameraWebUI": "رابط وبِ {{camera}} را باز کنید", + "debugging": "انجام اشکال‌زدایی", + "objectList": "فهرست اشیا", + "noObjects": "هیچ شیئی وجود ندارد", + "timestamp": { + "title": "مهر زمان", + "desc": "نمایش مهر زمان روی تصویر" + }, + "regions": { + "title": "مناطق", + "desc": "نمایش جعبهٔ ناحیهٔ مورد علاقهٔ ارسال‌شده به تشخیص‌دهندهٔ شیء", + "tips": "

    جعبه‌های ناحیه


    جعبه‌های سبز روشن روی نواحی مورد علاقه در فریم که به تشخیص‌دهندهٔ شیء ارسال می‌شوند نمایش داده می‌شوند.

    " + } + }, + "users": { + "management": { + "desc": "حساب‌های کاربری این نمونهٔ Frigate را مدیریت کنید.", + "title": "مدیریت کاربران" + }, + "addUser": "افزودن کاربر", + "updatePassword": "بازنشانی گذرواژه", + "toast": { + "success": { + "createUser": "کاربر {{user}} با موفقیت ایجاد شد", + "deleteUser": "کاربر {{user}} با موفقیت حذف شد", + "updatePassword": "گذرواژه با موفقیت به‌روزرسانی شد.", + "roleUpdated": "نقش برای {{user}} به‌روزرسانی شد" + }, + "error": { + "setPasswordFailed": "ذخیرهٔ گذرواژه ناموفق بود: {{errorMessage}}", + "createUserFailed": "ایجاد کاربر ناموفق بود: {{errorMessage}}", + "deleteUserFailed": "حذف کاربر ناموفق بود: {{errorMessage}}", + "roleUpdateFailed": "به‌روزرسانی نقش ناموفق بود: {{errorMessage}}" + } + }, + "table": { + "changeRole": "تغییر نقش کاربر", + "password": "بازنشانی گذرواژه", + "deleteUser": "حذف کاربر", + "username": "نام کاربری", + "actions": "اقدامات", + "role": "نقش", + "noUsers": "هیچ کاربری یافت نشد." + }, + "dialog": { + "form": { + "user": { + "title": "نام کاربری", + "desc": "فقط حروف، اعداد، نقطه و زیرخط مجاز هستند.", + "placeholder": "نام کاربری را وارد کنید" + }, + "password": { + "confirm": { + "title": "تأیید گذرواژه", + "placeholder": "تأیید گذرواژه" + }, + "strength": { + "title": "قدرت گذرواژه: · ", + "weak": "ضعیف", + "medium": "متوسط", + "strong": "قوی", + "veryStrong": "خیلی قوی" + }, + "requirements": { + "digit": "حداقل یک رقم", + "special": "حداقل یک نویسهٔ ویژه (!@#$%^&*(),.?\":{}|<>)", + "title": "الزامات رمز عبور:", + "length": "حداقل ۸ کاراکتر", + "uppercase": "حداقل یک حرف بزرگ" + }, + "match": "گذرواژه‌ها مطابقت دارند", + "notMatch": "گذرواژه‌ها مطابقت ندارند", + "show": "نمایش رمز عبور", + "hide": "پنهان کردن رمز عبور", + "title": "رمز عبور", + "placeholder": "رمز عبور را وارد کنید" + }, + "newPassword": { + "title": "گذرواژهٔ جدید", + "confirm": { + "placeholder": "رمز عبور جدید را دوباره وارد کنید" + }, + "placeholder": "رمز عبور جدید را وارد کنید" + }, + "passwordIsRequired": "گذرواژه الزامی است", + "currentPassword": { + "title": "رمز عبور فعلی", + "placeholder": "رمز عبور فعلی خود را وارد کنید" + }, + "usernameIsRequired": "نام کاربری الزامی است" + }, + "createUser": { + "title": "ایجاد کاربر جدید", + "desc": "یک حساب کاربری جدید اضافه کنید و یک نقش برای دسترسی به بخش‌های رابط کاربری Frigate تعیین کنید.", + "usernameOnlyInclude": "نام کاربری فقط می‌تواند شامل حروف، اعداد، . یا _ باشد", + "confirmPassword": "لطفاً گذرواژهٔ خود را تأیید کنید" + }, + "passwordSetting": { + "currentPasswordRequired": "گذرواژهٔ فعلی الزامی است", + "incorrectCurrentPassword": "گذرواژهٔ فعلی نادرست است", + "passwordVerificationFailed": "اعتبارسنجی گذرواژه ناموفق بود", + "updatePassword": "به‌روزرسانی گذرواژه برای {{username}}", + "setPassword": "تنظیم گذرواژه", + "desc": "برای ایمن‌سازی این حساب، یک گذرواژهٔ قوی بسازید.", + "doNotMatch": "رمزهای عبور مطابقت ندارند", + "multiDeviceWarning": "هر دستگاه دیگری که در آن وارد شده‌اید باید ظرف {{refresh_time}} دوباره وارد شود.", + "multiDeviceAdmin": "همچنین می‌توانید با چرخش رمز JWT خود، همهٔ کاربران را فوراً مجبور به احراز هویت مجدد کنید.", + "cannotBeEmpty": "رمز عبور نمی‌تواند خالی باشد" + }, + "changeRole": { + "desc": "به‌روزرسانی مجوزها برای {{username}} ", + "roleInfo": { + "intro": "نقش مناسب برای این کاربر را انتخاب کنید:", + "admin": "مدیر", + "adminDesc": "دسترسی کامل به همهٔ قابلیت‌ها.", + "viewer": "بیننده", + "customDesc": "نقش سفارشی با دسترسی مشخص به دوربین.", + "viewerDesc": "محدود به داشبوردهای زنده، بررسی، کاوش و خروجی‌گیری فقط." + }, + "title": "تغییر نقش کاربر", + "select": "یک نقش انتخاب کنید" + }, + "deleteUser": { + "title": "حذف کاربر", + "desc": "این عمل قابل بازگشت نیست. این کار حساب کاربری را به‌طور دائم حذف می‌کند و همهٔ داده‌های مرتبط را حذف می‌کند.", + "warn": "آیا مطمئن هستید که می‌خواهید {{username}} را حذف کنید؟" + } + }, + "title": "کاربران" + }, + "roles": { + "table": { + "role": "نقش", + "cameras": "دوربین‌ها", + "actions": "اقدام‌ها", + "noRoles": "هیچ نقش سفارشی‌ای یافت نشد.", + "editCameras": "ویرایش دوربین‌ها", + "deleteRole": "حذف نقش" + }, + "toast": { + "success": { + "createRole": "نقش {{role}} با موفقیت ایجاد شد", + "updateCameras": "دوربین‌ها برای نقش {{role}} به‌روزرسانی شدند", + "deleteRole": "نقش {{role}} با موفقیت حذف شد", + "userRolesUpdated_one": "{{count}} کاربری که به این نقش اختصاص داده شده بود به «بیننده» تغییر یافت و اکنون به همهٔ دوربین‌ها دسترسی دارد.", + "userRolesUpdated_other": "{{count}} کاربری که به این نقش اختصاص داده شده بودند به «بیننده» تغییر یافتند و اکنون به همهٔ دوربین‌ها دسترسی دارند." + }, + "error": { + "createRoleFailed": "ایجاد نقش ناموفق بود: {{errorMessage}}", + "updateCamerasFailed": "به‌روزرسانی دوربین‌ها ناموفق بود: {{errorMessage}}", + "deleteRoleFailed": "حذف نقش ناموفق بود: {{errorMessage}}", + "userUpdateFailed": "به‌روزرسانی نقش‌های کاربر ناموفق بود: {{errorMessage}}" + } + }, + "dialog": { + "createRole": { + "title": "ایجاد نقش جدید", + "desc": "یک نقش جدید اضافه کنید و سطح دسترسی به دوربین‌ها را تعیین کنید." + }, + "form": { + "role": { + "roleExists": "نقشی با این نام از قبل وجود دارد.", + "placeholder": "نام نقش را وارد کنید", + "desc": "فقط حروف، اعداد، نقطه و زیرخط مجاز است.", + "roleIsRequired": "نام نقش الزامی است", + "roleOnlyInclude": "نام نقش فقط می‌تواند شامل حروف، اعداد، . یا _ باشد", + "title": "نام نقش" + }, + "cameras": { + "title": "دوربین‌ها", + "desc": "دوربین‌هایی را که این نقش به آن‌ها دسترسی دارد انتخاب کنید. حداقل یک دوربین لازم است.", + "required": "حداقل باید یک دوربین انتخاب شود." + } + }, + "editCameras": { + "title": "ویرایش دوربین‌های نقش", + "desc": "به‌روزرسانی دسترسی به دوربین برای نقش {{role}} ." + }, + "deleteRole": { + "title": "حذف نقش", + "desc": "این عمل قابل بازگشت نیست. این کار نقش را به‌طور دائم حذف می‌کند و همهٔ کاربرانی که این نقش را دارند به نقش 'بیننده' اختصاص می‌دهد که دسترسی بیننده به همهٔ دوربین‌ها را می‌دهد.", + "warn": "آیا مطمئن هستید که می‌خواهید {{role}} را حذف کنید؟", + "deleting": "در حال حذف…" + } + }, + "management": { + "title": "مدیریت نقش بیننده", + "desc": "مدیریت نقش‌های بینندهٔ سفارشی و مجوزهای دسترسی به دوربین آن‌ها برای این نمونهٔ Frigate." + }, + "addRole": "افزودن نقش" + }, + "notification": { + "title": "اعلان‌ها", + "notificationSettings": { + "title": "تنظیمات اعلان‌ها", + "desc": "Frigate می‌تواند به‌صورت بومی وقتی در مرورگر اجرا می‌شود یا به‌عنوان PWA نصب شده است، اعلان‌های پوش را به دستگاه شما ارسال کند." + }, + "notificationUnavailable": { + "title": "اعلان‌ها در دسترس نیستند", + "desc": "اعلان‌های پوش وب نیاز به یک بستر امن دارند ( https://… ). این محدودیت مرورگر است. برای استفاده از اعلان‌ها، به‌صورت امن به Frigate دسترسی پیدا کنید." + }, + "globalSettings": { + "title": "تنظیمات عمومی", + "desc": "به‌طور موقت اعلان‌ها را برای دوربین‌های مشخص در همهٔ دستگاه‌های ثبت‌شده متوقف کنید." + }, + "sendTestNotification": "ارسال اعلان آزمایشی", + "unsavedRegistrations": "ثبت‌نام‌های اعلان ذخیره‌نشده", + "unsavedChanges": "تغییرات اعلان ذخیره‌نشده", + "active": "اعلان‌ها فعال هستند", + "suspended": "اعلان‌ها تعلیق شده‌اند {{time}}", + "suspendTime": { + "suspend": "تعلیق", + "5minutes": "تعلیق به مدت ۵ دقیقه", + "10minutes": "تعلیق به مدت ۱۰ دقیقه", + "30minutes": "تعلیق به مدت ۳۰ دقیقه", + "1hour": "تعلیق به مدت ۱ ساعت", + "24hours": "متوقف کردن به مدت ۲۴ ساعت", + "untilRestart": "متوقف کردن تا راه‌اندازی مجدد", + "12hours": "متوقف کردن به مدت ۱۲ ساعت" + }, + "email": { + "title": "ایمیل", + "placeholder": "مثلاً example@email.com", + "desc": "یک ایمیل معتبر الزامی است و در صورت بروز مشکل در سرویس push برای اطلاع‌رسانی به شما استفاده می‌شود." + }, + "cameras": { + "title": "دوربین‌ها", + "noCameras": "هیچ دوربینی در دسترس نیست", + "desc": "انتخاب کنید که برای کدام دوربین‌ها اعلان فعال شود." + }, + "cancelSuspension": "لغو توقف", + "toast": { + "success": { + "registered": "با موفقیت برای اعلان‌ها ثبت شد. راه‌اندازی مجدد Frigate قبل از ارسال هر اعلانی (از جمله اعلان آزمایشی) الزامی است.", + "settingSaved": "تنظیمات اعلان ذخیره شد." + }, + "error": { + "registerFailed": "ذخیرهٔ ثبت‌نام اعلان ناموفق بود." + } + }, + "deviceSpecific": "تنظیمات خاص دستگاه", + "registerDevice": "ثبت این دستگاه", + "unregisterDevice": "لغو ثبت این دستگاه" + }, + "frigatePlus": { + "apiKey": { + "notValidated": "کلید API ‏Frigate+ شناسایی نشده یا معتبرسازی نشده است", + "desc": "کلید API ‏Frigate+ امکان یکپارچه‌سازی با سرویس Frigate+ را فراهم می‌کند.", + "plusLink": "دربارهٔ Frigate+ بیشتر بخوانید", + "title": "کلید API فرigate+", + "validated": "کلید API فرigate+ شناسایی و تأیید شد" + }, + "snapshotConfig": { + "title": "پیکربندی عکس فوری", + "desc": "ارسال به Frigate+ نیازمند فعال بودنِ هم «عکس‌های فوری» و هم عکس‌های فوریِ clean_copy در پیکربندی شماست.", + "cleanCopyWarning": "برای برخی دوربین‌ها عکس فوری فعال است اما clean copy غیرفعال است. برای این‌که بتوانید تصاویر این دوربین‌ها را به Frigate+ ارسال کنید، باید clean_copy را در پیکربندی عکس فوری خود فعال کنید.", + "table": { + "camera": "دوربین", + "snapshots": "عکس‌های فوری", + "cleanCopySnapshots": "عکس‌های فوریِ clean_copy " + } + }, + "modelInfo": { + "title": "اطلاعات مدل", + "loadingAvailableModels": "در حال بارگذاری مدل‌های موجود…", + "modelSelect": "مدل‌های موجود شما در Frigate+ را می‌توان از اینجا انتخاب کرد. توجه داشته باشید که فقط مدل‌های سازگار با پیکربندی فعلی آشکارساز شما قابل انتخاب هستند.", + "modelType": "نوع مدل", + "cameras": "دوربین‌ها", + "loading": "در حال بارگذاری اطلاعات مدل…", + "error": "بارگذاری اطلاعات مدل ناموفق بود", + "availableModels": "مدل‌های موجود", + "trainDate": "تاریخ آموزش", + "baseModel": "مدل پایه", + "plusModelType": { + "baseModel": "مدل پایه", + "userModel": "بهینه‌شده" + }, + "supportedDetectors": "تشخیص‌دهنده‌های پشتیبانی‌شده" + }, + "unsavedChanges": "تغییرات تنظیمات Frigate+ ذخیره‌نشده", + "restart_required": "نیاز به راه‌اندازی مجدد (مدل Frigate+ تغییر کرد)", + "toast": { + "success": "تنظیمات Frigate+ ذخیره شد. برای اعمال تغییرات، Frigate را راه‌اندازی مجدد کنید.", + "error": "ذخیرهٔ تغییرات پیکربندی ناموفق بود: {{errorMessage}}" + }, + "title": "تنظیمات Frigate+" + }, + "triggers": { + "documentTitle": "تریگرها", + "semanticSearch": { + "title": "جستجوی معنایی غیرفعال است", + "desc": "برای استفاده از تریگرها باید جستجوی معنایی فعال باشد." + }, + "management": { + "title": "تریگرها", + "desc": "مدیریت محرک‌ها برای {{camera}}. از نوع بندانگشتی برای فعال‌سازی روی بندانگشتی‌های مشابه به شیء ردیابی‌شدهٔ انتخابی‌تان استفاده کنید، و از نوع توضیحات برای فعال‌سازی روی توضیحات مشابه به متنی که مشخص می‌کنید." + }, + "table": { + "lastTriggered": "آخرین بار فعال‌شده", + "noTriggers": "هیچ محرکی برای این دوربین پیکربندی نشده است.", + "edit": "ویرایش", + "deleteTrigger": "حذف محرک", + "name": "نام", + "type": "نوع", + "content": "محتوا", + "threshold": "آستانه", + "actions": "اقدامات" + }, + "type": { + "thumbnail": "پیش‌نمایش", + "description": "توضیحات" + }, + "actions": { + "notification": "ارسال اعلان", + "sub_label": "افزودن زیر‌برچسب", + "attribute": "افزودن ویژگی" + }, + "dialog": { + "createTrigger": { + "title": "ایجاد تریگر", + "desc": "برای دوربین {{camera}} یک تریگر ایجاد کنید" + }, + "editTrigger": { + "title": "ویرایش تریگر", + "desc": "تنظیمات تریگر روی دوربین {{camera}} را ویرایش کنید" + }, + "deleteTrigger": { + "title": "حذف تریگر", + "desc": "آیا مطمئن هستید که می‌خواهید تریگر {{triggerName}} را حذف کنید؟ این عمل قابل بازگشت نیست." + }, + "form": { + "name": { + "title": "نام", + "placeholder": "این تریگر را نام‌گذاری کنید", + "description": "یک نام یا توضیح یکتا وارد کنید تا این تریگر قابل شناسایی باشد", + "error": { + "minLength": "فیلد باید حداقل ۲ کاراکتر باشد.", + "invalidCharacters": "فیلد فقط می‌تواند شامل حروف، اعداد، زیرخط (_) و خط تیره (-) باشد.", + "alreadyExists": "تریگری با این نام از قبل برای این دوربین وجود دارد." + } + }, + "enabled": { + "description": "این تریگر را فعال یا غیرفعال کنید" + }, + "type": { + "title": "نوع", + "placeholder": "نوع تریگر را انتخاب کنید", + "description": "وقتی توضیحی مشابهِ شیء ردیابی‌شده تشخیص داده شود تریگر شود", + "thumbnail": "وقتی بندانگشتیِ مشابهِ شیء ردیابی‌شده تشخیص داده شود تریگر شود" + }, + "content": { + "title": "محتوا", + "imagePlaceholder": "یک بندانگشتی انتخاب کنید", + "textPlaceholder": "محتوای متنی را وارد کنید", + "imageDesc": "فقط ۱۰۰ بندانگشتیِ آخر نمایش داده می‌شوند. اگر بندانگشتیِ موردنظر خود را پیدا نمی‌کنید، لطفاً اشیای قدیمی‌تر را در Explore مرور کنید و از همان‌جا از منو یک تریگر تنظیم کنید.", + "textDesc": "متنی وارد کنید تا وقتی توضیحی مشابهِ شیء ردیابی‌شده تشخیص داده شد، این اقدام تریگر شود.", + "error": { + "required": "محتوا الزامی است." + } + }, + "threshold": { + "title": "آستانه", + "desc": "آستانهٔ شباهت را برای این تریگر تعیین کنید. آستانهٔ بالاتر یعنی برای فعال شدن تریگر، تطابق نزدیک‌تری لازم است.", + "error": { + "min": "آستانه باید حداقل ۰ باشد", + "max": "آستانه باید حداکثر ۱ باشد" + } + }, + "actions": { + "title": "اقدام‌ها", + "desc": "به‌طور پیش‌فرض، Frigate برای همهٔ تریگرها یک پیام MQTT ارسال می‌کند. زیر‌برچسب‌ها نام تریگر را به برچسب شیء اضافه می‌کنند. ویژگی‌ها فراداده‌های قابل جستجو هستند که جداگانه در فرادادهٔ شیء ردیابی‌شده ذخیره می‌شوند.", + "error": { + "min": "حداقل باید یک اقدام انتخاب شود." + } + } + } + }, + "wizard": { + "title": "ایجاد تریگر", + "step1": { + "description": "تنظیمات پایهٔ تریگر خود را پیکربندی کنید." + }, + "step2": { + "description": "محتوایی را که این اقدام را فعال می‌کند تنظیم کنید." + }, + "step3": { + "description": "آستانه و اقدام‌های این تریگر را پیکربندی کنید." + }, + "steps": { + "nameAndType": "نام و نوع", + "configureData": "پیکربندی داده‌ها", + "thresholdAndActions": "آستانه و اقدام‌ها" + } + }, + "toast": { + "success": { + "createTrigger": "تریگر {{name}} با موفقیت ایجاد شد.", + "updateTrigger": "تریگر {{name}} با موفقیت به‌روزرسانی شد.", + "deleteTrigger": "تریگر {{name}} با موفقیت حذف شد." + }, + "error": { + "createTriggerFailed": "ایجاد تریگر ناموفق بود: {{errorMessage}}", + "updateTriggerFailed": "به‌روزرسانی تریگر ناموفق بود: {{errorMessage}}", + "deleteTriggerFailed": "حذف تریگر ناموفق بود: {{errorMessage}}" + } + }, + "addTrigger": "افزودن محرک" } } diff --git a/web/public/locales/fa/views/system.json b/web/public/locales/fa/views/system.json index b33d6e505..090d4a97f 100644 --- a/web/public/locales/fa/views/system.json +++ b/web/public/locales/fa/views/system.json @@ -5,7 +5,197 @@ "general": "آمار عمومی - فریگیت", "enrichments": "آمار بهینه سازی - فریگیت", "logs": { - "frigate": "ثبت رخدادهای فریگیت - فریگیت" + "frigate": "ثبت رخدادهای فریگیت - فریگیت", + "go2rtc": "گزارش‌های Go2RTC - فریگیت", + "nginx": "گزارش‌های Nginx - فریگیت" } - } + }, + "title": "سیستم", + "metrics": "شاخص‌های سیستم", + "logs": { + "download": { + "label": "دانلود گزارش‌ها" + }, + "copy": { + "label": "کپی در کلیپ‌بورد", + "success": "گزارش‌ها در کلیپ‌بورد کپی شدند", + "error": "نمی‌توان گزارش‌ها را در کلیپ‌بورد کپی کرد" + }, + "type": { + "label": "نوع", + "timestamp": "برچسب زمانی", + "tag": "تگ", + "message": "پیام" + }, + "tips": "گزارش‌ها از سرور به‌صورت زنده در حال دریافت هستند", + "toast": { + "error": { + "fetchingLogsFailed": "خطا در دریافت گزارش‌ها: {{errorMessage}}", + "whileStreamingLogs": "خطا هنگام پخش زندهٔ گزارش‌ها: {{errorMessage}}" + } + } + }, + "general": { + "hardwareInfo": { + "title": "اطلاعات سخت‌افزار", + "gpuUsage": "مصرف GPU", + "gpuMemory": "حافظهٔ GPU", + "gpuEncoder": "رمزگذار GPU", + "gpuDecoder": "رمزگشای GPU", + "gpuInfo": { + "vainfoOutput": { + "title": "خروجی Vainfo", + "returnCode": "کد بازگشتی: {{code}}", + "processOutput": "خروجی فرایند:", + "processError": "خطای فرایند:" + }, + "nvidiaSMIOutput": { + "title": "خروجی Nvidia SMI", + "name": "ذخیرهٔ جست‌وجونام: {{name}}", + "driver": "درایور: {{driver}}", + "cudaComputerCapability": "قابلیت محاسباتی CUDA: {{cuda_compute}}", + "vbios": "اطلاعات VBios: {{vbios}}" + }, + "closeInfo": { + "label": "بستن اطلاعات GPU" + }, + "copyInfo": { + "label": "کپی اطلاعات GPU" + }, + "toast": { + "success": "اطلاعات GPU در کلیپ‌بورد کپی شد" + } + }, + "npuUsage": "میزان استفاده از NPU", + "npuMemory": "حافظهٔ NPU", + "intelGpuWarning": { + "title": "هشدار آمار GPU اینتل", + "message": "آمار GPU در دسترس نیست", + "description": "این یک باگ شناخته‌شده در ابزارهای گزارش‌دهی آمار GPU اینتل (intel_gpu_top) است که باعث می‌شود از کار بیفتد و حتی در مواردی که شتاب‌دهی سخت‌افزاری و تشخیص شیء به‌درستی روی (i)GPU اجرا می‌شوند، به‌طور مکرر میزان استفادهٔ GPU را ۰٪ برگرداند. این مشکل مربوط به Frigate نیست. می‌توانید میزبان را ری‌استارت کنید تا موقتاً مشکل برطرف شود و تأیید کنید که GPU درست کار می‌کند. این موضوع روی عملکرد تأثیری ندارد." + } + }, + "title": "عمومی", + "detector": { + "title": "آشکارسازها", + "inferenceSpeed": "سرعت استنتاج آشکارساز", + "temperature": "دمای آشکارساز", + "cpuUsage": "مصرف CPU آشکارساز", + "cpuUsageInformation": "CPU برای آماده‌سازی داده‌های ورودی و خروجی به/از مدل‌های تشخیص استفاده می‌شود. این مقدار مصرف استنتاج را اندازه‌گیری نمی‌کند، حتی اگر از GPU یا شتاب‌دهنده استفاده شود.", + "memoryUsage": "مصرف حافظهٔ آشکارساز" + }, + "otherProcesses": { + "title": "فرایندهای دیگر", + "processCpuUsage": "میزان استفادهٔ CPU فرایند", + "processMemoryUsage": "میزان استفادهٔ حافظهٔ فرایند" + } + }, + "storage": { + "recordings": { + "earliestRecording": "قدیمی‌ترین ضبط موجود:", + "title": "ضبط‌ها", + "tips": "این مقدار نشان‌دهندهٔ کل فضای ذخیره‌سازیِ استفاده‌شده توسط ضبط‌ها در پایگاه‌دادهٔ Frigate است. Frigate میزان استفاده از فضای ذخیره‌سازیِ همهٔ فایل‌های روی دیسک شما را ردیابی نمی‌کند." + }, + "shm": { + "warning": "اندازهٔ فعلی SHM برابر {{total}}MB خیلی کوچک است. آن را دست‌کم به {{min_shm}}MB افزایش دهید.", + "title": "اختصاص SHM (حافظهٔ اشتراکی)" + }, + "cameraStorage": { + "title": "ذخیره‌سازی دوربین", + "unusedStorageInformation": "اطلاعات فضای ذخیره‌سازیِ استفاده‌نشده", + "percentageOfTotalUsed": "درصد از کل", + "unused": { + "title": "استفاده‌نشده", + "tips": "اگر فایل‌های دیگری غیر از ضبط‌های Frigate روی دیسک شما ذخیره شده باشد، این مقدار ممکن است فضای آزادِ در دسترس برای Frigate را دقیق نشان ندهد. Frigate میزان استفاده از فضای ذخیره‌سازی خارج از ضبط‌های خودش را ردیابی نمی‌کند." + }, + "camera": "دوربین", + "storageUsed": "ذخیره‌سازی", + "bandwidth": "پهنای باند" + }, + "title": "ذخیره‌سازی", + "overview": "نمای کلی" + }, + "cameras": { + "overview": "نمای کلی", + "info": { + "cameraProbeInfo": "اطلاعات پروب دوربین {{camera}}", + "fetching": "در حال دریافت داده‌های دوربین", + "video": "ویدئو:", + "fps": "FPS:", + "audio": "صدا:", + "aspectRatio": "نسبت تصویر", + "streamDataFromFFPROBE": "داده‌های جریان با ffprobe به‌دست می‌آید.", + "stream": "جریان {{idx}}", + "codec": "کدک:", + "resolution": "وضوح:", + "unknown": "نامشخص", + "error": "خطا: {{error}}", + "tips": { + "title": "اطلاعات بررسی دوربین" + } + }, + "framesAndDetections": "فریم‌ها / تشخیص‌ها", + "label": { + "detect": "تشخیص", + "capture": "گرفتن", + "overallDetectionsPerSecond": "مجموع تشخیص‌ها در ثانیه", + "cameraCapture": "گرفتن {{camName}}", + "cameraDetectionsPerSecond": "تشخیص‌ها در ثانیهٔ {{camName}}", + "camera": "دوربین", + "skipped": "رد شد", + "ffmpeg": "FFmpeg", + "overallFramesPerSecond": "نرخ کلی فریم بر ثانیه", + "overallSkippedDetectionsPerSecond": "نرخ کلی تشخیص‌های ردشده بر ثانیه", + "cameraDetect": "تشخیص {{camName}}", + "cameraFfmpeg": "{{camName}} FFmpeg", + "cameraFramesPerSecond": "{{camName}} فریم بر ثانیه", + "cameraSkippedDetectionsPerSecond": "{{camName}} تشخیص‌های ردشده در ثانیه" + }, + "toast": { + "error": { + "unableToProbeCamera": "پروبِ دوربین ناموفق بود: {{errorMessage}}" + }, + "success": { + "copyToClipboard": "داده‌های بررسی در کلیپ‌بورد کپی شد." + } + }, + "title": "دوربین‌ها" + }, + "stats": { + "ffmpegHighCpuUsage": "{{camera}} استفادهٔ CPU بالایی برای FFmpeg دارد ({{ffmpegAvg}}%)", + "detectHighCpuUsage": "{{camera}} استفادهٔ CPU بالایی برای تشخیص دارد ({{detectAvg}}%)", + "reindexingEmbeddings": "بازتولید نمایهٔ embeddingها ({{processed}}% تکمیل شده)", + "cameraIsOffline": "{{camera}} آفلاین است", + "detectIsVerySlow": "{{detect}} بسیار کند است ({{speed}} ms)", + "shmTooLow": "اختصاص /dev/shm ({{total}} MB) باید دست‌کم تا {{min}} MB افزایش یابد.", + "healthy": "سامانه سالم است", + "detectIsSlow": "{{detect}} کند است ( {{speed}} میلی‌ثانیه )" + }, + "enrichments": { + "infPerSecond": "استنتاج‌ها در ثانیه", + "embeddings": { + "text_embedding": "امبدینگ متن", + "image_embedding_speed": "سرعت امبدینگ تصویر", + "plate_recognition_speed": "سرعت تشخیص پلاک", + "yolov9_plate_detection": "تشخیص پلاک YOLOv9", + "review_description_events_per_second": "توضیح بازبینی", + "object_description": "توضیح شیء", + "image_embedding": "امبدینگ تصویر", + "face_recognition": "شناسایی چهره", + "plate_recognition": "شناسایی پلاک", + "face_embedding_speed": "سرعت امبدینگ چهره", + "face_recognition_speed": "سرعت شناسایی چهره", + "text_embedding_speed": "سرعت امبدینگ متن", + "yolov9_plate_detection_speed": "سرعت تشخیص پلاک YOLOv9", + "review_description": "توضیحات بازبینی", + "review_description_speed": "سرعت توضیحات بازبینی", + "object_description_speed": "سرعت توضیحات شیء", + "object_description_events_per_second": "توضیحات شیء", + "classification": "طبقه‌بندی {{name}}", + "classification_speed": "سرعت طبقه‌بندی {{name}}", + "classification_events_per_second": "رویدادهای طبقه‌بندی {{name}} در ثانیه" + }, + "title": "غنی‌سازی‌ها", + "averageInf": "میانگین زمان استنتاج" + }, + "lastRefreshed": "آخرین به‌روزرسانی: · " } From bd568ab3b14548c6de8735b7b9f066d14328390e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:57 +0100 Subject: [PATCH 30/98] Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (49 of 49 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 11.9% (78 of 654 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (214 of 214 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (55 of 55 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 97.6% (42 of 43 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 99.2% (135 of 136 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (53 of 53 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (74 of 74 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (131 of 131 strings) Co-authored-by: Hosted Weblate Co-authored-by: J P Co-authored-by: windasd Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-search/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/zh_Hant/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/zh_Hant/ Translation: Frigate NVR/common Translation: Frigate NVR/components-dialog Translation: Frigate NVR/components-filter Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-search Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/zh-Hant/common.json | 4 +- .../locales/zh-Hant/components/dialog.json | 5 +- .../locales/zh-Hant/components/filter.json | 8 ++- web/public/locales/zh-Hant/views/events.json | 6 ++- web/public/locales/zh-Hant/views/explore.json | 54 +++++++++++++++++-- .../locales/zh-Hant/views/faceLibrary.json | 3 +- web/public/locales/zh-Hant/views/search.json | 3 +- .../locales/zh-Hant/views/settings.json | 8 +++ web/public/locales/zh-Hant/views/system.json | 30 +++++++++-- 9 files changed, 105 insertions(+), 16 deletions(-) diff --git a/web/public/locales/zh-Hant/common.json b/web/public/locales/zh-Hant/common.json index f512332f0..17a60efaa 100644 --- a/web/public/locales/zh-Hant/common.json +++ b/web/public/locales/zh-Hant/common.json @@ -105,8 +105,8 @@ "enable": "啟用", "disabled": "已停用", "disable": "停用", - "save": "保存", - "saving": "保存中…", + "save": "儲存", + "saving": "儲存中…", "cancel": "取消", "close": "關閉", "copy": "複製", diff --git a/web/public/locales/zh-Hant/components/dialog.json b/web/public/locales/zh-Hant/components/dialog.json index 3927a8c20..b28ccca48 100644 --- a/web/public/locales/zh-Hant/components/dialog.json +++ b/web/public/locales/zh-Hant/components/dialog.json @@ -81,7 +81,7 @@ }, "search": { "saveSearch": { - "label": "保存搜尋", + "label": "儲存搜尋", "desc": "替此保存的搜尋命名。", "placeholder": "請輸入搜尋的名稱", "overwrite": "{{searchName}} 已存在。保存將會覆蓋現有資料。", @@ -116,6 +116,7 @@ "unknownLabel": "已儲存觸發圖片", "search": { "placeholder": "以標籤或子標籤搜尋..." - } + }, + "noImages": "未找到此攝影機的縮圖" } } diff --git a/web/public/locales/zh-Hant/components/filter.json b/web/public/locales/zh-Hant/components/filter.json index 29ccaa5c2..1cbef2fd3 100644 --- a/web/public/locales/zh-Hant/components/filter.json +++ b/web/public/locales/zh-Hant/components/filter.json @@ -121,7 +121,9 @@ "loading": "讀取已辨識車牌中…", "placeholder": "輸入以搜尋車牌…", "noLicensePlatesFound": "未找到車牌。", - "selectPlatesFromList": "從列表中選擇一個或多個車牌。" + "selectPlatesFromList": "從列表中選擇一個或多個車牌。", + "selectAll": "全選", + "clearAll": "全部清除" }, "classes": { "label": "類別", @@ -130,5 +132,9 @@ }, "count_one": "{{count}} 個類別", "count_other": "{{count}} 個類別" + }, + "attributes": { + "label": "分類屬性", + "all": "所有屬性" } } diff --git a/web/public/locales/zh-Hant/views/events.json b/web/public/locales/zh-Hant/views/events.json index 314779d5d..c8883f420 100644 --- a/web/public/locales/zh-Hant/views/events.json +++ b/web/public/locales/zh-Hant/views/events.json @@ -8,7 +8,11 @@ "empty": { "motion": "未找到移動資料", "alert": "沒有警告需要審核", - "detection": "沒有偵測到的內容需要審核" + "detection": "沒有偵測到的內容需要審核", + "recordingsDisabled": { + "title": "必須啟用錄製功能", + "description": "僅當該攝影機啟用錄製功能時,才能為該攝影機建立審查項目。" + } }, "timeline": "時間線", "timeline.aria": "選擇時間線", diff --git a/web/public/locales/zh-Hant/views/explore.json b/web/public/locales/zh-Hant/views/explore.json index 59602f909..598700963 100644 --- a/web/public/locales/zh-Hant/views/explore.json +++ b/web/public/locales/zh-Hant/views/explore.json @@ -47,12 +47,16 @@ "success": { "regenerate": "已從 {{provider}} 請求新的說明。根據提供者的速度,生成新的說明可能會需要一段時間。", "updatedSublabel": "成功更新子標籤。", - "updatedLPR": "成功更新車牌。" + "updatedLPR": "成功更新車牌。", + "updatedAttributes": "已成功更新屬性。", + "audioTranscription": "已成功送出音訊轉錄請求。轉錄完成所需時間會依您的 Frigate 伺服器速度而定,可能需要一段時間。" }, "error": { "regenerate": "請求 {{provider}} 生成新的說明失敗:{{errorMessage}}", "updatedSublabelFailed": "更新子標籤失敗:{{errorMessage}}", - "updatedLPRFailed": "更新車牌失敗:{{errorMessage}}" + "updatedLPRFailed": "更新車牌失敗:{{errorMessage}}", + "updatedAttributesFailed": "更新屬性失敗:{{errorMessage}}", + "audioTranscription": "請求音訊轉錄失敗:{{errorMessage}}" } } }, @@ -97,6 +101,17 @@ "tips": { "descriptionSaved": "成功保存說明", "saveDescriptionFailed": "更新說明失敗:{{errorMessage}}" + }, + "editAttributes": { + "title": "編輯屬性", + "desc": "為此 {{label}} 選擇分類屬性" + }, + "score": { + "label": "分數" + }, + "attributes": "分類屬性", + "title": { + "label": "標題" } }, "trackedObjectDetails": "追蹤物件詳情", @@ -184,6 +199,28 @@ }, "deleteTrackedObject": { "label": "刪除此追蹤物件" + }, + "hideObjectDetails": { + "label": "隱藏物件路徑" + }, + "showObjectDetails": { + "label": "顯示物件路徑" + }, + "addTrigger": { + "label": "新增觸發器", + "aria": "為此追蹤物件新增觸發器" + }, + "audioTranscription": { + "label": "轉錄", + "aria": "請求音訊轉錄" + }, + "downloadCleanSnapshot": { + "label": "下載乾淨的快照", + "aria": "下載乾淨的快照" + }, + "viewTrackingDetails": { + "label": "檢視追蹤詳細資訊", + "aria": "顯示追蹤詳細資訊" } }, "dialog": { @@ -202,7 +239,9 @@ "success": "成功刪除蹤物件。", "error": "刪除追蹤物件失敗:{{errorMessage}}" } - } + }, + "previousTrackedObject": "上一個追蹤物件", + "nextTrackedObject": "下一個追蹤物件" }, "trackingDetails": { "title": "追蹤詳情", @@ -244,9 +283,16 @@ "millisecondsToOffset": "偵測標記偏移補償的毫秒數。預設值: 0", "tips": "如果影片播放進度超前於方框和路徑點,則降低該值;如果影片播放進度落後於方框和路徑點,則增加該數值。該值可以為負數。", "toast": { - "success": "{{camera}} 的標記偏移補償量已儲存至設定檔,重新啟動 Frigate 以套用變更。" + "success": "{{camera}} 的標記偏移補償量已儲存至設定檔。" } } + }, + "carousel": { + "previous": "上一張投影片", + "next": "下一張投影片" } + }, + "aiAnalysis": { + "title": "AI 分析" } } diff --git a/web/public/locales/zh-Hant/views/faceLibrary.json b/web/public/locales/zh-Hant/views/faceLibrary.json index 99158e352..938bf1581 100644 --- a/web/public/locales/zh-Hant/views/faceLibrary.json +++ b/web/public/locales/zh-Hant/views/faceLibrary.json @@ -37,7 +37,8 @@ "train": { "title": "最近的識別紀錄", "aria": "選擇最近的識別紀錄", - "empty": "最近沒有辨識人臉的操作" + "empty": "最近沒有辨識人臉的操作", + "titleShort": "最近" }, "selectFace": "選擇人臉", "deleteFaceLibrary": { diff --git a/web/public/locales/zh-Hant/views/search.json b/web/public/locales/zh-Hant/views/search.json index 09e408fa7..7fe475e5e 100644 --- a/web/public/locales/zh-Hant/views/search.json +++ b/web/public/locales/zh-Hant/views/search.json @@ -26,7 +26,8 @@ "recognized_license_plate": "已辨識的車牌", "has_clip": "包含片段", "has_snapshot": "包含截圖", - "time_range": "時間範圍" + "time_range": "時間範圍", + "attributes": "屬性" }, "searchType": { "thumbnail": "截圖", diff --git a/web/public/locales/zh-Hant/views/settings.json b/web/public/locales/zh-Hant/views/settings.json index 701a2f18e..652583a09 100644 --- a/web/public/locales/zh-Hant/views/settings.json +++ b/web/public/locales/zh-Hant/views/settings.json @@ -134,5 +134,13 @@ "selectTransport": "選擇協議", "cameraBrand": "相機品牌" } + }, + "triggers": { + "toast": { + "error": { + "deleteTriggerFailed": "刪除觸發器失敗:{{errorMessage}}", + "updateTriggerFailed": "更新觸發器失敗:{{errorMessage}}" + } + } } } diff --git a/web/public/locales/zh-Hant/views/system.json b/web/public/locales/zh-Hant/views/system.json index 7c87b59d8..e956b9a42 100644 --- a/web/public/locales/zh-Hant/views/system.json +++ b/web/public/locales/zh-Hant/views/system.json @@ -86,7 +86,14 @@ "otherProcesses": { "title": "其他行程", "processCpuUsage": "行程 CPU 使用率", - "processMemoryUsage": "行程記憶體使用量" + "processMemoryUsage": "行程記憶體使用量", + "series": { + "recording": "记录", + "review_segment": "评论部分", + "embeddings": "嵌入", + "audio_detector": "音訊偵測器", + "go2rtc": "go2rtc" + } } }, "storage": { @@ -108,6 +115,10 @@ "title": "未使用", "tips": "在磁碟中有除了 Frigate 錄影內容以外的檔案時,此數值可能無法正確反應可用的空間。Frigate 不會追蹤錄影資料以外的檔案的儲存空間用量。" } + }, + "shm": { + "title": "SHM(共享記憶體)配置", + "warning": "目前的 SHM 大小為 {{total}}MB,過小。請將其增加至至少 {{min_shm}}MB。" } }, "cameras": { @@ -164,7 +175,8 @@ "reindexingEmbeddings": "正在重新替嵌入資料建立索引(已完成 {{processed}}%)", "cameraIsOffline": "{{camera}} 已離線", "detectIsSlow": "{{detect}} 偵測速度較慢({{speed}} 毫秒)", - "detectIsVerySlow": "{{detect}} 偵測速度緩慢({{speed}} 毫秒)" + "detectIsVerySlow": "{{detect}} 偵測速度緩慢({{speed}} 毫秒)", + "shmTooLow": "/dev/shm 配置({{total}} MB)應增加至至少{{min}} MB。" }, "enrichments": { "title": "進階功能", @@ -180,7 +192,17 @@ "plate_recognition_speed": "車牌辨識速度", "text_embedding_speed": "文字提取速度", "yolov9_plate_detection_speed": "YOLOv9 車牌偵測速度", - "yolov9_plate_detection": "YOLOv9 車牌辨識" - } + "yolov9_plate_detection": "YOLOv9 車牌辨識", + "review_description": "審查說明", + "review_description_speed": "審查描述速度", + "review_description_events_per_second": "審查說明", + "object_description": "物件說明", + "object_description_speed": "物件說明速度", + "object_description_events_per_second": "物件說明", + "classification": "{{name}} 分類", + "classification_speed": "{{name}}分類速度", + "classification_events_per_second": "{{name}} 分類每秒事件數" + }, + "averageInf": "平均推論時間" } } From 5e57dbe0707fa3d44deda9b0784342d090502ba5 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:58 +0100 Subject: [PATCH 31/98] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (654 of 654 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (501 of 501 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (118 of 118 strings) Co-authored-by: GuoQing Liu <842607283@qq.com> Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/zh_Hans/ Translation: Frigate NVR/audio Translation: Frigate NVR/common Translation: Frigate NVR/objects Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-settings Translation: Frigate NVR/views-system --- web/public/locales/zh-CN/audio.json | 2 +- web/public/locales/zh-CN/common.json | 3 +- web/public/locales/zh-CN/objects.json | 2 +- web/public/locales/zh-CN/views/events.json | 6 +++- web/public/locales/zh-CN/views/explore.json | 7 +++-- web/public/locales/zh-CN/views/settings.json | 10 +++---- web/public/locales/zh-CN/views/system.json | 31 ++++++++++++-------- 7 files changed, 38 insertions(+), 23 deletions(-) diff --git a/web/public/locales/zh-CN/audio.json b/web/public/locales/zh-CN/audio.json index 4c321c2e9..848418f84 100644 --- a/web/public/locales/zh-CN/audio.json +++ b/web/public/locales/zh-CN/audio.json @@ -60,7 +60,7 @@ "bow_wow": "汪汪", "growling": "咆哮", "whimper_dog": "狗呜咽", - "cat": "猫叫", + "cat": "猫", "purr": "咕噜", "meow": "喵喵", "hiss": "嘶嘶声", diff --git a/web/public/locales/zh-CN/common.json b/web/public/locales/zh-CN/common.json index b9bdbad33..42b1f5c65 100644 --- a/web/public/locales/zh-CN/common.json +++ b/web/public/locales/zh-CN/common.json @@ -104,7 +104,8 @@ "show": "显示 {{item}}", "ID": "ID", "none": "无", - "all": "所有" + "all": "所有", + "other": "其他" }, "pagination": { "label": "分页", diff --git a/web/public/locales/zh-CN/objects.json b/web/public/locales/zh-CN/objects.json index 6c155b8fb..193f87179 100644 --- a/web/public/locales/zh-CN/objects.json +++ b/web/public/locales/zh-CN/objects.json @@ -14,7 +14,7 @@ "parking_meter": "停车计时器", "bench": "长椅", "bird": "鸟", - "cat": "猫叫", + "cat": "猫", "dog": "狗", "horse": "马", "sheep": "绵羊", diff --git a/web/public/locales/zh-CN/views/events.json b/web/public/locales/zh-CN/views/events.json index ac795e2a9..9c95ed1c4 100644 --- a/web/public/locales/zh-CN/views/events.json +++ b/web/public/locales/zh-CN/views/events.json @@ -9,7 +9,11 @@ "empty": { "alert": "还没有“警报”类核查项", "detection": "还没有“检测”类核查项", - "motion": "还没有画面变动类数据" + "motion": "还没有画面变动类数据", + "recordingsDisabled": { + "title": "必须要开启录制功能", + "description": "必须要摄像头启用录制功能时,才可为其创建回放项目。" + } }, "timeline": "时间线", "timeline.aria": "选择时间线", diff --git a/web/public/locales/zh-CN/views/explore.json b/web/public/locales/zh-CN/views/explore.json index 45b89169a..8e66f2255 100644 --- a/web/public/locales/zh-CN/views/explore.json +++ b/web/public/locales/zh-CN/views/explore.json @@ -166,7 +166,10 @@ "title": "编辑属性", "desc": "为 {{label}} 选择分类属性" }, - "attributes": "分类属性" + "attributes": "分类属性", + "title": { + "label": "标题" + } }, "itemMenu": { "downloadVideo": { @@ -265,7 +268,7 @@ "other": "{{label}} 被识别为 {{attribute}}" }, "gone": "{{label}} 离开", - "heard": "{{label}} 被听到", + "heard": "听到 {{label}}", "external": "已检测到 {{label}}", "header": { "zones": "区", diff --git a/web/public/locales/zh-CN/views/settings.json b/web/public/locales/zh-CN/views/settings.json index 700b22377..a9a2ee567 100644 --- a/web/public/locales/zh-CN/views/settings.json +++ b/web/public/locales/zh-CN/views/settings.json @@ -405,7 +405,7 @@ "motionDetectionTuner": { "title": "画面变动检测调整", "desc": { - "title": "Frigate 将使用画面变化检测作为首个步骤,以确认一帧画面中是否有目标或物体需要使用目标检测。", + "title": "Frigate 将首先使用画面变动检测来确认每一帧画面中是否有变动的区域,然后再对该区域使用目标检测。", "documentation": "阅读有关画面变动检测的文档" }, "Threshold": { @@ -735,7 +735,7 @@ "readTheDocumentation": "阅读文档" }, "licensePlateRecognition": { - "desc": "Frigate 可以识别车辆的车牌,并自动将检测到的字符添加到 recognized_license_plate 字段中,或将已知车牌对应的名称作为子标签添加到该车辆目标中。一般常用于读取驶入车道的车辆车牌或经过街道的车辆车牌。", + "desc": "Frigate 可以识别车辆的车牌,并自动将检测到的字符添加到 识别的车牌(recognized_license_plate)字段中,或将已知车牌对应的名称作为子标签添加到该车辆目标中。该功能常用于识别驶入车道的车辆车牌或经过街道的车辆车牌。", "title": "车牌识别", "readTheDocumentation": "阅读文档" }, @@ -1212,7 +1212,7 @@ "noAudioWarning": "检测到该视频流无音频信号,录制视频将没有声音。", "audioCodecRecordError": "录制功能需要 AAC 音频编解码器以实现音频支持。", "audioCodecRequired": "要实现音频检测功能,必须要有音频流。", - "restreamingWarning": "为录制流开启“减少与摄像头的连接数”可能会略微增加CPU使用率。", + "restreamingWarning": "为录制流开启“减少与摄像头的连接数”可能会略微增加 CPU 使用率。", "brands": { "reolink-rtsp": "不建议使用 Reolink 的 RTSP 协议。请在摄像头后台设置中启用 HTTP协议,并重新启动向导。", "reolink-http": "Reolink HTTP 视频流应该使用 FFmpeg 以获得更好的兼容性,为此视频流启用“使用流兼容模式”。" @@ -1286,8 +1286,8 @@ "title": "核查分类", "desc": "Frigate 将核查项的严重程度分为“警报”和“检测”两个等级。默认情况下,所有的汽车 目标都将视为警报。你可以通过修改配置文件配置区域来细分。", "noDefinedZones": "此摄像头未设置任何监控区。", - "objectAlertsTips": "所有 {{alertsLabels}} 类目标或物体在 {{cameraName}} 下都将显示为警报。", - "zoneObjectAlertsTips": "所有 {{alertsLabels}} 类目标或物体在 {{cameraName}} 下的 {{zone}} 区域内都将显示为警报。", + "objectAlertsTips": "所有 {{alertsLabels}} 类目标或物体在 {{cameraName}} 下都将视为警报。", + "zoneObjectAlertsTips": "所有 {{alertsLabels}} 类目标或物体在 {{cameraName}} 下的 {{zone}} 区域内都将视为警报。", "objectDetectionsTips": "所有在摄像头 {{cameraName}} 上,检测到的 {{detectionsLabels}} 目标或物体,无论它位于哪个区,都将显示为检测。", "zoneObjectDetectionsTips": { "text": "所有在摄像头 {{cameraName}} 下的 {{zone}} 区域内检测到未分类的 {{detectionsLabels}} 目标或物体,都将显示为检测。", diff --git a/web/public/locales/zh-CN/views/system.json b/web/public/locales/zh-CN/views/system.json index 94ef1b7c8..4d06a16bf 100644 --- a/web/public/locales/zh-CN/views/system.json +++ b/web/public/locales/zh-CN/views/system.json @@ -40,17 +40,17 @@ "detector": { "title": "检测器", "inferenceSpeed": "检测器推理速度", - "cpuUsage": "检测器CPU使用率", + "cpuUsage": "检测器 CPU 使用率", "memoryUsage": "检测器内存使用率", "temperature": "检测器温度", - "cpuUsageInformation": "用于准备输入和输出数据的 CPU 资源,这些数据是供检测模型使用或由检测模型产生的。该数值并不衡量推理过程中的 CPU 使用情况,即使使用了 GPU 或加速器也是如此。" + "cpuUsageInformation": "此处的 CPU 使用率,只统计在给检测模型准备输入数据和处理输出数据时用到的 CPU。它不统计模型推理本身的资源占用,即使推理是在 GPU 或其他检测器上进行的。" }, "hardwareInfo": { "title": "硬件信息", - "gpuUsage": "GPU使用率", - "gpuMemory": "GPU显存", - "gpuEncoder": "GPU编码", - "gpuDecoder": "GPU解码", + "gpuUsage": "GPU 使用率", + "gpuMemory": "GPU 显存", + "gpuEncoder": "GPU 编码", + "gpuDecoder": "GPU 解码", "gpuInfo": { "vainfoOutput": { "title": "Vainfo 输出", @@ -66,17 +66,17 @@ "vbios": "VBios信息:{{vbios}}" }, "closeInfo": { - "label": "关闭GPU信息" + "label": "关闭 GPU 信息" }, "copyInfo": { - "label": "复制GPU信息" + "label": "复制 GPU 信息" }, "toast": { - "success": "已复制GPU信息到剪贴板" + "success": "已复制 GPU 信息到剪贴板" } }, "npuMemory": "NPU内存", - "npuUsage": "NPU使用率", + "npuUsage": "NPU 使用率", "intelGpuWarning": { "title": "Intel GPU 处于警告状态", "message": "GPU 状态不可用", @@ -85,8 +85,15 @@ }, "otherProcesses": { "title": "其他进程", - "processCpuUsage": "主进程CPU使用率", - "processMemoryUsage": "主进程内存使用率" + "processCpuUsage": "主进程 CPU 使用率", + "processMemoryUsage": "主进程内存使用率", + "series": { + "go2rtc": "go2rtc", + "recording": "录制", + "review_segment": "核查片段", + "embeddings": "增强功能", + "audio_detector": "音频检测" + } } }, "storage": { From cd37af43653ba44d3898b7038e92ee38f1346a40 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 13 Jan 2026 21:00:58 +0100 Subject: [PATCH 32/98] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (136 of 136 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (215 of 215 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (43 of 43 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (136 of 136 strings) Co-authored-by: Hosted Weblate Co-authored-by: OverTheHillsAndFarAway Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/nb_NO/ Translation: Frigate NVR/common Translation: Frigate NVR/views-events Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-system --- web/public/locales/nb-NO/common.json | 3 ++- web/public/locales/nb-NO/views/events.json | 6 +++++- web/public/locales/nb-NO/views/explore.json | 5 ++++- web/public/locales/nb-NO/views/system.json | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/public/locales/nb-NO/common.json b/web/public/locales/nb-NO/common.json index a2fbcdf09..f58f12ea4 100644 --- a/web/public/locales/nb-NO/common.json +++ b/web/public/locales/nb-NO/common.json @@ -262,7 +262,8 @@ "show": "Vis {{item}}", "ID": "ID", "none": "Ingen", - "all": "Alle" + "all": "Alle", + "other": "Andre" }, "toast": { "copyUrlToClipboard": "Nettadresse kopiert til utklippstavlen.", diff --git a/web/public/locales/nb-NO/views/events.json b/web/public/locales/nb-NO/views/events.json index 8c54ca7a2..5e77f38ed 100644 --- a/web/public/locales/nb-NO/views/events.json +++ b/web/public/locales/nb-NO/views/events.json @@ -3,7 +3,11 @@ "empty": { "alert": "Det er ingen varsler å inspisere", "detection": "Det er ingen deteksjoner å inspisere", - "motion": "Ingen bevegelsesdata funnet" + "motion": "Ingen bevegelsesdata funnet", + "recordingsDisabled": { + "title": "Opptak må være aktivert", + "description": "Inspeksjonselementer kan kun opprettes for et kamera når opptak er aktivert for det kameraet." + } }, "timeline": "Tidslinje", "events": { diff --git a/web/public/locales/nb-NO/views/explore.json b/web/public/locales/nb-NO/views/explore.json index c0d395603..a9fe5230a 100644 --- a/web/public/locales/nb-NO/views/explore.json +++ b/web/public/locales/nb-NO/views/explore.json @@ -158,7 +158,10 @@ "title": "Rediger attributter", "desc": "Velg klassifiseringsattributter for denne {{label}}" }, - "attributes": "Klassifiseringsattributter" + "attributes": "Klassifiseringsattributter", + "title": { + "label": "Tittel" + } }, "itemMenu": { "viewInHistory": { diff --git a/web/public/locales/nb-NO/views/system.json b/web/public/locales/nb-NO/views/system.json index 8348b8baf..d04cefd93 100644 --- a/web/public/locales/nb-NO/views/system.json +++ b/web/public/locales/nb-NO/views/system.json @@ -84,7 +84,14 @@ "otherProcesses": { "title": "Andre prosesser", "processCpuUsage": "Prosessenes CPU-belastning", - "processMemoryUsage": "Prosessenes minnebruk" + "processMemoryUsage": "Prosessenes minnebruk", + "series": { + "go2rtc": "go2rtc", + "recording": "opptak", + "review_segment": "inspeksjonselementer", + "embeddings": "vektorrepresentasjoner", + "audio_detector": "lyddetektor" + } } }, "storage": { From c222aa0e6522200569b9054a019fe62683e094b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 07:12:48 -0600 Subject: [PATCH 33/98] Bump form-data from 4.0.0 to 4.0.4 in /web (#19242) Bumps [form-data](https://github.com/form-data/form-data) from 4.0.0 to 4.0.4. - [Release notes](https://github.com/form-data/form-data/releases) - [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md) - [Commits](https://github.com/form-data/form-data/compare/v4.0.0...v4.0.4) --- updated-dependencies: - dependency-name: form-data dependency-version: 4.0.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 173 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 6 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 8df3356c5..34a05c201 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -4683,6 +4683,19 @@ "node": ">=8" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5619,6 +5632,20 @@ "csstype": "^3.0.2" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -5679,6 +5706,24 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", @@ -5686,6 +5731,33 @@ "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", @@ -6222,12 +6294,15 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -6307,6 +6382,30 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-nonce": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", @@ -6316,6 +6415,19 @@ "node": ">=6" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -6384,6 +6496,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -6413,10 +6537,38 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -7140,6 +7292,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", From 90d857ad6d1ab2101fcb4f17eb236c5a262d2d9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 07:26:04 -0600 Subject: [PATCH 34/98] Bump vite from 6.2.0 to 6.4.1 in /web (#20593) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.2.0 to 6.4.1. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/create-vite@6.4.1/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 6.4.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 92 ++++++++++++++++++++++++++++++++++++++++--- web/package.json | 2 +- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 34a05c201..0ad2cef41 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -116,7 +116,7 @@ "prettier-plugin-tailwindcss": "^0.6.5", "tailwindcss": "^3.4.9", "typescript": "^5.8.2", - "vite": "^6.2.0", + "vite": "^6.4.1", "vitest": "^3.0.7" } }, @@ -9663,6 +9663,54 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tinypool": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", @@ -10029,15 +10077,18 @@ } }, "node_modules/vite": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", - "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.30.1" + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" @@ -10131,6 +10182,37 @@ "monaco-editor": ">=0.33.0" } }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vitest": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.7.tgz", diff --git a/web/package.json b/web/package.json index 27256bd81..8e764ff3c 100644 --- a/web/package.json +++ b/web/package.json @@ -122,7 +122,7 @@ "prettier-plugin-tailwindcss": "^0.6.5", "tailwindcss": "^3.4.9", "typescript": "^5.8.2", - "vite": "^6.2.0", + "vite": "^6.4.1", "vitest": "^3.0.7" } } From 43c8f68e44a5cbb1cf9c533f28177deb678295b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 07:26:36 -0600 Subject: [PATCH 35/98] Bump qs from 6.14.0 to 6.14.1 in /docs (#21504) Bumps [qs](https://github.com/ljharb/qs) from 6.14.0 to 6.14.1. - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.14.0...v6.14.1) --- updated-dependencies: - dependency-name: qs dependency-version: 6.14.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 4d5954785..be16754be 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -18490,9 +18490,9 @@ } }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" From 2e1706baa0d4132a5b2efc03b6ef4dcabef319e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 07:26:56 -0600 Subject: [PATCH 36/98] Bump @remix-run/router and react-router-dom in /web (#21580) Bumps [@remix-run/router](https://github.com/remix-run/react-router/tree/HEAD/packages/router) to 1.23.2 and updates ancestor dependency [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom). These dependencies need to be updated together. Updates `@remix-run/router` from 1.19.0 to 1.23.2 - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/@remix-run/router@1.23.2/packages/router/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/@remix-run/router@1.23.2/packages/router) Updates `react-router-dom` from 6.26.0 to 6.30.3 - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.30.3/packages/react-router-dom) --- updated-dependencies: - dependency-name: "@remix-run/router" dependency-version: 1.23.2 dependency-type: indirect - dependency-name: react-router-dom dependency-version: 6.30.3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 26 +++++++++++++------------- web/package.json | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 0ad2cef41..2fd083427 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -64,7 +64,7 @@ "react-i18next": "^15.2.0", "react-icons": "^5.5.0", "react-konva": "^18.2.10", - "react-router-dom": "^6.26.0", + "react-router-dom": "^6.30.3", "react-swipeable": "^7.0.2", "react-tracked": "^2.0.1", "react-transition-group": "^4.4.5", @@ -3293,9 +3293,9 @@ "license": "MIT" }, "node_modules/@remix-run/router": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.0.tgz", - "integrity": "sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA==", + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", + "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -8617,12 +8617,12 @@ } }, "node_modules/react-router": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.0.tgz", - "integrity": "sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg==", + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz", + "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.19.0" + "@remix-run/router": "1.23.2" }, "engines": { "node": ">=14.0.0" @@ -8632,13 +8632,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.0.tgz", - "integrity": "sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ==", + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz", + "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.19.0", - "react-router": "6.26.0" + "@remix-run/router": "1.23.2", + "react-router": "6.30.3" }, "engines": { "node": ">=14.0.0" diff --git a/web/package.json b/web/package.json index 8e764ff3c..546c22f31 100644 --- a/web/package.json +++ b/web/package.json @@ -70,7 +70,7 @@ "react-i18next": "^15.2.0", "react-icons": "^5.5.0", "react-konva": "^18.2.10", - "react-router-dom": "^6.26.0", + "react-router-dom": "^6.30.3", "react-swipeable": "^7.0.2", "react-tracked": "^2.0.1", "react-transition-group": "^4.4.5", From bf099c3edd39827c360033d5339d60c13999a4f2 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Thu, 15 Jan 2026 07:08:49 -0700 Subject: [PATCH 37/98] Miscellaneous fixes (0.17 beta) (#21655) * Fix jetson stats reading * Return result * Avoid unknown class for cover image * fix double encoding of passwords in camera wizard * formatting * empty homekit config fixes * add locks to jina v1 embeddings protect tokenizer and feature extractor in jina_v1_embedding with per-instance thread lock to avoid the "Already borrowed" RuntimeError during concurrent tokenization * Capitalize correctly * replace deprecated google-generativeai with google-genai update gemini genai provider with new calls from SDK provider_options specifies any http options suppress unneeded info logging * fix attribute area on detail stream hover --------- Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> --- docker/main/requirements-wheels.txt | 2 +- .../rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run | 6 +-- frigate/api/camera.py | 17 +++---- frigate/embeddings/onnx/jina_v1_embedding.py | 37 ++++++++------ frigate/genai/gemini.py | 49 +++++++++++-------- frigate/log.py | 1 + frigate/util/services.py | 13 +++-- web/src/components/timeline/DetailStream.tsx | 5 +- web/src/utils/cameraUtil.ts | 3 +- .../classification/ModelSelectionView.tsx | 5 +- .../classification/ModelTrainingView.tsx | 3 +- 11 files changed, 83 insertions(+), 58 deletions(-) diff --git a/docker/main/requirements-wheels.txt b/docker/main/requirements-wheels.txt index 30e32ba6a..f81fefea4 100644 --- a/docker/main/requirements-wheels.txt +++ b/docker/main/requirements-wheels.txt @@ -47,7 +47,7 @@ onnxruntime == 1.22.* # Embeddings transformers == 4.45.* # Generative AI -google-generativeai == 0.8.* +google-genai == 1.58.* ollama == 0.6.* openai == 1.65.* # push notifications diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run index 349027bd1..7df29f8f5 100755 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run @@ -69,15 +69,15 @@ function setup_homekit_config() { local cleaned_json="/tmp/cache/homekit_cleaned.json" jq ' # Keep only the homekit section if it exists, otherwise empty object - if has("homekit") then {homekit: .homekit} else {homekit: {}} end + if has("homekit") then {homekit: .homekit} else {} end ' "${temp_json}" > "${cleaned_json}" 2>/dev/null || { - echo '{"homekit": {}}' > "${cleaned_json}" + echo '{}' > "${cleaned_json}" } # Convert back to YAML and write to the config file yq eval -P "${cleaned_json}" > "${config_path}" 2>/dev/null || { echo "[WARNING] Failed to convert cleaned config to YAML, creating minimal config" - echo 'homekit: {}' > "${config_path}" + echo '{}' > "${config_path}" } # Clean up temp files diff --git a/frigate/api/camera.py b/frigate/api/camera.py index 936a0bb09..488ec1e1f 100644 --- a/frigate/api/camera.py +++ b/frigate/api/camera.py @@ -848,9 +848,10 @@ async def onvif_probe( try: if isinstance(uri, str) and uri.startswith("rtsp://"): if username and password and "@" not in uri: - # Inject URL-encoded credentials and add only the - # authenticated version. - cred = f"{quote_plus(username)}:{quote_plus(password)}@" + # Inject raw credentials and add only the + # authenticated version. The credentials will be encoded + # later by ffprobe_stream or the config system. + cred = f"{username}:{password}@" injected = uri.replace( "rtsp://", f"rtsp://{cred}", 1 ) @@ -903,12 +904,8 @@ async def onvif_probe( "/cam/realmonitor?channel=1&subtype=0", "/11", ] - # Use URL-encoded credentials for pattern fallback URIs when provided - auth_str = ( - f"{quote_plus(username)}:{quote_plus(password)}@" - if username and password - else "" - ) + # Use raw credentials for pattern fallback URIs when provided + auth_str = f"{username}:{password}@" if username and password else "" rtsp_port = 554 for path in common_paths: uri = f"rtsp://{auth_str}{host}:{rtsp_port}{path}" @@ -930,7 +927,7 @@ async def onvif_probe( and uri.startswith("rtsp://") and "@" not in uri ): - cred = f"{quote_plus(username)}:{quote_plus(password)}@" + cred = f"{username}:{password}@" cred_uri = uri.replace("rtsp://", f"rtsp://{cred}", 1) if cred_uri not in to_test: to_test.append(cred_uri) diff --git a/frigate/embeddings/onnx/jina_v1_embedding.py b/frigate/embeddings/onnx/jina_v1_embedding.py index 519247f3c..5e3ee7f3b 100644 --- a/frigate/embeddings/onnx/jina_v1_embedding.py +++ b/frigate/embeddings/onnx/jina_v1_embedding.py @@ -2,6 +2,7 @@ import logging import os +import threading import warnings from transformers import AutoFeatureExtractor, AutoTokenizer @@ -54,6 +55,7 @@ class JinaV1TextEmbedding(BaseEmbedding): self.tokenizer = None self.feature_extractor = None self.runner = None + self._lock = threading.Lock() files_names = list(self.download_urls.keys()) + [self.tokenizer_file] if not all( @@ -134,17 +136,18 @@ class JinaV1TextEmbedding(BaseEmbedding): ) def _preprocess_inputs(self, raw_inputs): - max_length = max(len(self.tokenizer.encode(text)) for text in raw_inputs) - return [ - self.tokenizer( - text, - padding="max_length", - truncation=True, - max_length=max_length, - return_tensors="np", - ) - for text in raw_inputs - ] + with self._lock: + max_length = max(len(self.tokenizer.encode(text)) for text in raw_inputs) + return [ + self.tokenizer( + text, + padding="max_length", + truncation=True, + max_length=max_length, + return_tensors="np", + ) + for text in raw_inputs + ] class JinaV1ImageEmbedding(BaseEmbedding): @@ -174,6 +177,7 @@ class JinaV1ImageEmbedding(BaseEmbedding): self.download_path = os.path.join(MODEL_CACHE_DIR, self.model_name) self.feature_extractor = None self.runner: BaseModelRunner | None = None + self._lock = threading.Lock() files_names = list(self.download_urls.keys()) if not all( os.path.exists(os.path.join(self.download_path, n)) for n in files_names @@ -216,8 +220,9 @@ class JinaV1ImageEmbedding(BaseEmbedding): ) def _preprocess_inputs(self, raw_inputs): - processed_images = [self._process_image(img) for img in raw_inputs] - return [ - self.feature_extractor(images=image, return_tensors="np") - for image in processed_images - ] + with self._lock: + processed_images = [self._process_image(img) for img in raw_inputs] + return [ + self.feature_extractor(images=image, return_tensors="np") + for image in processed_images + ] diff --git a/frigate/genai/gemini.py b/frigate/genai/gemini.py index 01e8ef758..36e708594 100644 --- a/frigate/genai/gemini.py +++ b/frigate/genai/gemini.py @@ -3,8 +3,8 @@ import logging from typing import Optional -import google.generativeai as genai -from google.api_core.exceptions import GoogleAPICallError +from google import genai +from google.genai import errors, types from frigate.config import GenAIProviderEnum from frigate.genai import GenAIClient, register_genai_provider @@ -16,44 +16,51 @@ logger = logging.getLogger(__name__) class GeminiClient(GenAIClient): """Generative AI client for Frigate using Gemini.""" - provider: genai.GenerativeModel + provider: genai.Client def _init_provider(self): """Initialize the client.""" - genai.configure(api_key=self.genai_config.api_key) - return genai.GenerativeModel( - self.genai_config.model, **self.genai_config.provider_options + # Merge provider_options into HttpOptions + http_options_dict = { + "api_version": "v1", + "timeout": int(self.timeout * 1000), # requires milliseconds + } + + if isinstance(self.genai_config.provider_options, dict): + http_options_dict.update(self.genai_config.provider_options) + + return genai.Client( + api_key=self.genai_config.api_key, + http_options=types.HttpOptions(**http_options_dict), ) def _send(self, prompt: str, images: list[bytes]) -> Optional[str]: """Submit a request to Gemini.""" - data = [ - { - "mime_type": "image/jpeg", - "data": img, - } - for img in images + contents = [ + types.Part.from_bytes(data=img, mime_type="image/jpeg") for img in images ] + [prompt] try: # Merge runtime_options into generation_config if provided generation_config_dict = {"candidate_count": 1} generation_config_dict.update(self.genai_config.runtime_options) - response = self.provider.generate_content( - data, - generation_config=genai.types.GenerationConfig( - **generation_config_dict - ), - request_options=genai.types.RequestOptions( - timeout=self.timeout, + response = self.provider.models.generate_content( + model=self.genai_config.model, + contents=contents, + config=types.GenerateContentConfig( + **generation_config_dict, ), ) - except GoogleAPICallError as e: + except errors.APIError as e: logger.warning("Gemini returned an error: %s", str(e)) return None + except Exception as e: + logger.warning("An unexpected error occurred with Gemini: %s", str(e)) + return None + try: description = response.text.strip() - except ValueError: + except (ValueError, AttributeError): # No description was generated return None return description diff --git a/frigate/log.py b/frigate/log.py index 717cce19f..5cec0e0d8 100644 --- a/frigate/log.py +++ b/frigate/log.py @@ -89,6 +89,7 @@ def apply_log_levels(default: str, log_levels: dict[str, LogLevel]) -> None: "ws4py": LogLevel.error, "PIL": LogLevel.warning, "numba": LogLevel.warning, + "google_genai.models": LogLevel.warning, **log_levels, } diff --git a/frigate/util/services.py b/frigate/util/services.py index c51fe923a..64d83833d 100644 --- a/frigate/util/services.py +++ b/frigate/util/services.py @@ -540,9 +540,16 @@ def get_jetson_stats() -> Optional[dict[int, dict]]: try: results["mem"] = "-" # no discrete gpu memory - with open("/sys/devices/gpu.0/load", "r") as f: - gpuload = float(f.readline()) / 10 - results["gpu"] = f"{gpuload}%" + if os.path.exists("/sys/devices/gpu.0/load"): + with open("/sys/devices/gpu.0/load", "r") as f: + gpuload = float(f.readline()) / 10 + results["gpu"] = f"{gpuload}%" + elif os.path.exists("/sys/devices/platform/gpu.0/load"): + with open("/sys/devices/platform/gpu.0/load", "r") as f: + gpuload = float(f.readline()) / 10 + results["gpu"] = f"{gpuload}%" + else: + results["gpu"] = "-" except Exception: return None diff --git a/web/src/components/timeline/DetailStream.tsx b/web/src/components/timeline/DetailStream.tsx index ac560a4df..ef9cd6364 100644 --- a/web/src/components/timeline/DetailStream.tsx +++ b/web/src/components/timeline/DetailStream.tsx @@ -887,7 +887,10 @@ function LifecycleItem({ {attributeAreaPx}{" "} - {t("information.pixels", { ns: "common" })}{" "} + {t("information.pixels", { + ns: "common", + area: attributeAreaPx, + })}{" "} ·{" "} {attributeAreaPct}% diff --git a/web/src/utils/cameraUtil.ts b/web/src/utils/cameraUtil.ts index 4802c5e5f..543605ad0 100644 --- a/web/src/utils/cameraUtil.ts +++ b/web/src/utils/cameraUtil.ts @@ -81,7 +81,8 @@ export async function detectReolinkCamera( export function maskUri(uri: string): string { try { // Handle RTSP URLs with user:pass@host format - const rtspMatch = uri.match(/rtsp:\/\/([^:]+):([^@]+)@(.+)/); + // Use greedy match for password to handle passwords with @ + const rtspMatch = uri.match(/rtsp:\/\/([^:]+):(.+)@(.+)/); if (rtspMatch) { return `rtsp://${rtspMatch[1]}:${"*".repeat(4)}@${rtspMatch[3]}`; } diff --git a/web/src/views/classification/ModelSelectionView.tsx b/web/src/views/classification/ModelSelectionView.tsx index 0c1cfa1e6..3cd450bba 100644 --- a/web/src/views/classification/ModelSelectionView.tsx +++ b/web/src/views/classification/ModelSelectionView.tsx @@ -266,7 +266,10 @@ function ModelCard({ config, onClick, onUpdate, onDelete }: ModelCardProps) { return undefined; } - const keys = Object.keys(dataset.categories).filter((key) => key != "none"); + const keys = Object.keys(dataset.categories).filter( + (key) => key != "none" && key.toLowerCase() != "unknown", + ); + if (keys.length === 0) { return undefined; } diff --git a/web/src/views/classification/ModelTrainingView.tsx b/web/src/views/classification/ModelTrainingView.tsx index 10d52075d..81a8d613f 100644 --- a/web/src/views/classification/ModelTrainingView.tsx +++ b/web/src/views/classification/ModelTrainingView.tsx @@ -75,6 +75,7 @@ import SearchDetailDialog, { } from "@/components/overlay/detail/SearchDetailDialog"; import { SearchResult } from "@/types/search"; import { HiSparkles } from "react-icons/hi"; +import { capitalizeFirstLetter } from "@/utils/stringUtil"; type ModelTrainingViewProps = { model: CustomClassificationModelConfig; @@ -88,7 +89,7 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) { // title useEffect(() => { - document.title = `${model.name.toUpperCase()} - ${t("documentTitle")}`; + document.title = `${capitalizeFirstLetter(model.name)} - ${t("documentTitle")}`; }, [model.name, t]); // model state From cfeb86646f9f18d55617de5e2527fb57c29a7f32 Mon Sep 17 00:00:00 2001 From: Kirill Kulakov Date: Fri, 16 Jan 2026 20:23:23 -0600 Subject: [PATCH 38/98] fix(recording): handle unexpected filenames in cache maintainer to prevent crash (#21676) * fix(recording): handle unexpected filenames in cache maintainer to prevent crash * test(recording): add test for maintainer cache file parsing * Prevent log spam from unexpected cache files Addresses PR review feedback: Add deduplication to prevent warning messages from being logged repeatedly for the same unexpected file in the cache directory. Each unexpected filename is only logged once per RecordingMaintainer instance lifecycle. Also adds test to verify warning is only emitted once per filename. * Fix code formatting for test_maintainer.py * fixes + ruff --- frigate/record/maintainer.py | 18 ++++++++- frigate/test/test_maintainer.py | 66 +++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 frigate/test/test_maintainer.py diff --git a/frigate/record/maintainer.py b/frigate/record/maintainer.py index d60d7ccce..25c9d2cff 100644 --- a/frigate/record/maintainer.py +++ b/frigate/record/maintainer.py @@ -97,6 +97,7 @@ class RecordingMaintainer(threading.Thread): self.object_recordings_info: dict[str, list] = defaultdict(list) self.audio_recordings_info: dict[str, list] = defaultdict(list) self.end_time_cache: dict[str, Tuple[datetime.datetime, float]] = {} + self.unexpected_cache_files_logged: bool = False async def move_files(self) -> None: cache_files = [ @@ -112,7 +113,14 @@ class RecordingMaintainer(threading.Thread): for cache in cache_files: cache_path = os.path.join(CACHE_DIR, cache) basename = os.path.splitext(cache)[0] - camera, date = basename.rsplit("@", maxsplit=1) + try: + camera, date = basename.rsplit("@", maxsplit=1) + except ValueError: + if not self.unexpected_cache_files_logged: + logger.warning("Skipping unexpected files in cache") + self.unexpected_cache_files_logged = True + continue + start_time = datetime.datetime.strptime( date, CACHE_SEGMENT_FORMAT ).astimezone(datetime.timezone.utc) @@ -164,7 +172,13 @@ class RecordingMaintainer(threading.Thread): cache_path = os.path.join(CACHE_DIR, cache) basename = os.path.splitext(cache)[0] - camera, date = basename.rsplit("@", maxsplit=1) + try: + camera, date = basename.rsplit("@", maxsplit=1) + except ValueError: + if not self.unexpected_cache_files_logged: + logger.warning("Skipping unexpected files in cache") + self.unexpected_cache_files_logged = True + continue # important that start_time is utc because recordings are stored and compared in utc start_time = datetime.datetime.strptime( diff --git a/frigate/test/test_maintainer.py b/frigate/test/test_maintainer.py new file mode 100644 index 000000000..d978cfd9f --- /dev/null +++ b/frigate/test/test_maintainer.py @@ -0,0 +1,66 @@ +import sys +import unittest +from unittest.mock import MagicMock, patch + +# Mock complex imports before importing maintainer +sys.modules["frigate.comms.inter_process"] = MagicMock() +sys.modules["frigate.comms.detections_updater"] = MagicMock() +sys.modules["frigate.comms.recordings_updater"] = MagicMock() +sys.modules["frigate.config.camera.updater"] = MagicMock() + +# Now import the class under test +from frigate.config import FrigateConfig # noqa: E402 +from frigate.record.maintainer import RecordingMaintainer # noqa: E402 + + +class TestMaintainer(unittest.IsolatedAsyncioTestCase): + async def test_move_files_survives_bad_filename(self): + config = MagicMock(spec=FrigateConfig) + config.cameras = {} + stop_event = MagicMock() + + maintainer = RecordingMaintainer(config, stop_event) + + # We need to mock end_time_cache to avoid key errors if logic proceeds + maintainer.end_time_cache = {} + + # Mock filesystem + # One bad file, one good file + files = ["bad_filename.mp4", "camera@20210101000000+0000.mp4"] + + with patch("os.listdir", return_value=files): + with patch("os.path.isfile", return_value=True): + with patch( + "frigate.record.maintainer.psutil.process_iter", return_value=[] + ): + with patch("frigate.record.maintainer.logger.warning") as warn: + # Mock validate_and_move_segment to avoid further logic + maintainer.validate_and_move_segment = MagicMock() + + try: + await maintainer.move_files() + except ValueError as e: + if "not enough values to unpack" in str(e): + self.fail("move_files() crashed on bad filename!") + raise e + except Exception: + # Ignore other errors (like DB connection) as we only care about the unpack crash + pass + + # The bad filename is encountered in multiple loops, but should only warn once. + matching = [ + c + for c in warn.call_args_list + if c.args + and isinstance(c.args[0], str) + and "Skipping unexpected files in cache" in c.args[0] + ] + self.assertEqual( + 1, + len(matching), + f"Expected a single warning for unexpected files, got {len(matching)}", + ) + + +if __name__ == "__main__": + unittest.main() From 0a8f499640c753cf4b8f66b3821519764a8183d4 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sun, 18 Jan 2026 07:36:27 -0600 Subject: [PATCH 39/98] Miscellaneous fixes (0.17 beta) (#21683) * misc triggers tweaks i18n fixes fix toaster color fix clicking on labels selecting incorrect checkbox * update copilot instructions * lpr docs tweaks * add retry params to gemini * i18n fix * ensure users only see recognized plates from accessible cameras in explore * ensure all zone filters are converted to pixels zone-level filters were never converted from percentage area to pixels. RuntimeFilterConfig was only applied to filters at the camera level, not zone.filters. Fixes https://github.com/blakeblackshear/frigate/discussions/21694 * add test for percentage based zone filters * use export id for key instead of name * update gemini docs --- .github/copilot-instructions.md | 5 ++- docs/docs/configuration/genai.md | 6 +-- .../license_plate_recognition.md | 6 +-- frigate/api/app.py | 17 ++++++-- frigate/config/config.py | 7 +++ frigate/genai/gemini.py | 8 ++++ frigate/test/test_config.py | 43 +++++++++++++++++++ web/public/locales/en/common.json | 1 + .../overlay/CreateTriggerDialog.tsx | 13 +++--- .../wizard/Step3ThresholdAndActions.tsx | 15 ++++--- web/src/pages/Exports.tsx | 2 +- web/src/views/settings/TriggerView.tsx | 11 +++-- 12 files changed, 105 insertions(+), 29 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6c14bb166..89acd8a9b 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,2 +1,3 @@ -Never write strings in the frontend directly, always write to and reference the relevant translations file. -Always conform new and refactored code to the existing coding style in the project. +- For Frigate NVR, never write strings in the frontend directly. Since the project uses `react-i18next`, use `t()` and write the English string in the relevant translations file in `web/public/locales/en`. +- Always conform new and refactored code to the existing coding style in the project. +- Always have a way to test your work and confirm your changes. When running backend tests, use `python3 -u -m unittest`. diff --git a/docs/docs/configuration/genai.md b/docs/docs/configuration/genai.md index 875608766..292bf437a 100644 --- a/docs/docs/configuration/genai.md +++ b/docs/docs/configuration/genai.md @@ -66,8 +66,6 @@ Some models are labeled as **hybrid** (capable of both thinking and instruct tas **Recommendation:** Always select the `-instruct` or documented instruct/tagged variant of any model you use in your Frigate configuration. If in doubt, refer to your model provider’s documentation or model library for guidance on the correct model variant to use. - - ### Supported Models You must use a vision capable model with Frigate. Current model variants can be found [in their model library](https://ollama.com/search?c=vision). Note that Frigate will not automatically download the model you specify in your config, you must download the model to your local instance of Ollama first i.e. by running `ollama pull qwen3-vl:2b-instruct` on your Ollama server/Docker container. Note that the model specified in Frigate's config must match the downloaded model tag. @@ -93,7 +91,7 @@ genai: ## Google Gemini -Google Gemini has a free tier allowing [15 queries per minute](https://ai.google.dev/pricing) to the API, which is more than sufficient for standard Frigate usage. +Google Gemini has a [free tier](https://ai.google.dev/pricing) for the API, however the limits may not be sufficient for standard Frigate usage. Choose a plan appropriate for your installation. ### Supported Models @@ -114,7 +112,7 @@ To start using Gemini, you must first get an API key from [Google AI Studio](htt genai: provider: gemini api_key: "{FRIGATE_GEMINI_API_KEY}" - model: gemini-2.0-flash + model: gemini-2.5-flash ``` :::note diff --git a/docs/docs/configuration/license_plate_recognition.md b/docs/docs/configuration/license_plate_recognition.md index a18c822f5..5f70dd9a0 100644 --- a/docs/docs/configuration/license_plate_recognition.md +++ b/docs/docs/configuration/license_plate_recognition.md @@ -68,8 +68,8 @@ Fine-tune the LPR feature using these optional parameters at the global level of - Default: `1000` pixels. Note: this is intentionally set very low as it is an _area_ measurement (length x width). For reference, 1000 pixels represents a ~32x32 pixel square in your camera image. - Depending on the resolution of your camera's `detect` stream, you can increase this value to ignore small or distant plates. - **`device`**: Device to use to run license plate detection _and_ recognition models. - - Default: `CPU` - - This can be `CPU`, `GPU`, or the GPU's device number. For users without a model that detects license plates natively, using a GPU may increase performance of the YOLOv9 license plate detector model. See the [Hardware Accelerated Enrichments](/configuration/hardware_acceleration_enrichments.md) documentation. However, for users who run a model that detects `license_plate` natively, there is little to no performance gain reported with running LPR on GPU compared to the CPU. + - Default: `None` + - This is auto-selected by Frigate and can be `CPU`, `GPU`, or the GPU's device number. For users without a model that detects license plates natively, using a GPU may increase performance of the YOLOv9 license plate detector model. See the [Hardware Accelerated Enrichments](/configuration/hardware_acceleration_enrichments.md) documentation. However, for users who run a model that detects `license_plate` natively, there is little to no performance gain reported with running LPR on GPU compared to the CPU. - **`model_size`**: The size of the model used to identify regions of text on plates. - Default: `small` - This can be `small` or `large`. @@ -432,6 +432,6 @@ If you are using a model that natively detects `license_plate`, add an _object m If you are not using a model that natively detects `license_plate` or you are using dedicated LPR camera mode, only a _motion mask_ over your text is required. -### I see "Error running ... model" in my logs. How can I fix this? +### I see "Error running ... model" in my logs, or my inference time is very high. How can I fix this? This usually happens when your GPU is unable to compile or use one of the LPR models. Set your `device` to `CPU` and try again. GPU acceleration only provides a slight performance increase, and the models are lightweight enough to run without issue on most CPUs. diff --git a/frigate/api/app.py b/frigate/api/app.py index c87e929a6..440adfce4 100644 --- a/frigate/api/app.py +++ b/frigate/api/app.py @@ -23,7 +23,12 @@ from markupsafe import escape from peewee import SQL, fn, operator from pydantic import ValidationError -from frigate.api.auth import allow_any_authenticated, allow_public, require_role +from frigate.api.auth import ( + allow_any_authenticated, + allow_public, + get_allowed_cameras_for_filter, + require_role, +) from frigate.api.defs.query.app_query_parameters import AppTimelineHourlyQueryParameters from frigate.api.defs.request.app_body import AppConfigSetBody from frigate.api.defs.tags import Tags @@ -687,13 +692,19 @@ def plusModels(request: Request, filterByCurrentModelDetector: bool = False): @router.get( "/recognized_license_plates", dependencies=[Depends(allow_any_authenticated())] ) -def get_recognized_license_plates(split_joined: Optional[int] = None): +def get_recognized_license_plates( + split_joined: Optional[int] = None, + allowed_cameras: List[str] = Depends(get_allowed_cameras_for_filter), +): try: query = ( Event.select( SQL("json_extract(data, '$.recognized_license_plate') AS plate") ) - .where(SQL("json_extract(data, '$.recognized_license_plate') IS NOT NULL")) + .where( + (SQL("json_extract(data, '$.recognized_license_plate') IS NOT NULL")) + & (Event.camera << allowed_cameras) + ) .distinct() ) recognized_license_plates = [row[0] for row in query.tuples()] diff --git a/frigate/config/config.py b/frigate/config/config.py index a9c54976e..a26d4c50e 100644 --- a/frigate/config/config.py +++ b/frigate/config/config.py @@ -662,6 +662,13 @@ class FrigateConfig(FrigateBaseModel): # generate zone contours if len(camera_config.zones) > 0: for zone in camera_config.zones.values(): + if zone.filters: + for object_name, filter_config in zone.filters.items(): + zone.filters[object_name] = RuntimeFilterConfig( + frame_shape=camera_config.frame_shape, + **filter_config.model_dump(exclude_unset=True), + ) + zone.generate_contour(camera_config.frame_shape) # Set live view stream if none is set diff --git a/frigate/genai/gemini.py b/frigate/genai/gemini.py index 36e708594..83bd3340d 100644 --- a/frigate/genai/gemini.py +++ b/frigate/genai/gemini.py @@ -24,6 +24,14 @@ class GeminiClient(GenAIClient): http_options_dict = { "api_version": "v1", "timeout": int(self.timeout * 1000), # requires milliseconds + "retry_options": types.HttpRetryOptions( + attempts=3, + initial_delay=1.0, + max_delay=60.0, + exp_base=2.0, + jitter=1.0, + http_status_codes=[429, 500, 502, 503, 504], + ), } if isinstance(self.genai_config.provider_options, dict): diff --git a/frigate/test/test_config.py b/frigate/test/test_config.py index 4bafe7369..afe577f2f 100644 --- a/frigate/test/test_config.py +++ b/frigate/test/test_config.py @@ -632,6 +632,49 @@ class TestConfig(unittest.TestCase): ) assert frigate_config.cameras["back"].zones["test"].color != (0, 0, 0) + def test_zone_filter_area_percent_converts_to_pixels(self): + config = { + "mqtt": {"host": "mqtt"}, + "record": { + "alerts": { + "retain": { + "days": 20, + } + } + }, + "cameras": { + "back": { + "ffmpeg": { + "inputs": [ + {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]} + ] + }, + "detect": { + "height": 1080, + "width": 1920, + "fps": 5, + }, + "zones": { + "notification": { + "coordinates": "0.03,1,0.025,0,0.626,0,0.643,1", + "objects": ["person"], + "filters": {"person": {"min_area": 0.1}}, + } + }, + } + }, + } + + frigate_config = FrigateConfig(**config) + expected_min_area = int(1080 * 1920 * 0.1) + assert ( + frigate_config.cameras["back"] + .zones["notification"] + .filters["person"] + .min_area + == expected_min_area + ) + def test_zone_relative_matches_explicit(self): config = { "mqtt": {"host": "mqtt"}, diff --git a/web/public/locales/en/common.json b/web/public/locales/en/common.json index 2ae6297a1..8bf13ca61 100644 --- a/web/public/locales/en/common.json +++ b/web/public/locales/en/common.json @@ -3,6 +3,7 @@ "untilForTime": "Until {{time}}", "untilForRestart": "Until Frigate restarts.", "untilRestart": "Until restart", + "never": "Never", "ago": "{{timeAgo}} ago", "justNow": "Just now", "today": "Today", diff --git a/web/src/components/overlay/CreateTriggerDialog.tsx b/web/src/components/overlay/CreateTriggerDialog.tsx index 11734acaf..ef30c649d 100644 --- a/web/src/components/overlay/CreateTriggerDialog.tsx +++ b/web/src/components/overlay/CreateTriggerDialog.tsx @@ -268,7 +268,7 @@ export default function CreateTriggerDialog({
    - {t("enabled", { ns: "common" })} + {t("button.enabled", { ns: "common" })}
    {t("triggers.dialog.form.enabled.description")} @@ -394,7 +394,10 @@ export default function CreateTriggerDialog({
    {availableActions.map((action) => ( -
    +
    + + ))}
    diff --git a/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx b/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx index 33568dca7..2b560ded3 100644 --- a/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx +++ b/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx @@ -142,7 +142,10 @@ export default function Step3ThresholdAndActions({ {t("triggers.dialog.form.actions.title")}
    {availableActions.map((action) => ( -
    +
    + + ))}
    @@ -197,9 +200,7 @@ export default function Step3ThresholdAndActions({ {isLoading && } {isLoading ? t("button.saving", { ns: "common" }) - : t("triggers.dialog.form.save", { - defaultValue: "Save Trigger", - })} + : t("button.save", { ns: "common" })}
    diff --git a/web/src/pages/Exports.tsx b/web/src/pages/Exports.tsx index 69e9dc0e7..26a75801a 100644 --- a/web/src/pages/Exports.tsx +++ b/web/src/pages/Exports.tsx @@ -206,7 +206,7 @@ function Exports() { > {Object.values(exports).map((item) => ( {trigger_status?.triggers[trigger.name] ?.triggering_event_id && ( @@ -663,7 +664,9 @@ export default function TriggerView({ - {t("name", { ns: "common" })} + + {t("name", { ns: "triggers.table.name" })} + {t("triggers.table.type")} {t("triggers.table.lastTriggered")} @@ -759,7 +762,7 @@ export default function TriggerView({ date_style: "medium", }, ) - : "Never"} + : t("time.never", { ns: "common" })} {trigger_status?.triggers[trigger.name] ?.triggering_event_id && ( From d633c7d966d93923e6f0050c252579301d7c0019 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 20 Jan 2026 09:17:58 -0600 Subject: [PATCH 40/98] Miscellaneous fixes (0.17 beta) (#21699) * tracking details tweaks - fix 4:3 layout - get and use aspect of record stream if different from detect stream * aspect ratio docs tip * spacing * fix * i18n fix * additional logs on ffmpeg exit * improve no camera view instead of showing an "add camera" message, show a specific message for empty camera groups when frigate already has cameras added * add note about separate onvif accounts in some camera firmware * clarify review summary report docs * review settings tweaks - remove horizontal divider - update description language for switches - keep save button disabled until review classification settings change * use correct Toaster component from shadcn * clarify support for intel b-series (battlemage) gpus * add clarifying comment to dummy camera docs --- docs/docs/configuration/cameras.md | 8 ++++- .../configuration/genai/review_summaries.md | 4 +-- docs/docs/frigate/camera_setup.md | 6 ++++ docs/docs/frigate/hardware.md | 9 ++--- docs/docs/troubleshooting/dummy-camera.md | 2 +- frigate/video.py | 2 ++ web/public/locales/en/views/live.json | 10 ++++++ web/public/locales/en/views/settings.json | 4 +-- web/src/components/card/EmptyCard.tsx | 4 ++- .../overlay/detail/TrackingDetails.tsx | 19 ++++++++--- .../components/settings/CameraEditForm.tsx | 3 +- web/src/types/record.ts | 1 + web/src/views/live/LiveDashboardView.tsx | 33 ++++++++++++------- .../views/settings/CameraManagementView.tsx | 2 +- .../settings/CameraReviewSettingsView.tsx | 23 ++++++++++--- .../settings/FrigatePlusSettingsView.tsx | 2 +- web/src/views/settings/TriggerView.tsx | 4 +-- web/src/views/settings/UiSettingsView.tsx | 2 +- 18 files changed, 97 insertions(+), 41 deletions(-) diff --git a/docs/docs/configuration/cameras.md b/docs/docs/configuration/cameras.md index 5fafdabf4..47efa5bba 100644 --- a/docs/docs/configuration/cameras.md +++ b/docs/docs/configuration/cameras.md @@ -79,6 +79,12 @@ cameras: If the ONVIF connection is successful, PTZ controls will be available in the camera's WebUI. +:::note + +Some cameras use a separate ONVIF/service account that is distinct from the device administrator credentials. If ONVIF authentication fails with the admin account, try creating or using an ONVIF/service user in the camera's firmware. Refer to your camera manufacturer's documentation for more. + +::: + :::tip If your ONVIF camera does not require authentication credentials, you may still need to specify an empty string for `user` and `password`, eg: `user: ""` and `password: ""`. @@ -95,7 +101,7 @@ The FeatureList on the [ONVIF Conformant Products Database](https://www.onvif.or | Brand or specific camera | PTZ Controls | Autotracking | Notes | | ---------------------------- | :----------: | :----------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Amcrest | ✅ | ✅ | ⛔️ Generally, Amcrest should work, but some older models (like the common IP2M-841) don't support autotracking | +| Amcrest | ✅ | ✅ | ⛔️ Generally, Amcrest should work, but some older models (like the common IP2M-841) don't support autotracking | | Amcrest ASH21 | ✅ | ❌ | ONVIF service port: 80 | | Amcrest IP4M-S2112EW-AI | ✅ | ❌ | FOV relative movement not supported. | | Amcrest IP5M-1190EW | ✅ | ❌ | ONVIF Port: 80. FOV relative movement not supported. | diff --git a/docs/docs/configuration/genai/review_summaries.md b/docs/docs/configuration/genai/review_summaries.md index 9851ec2f6..df287446c 100644 --- a/docs/docs/configuration/genai/review_summaries.md +++ b/docs/docs/configuration/genai/review_summaries.md @@ -125,10 +125,10 @@ review: ## Review Reports -Along with individual review item summaries, Generative AI provides the ability to request a report of a given time period. For example, you can get a daily report while on a vacation of any suspicious activity or other concerns that may require review. +Along with individual review item summaries, Generative AI can also produce a single report of review items from all cameras marked "suspicious" over a specified time period (for example, a daily summary of suspicious activity while you're on vacation). ### Requesting Reports Programmatically -Review reports can be requested via the [API](/integrations/api#review-summarization) by sending a POST request to `/api/review/summarize/start/{start_ts}/end/{end_ts}` with Unix timestamps. +Review reports can be requested via the [API](/integrations/api/generate-review-summary-review-summarize-start-start-ts-end-end-ts-post) by sending a POST request to `/api/review/summarize/start/{start_ts}/end/{end_ts}` with Unix timestamps. For Home Assistant users, there is a built-in service (`frigate.review_summarize`) that makes it easy to request review reports as part of automations or scripts. This allows you to automatically generate daily summaries, vacation reports, or custom time period reports based on your specific needs. diff --git a/docs/docs/frigate/camera_setup.md b/docs/docs/frigate/camera_setup.md index 06d7d3b4a..64c650c13 100644 --- a/docs/docs/frigate/camera_setup.md +++ b/docs/docs/frigate/camera_setup.md @@ -11,6 +11,12 @@ Cameras configured to output H.264 video and AAC audio will offer the most compa - **Stream Viewing**: This stream will be rebroadcast as is to Home Assistant for viewing with the stream component. Setting this resolution too high will use significant bandwidth when viewing streams in Home Assistant, and they may not load reliably over slower connections. +:::tip + +For the best experience in Frigate's UI, configure your camera so that the detection and recording streams use the same aspect ratio. For example, if your main stream is 3840x2160 (16:9), set your substream to 640x360 (also 16:9) instead of 640x480 (4:3). While not strictly required, matching aspect ratios helps ensure seamless live stream display and preview/recordings playback. + +::: + ### Choosing a detect resolution The ideal resolution for detection is one where the objects you want to detect fit inside the dimensions of the model used by Frigate (320x320). Frigate does not pass the entire camera frame to object detection. It will crop an area of motion from the full frame and look in that portion of the frame. If the area being inspected is larger than 320x320, Frigate must resize it before running object detection. Higher resolutions do not improve the detection accuracy because the additional detail is lost in the resize. Below you can see a reference for how large a 320x320 area is against common resolutions. diff --git a/docs/docs/frigate/hardware.md b/docs/docs/frigate/hardware.md index 4aa79ee21..f7294042a 100644 --- a/docs/docs/frigate/hardware.md +++ b/docs/docs/frigate/hardware.md @@ -42,7 +42,7 @@ If the EQ13 is out of stock, the link below may take you to a suggested alternat | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------- | | Beelink EQ13 (Amazon) | Can run object detection on several 1080p cameras with low-medium activity | Dual gigabit NICs for easy isolated camera network. | | Intel 1120p ([Amazon](https://www.amazon.com/Beelink-i3-1220P-Computer-Display-Gigabit/dp/B0DDCKT9YP) | Can handle a large number of 1080p cameras with high activity | | -| Intel 125H ([Amazon](https://www.amazon.com/MINISFORUM-Pro-125H-Barebone-Computer-HDMI2-1/dp/B0FH21FSZM) | Can handle a significant number of 1080p cameras with high activity | Includes NPU for more efficient detection in 0.17+ | +| Intel 125H ([Amazon](https://www.amazon.com/MINISFORUM-Pro-125H-Barebone-Computer-HDMI2-1/dp/B0FH21FSZM) | Can handle a significant number of 1080p cameras with high activity | Includes NPU for more efficient detection in 0.17+ | ## Detectors @@ -55,12 +55,10 @@ Frigate supports multiple different detectors that work on different types of ha **Most Hardware** - [Hailo](#hailo-8): The Hailo8 and Hailo8L AI Acceleration module is available in m.2 format with a HAT for RPi devices offering a wide range of compatibility with devices. - - [Supports many model architectures](../../configuration/object_detectors#configuration) - Runs best with tiny or small size models - [Google Coral EdgeTPU](#google-coral-tpu): The Google Coral EdgeTPU is available in USB and m.2 format allowing for a wide range of compatibility with devices. - - [Supports primarily ssdlite and mobilenet model architectures](../../configuration/object_detectors#edge-tpu-detector) - [MemryX](#memryx-mx3): The MX3 M.2 accelerator module is available in m.2 format allowing for a wide range of compatibility with devices. @@ -89,7 +87,6 @@ Frigate supports multiple different detectors that work on different types of ha **Nvidia** - [TensortRT](#tensorrt---nvidia-gpu): TensorRT can run on Nvidia GPUs to provide efficient object detection. - - [Supports majority of model architectures via ONNX](../../configuration/object_detectors#onnx-supported-models) - Runs well with any size models including large @@ -152,9 +149,7 @@ The OpenVINO detector type is able to run on: :::note -Intel NPUs have seen [limited success in community deployments](https://github.com/blakeblackshear/frigate/discussions/13248#discussioncomment-12347357), although they remain officially unsupported. - -In testing, the NPU delivered performance that was only comparable to — or in some cases worse than — the integrated GPU. +Intel B-series (Battlemage) GPUs are not officially supported with Frigate 0.17, though a user has [provided steps to rebuild the Frigate container](https://github.com/blakeblackshear/frigate/discussions/21257) with support for them. ::: diff --git a/docs/docs/troubleshooting/dummy-camera.md b/docs/docs/troubleshooting/dummy-camera.md index c510f2ba8..89495844d 100644 --- a/docs/docs/troubleshooting/dummy-camera.md +++ b/docs/docs/troubleshooting/dummy-camera.md @@ -37,7 +37,7 @@ cameras: ## Steps -1. Export or copy the clip you want to replay to the Frigate host (e.g., `/media/frigate/` or `debug/clips/`). +1. Export or copy the clip you want to replay to the Frigate host (e.g., `/media/frigate/` or `debug/clips/`). Depending on what you are looking to debug, it is often helpful to add some "pre-capture" time (where the tracked object is not yet visible) to the clip when exporting. 2. Add the temporary camera to `config/config.yml` (example above). Use a unique name such as `test` or `replay_camera` so it's easy to remove later. - If you're debugging a specific camera, copy the settings from that camera (frame rate, model/enrichment settings, zones, etc.) into the temporary camera so the replay closely matches the original environment. Leave `record` and `snapshots` disabled unless you are specifically debugging recording or snapshot behavior. 3. Restart Frigate. diff --git a/frigate/video.py b/frigate/video.py index a139c25f1..615c61d61 100755 --- a/frigate/video.py +++ b/frigate/video.py @@ -64,10 +64,12 @@ def stop_ffmpeg(ffmpeg_process: sp.Popen[Any], logger: logging.Logger): try: logger.info("Waiting for ffmpeg to exit gracefully...") ffmpeg_process.communicate(timeout=30) + logger.info("FFmpeg has exited") except sp.TimeoutExpired: logger.info("FFmpeg didn't exit. Force killing...") ffmpeg_process.kill() ffmpeg_process.communicate() + logger.info("FFmpeg has been killed") ffmpeg_process = None diff --git a/web/public/locales/en/views/live.json b/web/public/locales/en/views/live.json index 21f367ea9..c2efef84f 100644 --- a/web/public/locales/en/views/live.json +++ b/web/public/locales/en/views/live.json @@ -181,6 +181,16 @@ "restricted": { "title": "No Cameras Available", "description": "You don't have permission to view any cameras in this group." + }, + "default": { + "title": "No Cameras Configured", + "description": "Get started by connecting a camera to Frigate.", + "buttonText": "Add Camera" + }, + "group": { + "title": "No Cameras in Group", + "description": "This camera group has no assigned or enabled cameras.", + "buttonText": "Manage Groups" } } } diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index 1946a1c62..9f211a442 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -386,11 +386,11 @@ "title": "Camera Review Settings", "object_descriptions": { "title": "Generative AI Object Descriptions", - "desc": "Temporarily enable/disable Generative AI object descriptions for this camera. When disabled, AI generated descriptions will not be requested for tracked objects on this camera." + "desc": "Temporarily enable/disable Generative AI object descriptions for this camera until Frigate restarts. When disabled, AI generated descriptions will not be requested for tracked objects on this camera." }, "review_descriptions": { "title": "Generative AI Review Descriptions", - "desc": "Temporarily enable/disable Generative AI review descriptions for this camera. When disabled, AI generated descriptions will not be requested for review items on this camera." + "desc": "Temporarily enable/disable Generative AI review descriptions for this camera until Frigate restarts. When disabled, AI generated descriptions will not be requested for review items on this camera." }, "review": { "title": "Review", diff --git a/web/src/components/card/EmptyCard.tsx b/web/src/components/card/EmptyCard.tsx index 00b22d197..b9943b31a 100644 --- a/web/src/components/card/EmptyCard.tsx +++ b/web/src/components/card/EmptyCard.tsx @@ -35,7 +35,9 @@ export function EmptyCard({ {icon} {TitleComponent} {description && ( -
    {description}
    +
    + {description} +
    )} {buttonText?.length && ( - - {t("markAsReviewed")} - - )} + + + + + {t("markAsReviewed")} + {previews != undefined && alertVideosLoaded && (
    Date: Wed, 28 Jan 2026 06:56:15 -0600 Subject: [PATCH 44/98] Port go2rtc check (#21808) * version update * Restrict go2rtc exec sources by default (#21543) * Restrict go2rtc exec sources by default * add docs * check for addon value too --------- Co-authored-by: Nicolas Mowen --- Makefile | 2 +- .../rootfs/usr/local/go2rtc/create_config.py | 58 +++++++++++++++++-- docs/docs/configuration/restream.md | 25 ++++++++ 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 04eee68d5..50e383714 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ default_target: local COMMIT_HASH := $(shell git log -1 --pretty=format:"%h"|tail -1) -VERSION = 0.16.3 +VERSION = 0.16.4 IMAGE_REPO ?= ghcr.io/blakeblackshear/frigate GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) BOARDS= #Initialized empty diff --git a/docker/main/rootfs/usr/local/go2rtc/create_config.py b/docker/main/rootfs/usr/local/go2rtc/create_config.py index 1b44a8067..948387719 100644 --- a/docker/main/rootfs/usr/local/go2rtc/create_config.py +++ b/docker/main/rootfs/usr/local/go2rtc/create_config.py @@ -22,6 +22,22 @@ sys.path.remove("/opt/frigate") yaml = YAML() +# Check if arbitrary exec sources are allowed (defaults to False for security) +ALLOW_ARBITRARY_EXEC = os.environ.get( + "GO2RTC_ALLOW_ARBITRARY_EXEC", "false" +).lower() in ("true", "1", "yes") + +# check for the add-on options file +if not ALLOW_ARBITRARY_EXEC and os.path.isfile("/data/options.json"): + with open("/data/options.json") as f: + raw_options = f.read() + options = json.loads(raw_options) + addon_value = options.get("go2rtc_allow_arbitrary_exec", False) + if isinstance(addon_value, bool): + ALLOW_ARBITRARY_EXEC = addon_value + elif isinstance(addon_value, str): + ALLOW_ARBITRARY_EXEC = addon_value.lower() in ("true", "1", "yes") + FRIGATE_ENV_VARS = {k: v for k, v in os.environ.items() if k.startswith("FRIGATE_")} # read docker secret files as env vars too if os.path.isdir("/run/secrets"): @@ -109,14 +125,26 @@ if LIBAVFORMAT_VERSION_MAJOR < 59: elif go2rtc_config["ffmpeg"].get("rtsp") is None: go2rtc_config["ffmpeg"]["rtsp"] = rtsp_args -for name in go2rtc_config.get("streams", {}): + +def is_restricted_source(stream_source: str) -> bool: + """Check if a stream source is restricted (echo, expr, or exec).""" + return stream_source.strip().startswith(("echo:", "expr:", "exec:")) + + +for name in list(go2rtc_config.get("streams", {})): stream = go2rtc_config["streams"][name] if isinstance(stream, str): try: - go2rtc_config["streams"][name] = go2rtc_config["streams"][name].format( - **FRIGATE_ENV_VARS - ) + formatted_stream = stream.format(**FRIGATE_ENV_VARS) + if not ALLOW_ARBITRARY_EXEC and is_restricted_source(formatted_stream): + print( + f"[ERROR] Stream '{name}' uses a restricted source (echo/expr/exec) which is disabled by default for security. " + f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources." + ) + del go2rtc_config["streams"][name] + continue + go2rtc_config["streams"][name] = formatted_stream except KeyError as e: print( "[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info." @@ -124,15 +152,33 @@ for name in go2rtc_config.get("streams", {}): sys.exit(e) elif isinstance(stream, list): - for i, stream in enumerate(stream): + filtered_streams = [] + for i, stream_item in enumerate(stream): try: - go2rtc_config["streams"][name][i] = stream.format(**FRIGATE_ENV_VARS) + formatted_stream = stream_item.format(**FRIGATE_ENV_VARS) + if not ALLOW_ARBITRARY_EXEC and is_restricted_source(formatted_stream): + print( + f"[ERROR] Stream '{name}' item {i + 1} uses a restricted source (echo/expr/exec) which is disabled by default for security. " + f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources." + ) + continue + + filtered_streams.append(formatted_stream) except KeyError as e: print( "[ERROR] Invalid substitution found, see https://docs.frigate.video/configuration/restream#advanced-restream-configurations for more info." ) sys.exit(e) + if filtered_streams: + go2rtc_config["streams"][name] = filtered_streams + else: + print( + f"[ERROR] Stream '{name}' was removed because all sources were restricted (echo/expr/exec). " + f"Set GO2RTC_ALLOW_ARBITRARY_EXEC=true to enable arbitrary exec sources." + ) + del go2rtc_config["streams"][name] + # add birdseye restream stream if enabled if config.get("birdseye", {}).get("restream", False): birdseye: dict[str, Any] = config.get("birdseye") diff --git a/docs/docs/configuration/restream.md b/docs/docs/configuration/restream.md index 4564595cc..3e57c5a98 100644 --- a/docs/docs/configuration/restream.md +++ b/docs/docs/configuration/restream.md @@ -154,10 +154,35 @@ go2rtc: See [this comment](https://github.com/AlexxIT/go2rtc/issues/1217#issuecomment-2242296489) for more information. +## Security: Restricted Stream Sources + +For security reasons, the `echo:`, `expr:`, and `exec:` stream sources are disabled by default in go2rtc. These sources allow arbitrary command execution and can pose security risks if misconfigured. + +If you attempt to use these sources in your configuration, the streams will be removed and an error message will be printed in the logs. + +To enable these sources, you must set the environment variable `GO2RTC_ALLOW_ARBITRARY_EXEC=true`. This can be done in your Docker Compose file or container environment: + +```yaml +environment: + - GO2RTC_ALLOW_ARBITRARY_EXEC=true +``` + +:::warning + +Enabling arbitrary exec sources allows execution of arbitrary commands through go2rtc stream configurations. Only enable this if you understand the security implications and trust all sources of your configuration. + +::: + ## Advanced Restream Configurations The [exec](https://github.com/AlexxIT/go2rtc/tree/v1.9.9#source-exec) source in go2rtc can be used for custom ffmpeg commands. An example is below: +:::warning + +The `exec:`, `echo:`, and `expr:` sources are disabled by default for security. You must set `GO2RTC_ALLOW_ARBITRARY_EXEC=true` to use them. See [Security: Restricted Stream Sources](#security-restricted-stream-sources) for more information. + +::: + NOTE: The output will need to be passed with two curly braces `{{output}}` ```yaml From 338d85a9a27d1140d92d2ced79bf67b0c4d11022 Mon Sep 17 00:00:00 2001 From: Marijn0 <168113859+Marijn0@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:55:38 +0100 Subject: [PATCH 45/98] Fix i18n keys (#21814) --- web/src/components/settings/wizard/OnvifProbeResults.tsx | 6 +++--- web/src/views/classification/ModelTrainingView.tsx | 2 +- web/src/views/settings/TriggerView.tsx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/src/components/settings/wizard/OnvifProbeResults.tsx b/web/src/components/settings/wizard/OnvifProbeResults.tsx index 9e997dfec..c4f02dd08 100644 --- a/web/src/components/settings/wizard/OnvifProbeResults.tsx +++ b/web/src/components/settings/wizard/OnvifProbeResults.tsx @@ -168,8 +168,8 @@ export default function OnvifProbeResults({ {" "} {probeResult.ptz_supported - ? t("yes", { ns: "common" }) - : t("no", { ns: "common" })} + ? t("button.yes", { ns: "common" }) + : t("button.no", { ns: "common" })}
    )} @@ -179,7 +179,7 @@ export default function OnvifProbeResults({ {t("cameraWizard.step2.autotrackingSupport")}: {" "} - {t("yes", { ns: "common" })} + {t("button.yes", { ns: "common" })}
    )} diff --git a/web/src/views/classification/ModelTrainingView.tsx b/web/src/views/classification/ModelTrainingView.tsx index 81a8d613f..00e811d09 100644 --- a/web/src/views/classification/ModelTrainingView.tsx +++ b/web/src/views/classification/ModelTrainingView.tsx @@ -621,7 +621,7 @@ function LibrarySelector({
    {Object.keys(dataset).length <= 2 ? ( ) : ( <> diff --git a/web/src/views/settings/TriggerView.tsx b/web/src/views/settings/TriggerView.tsx index aabf89294..5d2e03b4c 100644 --- a/web/src/views/settings/TriggerView.tsx +++ b/web/src/views/settings/TriggerView.tsx @@ -599,7 +599,7 @@ export default function TriggerView({ date_style: "medium", }, ) - : t("never", { ns: "common" })} + : t("time.never", { ns: "common" })} {trigger_status?.triggers[trigger.name] ?.triggering_event_id && ( From 3b6814fbc9a09100c29c6cb974f8ffbf9472c307 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:30:21 -0600 Subject: [PATCH 46/98] Revert "Miscellaneous fixes (0.17 beta) (#21764)" (#21825) This reverts commit 50ac5a1483c94c86fca3a84c2a33a9e898a40de9. --- .github/copilot-instructions.md | 388 +----------------- docs/docs/frigate/hardware.md | 2 +- frigate/genai/__init__.py | 21 +- frigate/genai/azure-openai.py | 55 +-- frigate/genai/gemini.py | 10 +- frigate/genai/ollama.py | 8 +- frigate/genai/openai.py | 35 +- web/src/components/card/AnimatedEventCard.tsx | 41 +- 8 files changed, 60 insertions(+), 500 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index f053abe3f..89acd8a9b 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,385 +1,3 @@ -# GitHub Copilot Instructions for Frigate NVR - -This document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection. - -## Project Overview - -Frigate NVR is a realtime object detection system for IP cameras that uses: - -- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX -- **Frontend**: React with TypeScript, Vite, TailwindCSS -- **Architecture**: Multiprocessing design with ZMQ and MQTT communication -- **Focus**: Minimal resource usage with maximum performance - -## Code Review Guidelines - -When reviewing code, do NOT comment on: - -- Missing imports - Static analysis tooling catches these -- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting -- Minor style inconsistencies already enforced by linters - -## Python Backend Standards - -### Python Requirements - -- **Compatibility**: Python 3.13+ -- **Language Features**: Use modern Python features: - - Pattern matching - - Type hints (comprehensive typing preferred) - - f-strings (preferred over `%` or `.format()`) - - Dataclasses - - Async/await patterns - -### Code Quality Standards - -- **Formatting**: Ruff (configured in `pyproject.toml`) -- **Linting**: Ruff with rules defined in project config -- **Type Checking**: Use type hints consistently -- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests -- **Language**: American English for all code, comments, and documentation - -### Logging Standards - -- **Logger Pattern**: Use module-level logger - - ```python - import logging - - logger = logging.getLogger(__name__) - ``` - -- **Format Guidelines**: - - No periods at end of log messages - - No sensitive data (keys, tokens, passwords) - - Use lazy logging: `logger.debug("Message with %s", variable)` -- **Log Levels**: - - `debug`: Development and troubleshooting information - - `info`: Important runtime events (startup, shutdown, state changes) - - `warning`: Recoverable issues that should be addressed - - `error`: Errors that affect functionality but don't crash the app - - `exception`: Use in except blocks to include traceback - -### Error Handling - -- **Exception Types**: Choose most specific exception available -- **Try/Catch Best Practices**: - - Only wrap code that can throw exceptions - - Keep try blocks minimal - process data after the try/except - - Avoid bare exceptions except in background tasks - - Bad pattern: - - ```python - try: - data = await device.get_data() # Can throw - # ❌ Don't process data inside try block - processed = data.get("value", 0) * 100 - result = processed - except DeviceError: - logger.error("Failed to get data") - ``` - - Good pattern: - - ```python - try: - data = await device.get_data() # Can throw - except DeviceError: - logger.error("Failed to get data") - return - - # ✅ Process data outside try block - processed = data.get("value", 0) * 100 - result = processed - ``` - -### Async Programming - -- **External I/O**: All external I/O operations must be async -- **Best Practices**: - - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()` - - Avoid awaiting in loops - use `asyncio.gather()` instead - - No blocking calls in async functions - - Use `asyncio.create_task()` for background operations -- **Thread Safety**: Use proper synchronization for shared state - -### Documentation Standards - -- **Module Docstrings**: Concise descriptions at top of files - ```python - """Utilities for motion detection and analysis.""" - ``` -- **Function Docstrings**: Required for public functions and methods - - ```python - async def process_frame(frame: ndarray, config: Config) -> Detection: - """Process a video frame for object detection. - - Args: - frame: The video frame as numpy array - config: Detection configuration - - Returns: - Detection results with bounding boxes - """ - ``` - -- **Comment Style**: - - Explain the "why" not just the "what" - - Keep lines under 88 characters when possible - - Use clear, descriptive comments - -### File Organization - -- **API Endpoints**: `frigate/api/` - FastAPI route handlers -- **Configuration**: `frigate/config/` - Configuration parsing and validation -- **Detectors**: `frigate/detectors/` - Object detection backends -- **Events**: `frigate/events/` - Event management and storage -- **Utilities**: `frigate/util/` - Shared utility functions - -## Frontend (React/TypeScript) Standards - -### Internationalization (i18n) - -- **CRITICAL**: Never write user-facing strings directly in components -- **Always use react-i18next**: Import and use the `t()` function - - ```tsx - import { useTranslation } from "react-i18next"; - - function MyComponent() { - const { t } = useTranslation(["views/live"]); - return
    {t("camera_not_found")}
    ; - } - ``` - -- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en` -- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`) - -### Code Quality - -- **Linting**: ESLint (see `web/.eslintrc.cjs`) -- **Formatting**: Prettier with Tailwind CSS plugin -- **Type Safety**: TypeScript strict mode enabled -- **Testing**: Vitest for unit tests - -### Component Patterns - -- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`) -- **Styling**: TailwindCSS with `cn()` utility for class merging -- **State Management**: React hooks (useState, useEffect, useCallback, useMemo) -- **Data Fetching**: Custom hooks with proper loading and error states - -### ESLint Rules - -Key rules enforced: - -- `react-hooks/rules-of-hooks`: error -- `react-hooks/exhaustive-deps`: error -- `no-console`: error (use proper logging or remove) -- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`) -- Unused variables must be prefixed with `_` -- Comma dangles required for multiline objects/arrays - -### File Organization - -- **Pages**: `web/src/pages/` - Route components -- **Views**: `web/src/views/` - Complex view components -- **Components**: `web/src/components/` - Reusable components -- **Hooks**: `web/src/hooks/` - Custom React hooks -- **API**: `web/src/api/` - API client functions -- **Types**: `web/src/types/` - TypeScript type definitions - -## Testing Requirements - -### Backend Testing - -- **Framework**: Python unittest -- **Run Command**: `python3 -u -m unittest` -- **Location**: `frigate/test/` -- **Coverage**: Aim for comprehensive test coverage of core functionality -- **Pattern**: Use `TestCase` classes with descriptive test method names - ```python - class TestMotionDetection(unittest.TestCase): - def test_detects_motion_above_threshold(self): - # Test implementation - ``` - -### Test Best Practices - -- Always have a way to test your work and confirm your changes -- Write tests for bug fixes to prevent regressions -- Test edge cases and error conditions -- Mock external dependencies (cameras, APIs, hardware) -- Use fixtures for test data - -## Development Commands - -### Python Backend - -```bash -# Run all tests -python3 -u -m unittest - -# Run specific test file -python3 -u -m unittest frigate.test.test_ffmpeg_presets - -# Check formatting (Ruff) -ruff format --check frigate/ - -# Apply formatting -ruff format frigate/ - -# Run linter -ruff check frigate/ -``` - -### Frontend (from web/ directory) - -```bash -# Start dev server (AI agents should never run this directly unless asked) -npm run dev - -# Build for production -npm run build - -# Run linter -npm run lint - -# Fix linting issues -npm run lint:fix - -# Format code -npm run prettier:write -``` - -### Docker Development - -AI agents should never run these commands directly unless instructed. - -```bash -# Build local image -make local - -# Build debug image -make debug -``` - -## Common Patterns - -### API Endpoint Pattern - -```python -from fastapi import APIRouter, Request -from frigate.api.defs.tags import Tags - -router = APIRouter(tags=[Tags.Events]) - -@router.get("/events") -async def get_events(request: Request, limit: int = 100): - """Retrieve events from the database.""" - # Implementation -``` - -### Configuration Access - -```python -# Access Frigate configuration -config: FrigateConfig = request.app.frigate_config -camera_config = config.cameras["front_door"] -``` - -### Database Queries - -```python -from frigate.models import Event - -# Use Peewee ORM for database access -events = ( - Event.select() - .where(Event.camera == camera_name) - .order_by(Event.start_time.desc()) - .limit(limit) -) -``` - -## Common Anti-Patterns to Avoid - -### ❌ Avoid These - -```python -# Blocking operations in async functions -data = requests.get(url) # ❌ Use async HTTP client -time.sleep(5) # ❌ Use asyncio.sleep() - -# Hardcoded strings in React components -
    Camera not found
    # ❌ Use t("camera_not_found") - -# Missing error handling -data = await api.get_data() # ❌ No exception handling - -# Bare exceptions in regular code -try: - value = await sensor.read() -except Exception: # ❌ Too broad - logger.error("Failed") -``` - -### ✅ Use These Instead - -```python -# Async operations -import aiohttp -async with aiohttp.ClientSession() as session: - async with session.get(url) as response: - data = await response.json() - -await asyncio.sleep(5) # ✅ Non-blocking - -# Translatable strings in React -const { t } = useTranslation(); -
    {t("camera_not_found")}
    # ✅ Translatable - -# Proper error handling -try: - data = await api.get_data() -except ApiException as err: - logger.error("API error: %s", err) - raise - -# Specific exceptions -try: - value = await sensor.read() -except SensorException as err: # ✅ Specific - logger.exception("Failed to read sensor") -``` - -## Project-Specific Conventions - -### Configuration Files - -- Main config: `config/config.yml` - -### Directory Structure - -- Backend code: `frigate/` -- Frontend code: `web/` -- Docker files: `docker/` -- Documentation: `docs/` -- Database migrations: `migrations/` - -### Code Style Conformance - -Always conform new and refactored code to the existing coding style in the project: - -- Follow established patterns in similar files -- Match indentation and formatting of surrounding code -- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript) -- Maintain the same level of verbosity in comments and docstrings - -## Additional Resources - -- Documentation: https://docs.frigate.video -- Main Repository: https://github.com/blakeblackshear/frigate -- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration +- For Frigate NVR, never write strings in the frontend directly. Since the project uses `react-i18next`, use `t()` and write the English string in the relevant translations file in `web/public/locales/en`. +- Always conform new and refactored code to the existing coding style in the project. +- Always have a way to test your work and confirm your changes. When running backend tests, use `python3 -u -m unittest`. diff --git a/docs/docs/frigate/hardware.md b/docs/docs/frigate/hardware.md index 48ab2c647..f7294042a 100644 --- a/docs/docs/frigate/hardware.md +++ b/docs/docs/frigate/hardware.md @@ -167,7 +167,7 @@ Inference speeds vary greatly depending on the CPU or GPU used, some known examp | Intel N100 | ~ 15 ms | s-320: 30 ms | 320: ~ 25 ms | | Can only run one detector instance | | Intel N150 | ~ 15 ms | t-320: 16 ms s-320: 24 ms | | | | | Intel Iris XE | ~ 10 ms | t-320: 6 ms t-640: 14 ms s-320: 8 ms s-640: 16 ms | 320: ~ 10 ms 640: ~ 20 ms | 320-n: 33 ms | | -| Intel NPU | ~ 6 ms | s-320: 11 ms s-640: 30 ms | 320: ~ 14 ms 640: ~ 34 ms | 320-n: 40 ms | | +| Intel NPU | ~ 6 ms | s-320: 11 ms | 320: ~ 14 ms 640: ~ 34 ms | 320-n: 40 ms | | | Intel Arc A310 | ~ 5 ms | t-320: 7 ms t-640: 11 ms s-320: 8 ms s-640: 15 ms | 320: ~ 8 ms 640: ~ 14 ms | | | | Intel Arc A380 | ~ 6 ms | | 320: ~ 10 ms 640: ~ 22 ms | 336: 20 ms 448: 27 ms | | | Intel Arc A750 | ~ 4 ms | | 320: ~ 8 ms | | | diff --git a/frigate/genai/__init__.py b/frigate/genai/__init__.py index 821b449de..7f0192912 100644 --- a/frigate/genai/__init__.py +++ b/frigate/genai/__init__.py @@ -140,12 +140,7 @@ Each line represents a detection state, not necessarily unique individuals. Pare ) as f: f.write(context_prompt) - json_schema = { - "name": "review_metadata", - "schema": ReviewMetadata.model_json_schema(), - "strict": True, - } - response = self._send(context_prompt, thumbnails, json_schema=json_schema) + response = self._send(context_prompt, thumbnails) if debug_save and response: with open( @@ -157,8 +152,6 @@ Each line represents a detection state, not necessarily unique individuals. Pare f.write(response) if response: - # With JSON schema, response should already be valid JSON - # But keep regex cleanup as fallback for providers without schema support clean_json = re.sub( r"\n?```$", "", re.sub(r"^```[a-zA-Z0-9]*\n?", "", response) ) @@ -291,16 +284,8 @@ Guidelines: """Initialize the client.""" return None - def _send( - self, prompt: str, images: list[bytes], json_schema: Optional[dict] = None - ) -> Optional[str]: - """Submit a request to the provider. - - Args: - prompt: The text prompt to send - images: List of image bytes to include - json_schema: Optional JSON schema for structured output (provider-specific support) - """ + def _send(self, prompt: str, images: list[bytes]) -> Optional[str]: + """Submit a request to the provider.""" return None def get_context_size(self) -> int: diff --git a/frigate/genai/azure-openai.py b/frigate/genai/azure-openai.py index 9cc03fe75..eb08f7786 100644 --- a/frigate/genai/azure-openai.py +++ b/frigate/genai/azure-openai.py @@ -41,46 +41,29 @@ class OpenAIClient(GenAIClient): azure_endpoint=azure_endpoint, ) - def _send( - self, prompt: str, images: list[bytes], json_schema: Optional[dict] = None - ) -> Optional[str]: + def _send(self, prompt: str, images: list[bytes]) -> Optional[str]: """Submit a request to Azure OpenAI.""" encoded_images = [base64.b64encode(image).decode("utf-8") for image in images] - - request_params = { - "model": self.genai_config.model, - "messages": [ - { - "role": "user", - "content": [{"type": "text", "text": prompt}] - + [ - { - "type": "image_url", - "image_url": { - "url": f"data:image/jpeg;base64,{image}", - "detail": "low", - }, - } - for image in encoded_images - ], - }, - ], - "timeout": self.timeout, - } - - if json_schema: - request_params["response_format"] = { - "type": "json_schema", - "json_schema": { - "name": json_schema.get("name", "response"), - "schema": json_schema.get("schema", {}), - "strict": json_schema.get("strict", True), - }, - } - try: result = self.provider.chat.completions.create( - **request_params, + model=self.genai_config.model, + messages=[ + { + "role": "user", + "content": [{"type": "text", "text": prompt}] + + [ + { + "type": "image_url", + "image_url": { + "url": f"data:image/jpeg;base64,{image}", + "detail": "low", + }, + } + for image in encoded_images + ], + }, + ], + timeout=self.timeout, **self.genai_config.runtime_options, ) except Exception as e: diff --git a/frigate/genai/gemini.py b/frigate/genai/gemini.py index 1212f15ad..b700c33a4 100644 --- a/frigate/genai/gemini.py +++ b/frigate/genai/gemini.py @@ -41,9 +41,7 @@ class GeminiClient(GenAIClient): http_options=types.HttpOptions(**http_options_dict), ) - def _send( - self, prompt: str, images: list[bytes], json_schema: Optional[dict] = None - ) -> Optional[str]: + def _send(self, prompt: str, images: list[bytes]) -> Optional[str]: """Submit a request to Gemini.""" contents = [ types.Part.from_bytes(data=img, mime_type="image/jpeg") for img in images @@ -53,12 +51,6 @@ class GeminiClient(GenAIClient): generation_config_dict = {"candidate_count": 1} generation_config_dict.update(self.genai_config.runtime_options) - if json_schema and "schema" in json_schema: - generation_config_dict["response_mime_type"] = "application/json" - generation_config_dict["response_schema"] = types.Schema( - json_schema=json_schema["schema"] - ) - response = self.provider.models.generate_content( model=self.genai_config.model, contents=contents, diff --git a/frigate/genai/ollama.py b/frigate/genai/ollama.py index f798cbd19..ab6d3c0b3 100644 --- a/frigate/genai/ollama.py +++ b/frigate/genai/ollama.py @@ -50,9 +50,7 @@ class OllamaClient(GenAIClient): logger.warning("Error initializing Ollama: %s", str(e)) return None - def _send( - self, prompt: str, images: list[bytes], json_schema: Optional[dict] = None - ) -> Optional[str]: + def _send(self, prompt: str, images: list[bytes]) -> Optional[str]: """Submit a request to Ollama""" if self.provider is None: logger.warning( @@ -64,10 +62,6 @@ class OllamaClient(GenAIClient): **self.provider_options, **self.genai_config.runtime_options, } - - if json_schema and "schema" in json_schema: - ollama_options["format"] = json_schema["schema"] - result = self.provider.generate( self.genai_config.model, prompt, diff --git a/frigate/genai/openai.py b/frigate/genai/openai.py index a5ee6455e..1fb0dd852 100644 --- a/frigate/genai/openai.py +++ b/frigate/genai/openai.py @@ -31,9 +31,7 @@ class OpenAIClient(GenAIClient): } return OpenAI(api_key=self.genai_config.api_key, **provider_opts) - def _send( - self, prompt: str, images: list[bytes], json_schema: Optional[dict] = None - ) -> Optional[str]: + def _send(self, prompt: str, images: list[bytes]) -> Optional[str]: """Submit a request to OpenAI.""" encoded_images = [base64.b64encode(image).decode("utf-8") for image in images] messages_content = [] @@ -53,31 +51,16 @@ class OpenAIClient(GenAIClient): "text": prompt, } ) - - request_params = { - "model": self.genai_config.model, - "messages": [ - { - "role": "user", - "content": messages_content, - }, - ], - "timeout": self.timeout, - } - - if json_schema: - request_params["response_format"] = { - "type": "json_schema", - "json_schema": { - "name": json_schema.get("name", "response"), - "schema": json_schema.get("schema", {}), - "strict": json_schema.get("strict", True), - }, - } - try: result = self.provider.chat.completions.create( - **request_params, + model=self.genai_config.model, + messages=[ + { + "role": "user", + "content": messages_content, + }, + ], + timeout=self.timeout, **self.genai_config.runtime_options, ) if ( diff --git a/web/src/components/card/AnimatedEventCard.tsx b/web/src/components/card/AnimatedEventCard.tsx index c5da99aa2..a67dd8305 100644 --- a/web/src/components/card/AnimatedEventCard.tsx +++ b/web/src/components/card/AnimatedEventCard.tsx @@ -12,7 +12,7 @@ import { useCameraPreviews } from "@/hooks/use-camera-previews"; import { baseUrl } from "@/api/baseUrl"; import { VideoPreview } from "../preview/ScrubbablePreview"; import { useApiHost } from "@/api"; -import { isSafari } from "react-device-detect"; +import { isDesktop, isSafari } from "react-device-detect"; import { useUserPersistence } from "@/hooks/use-user-persistence"; import { Skeleton } from "../ui/skeleton"; import { Button } from "../ui/button"; @@ -87,6 +87,7 @@ export function AnimatedEventCard({ }, [visibilityListener]); const [isLoaded, setIsLoaded] = useState(false); + const [isHovered, setIsHovered] = useState(false); // interaction @@ -133,27 +134,31 @@ export function AnimatedEventCard({
    setIsHovered(true) : undefined} + onMouseLeave={isDesktop ? () => setIsHovered(false) : undefined} > - - - - - {t("markAsReviewed")} - + {isHovered && ( + + + + + {t("markAsReviewed")} + + )} {previews != undefined && alertVideosLoaded && (
    Date: Thu, 29 Jan 2026 13:42:06 -0600 Subject: [PATCH 47/98] Miscellaneous fixes (0.17 beta) (#21826) * revert other changes * fix verified icon overlay in debug view list * Add classification object debug logs * Formatting --------- Co-authored-by: Nicolas Mowen --- .github/copilot-instructions.md | 388 +++++++++++++++++- docs/docs/frigate/hardware.md | 2 +- .../real_time/custom_classification.py | 35 +- web/src/utils/iconUtil.tsx | 8 +- web/src/views/settings/ObjectSettingsView.tsx | 2 +- 5 files changed, 425 insertions(+), 10 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 89acd8a9b..f053abe3f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,3 +1,385 @@ -- For Frigate NVR, never write strings in the frontend directly. Since the project uses `react-i18next`, use `t()` and write the English string in the relevant translations file in `web/public/locales/en`. -- Always conform new and refactored code to the existing coding style in the project. -- Always have a way to test your work and confirm your changes. When running backend tests, use `python3 -u -m unittest`. +# GitHub Copilot Instructions for Frigate NVR + +This document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection. + +## Project Overview + +Frigate NVR is a realtime object detection system for IP cameras that uses: + +- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX +- **Frontend**: React with TypeScript, Vite, TailwindCSS +- **Architecture**: Multiprocessing design with ZMQ and MQTT communication +- **Focus**: Minimal resource usage with maximum performance + +## Code Review Guidelines + +When reviewing code, do NOT comment on: + +- Missing imports - Static analysis tooling catches these +- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting +- Minor style inconsistencies already enforced by linters + +## Python Backend Standards + +### Python Requirements + +- **Compatibility**: Python 3.13+ +- **Language Features**: Use modern Python features: + - Pattern matching + - Type hints (comprehensive typing preferred) + - f-strings (preferred over `%` or `.format()`) + - Dataclasses + - Async/await patterns + +### Code Quality Standards + +- **Formatting**: Ruff (configured in `pyproject.toml`) +- **Linting**: Ruff with rules defined in project config +- **Type Checking**: Use type hints consistently +- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests +- **Language**: American English for all code, comments, and documentation + +### Logging Standards + +- **Logger Pattern**: Use module-level logger + + ```python + import logging + + logger = logging.getLogger(__name__) + ``` + +- **Format Guidelines**: + - No periods at end of log messages + - No sensitive data (keys, tokens, passwords) + - Use lazy logging: `logger.debug("Message with %s", variable)` +- **Log Levels**: + - `debug`: Development and troubleshooting information + - `info`: Important runtime events (startup, shutdown, state changes) + - `warning`: Recoverable issues that should be addressed + - `error`: Errors that affect functionality but don't crash the app + - `exception`: Use in except blocks to include traceback + +### Error Handling + +- **Exception Types**: Choose most specific exception available +- **Try/Catch Best Practices**: + - Only wrap code that can throw exceptions + - Keep try blocks minimal - process data after the try/except + - Avoid bare exceptions except in background tasks + + Bad pattern: + + ```python + try: + data = await device.get_data() # Can throw + # ❌ Don't process data inside try block + processed = data.get("value", 0) * 100 + result = processed + except DeviceError: + logger.error("Failed to get data") + ``` + + Good pattern: + + ```python + try: + data = await device.get_data() # Can throw + except DeviceError: + logger.error("Failed to get data") + return + + # ✅ Process data outside try block + processed = data.get("value", 0) * 100 + result = processed + ``` + +### Async Programming + +- **External I/O**: All external I/O operations must be async +- **Best Practices**: + - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()` + - Avoid awaiting in loops - use `asyncio.gather()` instead + - No blocking calls in async functions + - Use `asyncio.create_task()` for background operations +- **Thread Safety**: Use proper synchronization for shared state + +### Documentation Standards + +- **Module Docstrings**: Concise descriptions at top of files + ```python + """Utilities for motion detection and analysis.""" + ``` +- **Function Docstrings**: Required for public functions and methods + + ```python + async def process_frame(frame: ndarray, config: Config) -> Detection: + """Process a video frame for object detection. + + Args: + frame: The video frame as numpy array + config: Detection configuration + + Returns: + Detection results with bounding boxes + """ + ``` + +- **Comment Style**: + - Explain the "why" not just the "what" + - Keep lines under 88 characters when possible + - Use clear, descriptive comments + +### File Organization + +- **API Endpoints**: `frigate/api/` - FastAPI route handlers +- **Configuration**: `frigate/config/` - Configuration parsing and validation +- **Detectors**: `frigate/detectors/` - Object detection backends +- **Events**: `frigate/events/` - Event management and storage +- **Utilities**: `frigate/util/` - Shared utility functions + +## Frontend (React/TypeScript) Standards + +### Internationalization (i18n) + +- **CRITICAL**: Never write user-facing strings directly in components +- **Always use react-i18next**: Import and use the `t()` function + + ```tsx + import { useTranslation } from "react-i18next"; + + function MyComponent() { + const { t } = useTranslation(["views/live"]); + return
    {t("camera_not_found")}
    ; + } + ``` + +- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en` +- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`) + +### Code Quality + +- **Linting**: ESLint (see `web/.eslintrc.cjs`) +- **Formatting**: Prettier with Tailwind CSS plugin +- **Type Safety**: TypeScript strict mode enabled +- **Testing**: Vitest for unit tests + +### Component Patterns + +- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`) +- **Styling**: TailwindCSS with `cn()` utility for class merging +- **State Management**: React hooks (useState, useEffect, useCallback, useMemo) +- **Data Fetching**: Custom hooks with proper loading and error states + +### ESLint Rules + +Key rules enforced: + +- `react-hooks/rules-of-hooks`: error +- `react-hooks/exhaustive-deps`: error +- `no-console`: error (use proper logging or remove) +- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`) +- Unused variables must be prefixed with `_` +- Comma dangles required for multiline objects/arrays + +### File Organization + +- **Pages**: `web/src/pages/` - Route components +- **Views**: `web/src/views/` - Complex view components +- **Components**: `web/src/components/` - Reusable components +- **Hooks**: `web/src/hooks/` - Custom React hooks +- **API**: `web/src/api/` - API client functions +- **Types**: `web/src/types/` - TypeScript type definitions + +## Testing Requirements + +### Backend Testing + +- **Framework**: Python unittest +- **Run Command**: `python3 -u -m unittest` +- **Location**: `frigate/test/` +- **Coverage**: Aim for comprehensive test coverage of core functionality +- **Pattern**: Use `TestCase` classes with descriptive test method names + ```python + class TestMotionDetection(unittest.TestCase): + def test_detects_motion_above_threshold(self): + # Test implementation + ``` + +### Test Best Practices + +- Always have a way to test your work and confirm your changes +- Write tests for bug fixes to prevent regressions +- Test edge cases and error conditions +- Mock external dependencies (cameras, APIs, hardware) +- Use fixtures for test data + +## Development Commands + +### Python Backend + +```bash +# Run all tests +python3 -u -m unittest + +# Run specific test file +python3 -u -m unittest frigate.test.test_ffmpeg_presets + +# Check formatting (Ruff) +ruff format --check frigate/ + +# Apply formatting +ruff format frigate/ + +# Run linter +ruff check frigate/ +``` + +### Frontend (from web/ directory) + +```bash +# Start dev server (AI agents should never run this directly unless asked) +npm run dev + +# Build for production +npm run build + +# Run linter +npm run lint + +# Fix linting issues +npm run lint:fix + +# Format code +npm run prettier:write +``` + +### Docker Development + +AI agents should never run these commands directly unless instructed. + +```bash +# Build local image +make local + +# Build debug image +make debug +``` + +## Common Patterns + +### API Endpoint Pattern + +```python +from fastapi import APIRouter, Request +from frigate.api.defs.tags import Tags + +router = APIRouter(tags=[Tags.Events]) + +@router.get("/events") +async def get_events(request: Request, limit: int = 100): + """Retrieve events from the database.""" + # Implementation +``` + +### Configuration Access + +```python +# Access Frigate configuration +config: FrigateConfig = request.app.frigate_config +camera_config = config.cameras["front_door"] +``` + +### Database Queries + +```python +from frigate.models import Event + +# Use Peewee ORM for database access +events = ( + Event.select() + .where(Event.camera == camera_name) + .order_by(Event.start_time.desc()) + .limit(limit) +) +``` + +## Common Anti-Patterns to Avoid + +### ❌ Avoid These + +```python +# Blocking operations in async functions +data = requests.get(url) # ❌ Use async HTTP client +time.sleep(5) # ❌ Use asyncio.sleep() + +# Hardcoded strings in React components +
    Camera not found
    # ❌ Use t("camera_not_found") + +# Missing error handling +data = await api.get_data() # ❌ No exception handling + +# Bare exceptions in regular code +try: + value = await sensor.read() +except Exception: # ❌ Too broad + logger.error("Failed") +``` + +### ✅ Use These Instead + +```python +# Async operations +import aiohttp +async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + data = await response.json() + +await asyncio.sleep(5) # ✅ Non-blocking + +# Translatable strings in React +const { t } = useTranslation(); +
    {t("camera_not_found")}
    # ✅ Translatable + +# Proper error handling +try: + data = await api.get_data() +except ApiException as err: + logger.error("API error: %s", err) + raise + +# Specific exceptions +try: + value = await sensor.read() +except SensorException as err: # ✅ Specific + logger.exception("Failed to read sensor") +``` + +## Project-Specific Conventions + +### Configuration Files + +- Main config: `config/config.yml` + +### Directory Structure + +- Backend code: `frigate/` +- Frontend code: `web/` +- Docker files: `docker/` +- Documentation: `docs/` +- Database migrations: `migrations/` + +### Code Style Conformance + +Always conform new and refactored code to the existing coding style in the project: + +- Follow established patterns in similar files +- Match indentation and formatting of surrounding code +- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript) +- Maintain the same level of verbosity in comments and docstrings + +## Additional Resources + +- Documentation: https://docs.frigate.video +- Main Repository: https://github.com/blakeblackshear/frigate +- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration diff --git a/docs/docs/frigate/hardware.md b/docs/docs/frigate/hardware.md index f7294042a..48ab2c647 100644 --- a/docs/docs/frigate/hardware.md +++ b/docs/docs/frigate/hardware.md @@ -167,7 +167,7 @@ Inference speeds vary greatly depending on the CPU or GPU used, some known examp | Intel N100 | ~ 15 ms | s-320: 30 ms | 320: ~ 25 ms | | Can only run one detector instance | | Intel N150 | ~ 15 ms | t-320: 16 ms s-320: 24 ms | | | | | Intel Iris XE | ~ 10 ms | t-320: 6 ms t-640: 14 ms s-320: 8 ms s-640: 16 ms | 320: ~ 10 ms 640: ~ 20 ms | 320-n: 33 ms | | -| Intel NPU | ~ 6 ms | s-320: 11 ms | 320: ~ 14 ms 640: ~ 34 ms | 320-n: 40 ms | | +| Intel NPU | ~ 6 ms | s-320: 11 ms s-640: 30 ms | 320: ~ 14 ms 640: ~ 34 ms | 320-n: 40 ms | | | Intel Arc A310 | ~ 5 ms | t-320: 7 ms t-640: 11 ms s-320: 8 ms s-640: 15 ms | 320: ~ 8 ms 640: ~ 14 ms | | | | Intel Arc A380 | ~ 6 ms | | 320: ~ 10 ms 640: ~ 22 ms | 336: 20 ms 448: 27 ms | | | Intel Arc A750 | ~ 4 ms | | 320: ~ 8 ms | | | diff --git a/frigate/data_processing/real_time/custom_classification.py b/frigate/data_processing/real_time/custom_classification.py index fac0ecc3d..19a40fd99 100644 --- a/frigate/data_processing/real_time/custom_classification.py +++ b/frigate/data_processing/real_time/custom_classification.py @@ -419,14 +419,21 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi): """ if object_id not in self.classification_history: self.classification_history[object_id] = [] + logger.debug(f"Created new classification history for {object_id}") self.classification_history[object_id].append( (current_label, current_score, current_time) ) history = self.classification_history[object_id] + logger.debug( + f"History for {object_id}: {len(history)} entries, latest=({current_label}, {current_score})" + ) if len(history) < 3: + logger.debug( + f"History for {object_id} has {len(history)} entries, need at least 3" + ) return None, 0.0 label_counts = {} @@ -445,14 +452,27 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi): best_count = label_counts[best_label] consensus_threshold = total_attempts * 0.6 + logger.debug( + f"Consensus calc for {object_id}: label_counts={label_counts}, " + f"best_label={best_label}, best_count={best_count}, " + f"total={total_attempts}, threshold={consensus_threshold}" + ) + if best_count < consensus_threshold: + logger.debug( + f"No consensus for {object_id}: {best_count} < {consensus_threshold}" + ) return None, 0.0 avg_score = sum(label_scores[best_label]) / len(label_scores[best_label]) if best_label == "none": + logger.debug(f"Filtering 'none' label for {object_id}") return None, 0.0 + logger.debug( + f"Consensus reached for {object_id}: {best_label} with avg_score={avg_score}" + ) return best_label, avg_score def process_frame(self, obj_data, frame): @@ -560,17 +580,30 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi): ) if score < self.model_config.threshold: - logger.debug(f"Score {score} is less than threshold.") + logger.debug( + f"{self.model_config.name}: Score {score} < threshold {self.model_config.threshold} for {object_id}, skipping" + ) return sub_label = self.labelmap[best_id] + logger.debug( + f"{self.model_config.name}: Object {object_id} (label={obj_data['label']}) passed threshold with sub_label={sub_label}, score={score}" + ) + consensus_label, consensus_score = self.get_weighted_score( object_id, sub_label, score, now ) + logger.debug( + f"{self.model_config.name}: get_weighted_score returned consensus_label={consensus_label}, consensus_score={consensus_score} for {object_id}" + ) + if consensus_label is not None: camera = obj_data["camera"] + logger.info( + f"{self.model_config.name}: Publishing sub_label={consensus_label} for {obj_data['label']} object {object_id} on {camera}" + ) if ( self.model_config.object_config.classification_type diff --git a/web/src/utils/iconUtil.tsx b/web/src/utils/iconUtil.tsx index 156b4529b..8ddf3ea08 100644 --- a/web/src/utils/iconUtil.tsx +++ b/web/src/utils/iconUtil.tsx @@ -173,9 +173,9 @@ function getVerifiedIcon( const simpleLabel = label.substring(0, label.lastIndexOf("-")); return ( -
    +
    {getIconForLabel(simpleLabel, type, className)} - +
    ); } @@ -188,9 +188,9 @@ function getRecognizedPlateIcon( const simpleLabel = label.substring(0, label.lastIndexOf("-")); return ( -
    +
    {getIconForLabel(simpleLabel, type, className)} - +
    ); } diff --git a/web/src/views/settings/ObjectSettingsView.tsx b/web/src/views/settings/ObjectSettingsView.tsx index 3c03269b5..2f4ec5eaf 100644 --- a/web/src/views/settings/ObjectSettingsView.tsx +++ b/web/src/views/settings/ObjectSettingsView.tsx @@ -391,7 +391,7 @@ function ObjectList({ cameraConfig, objects }: ObjectListProps) { ); return ( -
    +
    {objects && objects.length > 0 ? ( objects.map((obj: ObjectType) => { return ( From 2d8399228400e92606d84a68ff1189bbddb5b18c Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Tue, 3 Feb 2026 07:31:00 -0700 Subject: [PATCH 48/98] Miscellaneous fixes (0.17 beta) (#21867) * Adjust title prompt to have less rigidity * Improve motion boxes handling for features that don't require motion * Improve handling of classes starting with digits * Improve vehicle nuance * tweak lpr docs * Improve grammar * Don't allow # in face name * add password requirements to new user dialog * change password requirements * Clenaup --------- Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> --- docs/docs/configuration/authentication.md | 4 + .../license_plate_recognition.md | 1 + frigate/api/auth.py | 29 ++-- frigate/config/camera/review.py | 7 +- .../real_time/custom_classification.py | 4 +- frigate/embeddings/maintainer.py | 8 +- frigate/genai/__init__.py | 2 +- frigate/util/builtin.py | 7 +- web/public/locales/en/views/faceLibrary.json | 3 +- web/public/locales/en/views/settings.json | 5 +- web/src/components/input/TextEntry.tsx | 7 + .../components/overlay/CreateUserDialog.tsx | 163 ++++++++++++++++-- .../components/overlay/SetPasswordDialog.tsx | 117 ++----------- .../overlay/detail/FaceCreateWizardDialog.tsx | 2 + .../overlay/dialog/TextEntryDialog.tsx | 6 + web/src/pages/FaceLibrary.tsx | 2 + web/src/utils/passwordUtil.ts | 34 ++++ 17 files changed, 256 insertions(+), 145 deletions(-) create mode 100644 web/src/utils/passwordUtil.ts diff --git a/docs/docs/configuration/authentication.md b/docs/docs/configuration/authentication.md index 17718c405..474998263 100644 --- a/docs/docs/configuration/authentication.md +++ b/docs/docs/configuration/authentication.md @@ -29,6 +29,10 @@ auth: reset_admin_password: true ``` +## Password guidance + +Constructing secure passwords and managing them properly is important. Frigate requires a minimum length of 12 characters. For guidance on password standards see [NIST SP 800-63B](https://pages.nist.gov/800-63-3/sp800-63b.html). To learn what makes a password truly secure, read this [article](https://medium.com/peerio/how-to-build-a-billion-dollar-password-3d92568d9277). + ## Login failure rate limiting In order to limit the risk of brute force attacks, rate limiting is available for login failures. This is implemented with SlowApi, and the string notation for valid values is available in [the documentation](https://limits.readthedocs.io/en/stable/quickstart.html#examples). diff --git a/docs/docs/configuration/license_plate_recognition.md b/docs/docs/configuration/license_plate_recognition.md index 5f70dd9a0..ac7942675 100644 --- a/docs/docs/configuration/license_plate_recognition.md +++ b/docs/docs/configuration/license_plate_recognition.md @@ -381,6 +381,7 @@ Start with ["Why isn't my license plate being detected and recognized?"](#why-is ```yaml lpr: enabled: true + device: CPU debug_save_plates: true ``` diff --git a/frigate/api/auth.py b/frigate/api/auth.py index 7ba845f45..bfb3b81a1 100644 --- a/frigate/api/auth.py +++ b/frigate/api/auth.py @@ -350,21 +350,15 @@ def validate_password_strength(password: str) -> tuple[bool, Optional[str]]: Validate password strength. Returns a tuple of (is_valid, error_message). + + Longer passwords are harder to crack than shorter complex ones. + https://pages.nist.gov/800-63-3/sp800-63b.html """ if not password: return False, "Password cannot be empty" - if len(password) < 8: - return False, "Password must be at least 8 characters long" - - if not any(c.isupper() for c in password): - return False, "Password must contain at least one uppercase letter" - - if not any(c.isdigit() for c in password): - return False, "Password must contain at least one digit" - - if not any(c in '!@#$%^&*(),.?":{}|<>' for c in password): - return False, "Password must contain at least one special character" + if len(password) < 12: + return False, "Password must be at least 12 characters long" return True, None @@ -800,7 +794,7 @@ def get_users(): "/users", dependencies=[Depends(require_role(["admin"]))], summary="Create new user", - description='Creates a new user with the specified username, password, and role. Requires admin role. Password must meet strength requirements: minimum 8 characters, at least one uppercase letter, at least one digit, and at least one special character (!@#$%^&*(),.?":{} |<>).', + description="Creates a new user with the specified username, password, and role. Requires admin role. Password must be at least 12 characters long.", ) def create_user( request: Request, @@ -817,6 +811,15 @@ def create_user( content={"message": f"Role must be one of: {', '.join(config_roles)}"}, status_code=400, ) + + # Validate password strength + is_valid, error_message = validate_password_strength(body.password) + if not is_valid: + return JSONResponse( + content={"message": error_message}, + status_code=400, + ) + role = body.role or "viewer" password_hash = hash_password(body.password, iterations=HASH_ITERATIONS) User.insert( @@ -851,7 +854,7 @@ def delete_user(request: Request, username: str): "/users/{username}/password", dependencies=[Depends(allow_any_authenticated())], summary="Update user password", - description="Updates a user's password. Users can only change their own password unless they have admin role. Requires the current password to verify identity for non-admin users. Password must meet strength requirements: minimum 8 characters, at least one uppercase letter, at least one digit, and at least one special character (!@#$%^&*(),.?\":{} |<>). If user changes their own password, a new JWT cookie is automatically issued.", + description="Updates a user's password. Users can only change their own password unless they have admin role. Requires the current password to verify identity for non-admin users. Password must be at least 12 characters long. If user changes their own password, a new JWT cookie is automatically issued.", ) async def update_password( request: Request, diff --git a/frigate/config/camera/review.py b/frigate/config/camera/review.py index 67ba3b60c..6e55b6242 100644 --- a/frigate/config/camera/review.py +++ b/frigate/config/camera/review.py @@ -108,12 +108,13 @@ class GenAIReviewConfig(FrigateBaseModel): default="""### Normal Activity Indicators (Level 0) - Known/verified people in any zone at any time - People with pets in residential areas +- Routine residential vehicle access during daytime/evening (6 AM - 10 PM): entering, exiting, loading/unloading items — normal commute and travel patterns - Deliveries or services during daytime/evening (6 AM - 10 PM): carrying packages to doors/porches, placing items, leaving - Services/maintenance workers with visible tools, uniforms, or service vehicles during daytime - Activity confined to public areas only (sidewalks, streets) without entering property at any time ### Suspicious Activity Indicators (Level 1) -- **Testing or attempting to open doors/windows/handles on vehicles or buildings** — ALWAYS Level 1 regardless of time or duration +- **Checking or probing vehicle/building access**: trying handles without entering, peering through windows, examining multiple vehicles, or possessing break-in tools — Level 1 - **Unidentified person in private areas (driveways, near vehicles/buildings) during late night/early morning (11 PM - 5 AM)** — ALWAYS Level 1 regardless of activity or duration - Taking items that don't belong to them (packages, objects from porches/driveways) - Climbing or jumping fences/barriers to access property @@ -133,8 +134,8 @@ Evaluate in this order: 1. **If person is verified/known** → Level 0 regardless of time or activity 2. **If person is unidentified:** - Check time: If late night/early morning (11 PM - 5 AM) AND in private areas (driveways, near vehicles/buildings) → Level 1 - - Check actions: If testing doors/handles, taking items, climbing → Level 1 - - Otherwise, if daytime/evening (6 AM - 10 PM) with clear legitimate purpose (delivery, service worker) → Level 0 + - Check actions: If probing access (trying handles without entering, checking multiple vehicles), taking items, climbing → Level 1 + - Otherwise, if daytime/evening (6 AM - 10 PM) with clear legitimate purpose (delivery, service, routine vehicle access) → Level 0 3. **Escalate to Level 2 if:** Weapons, break-in tools, forced entry in progress, violence, or active property damage visible (escalates from Level 0 or 1) The mere presence of an unidentified person in private areas during late night hours is inherently suspicious and warrants human review, regardless of what activity they appear to be doing or how brief the sequence is.""", diff --git a/frigate/data_processing/real_time/custom_classification.py b/frigate/data_processing/real_time/custom_classification.py index 19a40fd99..5a58cf122 100644 --- a/frigate/data_processing/real_time/custom_classification.py +++ b/frigate/data_processing/real_time/custom_classification.py @@ -97,7 +97,7 @@ class CustomStateClassificationProcessor(RealTimeProcessorApi): self.interpreter.allocate_tensors() self.tensor_input_details = self.interpreter.get_input_details() self.tensor_output_details = self.interpreter.get_output_details() - self.labelmap = load_labels(labelmap_path, prefill=0) + self.labelmap = load_labels(labelmap_path, prefill=0, indexed=False) self.classifications_per_second.start() def __update_metrics(self, duration: float) -> None: @@ -398,7 +398,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi): self.interpreter.allocate_tensors() self.tensor_input_details = self.interpreter.get_input_details() self.tensor_output_details = self.interpreter.get_output_details() - self.labelmap = load_labels(labelmap_path, prefill=0) + self.labelmap = load_labels(labelmap_path, prefill=0, indexed=False) def __update_metrics(self, duration: float) -> None: self.classifications_per_second.update() diff --git a/frigate/embeddings/maintainer.py b/frigate/embeddings/maintainer.py index 1a0950cbb..bd707de15 100644 --- a/frigate/embeddings/maintainer.py +++ b/frigate/embeddings/maintainer.py @@ -633,7 +633,7 @@ class EmbeddingMaintainer(threading.Thread): camera, frame_name, _, _, motion_boxes, _ = data - if not camera or len(motion_boxes) == 0 or camera not in self.config.cameras: + if not camera or camera not in self.config.cameras: return camera_config = self.config.cameras[camera] @@ -660,8 +660,10 @@ class EmbeddingMaintainer(threading.Thread): return for processor in self.realtime_processors: - if dedicated_lpr_enabled and isinstance( - processor, LicensePlateRealTimeProcessor + if ( + dedicated_lpr_enabled + and len(motion_boxes) > 0 + and isinstance(processor, LicensePlateRealTimeProcessor) ): processor.process_frame(camera, yuv_frame, True) diff --git a/frigate/genai/__init__.py b/frigate/genai/__init__.py index 7f0192912..be1f6d1e7 100644 --- a/frigate/genai/__init__.py +++ b/frigate/genai/__init__.py @@ -99,8 +99,8 @@ When forming your description: ## Response Format Your response MUST be a flat JSON object with: -- `title` (string): A concise, direct title that describes the primary action or event in the sequence, not just what you literally see. Use spatial context when available to make titles more meaningful. When multiple objects/actions are present, prioritize whichever is most prominent or occurs first. Use names from "Objects in Scene" based on what you visually observe. If you see both a name and an unidentified object of the same type but visually observe only one person/object, use ONLY the name. Examples: "Joe walking dog", "Person taking out trash", "Vehicle arriving in driveway", "Joe accessing vehicle", "Person leaving porch for driveway". - `scene` (string): A narrative description of what happens across the sequence from start to finish, in chronological order. Start by describing how the sequence begins, then describe the progression of events. **Describe all significant movements and actions in the order they occur.** For example, if a vehicle arrives and then a person exits, describe both actions sequentially. **Only describe actions you can actually observe happening in the frames provided.** Do not infer or assume actions that aren't visible (e.g., if you see someone walking but never see them sit, don't say they sat down). Include setting, detected objects, and their observable actions. Avoid speculation or filling in assumed behaviors. Your description should align with and support the threat level you assign. +- `title` (string): A concise, grammatically complete title in the format "[Subject] [action verb] [context]" that matches your scene description. Use names from "Objects in Scene" when you visually observe them. - `shortSummary` (string): A brief 2-sentence summary of the scene, suitable for notifications. Should capture the key activity and context without full detail. This should be a condensed version of the scene description above. - `confidence` (float): 0-1 confidence in your analysis. Higher confidence when objects/actions are clearly visible and context is unambiguous. Lower confidence when the sequence is unclear, objects are partially obscured, or context is ambiguous. - `potential_threat_level` (integer): 0, 1, or 2 as defined in "Normal Activity Patterns for This Property" above. Your threat level must be consistent with your scene description and the guidance above. diff --git a/frigate/util/builtin.py b/frigate/util/builtin.py index b1a76214b..867d2533d 100644 --- a/frigate/util/builtin.py +++ b/frigate/util/builtin.py @@ -129,7 +129,9 @@ def get_ffmpeg_arg_list(arg: Any) -> list: return arg if isinstance(arg, list) else shlex.split(arg) -def load_labels(path: Optional[str], encoding="utf-8", prefill=91): +def load_labels( + path: Optional[str], encoding="utf-8", prefill=91, indexed: bool | None = None +): """Loads labels from file (with or without index numbers). Args: path: path to label file. @@ -146,11 +148,12 @@ def load_labels(path: Optional[str], encoding="utf-8", prefill=91): if not lines: return {} - if lines[0].split(" ", maxsplit=1)[0].isdigit(): + if indexed != False and lines[0].split(" ", maxsplit=1)[0].isdigit(): pairs = [line.split(" ", maxsplit=1) for line in lines] labels.update({int(index): label.strip() for index, label in pairs}) else: labels.update({index: line.strip() for index, line in enumerate(lines)}) + return labels diff --git a/web/public/locales/en/views/faceLibrary.json b/web/public/locales/en/views/faceLibrary.json index 2dbb1a4fd..354049156 100644 --- a/web/public/locales/en/views/faceLibrary.json +++ b/web/public/locales/en/views/faceLibrary.json @@ -2,7 +2,8 @@ "description": { "addFace": "Add a new collection to the Face Library by uploading your first image.", "placeholder": "Enter a name for this collection", - "invalidName": "Invalid name. Names can only include letters, numbers, spaces, apostrophes, underscores, and hyphens." + "invalidName": "Invalid name. Names can only include letters, numbers, spaces, apostrophes, underscores, and hyphens.", + "nameCannotContainHash": "Name cannot contain #." }, "details": { "timestamp": "Timestamp", diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index 9f211a442..78d6a464d 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -728,10 +728,7 @@ }, "requirements": { "title": "Password requirements:", - "length": "At least 8 characters", - "uppercase": "At least one uppercase letter", - "digit": "At least one digit", - "special": "At least one special character (!@#$%^&*(),.?\":{}|<>)" + "length": "At least 12 characters" }, "match": "Passwords match", "notMatch": "Passwords don't match" diff --git a/web/src/components/input/TextEntry.tsx b/web/src/components/input/TextEntry.tsx index e266444c7..4abf942ac 100644 --- a/web/src/components/input/TextEntry.tsx +++ b/web/src/components/input/TextEntry.tsx @@ -20,6 +20,8 @@ type TextEntryProps = { children?: React.ReactNode; regexPattern?: RegExp; regexErrorMessage?: string; + forbiddenPattern?: RegExp; + forbiddenErrorMessage?: string; }; export default function TextEntry({ @@ -30,11 +32,16 @@ export default function TextEntry({ children, regexPattern, regexErrorMessage = "Input does not match the required format", + forbiddenPattern, + forbiddenErrorMessage = "Input contains invalid characters", }: TextEntryProps) { const formSchema = z.object({ text: z .string() .optional() + .refine((val) => !val || !forbiddenPattern?.test(val), { + message: forbiddenErrorMessage, + }) .refine( (val) => { if (!allowEmpty && !val) return false; diff --git a/web/src/components/overlay/CreateUserDialog.tsx b/web/src/components/overlay/CreateUserDialog.tsx index 6f2b3ecf3..1ce32b61b 100644 --- a/web/src/components/overlay/CreateUserDialog.tsx +++ b/web/src/components/overlay/CreateUserDialog.tsx @@ -32,11 +32,17 @@ import { SelectValue, } from "../ui/select"; import { Shield, User } from "lucide-react"; -import { LuCheck, LuX } from "react-icons/lu"; +import { LuCheck, LuX, LuEye, LuEyeOff } from "react-icons/lu"; import { useTranslation } from "react-i18next"; import { isDesktop, isMobile } from "react-device-detect"; import { cn } from "@/lib/utils"; import { FrigateConfig } from "@/types/frigateConfig"; +import { + calculatePasswordStrength, + getPasswordRequirements, + getPasswordStrengthLabel, + getPasswordStrengthColor, +} from "@/utils/passwordUtil"; import { MobilePage, MobilePageContent, @@ -59,6 +65,10 @@ export default function CreateUserDialog({ const { data: config } = useSWR("config"); const { t } = useTranslation(["views/settings"]); const [isLoading, setIsLoading] = useState(false); + const [showPasswordVisible, setShowPasswordVisible] = + useState(false); + const [showConfirmPassword, setShowConfirmPassword] = + useState(false); const roles = useMemo(() => { const existingRoles = config ? Object.keys(config.auth?.roles || {}) : []; @@ -73,7 +83,9 @@ export default function CreateUserDialog({ .regex(/^[A-Za-z0-9._]+$/, { message: t("users.dialog.createUser.usernameOnlyInclude"), }), - password: z.string().min(1, t("users.dialog.form.passwordIsRequired")), + password: z + .string() + .min(12, t("users.dialog.form.password.requirements.length")), confirmPassword: z .string() .min(1, t("users.dialog.createUser.confirmPassword")), @@ -108,13 +120,27 @@ export default function CreateUserDialog({ const passwordsMatch = password === confirmPassword; const showMatchIndicator = password && confirmPassword; + // Password strength calculation + const passwordStrength = useMemo( + () => calculatePasswordStrength(password), + [password], + ); + + const requirements = useMemo( + () => getPasswordRequirements(password), + [password], + ); + useEffect(() => { if (!show) { form.reset({ user: "", password: "", + confirmPassword: "", role: "viewer", }); + setShowPasswordVisible(false); + setShowConfirmPassword(false); } }, [show, form]); @@ -122,8 +148,11 @@ export default function CreateUserDialog({ form.reset({ user: "", password: "", + confirmPassword: "", role: "viewer", }); + setShowPasswordVisible(false); + setShowConfirmPassword(false); onCancel(); }; @@ -184,13 +213,88 @@ export default function CreateUserDialog({ {t("users.dialog.form.password.title")} - +
    + + +
    + + {password && ( +
    +
    +
    +
    +

    + {t("users.dialog.form.password.strength.title")} + + {getPasswordStrengthLabel(password, t)} + +

    + +
    +

    + {t("users.dialog.form.password.requirements.title")} +

    +
      +
    • + {requirements.length ? ( + + ) : ( + + )} + + {t( + "users.dialog.form.password.requirements.length", + )} + +
    • +
    +
    +
    + )} + )} @@ -204,14 +308,41 @@ export default function CreateUserDialog({ {t("users.dialog.form.password.confirm.title")} - +
    + + +
    {showMatchIndicator && (
    diff --git a/web/src/components/overlay/SetPasswordDialog.tsx b/web/src/components/overlay/SetPasswordDialog.tsx index 7708201aa..084a841e4 100644 --- a/web/src/components/overlay/SetPasswordDialog.tsx +++ b/web/src/components/overlay/SetPasswordDialog.tsx @@ -28,6 +28,12 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { useIsAdmin } from "@/hooks/use-is-admin"; +import { + calculatePasswordStrength, + getPasswordRequirements, + getPasswordStrengthLabel, + getPasswordStrengthColor, +} from "@/utils/passwordUtil"; type SetPasswordProps = { show: boolean; @@ -70,13 +76,7 @@ export default function SetPasswordDialog({ const baseSchema = { password: z .string() - .min(8, t("users.dialog.form.password.requirements.length")) - .regex(/[A-Z]/, t("users.dialog.form.password.requirements.uppercase")) - .regex(/\d/, t("users.dialog.form.password.requirements.digit")) - .regex( - /[!@#$%^&*(),.?":{}|<>]/, - t("users.dialog.form.password.requirements.special"), - ), + .min(12, t("users.dialog.form.password.requirements.length")), confirmPassword: z.string(), }; @@ -125,25 +125,13 @@ export default function SetPasswordDialog({ const confirmPassword = form.watch("confirmPassword"); // Password strength calculation - const passwordStrength = useMemo(() => { - if (!password) return 0; - - let strength = 0; - if (password.length >= 8) strength += 1; - if (/\d/.test(password)) strength += 1; - if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) strength += 1; - if (/[A-Z]/.test(password)) strength += 1; - - return strength; - }, [password]); + const passwordStrength = useMemo( + () => calculatePasswordStrength(password), + [password], + ); const requirements = useMemo( - () => ({ - length: password?.length >= 8, - uppercase: /[A-Z]/.test(password || ""), - digit: /\d/.test(password || ""), - special: /[!@#$%^&*(),.?":{}|<>]/.test(password || ""), - }), + () => getPasswordRequirements(password), [password], ); @@ -196,25 +184,6 @@ export default function SetPasswordDialog({ onSave(values.password, oldPassword); }; - const getStrengthLabel = () => { - if (!password) return ""; - if (passwordStrength <= 1) - return t("users.dialog.form.password.strength.weak"); - if (passwordStrength === 2) - return t("users.dialog.form.password.strength.medium"); - if (passwordStrength === 3) - return t("users.dialog.form.password.strength.strong"); - return t("users.dialog.form.password.strength.veryStrong"); - }; - - const getStrengthColor = () => { - if (!password) return "bg-gray-200"; - if (passwordStrength <= 1) return "bg-red-500"; - if (passwordStrength === 2) return "bg-yellow-500"; - if (passwordStrength === 3) return "bg-green-500"; - return "bg-green-600"; - }; - return ( @@ -367,14 +336,16 @@ export default function SetPasswordDialog({

    {t("users.dialog.form.password.strength.title")} - {getStrengthLabel()} + {getPasswordStrengthLabel(password, t)}

    @@ -401,60 +372,6 @@ export default function SetPasswordDialog({ )} -
  • - {requirements.uppercase ? ( - - ) : ( - - )} - - {t( - "users.dialog.form.password.requirements.uppercase", - )} - -
  • -
  • - {requirements.digit ? ( - - ) : ( - - )} - - {t( - "users.dialog.form.password.requirements.digit", - )} - -
  • -
  • - {requirements.special ? ( - - ) : ( - - )} - - {t( - "users.dialog.form.password.requirements.special", - )} - -
  • diff --git a/web/src/components/overlay/detail/FaceCreateWizardDialog.tsx b/web/src/components/overlay/detail/FaceCreateWizardDialog.tsx index 6436ef040..86eae6acb 100644 --- a/web/src/components/overlay/detail/FaceCreateWizardDialog.tsx +++ b/web/src/components/overlay/detail/FaceCreateWizardDialog.tsx @@ -128,6 +128,8 @@ export default function CreateFaceWizardDialog({ }} regexPattern={/^[\p{L}\p{N}\s'_-]{1,50}$/u} regexErrorMessage={t("description.invalidName")} + forbiddenPattern={/#/} + forbiddenErrorMessage={t("description.nameCannotContainHash")} >
    - - {t("markAsReviewed")} - - )} + + + + + {t("markAsReviewed")} + {previews != undefined && alertVideosLoaded && (
    { + if (review.data.objects.includes(text)) return "object"; + if (review.data.audio.includes(text)) return "audio"; + if (review.data.sub_labels?.includes(text)) return "manual"; + return "object"; + }; + return (
    item !== undefined && !item.includes("-verified"), ) - .map((text) => getTranslatedLabel(text)) + .map((text) => getTranslatedLabel(text, getEventType(text))) .sort() .join(", ")} From e1c273be8d777e277076a9816179e0d1f2d46822 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:03:57 +0100 Subject: [PATCH 88/98] Translated using Weblate (German) Currently translated at 100.0% (54 of 54 strings) Translated using Weblate (German) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (German) Currently translated at 100.0% (217 of 217 strings) Co-authored-by: Hosted Weblate Co-authored-by: Sebastian Sie Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/de/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/de/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/de/common.json | 3 ++- web/public/locales/de/views/faceLibrary.json | 3 ++- web/public/locales/de/views/settings.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/web/public/locales/de/common.json b/web/public/locales/de/common.json index c24eaf5bd..8ecd25ab6 100644 --- a/web/public/locales/de/common.json +++ b/web/public/locales/de/common.json @@ -179,7 +179,8 @@ "lt": "Lietuvių (Litauisch)", "bg": "Български (bulgarisch)", "gl": "Galego (Galicisch)", - "id": "Bahasa Indonesia (Indonesisch)" + "id": "Bahasa Indonesia (Indonesisch)", + "hr": "Hrvatski (Kroatisch)" }, "appearance": "Erscheinung", "theme": { diff --git a/web/public/locales/de/views/faceLibrary.json b/web/public/locales/de/views/faceLibrary.json index 1c96176e5..8461b1f69 100644 --- a/web/public/locales/de/views/faceLibrary.json +++ b/web/public/locales/de/views/faceLibrary.json @@ -2,7 +2,8 @@ "description": { "placeholder": "Gib einen Name für diese Kollektion ein", "addFace": "Füge der Gesichtsbibliothek eine neue Sammlung hinzu, indem du ein Bild hochlädst.", - "invalidName": "Ungültiger Name. Namen dürfen nur Buchstaben, Zahlen, Leerzeichen, Apostrophe, Unterstriche und Bindestriche enthalten." + "invalidName": "Ungültiger Name. Namen dürfen nur Buchstaben, Zahlen, Leerzeichen, Apostrophe, Unterstriche und Bindestriche enthalten.", + "nameCannotContainHash": "Der Name darf keine # enthalten." }, "details": { "person": "Person", diff --git a/web/public/locales/de/views/settings.json b/web/public/locales/de/views/settings.json index 49f606523..eb434e4d5 100644 --- a/web/public/locales/de/views/settings.json +++ b/web/public/locales/de/views/settings.json @@ -544,7 +544,7 @@ "placeholder": "Passwort eingeben", "requirements": { "title": "Passwort Anforderungen:", - "length": "Mindestens 8 Zeichen", + "length": "Mindestens 12 Zeichen", "uppercase": "Mindestens ein Großbuchstabe", "digit": "Mindestens eine Ziffer", "special": "Mindestens ein Sonderzeichen (!@#$%^&*(),.?\":{}|<>)" From 2cfb118981d0d51cf18cf9542f24ae0a3d20e376 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:03:58 +0100 Subject: [PATCH 89/98] Translated using Weblate (Danish) Currently translated at 39.1% (196 of 501 strings) Translated using Weblate (Danish) Currently translated at 56.1% (55 of 98 strings) Translated using Weblate (Danish) Currently translated at 100.0% (217 of 217 strings) Translated using Weblate (Danish) Currently translated at 100.0% (25 of 25 strings) Co-authored-by: Bjorn Jorgensen Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/da/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/da/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-player/da/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/da/ Translation: Frigate NVR/audio Translation: Frigate NVR/common Translation: Frigate NVR/components-player Translation: Frigate NVR/views-live --- web/public/locales/da/audio.json | 4 +- web/public/locales/da/common.json | 21 ++-- web/public/locales/da/components/player.json | 25 +++-- web/public/locales/da/views/live.json | 100 ++++++++++++++++++- 4 files changed, 130 insertions(+), 20 deletions(-) diff --git a/web/public/locales/da/audio.json b/web/public/locales/da/audio.json index 5c7ee6756..168ef4c67 100644 --- a/web/public/locales/da/audio.json +++ b/web/public/locales/da/audio.json @@ -27,7 +27,7 @@ "harp": "Harpe", "bell": "Klokke", "harmonica": "Harmonika", - "bagpipes": "Sækkepibe", + "bagpipes": "Sækkepiber", "didgeridoo": "Didgeridoo", "jazz": "Jazz", "opera": "Opera", @@ -78,7 +78,7 @@ "camera": "Kamera", "tools": "Værktøj", "hammer": "Hammer", - "drill": "Bore", + "drill": "Boremaskine", "explosion": "Eksplosion", "fireworks": "Nytårskrudt", "babbling": "Pludren", diff --git a/web/public/locales/da/common.json b/web/public/locales/da/common.json index 13740b9c7..62b6d7036 100644 --- a/web/public/locales/da/common.json +++ b/web/public/locales/da/common.json @@ -193,7 +193,8 @@ "bg": "Български (Bulgarsk)", "gl": "Galego (Galisisk)", "id": "Bahasa Indonesia (Indonesisk)", - "ur": "اردو (Urdu)" + "ur": "اردو (Urdu)", + "hr": "Hrvatski (Kroatisk)" }, "appearance": "Udseende", "darkMode": { @@ -221,7 +222,7 @@ }, "restart": "Genstart Frigate", "live": { - "title": "Live", + "title": "Direkte", "allCameras": "Alle kameraer", "cameras": { "title": "Kameraer", @@ -240,17 +241,17 @@ "current": "Aktiv bruger: {{user}}", "anonymous": "anonym", "logout": "Log ud", - "setPassword": "Set Password" + "setPassword": "Vælg kodeord" }, "classification": "Kategorisering" }, "toast": { - "copyUrlToClipboard": "Kopieret URL til klippebord.", + "copyUrlToClipboard": "Kopieret URL til udklipsholder.", "save": { "title": "Gem", "error": { - "title": "Ændringer kan ikke gemmes: {{errorMessage}}", - "noMessage": "Kan ikke gemme konfigurationsændringer" + "title": "Ændringer kunne ikke gemmes: {{errorMessage}}", + "noMessage": "Kunne ikke gemme konfigurationsændringer" } } }, @@ -261,7 +262,7 @@ "desc": "Admins har fuld adgang til Frigate UI. Viewers er begrænset til at se kameraer, gennemse items, og historik i UI." }, "pagination": { - "label": "paginering", + "label": "sideinddeling", "previous": { "title": "Forrige", "label": "Gå til forrige side" @@ -273,9 +274,9 @@ "more": "Flere sider" }, "accessDenied": { - "documentTitle": "Adgang forbudt - Frigate", - "title": "Adgang forbudt", - "desc": "Du har ikke tiiladelse til at se denne side." + "documentTitle": "Adgang nægtet - Frigate", + "title": "Adgang nægtet", + "desc": "Du har ikke rettigheder til at se denne side." }, "notFound": { "documentTitle": "Ikke fundet - Frigate", diff --git a/web/public/locales/da/components/player.json b/web/public/locales/da/components/player.json index b7ab20e5b..9f9676ba3 100644 --- a/web/public/locales/da/components/player.json +++ b/web/public/locales/da/components/player.json @@ -4,13 +4,13 @@ "cameraDisabled": "Kamera er deaktiveret", "noPreviewFoundFor": "Ingen forhåndsvisning fundet for {{cameraName}}", "submitFrigatePlus": { - "title": "Indsend denne frame til Frigate+?", + "title": "Indsend dette billede til Frigate+?", "submit": "Indsend" }, "livePlayerRequiredIOSVersion": "iOS 17.1 eller nyere kræves for denne type livestream.", "streamOffline": { "title": "Stream offline", - "desc": "Der er ikke modtaget nogen frames på {{cameraName}}-detect-streamen, tjek fejlloggene." + "desc": "Der er ikke modtaget nogen billeder på {{cameraName}}-detect-streamen, tjek fejllogs." }, "stats": { "streamType": { @@ -18,8 +18,8 @@ "short": "Type" }, "bandwidth": { - "title": "Bandbredde:", - "short": "Bandbredde" + "title": "Båndbredde:", + "short": "Båndbredde" }, "latency": { "title": "Latenstid:", @@ -31,8 +31,21 @@ }, "droppedFrames": { "short": { - "title": "Tabt" - } + "title": "Tabt", + "value": "{{droppedFrames}} billeder" + }, + "title": "Tabte billeder:" + }, + "totalFrames": "Antal billeder i alt:", + "decodedFrames": "Dekodede billeder:", + "droppedFrameRate": "Rate for tabte billeder:" + }, + "toast": { + "success": { + "submittedFrigatePlus": "Billede sendt til Frigate+" + }, + "error": { + "submitFrigatePlusFailed": "Kunne ikke sende billede til Frigate+" } } } diff --git a/web/public/locales/da/views/live.json b/web/public/locales/da/views/live.json index 254539b38..6de5619fd 100644 --- a/web/public/locales/da/views/live.json +++ b/web/public/locales/da/views/live.json @@ -14,8 +14,104 @@ "move": { "clickMove": { "label": "Klik i billedrammen for at centrere kameraet", - "enable": "Aktivér klik for at flytte" + "enable": "Aktivér klik for at flytte", + "disable": "Deaktiver klik for at flytte" + }, + "left": { + "label": "Flyt PTZ-kameraet til venstre" + }, + "up": { + "label": "Flyt PTZ kamera op" + }, + "down": { + "label": "Flyt PTZ-kameraet ned" + }, + "right": { + "label": "Flyt PTZ-kameraet til højre" } - } + }, + "zoom": { + "in": { + "label": "Zoom PTZ-kamera ind" + }, + "out": { + "label": "Zoom PTZ kamera ud" + } + }, + "focus": { + "in": { + "label": "Focus PTZ kamera ind" + }, + "out": { + "label": "Focus PTZ kamera ud" + } + }, + "frame": { + "center": { + "label": "Klik på billedet for at centrere PTZ-kameraet" + } + }, + "presets": "PTZ kamera forudindstillinger" + }, + "camera": { + "enable": "Aktivér kamera", + "disable": "Deaktivér kamera" + }, + "muteCameras": { + "enable": "Slå lyd på alle kameraer fra", + "disable": "Slå lyd på alle kameraer til" + }, + "detect": { + "enable": "Aktiver detektering", + "disable": "Deaktiver detektering" + }, + "recording": { + "enable": "Aktivér optagelse", + "disable": "Deaktiver optagelse" + }, + "snapshots": { + "enable": "Aktivér Snapshots", + "disable": "Deaktivér Snapshots" + }, + "snapshot": { + "takeSnapshot": "Hent instant snapshot", + "noVideoSource": "Ingen videokilde til snapshot.", + "captureFailed": "Kunne ikke tage snapshot.", + "downloadStarted": "Hentning af snapshot startet." + }, + "audioDetect": { + "enable": "Aktiver lyddetektor", + "disable": "Deaktiver lyddetektor" + }, + "transcription": { + "enable": "Aktiver Live Audio Transkription", + "disable": "Deaktiver Live Audio Transkription" + }, + "autotracking": { + "enable": "Aktiver Autotracking", + "disable": "Deaktiver Autotracking" + }, + "streamStats": { + "enable": "Vis Stream statistik", + "disable": "Skjul Stream statistik" + }, + "manualRecording": { + "title": "Manuel optagelse", + "tips": "Hent et øjebliksbillede eller start en manuel begivenhed baseret på dette kameras indstillinger for optagelse af opbevaring.", + "playInBackground": { + "label": "Afspil i baggrunden", + "desc": "Aktiver denne mulighed for at fortsætte streaming, når afspilleren er skjult." + }, + "showStats": { + "label": "Vis statistik", + "desc": "Aktiver denne mulighed for at vise streamstatistikker som en overlejring på kameraets feed." + }, + "debugView": "Debug View", + "start": "Start on-demand optagelse", + "started": "Start manuel optagelse.", + "failedToStart": "Manuel optagelse fejlede.", + "recordDisabledTips": "Da optagelsen er deaktiveret eller begrænset i konfig for dette kamera, gemmes der kun et snapshot.", + "end": "Afslut manuel optagelse", + "ended": "Afsluttet manuel optagelse." } } From 11576e9e68c702860dfff0fb707a56da911f0767 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:03:59 +0100 Subject: [PATCH 90/98] Translated using Weblate (Estonian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 29.4% (192 of 651 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (217 of 217 strings) Translated using Weblate (Estonian) Currently translated at 33.0% (45 of 136 strings) Co-authored-by: Hosted Weblate Co-authored-by: Priit Jõerüüt Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-explore/et/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/et/ Translation: Frigate NVR/common Translation: Frigate NVR/views-explore Translation: Frigate NVR/views-settings --- web/public/locales/et/common.json | 3 +- web/public/locales/et/views/explore.json | 21 +- web/public/locales/et/views/settings.json | 252 +++++++++++++++++++++- 3 files changed, 260 insertions(+), 16 deletions(-) diff --git a/web/public/locales/et/common.json b/web/public/locales/et/common.json index 4c9055524..8f68c3cb8 100644 --- a/web/public/locales/et/common.json +++ b/web/public/locales/et/common.json @@ -139,7 +139,8 @@ "bg": "Български (bulgaaria keel)", "gl": "Galego (galeegi keel)", "id": "Bahasa Indonesia (indoneesia keel)", - "ur": "اردو (urdu keel)" + "ur": "اردو (urdu keel)", + "hr": "Hrvatski (horvaadi keel)" }, "system": "Süsteem", "systemMetrics": "Süsteemi meetrika", diff --git a/web/public/locales/et/views/explore.json b/web/public/locales/et/views/explore.json index 76592a97d..1676f3ccd 100644 --- a/web/public/locales/et/views/explore.json +++ b/web/public/locales/et/views/explore.json @@ -30,11 +30,21 @@ "stationary": "{{label}} jäi paigale", "active": "{{label}} muutus aktiivseks", "entered_zone": "{{label}} sisenes tsooni {{zones}}", - "visible": "{{label}} on tuvastatud" + "visible": "{{label}} on tuvastatud", + "header": { + "zones": "Tsoonid", + "ratio": "Suhtarv", + "area": "Ala", + "score": "Punktiskoor" + } }, "title": "Jälgimise üksikasjad", "noImageFound": "Selle ajatempli kohta ei leidu pilti.", - "createObjectMask": "Loo objektimask" + "createObjectMask": "Loo objektimask", + "carousel": { + "previous": "Eelmine slaid", + "next": "Järgmine slaid" + } }, "documentTitle": "Avasta - Frigate", "generativeAI": "Generatiivne tehisaru", @@ -63,12 +73,15 @@ "tips": { "mismatch_one": "Tuvastasin {{count}} võõra objekti ja need on lisatud ülevaatamiseks. Need objektid kas ei ole piisavad häire või tuvastamise jaoks, aga ka võivad juba olla eemaldatud või kustutatud.", "mismatch_other": "Tuvastasin {{count}} võõrast objekti ja need on lisatud ülevaatamiseks. Need objektid kas ei ole piisavad häire või tuvastamise jaoks, aga ka võivad juba olla eemaldatud või kustutatud." - } + }, + "title": "Vaata objekti üksikasju", + "desc": "Vaata objekti üksikasju" }, "snapshotScore": { "label": "Hetkvõttete punktiskoor" }, "regenerateFromSnapshot": "Loo uuesti hetkvõttest", "timestamp": "Ajatampel" - } + }, + "trackedObjectDetails": "Jälgitava objekti üksikasjad" } diff --git a/web/public/locales/et/views/settings.json b/web/public/locales/et/views/settings.json index c3398cf7b..ce100a719 100644 --- a/web/public/locales/et/views/settings.json +++ b/web/public/locales/et/views/settings.json @@ -4,10 +4,23 @@ "password": "Salasõna", "passwordPlaceholder": "Valikuline", "customUrlPlaceholder": "rtsp://kasutajanimi:salasõna@host:port/asukoht", - "connectionSettings": "Ühenduse seadistused" + "connectionSettings": "Ühenduse seadistused", + "port": "Port", + "username": "Kasutajanimi", + "usernamePlaceholder": "Valikuline" }, "step3": { - "streamUrlPlaceholder": "rtsp://kasutajanimi:salasõna@host:port/asukoht" + "streamUrlPlaceholder": "rtsp://kasutajanimi:salasõna@host:port/asukoht", + "url": "Võrguaadress", + "resolution": "Resolutsioon", + "quality": "Kvaliteet", + "roles": "Rollid", + "roleLabels": { + "record": "Salvestamine", + "audio": "Heliriba" + }, + "connected": "Ühendatud", + "featuresTitle": "Funktsionaalsused" }, "steps": { "probeOrSnapshot": "Võta proov või tee hetkvõte" @@ -15,7 +28,34 @@ "step2": { "testing": { "fetchingSnapshot": "Laadin kaamera hetkvõtet alla..." - } + }, + "retry": "Proovi uuesti", + "manufacturer": "Tootja", + "model": "Mudel", + "firmware": "Püsivara", + "profiles": "Profiilid", + "presets": "Eelseadistused", + "useCandidate": "Kasuta", + "uriCopy": "Kopeeri", + "connected": "Ühendatud" + }, + "testResultLabels": { + "resolution": "Resolutsioon", + "video": "Video", + "audio": "Heliriba", + "fps": "Kaadrisagedus" + }, + "step4": { + "reload": "Laadi uuesti", + "connecting": "Ühendan…", + "valid": "Kehtiv", + "failed": "Ebaõnnestunud", + "connectStream": "Ühenda", + "connectingStream": "Ühendan", + "disconnectStream": "Katkesta ühendus", + "roles": "Rollid", + "none": "Määramata", + "error": "Viga" } }, "users": { @@ -29,7 +69,10 @@ } }, "table": { - "password": "Lähtesta salasõna" + "password": "Lähtesta salasõna", + "username": "Kasutajanimi", + "actions": "Tegevused", + "role": "Roll" }, "dialog": { "form": { @@ -53,7 +96,7 @@ "hide": "Peida salasõna", "requirements": { "title": "Salasõna reeglid:", - "length": "Vähemalt 8 tähemärki", + "length": "Vähemalt 12 tähemärki", "uppercase": "Vähemalt üks suurtäht", "digit": "Vähemalt üks number", "special": "Vähemalt üks erimärk (!@#$%^&*(),.?\":{}|<>)" @@ -70,6 +113,9 @@ "currentPassword": { "title": "Senine salasõna", "placeholder": "Sisesta oma senine salasõna" + }, + "user": { + "title": "Kasutajanimi" } }, "createUser": { @@ -84,12 +130,42 @@ "currentPasswordRequired": "Senine salasõna on vajalik", "incorrectCurrentPassword": "Senine salasõna pole õige", "passwordVerificationFailed": "Salasõna kontrollimine ei õnnestunud" + }, + "changeRole": { + "roleInfo": { + "admin": "Peakasutaja", + "viewer": "Vaataja" + } } - } + }, + "title": "Kasutajad" }, "debug": { "boundingBoxes": { "desc": "Näita jälgitavate objektide ümber märgiskaste" + }, + "title": "Silumine ja veaotsing", + "debugging": "Veaotsing ja silumine", + "audio": { + "title": "Heliriba", + "score": "punktiskoor" + }, + "timestamp": { + "title": "Ajatempel" + }, + "zones": { + "title": "Tsoonid" + }, + "regions": { + "title": "Alad" + }, + "paths": { + "title": "Asukohad" + }, + "objectShapeFilterDrawing": { + "score": "Punktiskoor", + "ratio": "Suhtarv", + "area": "Ala" } }, "documentTitle": { @@ -113,10 +189,31 @@ "automaticLiveView": { "label": "Automaatne otseülekande vaade" } + }, + "calendar": { + "title": "Kalender", + "firstWeekday": { + "sunday": "Pühapäev", + "monday": "Esmaspäev", + "label": "Esimene nädalapäev" + } + }, + "storedLayouts": { + "title": "Salvestatud paigutused" + }, + "recordingsViewer": { + "title": "Salvestuste vaataja" } }, "cameraManagement": { - "backToSettings": "Tagasi kaameraseadistuste juurde" + "backToSettings": "Tagasi kaameraseadistuste juurde", + "cameraConfig": { + "enabled": "Kasutusel", + "ffmpeg": { + "pathPlaceholder": "rtsp://...", + "roles": "Rollid" + } + } }, "notification": { "notificationSettings": { @@ -130,6 +227,16 @@ "success": { "settingSaved": "Teavituste seadistused on salvestatud." } + }, + "title": "Teavitused", + "email": { + "title": "E-post" + }, + "cameras": { + "title": "Kaamerad" + }, + "suspendTime": { + "suspend": "Peata arvuti töö" } }, "frigatePlus": { @@ -145,20 +252,48 @@ "cleanCopySnapshots": "clean_copy Hetkvõtted", "camera": "Kaamera" } + }, + "modelInfo": { + "plusModelType": { + "userModel": "Peenhäälestatud" + }, + "cameras": "Kaamerad" } }, "masksAndZones": { "zones": { "point_one": "{{count}} punkt", - "point_other": "{{count}} punkti" + "point_other": "{{count}} punkti", + "label": "Tsoonid", + "desc": { + "documentation": "Dokumentatsioon" + }, + "name": { + "title": "Nimi" + }, + "inertia": { + "title": "Inerts" + }, + "objects": { + "title": "Objektid" + } }, "motionMasks": { "point_one": "{{count}} punkt", - "point_other": "{{count}} punkti" + "point_other": "{{count}} punkti", + "desc": { + "documentation": "Dokumentatsioon" + } }, "objectMasks": { "point_one": "{{count}} punkt", - "point_other": "{{count}} punkti" + "point_other": "{{count}} punkti", + "desc": { + "documentation": "Dokumentatsioon" + }, + "objects": { + "title": "Objektid" + } } }, "roles": { @@ -167,6 +302,21 @@ "userRolesUpdated_one": "{{count}} selle rolliga kasutaja on nüüd määratud Vaatajaks, kellel on ligipääs kõikidele kaameratele.", "userRolesUpdated_other": "{{count}} selle rolliga kasutajat on nüüd määratud Vaatajaks, kellel on ligipääs kõikidele kaameratele." } + }, + "table": { + "role": "Roll", + "cameras": "Kaamerad", + "actions": "Tegevused" + }, + "dialog": { + "deleteRole": { + "deleting": "Kustutan..." + }, + "form": { + "cameras": { + "title": "Kaamerad" + } + } } }, "menu": { @@ -178,7 +328,8 @@ "users": "Kasutajad", "roles": "Rollid", "notifications": "Teavitused", - "frigateplus": "Frigate+" + "frigateplus": "Frigate+", + "cameraReview": "Ülevaatamine" }, "dialog": { "unsavedChanges": { @@ -189,5 +340,84 @@ "cameraSetting": { "camera": "Kaamera", "noCamera": "Kaamerat pole" + }, + "enrichments": { + "semanticSearch": { + "reindexNow": { + "confirmButton": "Indekseeri uuesti", + "label": "Indekseeri uuesti kohe" + }, + "modelSize": { + "small": { + "title": "väike" + }, + "large": { + "title": "suur" + } + }, + "title": "Semantiline otsing" + }, + "faceRecognition": { + "modelSize": { + "small": { + "title": "väike" + }, + "large": { + "title": "suur" + } + } + }, + "birdClassification": { + "title": "Lindude klassifikatsioon" + } + }, + "cameraReview": { + "review": { + "title": "Ülevaatamine", + "alerts": "Hoiatused ", + "detections": "Tuvastamise tulemused " + } + }, + "motionDetectionTuner": { + "Threshold": { + "title": "Lävi" + } + }, + "triggers": { + "documentTitle": "Päästikud", + "management": { + "title": "Päästikud" + }, + "table": { + "name": "Nimi", + "type": "Tüüp", + "content": "Sisu", + "threshold": "Lävi", + "actions": "Tegevused", + "edit": "Muuda" + }, + "type": { + "thumbnail": "Pisipilt", + "description": "Kirjeldus" + }, + "dialog": { + "form": { + "name": { + "title": "Nimi" + }, + "type": { + "title": "Tüüp" + }, + "content": { + "title": "Sisu" + }, + "threshold": { + "title": "Lävi" + }, + "actions": { + "title": "Tegevused" + } + } + } } } From ecd7d042288fba2a7d8b1e59e160a0286504b47e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:01 +0100 Subject: [PATCH 91/98] Translated using Weblate (Romanian) Currently translated at 100.0% (217 of 217 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (54 of 54 strings) Co-authored-by: Hosted Weblate Co-authored-by: lukasig Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ro/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/ro/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/ro/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/ro/common.json | 3 ++- web/public/locales/ro/views/faceLibrary.json | 3 ++- web/public/locales/ro/views/settings.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/web/public/locales/ro/common.json b/web/public/locales/ro/common.json index 77824732e..1148d60c8 100644 --- a/web/public/locales/ro/common.json +++ b/web/public/locales/ro/common.json @@ -135,7 +135,8 @@ "bg": "Български (Bulgară)", "gl": "Galego (Galiciană)", "id": "Bahasa Indonesia (Indoneziană)", - "ur": "اردو (Urdu)" + "ur": "اردو (Urdu)", + "hr": "Hrvatski (Croată)" }, "theme": { "default": "Implicit", diff --git a/web/public/locales/ro/views/faceLibrary.json b/web/public/locales/ro/views/faceLibrary.json index 360143d5d..570db33fb 100644 --- a/web/public/locales/ro/views/faceLibrary.json +++ b/web/public/locales/ro/views/faceLibrary.json @@ -2,7 +2,8 @@ "description": { "addFace": "Adaugă o colecție nouă în Biblioteca de fețe încărcând prima ta imagine.", "placeholder": "Introduceti un nume pentru aceasta colectie", - "invalidName": "Nume invalid. Numele pot include doar litere, cifre, spații, apostrofuri, underscore-uri și liniuțe." + "invalidName": "Nume invalid. Numele pot include doar litere, cifre, spații, apostrofuri, underscore-uri și liniuțe.", + "nameCannotContainHash": "Numele nu poate conține #." }, "details": { "person": "Persoană", diff --git a/web/public/locales/ro/views/settings.json b/web/public/locales/ro/views/settings.json index d03eda352..3a8da57f0 100644 --- a/web/public/locales/ro/views/settings.json +++ b/web/public/locales/ro/views/settings.json @@ -508,7 +508,7 @@ "hide": "Ascunde parola", "requirements": { "title": "Cerințe parolă:", - "length": "Cel puțin 8 caracter", + "length": "Cel puțin 12 caractere", "uppercase": "Cel puțin o literă majusculă", "digit": "Cel puțin o cifră", "special": "Cel puțin un caracter special (!@#$%^&*(),.?\":{}|<>)" From 92c503070c342c0d145f4a1e853e1237688fc7b6 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:02 +0100 Subject: [PATCH 92/98] Translated using Weblate (Japanese) Currently translated at 100.0% (98 of 98 strings) Translated using Weblate (Japanese) Currently translated at 99.2% (135 of 136 strings) Translated using Weblate (Japanese) Currently translated at 99.5% (216 of 217 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (54 of 54 strings) Co-authored-by: Hosted Weblate Co-authored-by: Yusuke, Hirota Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ja/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/ja/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-live/ja/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/ja/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-live Translation: Frigate NVR/views-system --- web/public/locales/ja/common.json | 6 ++++-- web/public/locales/ja/views/faceLibrary.json | 3 ++- web/public/locales/ja/views/live.json | 10 ++++++++++ web/public/locales/ja/views/system.json | 8 +++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/web/public/locales/ja/common.json b/web/public/locales/ja/common.json index 7cef62aa5..18407fc2a 100644 --- a/web/public/locales/ja/common.json +++ b/web/public/locales/ja/common.json @@ -69,7 +69,8 @@ }, "inProgress": "処理中", "invalidStartTime": "開始時刻が無効です", - "invalidEndTime": "終了時刻が無効です" + "invalidEndTime": "終了時刻が無効です", + "never": "なし" }, "readTheDocumentation": "ドキュメントを見る", "unit": { @@ -232,7 +233,8 @@ "ur": "اردو (ウルドゥー語)", "withSystem": { "label": "システム設定に従う" - } + }, + "hr": "Hrvatski (クロアチア語)" }, "classification": "分類" }, diff --git a/web/public/locales/ja/views/faceLibrary.json b/web/public/locales/ja/views/faceLibrary.json index 5b9392caf..fdf43a65c 100644 --- a/web/public/locales/ja/views/faceLibrary.json +++ b/web/public/locales/ja/views/faceLibrary.json @@ -2,7 +2,8 @@ "description": { "placeholder": "このコレクションの名前を入力", "addFace": "最初の画像をアップロードして、フェイスライブラリに新しいコレクションを追加してください。", - "invalidName": "無効な名前です。使用できるのは、英数字、空白、アポストロフィ、アンダースコア、ハイフンのみです。" + "invalidName": "無効な名前です。使用できるのは、英数字、空白、アポストロフィ、アンダースコア、ハイフンのみです。", + "nameCannotContainHash": "名前に # は使用できません。" }, "details": { "person": "人物", diff --git a/web/public/locales/ja/views/live.json b/web/public/locales/ja/views/live.json index f88901ab8..fe73c1d08 100644 --- a/web/public/locales/ja/views/live.json +++ b/web/public/locales/ja/views/live.json @@ -176,6 +176,16 @@ "restricted": { "title": "利用可能なカメラがありません", "description": "このグループ内のカメラを表示する権限がありません。" + }, + "default": { + "title": "設定済みのカメラがありません", + "description": "Frigate にカメラを接続して開始しましょう。", + "buttonText": "カメラを追加" + }, + "group": { + "title": "このグループにカメラがありません", + "description": "このカメラグループには、割り当て済みまたは有効なカメラがありません。", + "buttonText": "グループを管理" } }, "snapshot": { diff --git a/web/public/locales/ja/views/system.json b/web/public/locales/ja/views/system.json index 222b65b3c..0f95b300e 100644 --- a/web/public/locales/ja/views/system.json +++ b/web/public/locales/ja/views/system.json @@ -86,7 +86,13 @@ "otherProcesses": { "title": "その他のプロセス", "processCpuUsage": "プロセスの CPU 使用率", - "processMemoryUsage": "プロセスのメモリ使用量" + "processMemoryUsage": "プロセスのメモリ使用量", + "series": { + "recording": "録画", + "review_segment": "レビューセグメント", + "audio_detector": "音声検知", + "go2rtc": "go2rtc" + } } }, "storage": { From 334acd6078ec3624c24b2800bd66d2badb9f1b19 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:03 +0100 Subject: [PATCH 93/98] Translated using Weblate (Catalan) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (54 of 54 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (217 of 217 strings) Co-authored-by: Eduardo Pastor Fernández <123eduardoneko123@gmail.com> Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/ca/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/ca/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/ca/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/ca/common.json | 3 ++- web/public/locales/ca/views/faceLibrary.json | 3 ++- web/public/locales/ca/views/settings.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/web/public/locales/ca/common.json b/web/public/locales/ca/common.json index c845054a2..c5dd5434f 100644 --- a/web/public/locales/ca/common.json +++ b/web/public/locales/ca/common.json @@ -48,7 +48,8 @@ "bg": "Български (Búlgar)", "gl": "Galego (Gallec)", "id": "Bahasa Indonesia (Indonesi)", - "ur": "اردو (Urdú)" + "ur": "اردو (Urdú)", + "hr": "Hrvatski (croat)" }, "system": "Sistema", "systemMetrics": "Mètriques del sistema", diff --git a/web/public/locales/ca/views/faceLibrary.json b/web/public/locales/ca/views/faceLibrary.json index d2a5fcf34..069049255 100644 --- a/web/public/locales/ca/views/faceLibrary.json +++ b/web/public/locales/ca/views/faceLibrary.json @@ -19,7 +19,8 @@ "description": { "addFace": "Afegiu una col·lecció nova a la biblioteca de cares pujant la vostra primera imatge.", "placeholder": "Introduïu un nom per a aquesta col·lecció", - "invalidName": "Nom no vàlid. Els noms només poden incloure lletres, números, espais, apòstrofs, guions baixos i guions." + "invalidName": "Nom no vàlid. Els noms només poden incloure lletres, números, espais, apòstrofs, guions baixos i guions.", + "nameCannotContainHash": "El nom no pot contenir #." }, "documentTitle": "Biblioteca de rostres - Frigate", "uploadFaceImage": { diff --git a/web/public/locales/ca/views/settings.json b/web/public/locales/ca/views/settings.json index 9826656a8..7c90d9190 100644 --- a/web/public/locales/ca/views/settings.json +++ b/web/public/locales/ca/views/settings.json @@ -532,7 +532,7 @@ "hide": "Amaga contrasenya", "requirements": { "title": "Requisits contrasenya:", - "length": "Com a mínim 8 carácters", + "length": "Com a mínim 12 carácters", "uppercase": "Com a mínim una majúscula", "digit": "Com a mínim un digit", "special": "Com a mínim un carácter especial (!@#$%^&*(),.?\":{}|<>)" From 9fbc854bf5fef17002705426226612c0f0f95e3f Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:04 +0100 Subject: [PATCH 94/98] Translated using Weblate (Polish) Currently translated at 100.0% (217 of 217 strings) Translated using Weblate (Polish) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (Polish) Currently translated at 100.0% (54 of 54 strings) Co-authored-by: Hosted Weblate Co-authored-by: Kamil AvH Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/pl/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/pl/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/pl/common.json | 3 ++- web/public/locales/pl/views/faceLibrary.json | 3 ++- web/public/locales/pl/views/settings.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/web/public/locales/pl/common.json b/web/public/locales/pl/common.json index 3485d44aa..e6fea5b42 100644 --- a/web/public/locales/pl/common.json +++ b/web/public/locales/pl/common.json @@ -206,7 +206,8 @@ "bg": "Български (Bułgarski)", "gl": "Galego (Galicyjski)", "id": "Bahasa Indonesia (Indonezyjski)", - "ur": "اردو (Urdu)" + "ur": "اردو (Urdu)", + "hr": "Hrvatski (Chorwacki)" }, "appearance": "Wygląd", "darkMode": { diff --git a/web/public/locales/pl/views/faceLibrary.json b/web/public/locales/pl/views/faceLibrary.json index 4bd3944f8..19b6dbbe3 100644 --- a/web/public/locales/pl/views/faceLibrary.json +++ b/web/public/locales/pl/views/faceLibrary.json @@ -3,7 +3,8 @@ "description": { "addFace": "Dodaj nową kolekcję do biblioteki twarzy, przesyłając swoje pierwsze zdjęcie.", "placeholder": "Wprowadź nazwę tej kolekcji", - "invalidName": "Niepoprawna nazwa. Nazwy mogą zawierać tylko: litery, cyfry, spacje, cudzysłowy, podkreślniniki i myślniki." + "invalidName": "Niepoprawna nazwa. Nazwy mogą zawierać tylko: litery, cyfry, spacje, cudzysłowy, podkreślniniki i myślniki.", + "nameCannotContainHash": "Nazwa nie może zawierać #." }, "details": { "person": "Osoba", diff --git a/web/public/locales/pl/views/settings.json b/web/public/locales/pl/views/settings.json index dfc74b7dc..37a560444 100644 --- a/web/public/locales/pl/views/settings.json +++ b/web/public/locales/pl/views/settings.json @@ -543,7 +543,7 @@ "hide": "Ukryj hasło", "requirements": { "title": "Wymagania hasła:", - "length": "Co najmniej 8 znaków", + "length": "Co najmniej 12 znaków", "uppercase": "Co najmniej jedna duża litera", "digit": "Co najmniej jedna cyfra", "special": "Co najmniej jeden znak specjalny (!@#$%^&*(),.?\":{}|<>)" From 44e695362a5b1658bfe53ac102ad652538219054 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:06 +0100 Subject: [PATCH 95/98] Translated using Weblate (French) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (French) Currently translated at 100.0% (54 of 54 strings) Translated using Weblate (French) Currently translated at 100.0% (217 of 217 strings) Co-authored-by: Apocoloquintose Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/fr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/fr/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/fr/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/fr/common.json | 3 ++- web/public/locales/fr/views/faceLibrary.json | 3 ++- web/public/locales/fr/views/settings.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/web/public/locales/fr/common.json b/web/public/locales/fr/common.json index ae0535354..39820367c 100644 --- a/web/public/locales/fr/common.json +++ b/web/public/locales/fr/common.json @@ -175,7 +175,8 @@ "bg": "Български (Bulgare)", "gl": "Galego (Galicien)", "id": "Bahasa Indonesia (Indonésien)", - "ur": "اردو (Ourdou)" + "ur": "اردو (Ourdou)", + "hr": "Hrvatski (Croate)" }, "appearance": "Apparence", "darkMode": { diff --git a/web/public/locales/fr/views/faceLibrary.json b/web/public/locales/fr/views/faceLibrary.json index 7d65a5e91..4389786cd 100644 --- a/web/public/locales/fr/views/faceLibrary.json +++ b/web/public/locales/fr/views/faceLibrary.json @@ -2,7 +2,8 @@ "description": { "addFace": "Ajoutez une nouvelle collection à la bibliothèque de visages en téléversant votre première image.", "placeholder": "Saisissez un nom pour cette collection.", - "invalidName": "Nom invalide. Les noms ne peuvent contenir que des lettres, des chiffres, des espaces, des apostrophes, des traits de soulignement et des tirets." + "invalidName": "Nom invalide. Les noms ne peuvent contenir que des lettres, des chiffres, des espaces, des apostrophes, des traits de soulignement et des tirets.", + "nameCannotContainHash": "Le nom ne peut pas contenir le caractère #." }, "details": { "person": "Personne", diff --git a/web/public/locales/fr/views/settings.json b/web/public/locales/fr/views/settings.json index d608bc50e..2b989ac80 100644 --- a/web/public/locales/fr/views/settings.json +++ b/web/public/locales/fr/views/settings.json @@ -649,7 +649,7 @@ "hide": "Masquer le mot de passe", "requirements": { "title": "Critères du mot de passe :", - "length": "Au moins 8 caractères", + "length": "Au moins 12 caractères", "uppercase": "Au moins une lettre majuscule", "digit": "Au moins un chiffre", "special": "Au moins un caractère spécial (!@#$%^&*(),.?\":{}|<>)" From fc3f798bd6b6d7d6a268f5a1e471250674cc4640 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:08 +0100 Subject: [PATCH 96/98] Translated using Weblate (Swedish) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (54 of 54 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (217 of 217 strings) Co-authored-by: Hosted Weblate Co-authored-by: bittin1ddc447d824349b2 Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/sv/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/sv/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/sv/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/sv/common.json | 3 ++- web/public/locales/sv/views/faceLibrary.json | 3 ++- web/public/locales/sv/views/settings.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/web/public/locales/sv/common.json b/web/public/locales/sv/common.json index ccf3b6da6..d6c185dff 100644 --- a/web/public/locales/sv/common.json +++ b/web/public/locales/sv/common.json @@ -159,7 +159,8 @@ "bg": "Български (Bulgariska)", "gl": "Galego (Galiciska)", "id": "Bahasa Indonesia (Indonesiska)", - "ur": "اردو (Urdu)" + "ur": "اردو (Urdu)", + "hr": "Hrvatski (kroatiska)" }, "darkMode": { "withSystem": { diff --git a/web/public/locales/sv/views/faceLibrary.json b/web/public/locales/sv/views/faceLibrary.json index 485dfdd1f..76a80ce92 100644 --- a/web/public/locales/sv/views/faceLibrary.json +++ b/web/public/locales/sv/views/faceLibrary.json @@ -12,7 +12,8 @@ "description": { "placeholder": "Ange ett namn för denna samling", "addFace": "Lägg till en ny samling i ansiktsbiblioteket genom att ladda upp din första bild.", - "invalidName": "Ogiltigt namn. Namn får endast innehålla bokstäver, siffror, mellanslag, apostrofer, understreck och bindestreck." + "invalidName": "Ogiltigt namn. Namn får endast innehålla bokstäver, siffror, mellanslag, apostrofer, understreck och bindestreck.", + "nameCannotContainHash": "Namn får inte innehålla #." }, "documentTitle": "Ansiktsbibliotek - Frigate", "steps": { diff --git a/web/public/locales/sv/views/settings.json b/web/public/locales/sv/views/settings.json index 14b03a3bf..8f02a3f22 100644 --- a/web/public/locales/sv/views/settings.json +++ b/web/public/locales/sv/views/settings.json @@ -540,7 +540,7 @@ "hide": "Dölj lösenord", "requirements": { "title": "Lösenordskrav:", - "length": "Minst 8 tecken", + "length": "Minst 12 tecken", "uppercase": "Minst en stor bokstav", "digit": "Minst en siffra", "special": "Minst ett specialtecken (!@#$%^&*(),.?\":{}|<>)" From ff20be58b4e75a9d77ba57958dea3189b3a0a4f1 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:09 +0100 Subject: [PATCH 97/98] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (217 of 217 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (54 of 54 strings) Co-authored-by: GuoQing Liu <842607283@qq.com> Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/zh_Hans/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/zh-CN/common.json | 3 ++- web/public/locales/zh-CN/views/faceLibrary.json | 3 ++- web/public/locales/zh-CN/views/settings.json | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/web/public/locales/zh-CN/common.json b/web/public/locales/zh-CN/common.json index 51d82e621..28fa8bd48 100644 --- a/web/public/locales/zh-CN/common.json +++ b/web/public/locales/zh-CN/common.json @@ -208,7 +208,8 @@ "bg": "保加利亚语 (Български)", "gl": "加利西亚语 (Galego)", "id": "印度尼西亚语 (Bahasa Indonesia)", - "ur": "乌尔都语 (اردو)" + "ur": "乌尔都语 (اردو)", + "hr": "克罗地亚语(Hrvatski)" }, "appearance": "外观", "darkMode": { diff --git a/web/public/locales/zh-CN/views/faceLibrary.json b/web/public/locales/zh-CN/views/faceLibrary.json index 0e05f0df7..b8e9a9501 100644 --- a/web/public/locales/zh-CN/views/faceLibrary.json +++ b/web/public/locales/zh-CN/views/faceLibrary.json @@ -2,7 +2,8 @@ "description": { "addFace": "我们将引导你如何向人脸库中添加新的合集。", "placeholder": "请输入此合集的名称", - "invalidName": "名称无效。名称只能包含字母、数字、空格、撇号、下划线和连字符。" + "invalidName": "名称无效。名称只能包含字母、数字、空格、撇号、下划线和连字符。", + "nameCannotContainHash": "名称中不允许包含“#”符号。" }, "details": { "person": "人", diff --git a/web/public/locales/zh-CN/views/settings.json b/web/public/locales/zh-CN/views/settings.json index 7e141a943..b1e0a78d8 100644 --- a/web/public/locales/zh-CN/views/settings.json +++ b/web/public/locales/zh-CN/views/settings.json @@ -282,7 +282,7 @@ }, "delete": { "title": "确认删除", - "desc": "你确定要删除{{type}} {{name}} 吗?", + "desc": "你确定要删除{{type}} “{{name}}” 吗?", "success": "{{name}} 已被删除。" }, "error": { @@ -543,7 +543,7 @@ "hide": "隐藏密码", "requirements": { "title": "密码要求:", - "length": "至少8个字符", + "length": "至少需要 12 位字符", "uppercase": "至少一个大写字母", "digit": "至少一位数字", "special": "至少一个特殊符号 (!@#$%^&*(),.?\":{}|<>)" From 6accc382756f39d36f547e631b337dbb71728282 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 6 Feb 2026 17:04:11 +0100 Subject: [PATCH 98/98] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (651 of 651 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (217 of 217 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (54 of 54 strings) Translated using Weblate (Norwegian Bokmål) Currently translated at 100.0% (651 of 651 strings) Co-authored-by: Hosted Weblate Co-authored-by: OverTheHillsAndFarAway Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-facelibrary/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/nb_NO/ Translation: Frigate NVR/common Translation: Frigate NVR/views-facelibrary Translation: Frigate NVR/views-settings --- web/public/locales/nb-NO/common.json | 3 ++- web/public/locales/nb-NO/views/faceLibrary.json | 3 ++- web/public/locales/nb-NO/views/settings.json | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/web/public/locales/nb-NO/common.json b/web/public/locales/nb-NO/common.json index 190d04b14..a614cced1 100644 --- a/web/public/locales/nb-NO/common.json +++ b/web/public/locales/nb-NO/common.json @@ -203,7 +203,8 @@ "bg": "Български (Bulgarsk)", "gl": "Galego (Galisisk)", "id": "Bahasa Indonesia (Indonesisk)", - "ur": "اردو (Urdu)" + "ur": "اردو (Urdu)", + "hr": "Hrvatski (Kroatisk)" }, "appearance": "Utseende", "darkMode": { diff --git a/web/public/locales/nb-NO/views/faceLibrary.json b/web/public/locales/nb-NO/views/faceLibrary.json index d2e0f6bd4..89cc60aa1 100644 --- a/web/public/locales/nb-NO/views/faceLibrary.json +++ b/web/public/locales/nb-NO/views/faceLibrary.json @@ -3,7 +3,8 @@ "description": { "addFace": "Legg til en ny samling i ansiktsbiblioteket ved å laste opp ditt første bilde.", "placeholder": "Skriv inn et navn for denne samlingen", - "invalidName": "Ugyldig navn. Navn kan kun inneholde bokstaver, tall, mellomrom, apostrof, understrek og bindestrek." + "invalidName": "Ugyldig navn. Navn kan kun inneholde bokstaver, tall, mellomrom, apostrof, understrek og bindestrek.", + "nameCannotContainHash": "Navn kan ikke inneholde #." }, "details": { "person": "Person", diff --git a/web/public/locales/nb-NO/views/settings.json b/web/public/locales/nb-NO/views/settings.json index 2f6e44f23..d45554c1a 100644 --- a/web/public/locales/nb-NO/views/settings.json +++ b/web/public/locales/nb-NO/views/settings.json @@ -537,7 +537,7 @@ "hide": "Skjul passord", "requirements": { "title": "Passordkrav:", - "length": "Minst 8 tegn", + "length": "Minst 12 tegn", "uppercase": "Minst en stor bokstav", "digit": "Minst ett tall", "special": "Minst ett spesialtegn (!@#$%^&*(),.?\":{}|<>)" @@ -591,7 +591,7 @@ "incorrectCurrentPassword": "Nåværende passord er feil", "passwordVerificationFailed": "Kunne ikke verifisere passord", "multiDeviceWarning": "Andre enheter du er logget inn på vil kreve ny innlogging innen {{refresh_time}}.", - "multiDeviceAdmin": "Du kan også tvinge alle brukere til å logge inn på nytt umiddelbart ved å rotere JWT-hemmeligheten din." + "multiDeviceAdmin": "Du kan også tvinge alle brukere til å logge inn på nytt ved å endre JWT (JSON Web Token)-nøkkelen." } }, "table": {