@camstack/addon-post-analysis 1.2.369 → 1.2.370

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (15) hide show
  1. package/dist/{clip-model-registry-E4CGZ8NR.js → clip-model-registry-C3AUTkBR.js} +1618 -45
  2. package/dist/{clip-model-registry-C_-tWzrX.mjs → clip-model-registry-CCwyUQ7k.mjs} +1595 -46
  3. package/dist/embedding-encoder/index.js +1 -1
  4. package/dist/embedding-encoder/index.mjs +1 -1
  5. package/dist/pipeline-analytics/_stub.js +752 -631
  6. package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Bac17NNv.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-C1gR-74b.mjs} +3 -3
  7. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BRMRfKVO.mjs +26 -0
  8. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CkaRW2Sy.mjs +26 -0
  9. package/dist/pipeline-analytics/{hostInit-CMFNXHOl.mjs → hostInit-s-NoTpFK.mjs} +3 -3
  10. package/dist/pipeline-analytics/index.js +982 -82
  11. package/dist/pipeline-analytics/index.mjs +1013 -113
  12. package/dist/pipeline-analytics/remoteEntry.js +1 -1
  13. package/package.json +5 -1
  14. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DOGD-EFh.mjs +0 -26
  15. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bb1tsxlC.mjs +0 -26
@@ -1,13 +1,13 @@
1
1
  import { a as e, i as t, n, o as r, r as i, t as a } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.js-C0AuF9av.mjs";
2
2
  import { t as o } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-B3Wx5J80.mjs";
3
- import { a as s, i as c, n as l, o as u, r as d, s as f, t as p } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bb1tsxlC.mjs";
4
- import { n as m, r as h, t as g } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-Bm-iyjmq.mjs";
5
- import { t as _ } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DOGD-EFh.mjs";
3
+ import { a as s, c, i as l, n as u, o as d, r as f, s as p, t as m } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CkaRW2Sy.mjs";
4
+ import { n as h, r as g, t as _ } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-Bm-iyjmq.mjs";
5
+ import { t as v } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BRMRfKVO.mjs";
6
6
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
7
- var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), y = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), b = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), x = (e) => {
8
- let t = b(e);
7
+ var y = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), b = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), x = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), S = (e) => {
8
+ let t = x(e);
9
9
  return t.charAt(0).toUpperCase() + t.slice(1);
10
- }, S = {
10
+ }, C = {
11
11
  xmlns: "http://www.w3.org/2000/svg",
12
12
  width: 24,
13
13
  height: 24,
@@ -17,31 +17,31 @@ var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
17
17
  strokeWidth: 2,
18
18
  strokeLinecap: "round",
19
19
  strokeLinejoin: "round"
20
- }, C = (e) => {
20
+ }, w = (e) => {
21
21
  for (let t in e) if (t.startsWith("aria-") || t === "role" || t === "title") return !0;
22
22
  return !1;
23
- }, w = n(({ color: e = "currentColor", size: t = 24, strokeWidth: n = 2, absoluteStrokeWidth: r, className: i = "", children: o, iconNode: s, ...c }, l) => a("svg", {
23
+ }, T = n(({ color: e = "currentColor", size: t = 24, strokeWidth: n = 2, absoluteStrokeWidth: r, className: i = "", children: o, iconNode: s, ...c }, l) => a("svg", {
24
24
  ref: l,
25
- ...S,
25
+ ...C,
26
26
  width: t,
27
27
  height: t,
28
28
  stroke: e,
29
29
  strokeWidth: r ? Number(n) * 24 / Number(t) : n,
30
- className: v("lucide", i),
31
- ...!o && !C(c) && { "aria-hidden": "true" },
30
+ className: y("lucide", i),
31
+ ...!o && !w(c) && { "aria-hidden": "true" },
32
32
  ...c
33
- }, [...s.map(([e, t]) => a(e, t)), ...Array.isArray(o) ? o : [o]])), T = (e, t) => {
34
- let r = n(({ className: n, ...r }, i) => a(w, {
33
+ }, [...s.map(([e, t]) => a(e, t)), ...Array.isArray(o) ? o : [o]])), E = (e, t) => {
34
+ let r = n(({ className: n, ...r }, i) => a(T, {
35
35
  ref: i,
36
36
  iconNode: t,
37
- className: v(`lucide-${y(x(e))}`, `lucide-${e}`, n),
37
+ className: y(`lucide-${b(S(e))}`, `lucide-${e}`, n),
38
38
  ...r
39
39
  }));
40
- return r.displayName = x(e), r;
41
- }, E = T("activity", [["path", {
40
+ return r.displayName = S(e), r;
41
+ }, D = E("activity", [["path", {
42
42
  d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",
43
43
  key: "169zse"
44
- }]]), D = T("boxes", [
44
+ }]]), O = E("boxes", [
45
45
  ["path", {
46
46
  d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z",
47
47
  key: "lc1i9w"
@@ -90,7 +90,7 @@ var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
90
90
  d: "M12 13.5V8",
91
91
  key: "1io7kd"
92
92
  }]
93
- ]), O = T("eye", [["path", {
93
+ ]), k = E("eye", [["path", {
94
94
  d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",
95
95
  key: "1nclc0"
96
96
  }], ["circle", {
@@ -98,7 +98,7 @@ var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
98
98
  cy: "12",
99
99
  r: "3",
100
100
  key: "1v7zrd"
101
- }]]), k = T("layers", [
101
+ }]]), A = E("layers", [
102
102
  ["path", {
103
103
  d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",
104
104
  key: "zw3jo"
@@ -111,7 +111,7 @@ var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
111
111
  d: "M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",
112
112
  key: "kqbvx6"
113
113
  }]
114
- ]), A = T("map-pin-off", [
114
+ ]), j = E("map-pin-off", [
115
115
  ["path", {
116
116
  d: "M12.75 7.09a3 3 0 0 1 2.16 2.16",
117
117
  key: "1d4wjd"
@@ -132,7 +132,7 @@ var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
132
132
  d: "M9.13 9.13a3 3 0 0 0 3.74 3.74",
133
133
  key: "13wojd"
134
134
  }]
135
- ]), j = T("mic-off", [
135
+ ]), M = E("mic-off", [
136
136
  ["path", {
137
137
  d: "M12 19v3",
138
138
  key: "npa21l"
@@ -157,7 +157,7 @@ var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
157
157
  d: "M9 9v3a3 3 0 0 0 5.12 2.12",
158
158
  key: "r2i35w"
159
159
  }]
160
- ]), M = T("mic", [
160
+ ]), N = E("mic", [
161
161
  ["path", {
162
162
  d: "M12 19v3",
163
163
  key: "npa21l"
@@ -174,13 +174,178 @@ var v = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
174
174
  rx: "3",
175
175
  key: "s6n7sd"
176
176
  }]
177
- ]);
177
+ ]), { useT: P } = c("pipeline-analytics", {
178
+ en: {
179
+ missingDevice: "{{name}} requires a deviceId",
180
+ common: {
181
+ loading: "Loading…",
182
+ resolving: "Resolving device…",
183
+ justNow: "just now",
184
+ secondsAgo: "{{seconds}}s ago"
185
+ },
186
+ audioMetrics: {
187
+ title: "Audio Metrics",
188
+ noData: "No audio data yet — analytics pipeline must be active and audio enabled for this device.",
189
+ level: "Level",
190
+ silent: "silent",
191
+ peak: "peak {{value}} dB",
192
+ avg: "avg {{value}} dB",
193
+ window: "{{seconds}}s window",
194
+ now: "Now",
195
+ scoreAgo: "score {{score}}% — {{seconds}}s ago",
196
+ unclassified: "silence / unclassified",
197
+ last: "Last {{seconds}}s",
198
+ noClassified: "no classified audio",
199
+ hits: "{{count}}× hits"
200
+ },
201
+ occupancy: {
202
+ title: "Live Occupancy",
203
+ noData: "No occupancy data yet — analytics pipeline must be active for this device.",
204
+ frameTotal: "Frame total",
205
+ outsideZone: "Outside any zone",
206
+ perZone: "Per-zone",
207
+ noZones: "No zones defined for this camera.",
208
+ noObjects: "no objects"
209
+ },
210
+ audioHistory: {
211
+ title: "Audio Level History",
212
+ empty: "No audio history yet — analytics pipeline must be active.",
213
+ ariaLabel: "Audio dBFS history",
214
+ peakWindow: "peak (window)",
215
+ avgWindow: "avg (window)",
216
+ samples: "{{count}} samples · ~{{seconds}}s spacing",
217
+ peak: "peak {{value}} dB"
218
+ },
219
+ occupancyHistory: {
220
+ title: "Occupancy History",
221
+ filterByClass: "Filter by detected class",
222
+ allClasses: "All classes",
223
+ empty: "No occupancy history yet — analytics pipeline must be active.",
224
+ ariaLabel: "Frame occupancy history",
225
+ objects_one: "{{count}} object",
226
+ objects_other: "{{count}} objects",
227
+ class: "Class",
228
+ all: "all",
229
+ bucket: "Bucket",
230
+ buckets_one: "{{count}} bucket · 5 min resolution",
231
+ buckets_other: "{{count}} buckets · 5 min resolution",
232
+ peak: "peak {{value}} obj"
233
+ },
234
+ motionHistory: {
235
+ title: "Motion History",
236
+ empty: "No motion events in the selected window.",
237
+ ariaLabel: "Motion event histogram",
238
+ events_one: "{{count}} event",
239
+ events_other: "{{count}} events",
240
+ bucket: "Bucket",
241
+ count: "Count",
242
+ summary_one: "{{count}} event · {{bucket}} buckets",
243
+ summary_other: "{{count}} events · {{bucket}} buckets",
244
+ peak: "peak {{value}}/bucket"
245
+ },
246
+ detectionHistory: {
247
+ title: "Detection History",
248
+ filterByClass: "Filter by detected class",
249
+ allClasses: "All classes",
250
+ empty: "No detection events in the selected window.",
251
+ ariaLabel: "Detection event histogram",
252
+ detections_one: "{{count}} detection",
253
+ detections_other: "{{count}} detections",
254
+ other: "other",
255
+ summary_one: "{{count}} detection · {{bucket}} buckets",
256
+ summary_other: "{{count}} detections · {{bucket}} buckets",
257
+ peak: "peak {{value}}/bucket"
258
+ }
259
+ },
260
+ it: {
261
+ missingDevice: "{{name}} richiede un deviceId",
262
+ common: {
263
+ loading: "Caricamento…",
264
+ resolving: "Risoluzione del dispositivo…",
265
+ justNow: "adesso",
266
+ secondsAgo: "{{seconds}}s fa"
267
+ },
268
+ audioMetrics: {
269
+ title: "Metriche audio",
270
+ noData: "Ancora nessun dato audio: la pipeline di analisi deve essere attiva e l'audio abilitato per questo dispositivo.",
271
+ level: "Livello",
272
+ silent: "silenzio",
273
+ peak: "picco {{value}} dB",
274
+ avg: "media {{value}} dB",
275
+ window: "finestra di {{seconds}}s",
276
+ now: "Adesso",
277
+ scoreAgo: "punteggio {{score}}% — {{seconds}}s fa",
278
+ unclassified: "silenzio / non classificato",
279
+ last: "Ultimi {{seconds}}s",
280
+ noClassified: "nessun audio classificato",
281
+ hits: "{{count}}× rilevamenti"
282
+ },
283
+ occupancy: {
284
+ title: "Occupazione live",
285
+ noData: "Ancora nessun dato di occupazione: la pipeline di analisi deve essere attiva per questo dispositivo.",
286
+ frameTotal: "Totale fotogramma",
287
+ outsideZone: "Fuori da ogni zona",
288
+ perZone: "Per zona",
289
+ noZones: "Nessuna zona definita per questa telecamera.",
290
+ noObjects: "nessun oggetto"
291
+ },
292
+ audioHistory: {
293
+ title: "Storico livello audio",
294
+ empty: "Ancora nessuno storico audio: la pipeline di analisi deve essere attiva.",
295
+ ariaLabel: "Storico dBFS audio",
296
+ peakWindow: "picco (finestra)",
297
+ avgWindow: "media (finestra)",
298
+ samples: "{{count}} campioni · intervallo ~{{seconds}}s",
299
+ peak: "picco {{value}} dB"
300
+ },
301
+ occupancyHistory: {
302
+ title: "Storico occupazione",
303
+ filterByClass: "Filtra per classe rilevata",
304
+ allClasses: "Tutte le classi",
305
+ empty: "Ancora nessuno storico di occupazione: la pipeline di analisi deve essere attiva.",
306
+ ariaLabel: "Storico occupazione del fotogramma",
307
+ objects_one: "{{count}} oggetto",
308
+ objects_other: "{{count}} oggetti",
309
+ class: "Classe",
310
+ all: "tutte",
311
+ bucket: "Intervallo",
312
+ buckets_one: "{{count}} intervallo · risoluzione 5 min",
313
+ buckets_other: "{{count}} intervalli · risoluzione 5 min",
314
+ peak: "picco {{value}} ogg."
315
+ },
316
+ motionHistory: {
317
+ title: "Storico movimento",
318
+ empty: "Nessun evento di movimento nella finestra selezionata.",
319
+ ariaLabel: "Istogramma degli eventi di movimento",
320
+ events_one: "{{count}} evento",
321
+ events_other: "{{count}} eventi",
322
+ bucket: "Intervallo",
323
+ count: "Conteggio",
324
+ summary_one: "{{count}} evento · intervalli da {{bucket}}",
325
+ summary_other: "{{count}} eventi · intervalli da {{bucket}}",
326
+ peak: "picco {{value}}/intervallo"
327
+ },
328
+ detectionHistory: {
329
+ title: "Storico rilevamenti",
330
+ filterByClass: "Filtra per classe rilevata",
331
+ allClasses: "Tutte le classi",
332
+ empty: "Nessun evento di rilevamento nella finestra selezionata.",
333
+ ariaLabel: "Istogramma degli eventi di rilevamento",
334
+ detections_one: "{{count}} rilevamento",
335
+ detections_other: "{{count}} rilevamenti",
336
+ other: "altro",
337
+ summary_one: "{{count}} rilevamento · intervalli da {{bucket}}",
338
+ summary_other: "{{count}} rilevamenti · intervalli da {{bucket}}",
339
+ peak: "picco {{value}}/intervallo"
340
+ }
341
+ }
342
+ });
178
343
  //#endregion
179
344
  //#region src/pipeline-analytics/widgets/chart-utils.tsx
180
- function N({ presets: e, value: t, onChange: n }) {
181
- return /* @__PURE__ */ m("div", {
345
+ function F({ presets: e, value: t, onChange: n }) {
346
+ return /* @__PURE__ */ h("div", {
182
347
  className: "flex items-center gap-1 border border-border rounded-md p-0.5 bg-background",
183
- children: e.map(({ id: e, label: r }) => /* @__PURE__ */ m("button", {
348
+ children: e.map(({ id: e, label: r }) => /* @__PURE__ */ h("button", {
184
349
  type: "button",
185
350
  onClick: () => n(e),
186
351
  className: `px-2 py-0.5 rounded text-[10px] font-medium transition-colors ${t === e ? "bg-primary/10 text-primary" : "text-foreground-subtle hover:text-foreground"}`,
@@ -188,7 +353,7 @@ function N({ presets: e, value: t, onChange: n }) {
188
353
  }, e))
189
354
  });
190
355
  }
191
- function P(t = 0) {
356
+ function I(t = 0) {
192
357
  let n = e(null), [a, o] = r(0);
193
358
  return i(() => {
194
359
  let e = n.current;
@@ -202,7 +367,7 @@ function P(t = 0) {
202
367
  return i.observe(e), () => i.disconnect();
203
368
  }, [t]), [n, a];
204
369
  }
205
- function F(e, t) {
370
+ function L(e, t) {
206
371
  let n = new Date(e), r = String(n.getHours()).padStart(2, "0"), i = String(n.getMinutes()).padStart(2, "0");
207
372
  return t <= 1440 * 60 * 1e3 ? `${r}:${i}` : `${String(n.getDate()).padStart(2, "0")}/${String(n.getMonth() + 1).padStart(2, "0")} ${r}:${i}`;
208
373
  }
@@ -218,7 +383,7 @@ function te(e, t, n, r, i, a) {
218
383
  let n = t / Math.max(1, a - 1), i = e + o * n;
219
384
  s.push({
220
385
  x: r + n * c,
221
- label: F(i, o)
386
+ label: L(i, o)
222
387
  });
223
388
  }
224
389
  return s;
@@ -236,17 +401,17 @@ var ne = [
236
401
  function re(e) {
237
402
  return ne[e % ne.length] ?? "#64748b";
238
403
  }
239
- function I() {
404
+ function ie() {
240
405
  let [e, t] = r(null);
241
406
  return {
242
407
  state: e,
243
408
  bindHover: t
244
409
  };
245
410
  }
246
- function ie({ state: e, containerWidth: t }) {
411
+ function R({ state: e, containerWidth: t }) {
247
412
  if (!e) return null;
248
413
  let n = Math.max(114, t - 110 - 4), r = Math.max(114, Math.min(n, e.anchorX)), i = e.anchorX - r;
249
- return /* @__PURE__ */ h("div", {
414
+ return /* @__PURE__ */ g("div", {
250
415
  role: "tooltip",
251
416
  style: {
252
417
  position: "absolute",
@@ -257,30 +422,30 @@ function ie({ state: e, containerWidth: t }) {
257
422
  },
258
423
  className: "z-10 rounded-md border border-border bg-surface shadow-lg px-2.5 py-1.5 text-[10px] text-foreground min-w-[140px] max-w-[240px]",
259
424
  children: [
260
- /* @__PURE__ */ m("div", {
425
+ /* @__PURE__ */ h("div", {
261
426
  className: "font-semibold mb-1 truncate",
262
427
  children: e.title
263
428
  }),
264
- /* @__PURE__ */ m("div", {
429
+ /* @__PURE__ */ h("div", {
265
430
  className: "space-y-0.5",
266
- children: e.rows.map((e, t) => /* @__PURE__ */ h("div", {
431
+ children: e.rows.map((e, t) => /* @__PURE__ */ g("div", {
267
432
  className: "flex items-center justify-between gap-2",
268
- children: [/* @__PURE__ */ h("span", {
433
+ children: [/* @__PURE__ */ g("span", {
269
434
  className: "flex items-center gap-1 text-foreground-subtle truncate",
270
- children: [e.colour && /* @__PURE__ */ m("span", {
435
+ children: [e.colour && /* @__PURE__ */ h("span", {
271
436
  className: "inline-block h-1.5 w-1.5 rounded-sm flex-shrink-0",
272
437
  style: { backgroundColor: e.colour }
273
- }), /* @__PURE__ */ m("span", {
438
+ }), /* @__PURE__ */ h("span", {
274
439
  className: "truncate",
275
440
  children: e.label
276
441
  })]
277
- }), /* @__PURE__ */ m("span", {
442
+ }), /* @__PURE__ */ h("span", {
278
443
  className: "tabular-nums",
279
444
  children: e.value
280
445
  })]
281
446
  }, t))
282
447
  }),
283
- /* @__PURE__ */ m("span", {
448
+ /* @__PURE__ */ h("span", {
284
449
  "aria-hidden": !0,
285
450
  style: { left: `calc(50% + ${i}px)` },
286
451
  className: "absolute -bottom-1 -translate-x-1/2 h-2 w-2 rotate-45 bg-surface border-r border-b border-border"
@@ -290,7 +455,7 @@ function ie({ state: e, containerWidth: t }) {
290
455
  }
291
456
  //#endregion
292
457
  //#region src/pipeline-analytics/widgets/AudioHistoryChart.tsx
293
- var L = {
458
+ var z = {
294
459
  "5m": {
295
460
  label: "5 min",
296
461
  windowSec: 300,
@@ -312,17 +477,17 @@ var L = {
312
477
  }, ae = [
313
478
  {
314
479
  id: "5m",
315
- label: L["5m"].label
480
+ label: z["5m"].label
316
481
  },
317
482
  {
318
483
  id: "1h",
319
- label: L["1h"].label
484
+ label: z["1h"].label
320
485
  },
321
486
  {
322
487
  id: "24h",
323
- label: L["24h"].label
488
+ label: z["24h"].label
324
489
  }
325
- ], R = 140, z = {
490
+ ], B = 140, V = {
326
491
  top: 16,
327
492
  right: 12,
328
493
  bottom: 24,
@@ -339,132 +504,132 @@ function se(e) {
339
504
  return e ? oe[e.toLowerCase()] ?? "#6366f1" : "#71717a";
340
505
  }
341
506
  function ce({ deviceId: n }) {
342
- let i = p(c().trpcClient, n), [a, s] = r("5m"), l = L[a], [u, d] = P(), f = I(), _ = e(null), v = (e) => {
343
- let t = _.current;
507
+ let { t: i } = P(), a = m(l().trpcClient, n), [s, c] = r("5m"), u = z[s], [d, f] = I(), p = ie(), v = e(null), y = (e) => {
508
+ let t = v.current;
344
509
  if (!t) return e;
345
510
  let n = t.getBoundingClientRect();
346
- return n.width === 0 ? e : e / d * n.width;
347
- }, y = o({
511
+ return n.width === 0 ? e : e / f * n.width;
512
+ }, b = o({
348
513
  queryKey: [
349
514
  "audio-metrics",
350
515
  n,
351
516
  "history",
352
- a
517
+ s
353
518
  ],
354
- queryFn: async () => i ? await i.audioMetrics?.getHistory({
355
- windowSec: l.windowSec,
356
- sampleEveryMs: l.sampleEveryMs
519
+ queryFn: async () => a ? await a.audioMetrics?.getHistory({
520
+ windowSec: u.windowSec,
521
+ sampleEveryMs: u.sampleEveryMs
357
522
  }) ?? null : null,
358
- enabled: !!i,
359
- refetchInterval: l.pollIntervalMs,
360
- staleTime: Math.max(1e3, l.pollIntervalMs / 2)
361
- }), b = y.data, x = b?.points ?? [], S = t(() => pe(x), [x]), C = t(() => de(x, d, S), [
362
- x,
363
- d,
364
- S
365
- ]), w = t(() => fe(x, d, S), [
366
- x,
367
- d,
368
- S
369
- ]), T = t(() => me(S), [S]), D = t(() => he(x, d), [x, d]);
370
- return /* @__PURE__ */ h("div", {
523
+ enabled: !!a,
524
+ refetchInterval: u.pollIntervalMs,
525
+ staleTime: Math.max(1e3, u.pollIntervalMs / 2)
526
+ }), x = b.data, S = x?.points ?? [], C = t(() => pe(S), [S]), w = t(() => de(S, f, C), [
527
+ S,
528
+ f,
529
+ C
530
+ ]), T = t(() => fe(S, f, C), [
531
+ S,
532
+ f,
533
+ C
534
+ ]), E = t(() => me(C), [C]), O = t(() => he(S, f), [S, f]);
535
+ return /* @__PURE__ */ g("div", {
371
536
  className: "rounded-lg border border-border bg-surface overflow-hidden",
372
- children: [/* @__PURE__ */ h("div", {
537
+ children: [/* @__PURE__ */ g("div", {
373
538
  className: "border-b border-border px-4 py-2 flex items-center justify-between gap-3",
374
- children: [/* @__PURE__ */ h("div", {
539
+ children: [/* @__PURE__ */ g("div", {
375
540
  className: "flex items-center gap-1.5",
376
- children: [/* @__PURE__ */ m(E, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ m("h2", {
541
+ children: [/* @__PURE__ */ h(D, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ h("h2", {
377
542
  className: "text-xs font-semibold text-foreground uppercase tracking-wider",
378
- children: "Audio Level History"
543
+ children: i("audioHistory.title")
379
544
  })]
380
- }), /* @__PURE__ */ m(N, {
545
+ }), /* @__PURE__ */ h(F, {
381
546
  presets: ae,
382
- value: a,
383
- onChange: s
547
+ value: s,
548
+ onChange: c
384
549
  })]
385
- }), /* @__PURE__ */ h("div", {
386
- ref: u,
550
+ }), /* @__PURE__ */ g("div", {
551
+ ref: d,
387
552
  className: "p-3 min-w-0 relative",
388
- children: [x.length === 0 ? /* @__PURE__ */ m("div", {
553
+ children: [S.length === 0 ? /* @__PURE__ */ h("div", {
389
554
  className: "flex items-center justify-center h-32 text-[11px] text-foreground-subtle italic",
390
- children: y.isLoading ? "Loading…" : "No audio history yet — analytics pipeline must be active."
391
- }) : d === 0 ? /* @__PURE__ */ m("div", { className: "h-32" }) : /* @__PURE__ */ h(g, { children: [/* @__PURE__ */ h("svg", {
392
- ref: _,
555
+ children: b.isLoading ? i("common.loading") : i("audioHistory.empty")
556
+ }) : f === 0 ? /* @__PURE__ */ h("div", { className: "h-32" }) : /* @__PURE__ */ g(_, { children: [/* @__PURE__ */ g("svg", {
557
+ ref: v,
393
558
  role: "img",
394
- "aria-label": "Audio dBFS history",
559
+ "aria-label": i("audioHistory.ariaLabel"),
395
560
  width: "100%",
396
- height: R,
397
- viewBox: `0 0 ${d} ${R}`,
561
+ height: B,
562
+ viewBox: `0 0 ${f} ${B}`,
398
563
  preserveAspectRatio: "none",
399
564
  className: "block",
400
- onMouseLeave: () => f.bindHover(null),
565
+ onMouseLeave: () => p.bindHover(null),
401
566
  children: [
402
- T.map(({ y: e, label: t }, n) => /* @__PURE__ */ h("g", { children: [/* @__PURE__ */ m("line", {
403
- x1: z.left,
404
- x2: d - z.right,
567
+ E.map(({ y: e, label: t }, n) => /* @__PURE__ */ g("g", { children: [/* @__PURE__ */ h("line", {
568
+ x1: V.left,
569
+ x2: f - V.right,
405
570
  y1: e,
406
571
  y2: e,
407
572
  stroke: "currentColor",
408
573
  strokeOpacity: .08,
409
574
  strokeWidth: .5
410
- }), /* @__PURE__ */ m("text", {
411
- x: z.left - 6,
575
+ }), /* @__PURE__ */ h("text", {
576
+ x: V.left - 6,
412
577
  y: e + 3,
413
578
  textAnchor: "end",
414
579
  className: "text-[9px] fill-foreground-subtle",
415
580
  children: t
416
581
  })] }, `y-${n}`)),
417
- D.map(({ x: e, label: t }, n) => /* @__PURE__ */ m("text", {
582
+ O.map(({ x: e, label: t }, n) => /* @__PURE__ */ h("text", {
418
583
  x: e,
419
- y: R - z.bottom + 12,
584
+ y: B - V.bottom + 12,
420
585
  textAnchor: "middle",
421
586
  className: "text-[9px] fill-foreground-subtle",
422
587
  children: t
423
588
  }, `x-${n}`)),
424
- w && /* @__PURE__ */ m("path", {
425
- d: w,
589
+ T && /* @__PURE__ */ h("path", {
590
+ d: T,
426
591
  fill: "none",
427
592
  stroke: "currentColor",
428
593
  strokeOpacity: .25,
429
594
  strokeWidth: 1,
430
595
  strokeDasharray: "3 2"
431
596
  }),
432
- C && /* @__PURE__ */ m("path", {
433
- d: C,
597
+ w && /* @__PURE__ */ h("path", {
598
+ d: w,
434
599
  fill: "none",
435
600
  stroke: "currentColor",
436
601
  className: "text-primary",
437
602
  strokeWidth: 1.5
438
603
  }),
439
- x.map((e, t) => e.topClass === null ? null : /* @__PURE__ */ m("circle", {
440
- cx: B(t, x.length, d),
441
- cy: le(e.dbfs, S),
604
+ S.map((e, t) => e.topClass === null ? null : /* @__PURE__ */ h("circle", {
605
+ cx: H(t, S.length, f),
606
+ cy: le(e.dbfs, C),
442
607
  r: 3,
443
608
  fill: se(e.topClass),
444
609
  stroke: "#000",
445
610
  strokeOpacity: .3,
446
611
  strokeWidth: .5
447
612
  }, `dot-${t}`)),
448
- x.map((e, t) => {
449
- let n = B(t, x.length, d), r = le(e.dbfs, S), i = R - z.top - z.bottom, a = x.length > 1 ? (d - z.left - z.right) / (x.length - 1) : 24;
450
- return /* @__PURE__ */ m("rect", {
451
- x: n - a / 2,
452
- y: z.top,
453
- width: Math.max(2, a),
454
- height: i,
613
+ S.map((e, t) => {
614
+ let n = H(t, S.length, f), r = le(e.dbfs, C), a = B - V.top - V.bottom, o = S.length > 1 ? (f - V.left - V.right) / (S.length - 1) : 24;
615
+ return /* @__PURE__ */ h("rect", {
616
+ x: n - o / 2,
617
+ y: V.top,
618
+ width: Math.max(2, o),
619
+ height: a,
455
620
  fill: "transparent",
456
621
  onMouseEnter: () => {
457
- f.bindHover({
458
- anchorX: v(n),
622
+ p.bindHover({
623
+ anchorX: y(n),
459
624
  anchorY: r,
460
625
  title: `${ge(e.ts)} · ${e.dbfs?.toFixed(1) ?? "—"} dB`,
461
626
  rows: [
462
627
  {
463
- label: "peak (window)",
628
+ label: i("audioHistory.peakWindow"),
464
629
  value: `${e.peakDbfs.toFixed(1)} dB`
465
630
  },
466
631
  {
467
- label: "avg (window)",
632
+ label: i("audioHistory.avgWindow"),
468
633
  value: `${e.avgDbfs.toFixed(1)} dB`
469
634
  },
470
635
  ...e.topClass === null ? [] : [{
@@ -478,42 +643,36 @@ function ce({ deviceId: n }) {
478
643
  }, `hit-${t}`);
479
644
  })
480
645
  ]
481
- }), /* @__PURE__ */ m(ie, {
482
- state: f.state,
483
- containerWidth: d
484
- })] }), x.length > 0 && /* @__PURE__ */ h("div", {
646
+ }), /* @__PURE__ */ h(R, {
647
+ state: p.state,
648
+ containerWidth: f
649
+ })] }), S.length > 0 && /* @__PURE__ */ g("div", {
485
650
  className: "flex items-center justify-between text-[10px] text-foreground-subtle mt-1",
486
- children: [/* @__PURE__ */ h("span", { children: [
487
- x.length,
488
- " samples · ~",
489
- Math.round((b?.effectiveSampleEveryMs ?? l.sampleEveryMs) / 1e3),
490
- "s spacing"
491
- ] }), /* @__PURE__ */ h("span", { children: [
492
- "peak ",
493
- x.reduce((e, t) => Math.max(e, t.peakDbfs), -Infinity).toFixed(1),
494
- " dB"
495
- ] })]
651
+ children: [/* @__PURE__ */ h("span", { children: i("audioHistory.samples", {
652
+ count: S.length,
653
+ seconds: Math.round((x?.effectiveSampleEveryMs ?? u.sampleEveryMs) / 1e3)
654
+ }) }), /* @__PURE__ */ h("span", { children: i("audioHistory.peak", { value: S.reduce((e, t) => Math.max(e, t.peakDbfs), -Infinity).toFixed(1) }) })]
496
655
  })]
497
656
  })]
498
657
  });
499
658
  }
500
- function B(e, t, n) {
501
- if (t <= 1) return z.left;
502
- let r = n - z.left - z.right;
503
- return z.left + e / (t - 1) * r;
659
+ function H(e, t, n) {
660
+ if (t <= 1) return V.left;
661
+ let r = n - V.left - V.right;
662
+ return V.left + e / (t - 1) * r;
504
663
  }
505
664
  function le(e, t) {
506
665
  return ue(e === null || !Number.isFinite(e) ? t.min : Math.max(t.min, Math.min(t.max, e)), t);
507
666
  }
508
667
  function ue(e, t) {
509
- let n = R - z.top - z.bottom, r = Math.max(1, t.max - t.min), i = (e - t.min) / r;
510
- return z.top + (1 - i) * n;
668
+ let n = B - V.top - V.bottom, r = Math.max(1, t.max - t.min), i = (e - t.min) / r;
669
+ return V.top + (1 - i) * n;
511
670
  }
512
671
  function de(e, t, n) {
513
672
  if (e.length === 0) return null;
514
673
  let r = [];
515
674
  for (let i = 0; i < e.length; i++) {
516
- let a = B(i, e.length, t), o = le(e[i].dbfs, n);
675
+ let a = H(i, e.length, t), o = le(e[i].dbfs, n);
517
676
  r.push(`${i === 0 ? "M" : "L"} ${a.toFixed(1)} ${o.toFixed(1)}`);
518
677
  }
519
678
  return r.join(" ");
@@ -522,7 +681,7 @@ function fe(e, t, n) {
522
681
  if (e.length === 0) return null;
523
682
  let r = [];
524
683
  for (let i = 0; i < e.length; i++) {
525
- let a = B(i, e.length, t), o = ue(Math.max(n.min, Math.min(n.max, e[i].peakDbfs)), n);
684
+ let a = H(i, e.length, t), o = ue(Math.max(n.min, Math.min(n.max, e[i].peakDbfs)), n);
526
685
  r.push(`${i === 0 ? "M" : "L"} ${a.toFixed(1)} ${o.toFixed(1)}`);
527
686
  }
528
687
  return r.join(" ");
@@ -561,7 +720,7 @@ function he(e, t) {
561
720
  for (let e = 0; e < a; e++) {
562
721
  let o = e / Math.max(1, a - 1), s = n.ts + (r.ts - n.ts) * o;
563
722
  i.push({
564
- x: z.left + o * (t - z.left - z.right),
723
+ x: V.left + o * (t - V.left - V.right),
565
724
  label: ge(s)
566
725
  });
567
726
  }
@@ -576,168 +735,149 @@ function ge(e) {
576
735
  function _e(e) {
577
736
  return !Number.isFinite(e) || e <= 0 ? 60 : Math.round(e > 600 ? e / 1e3 : e);
578
737
  }
579
- function ve({ dev: e, deviceId: t, title: n = "Audio Metrics", variant: r = "full" }) {
580
- let i = l(c().trpcClient, e === void 0 && t !== void 0 ? t : null, (e) => e.audioMetrics), a = d(e ? e.state.audioMetrics : void 0), o = e === void 0 ? i : a;
581
- return o ? /* @__PURE__ */ m(ye, {
582
- title: n,
738
+ function ve({ dev: e, deviceId: t, title: n, variant: r = "full" }) {
739
+ let { t: i } = P(), a = n ?? i("audioMetrics.title"), o = u(l().trpcClient, e === void 0 && t !== void 0 ? t : null, (e) => e.audioMetrics), s = f(e ? e.state.audioMetrics : void 0), c = e === void 0 ? o : s;
740
+ return c ? /* @__PURE__ */ h(ye, {
741
+ title: a,
583
742
  variant: r,
584
- ts: o.ts,
585
- children: /* @__PURE__ */ h("div", {
743
+ ts: c.ts,
744
+ children: /* @__PURE__ */ g("div", {
586
745
  className: r === "compact" ? "space-y-2" : "grid grid-cols-1 2xl:grid-cols-3 gap-3",
587
746
  children: [
588
- /* @__PURE__ */ m(xe, { snapshot: o }),
589
- /* @__PURE__ */ m(Se, { snapshot: o }),
590
- /* @__PURE__ */ m(Ce, { snapshot: o })
747
+ /* @__PURE__ */ h(xe, { snapshot: c }),
748
+ /* @__PURE__ */ h(Se, { snapshot: c }),
749
+ /* @__PURE__ */ h(Ce, { snapshot: c })
591
750
  ]
592
751
  })
593
- }) : /* @__PURE__ */ m(ye, {
594
- title: n,
752
+ }) : /* @__PURE__ */ h(ye, {
753
+ title: a,
595
754
  variant: r,
596
- children: /* @__PURE__ */ m(be, {
597
- icon: /* @__PURE__ */ m(j, { className: "h-5 w-5 mb-2 opacity-30" }),
598
- message: e || t !== void 0 ? "No audio data yet — analytics pipeline must be active and audio enabled for this device." : "Resolving device…"
755
+ children: /* @__PURE__ */ h(be, {
756
+ icon: /* @__PURE__ */ h(M, { className: "h-5 w-5 mb-2 opacity-30" }),
757
+ message: i(e || t !== void 0 ? "audioMetrics.noData" : "common.resolving")
599
758
  })
600
759
  });
601
760
  }
602
761
  function ye({ title: e, variant: t, ts: n, children: r }) {
603
- let i = n ? Math.max(0, Math.floor((Date.now() - n) / 1e3)) : null;
604
- return /* @__PURE__ */ h("div", {
762
+ let { t: i } = P(), a = n ? Math.max(0, Math.floor((Date.now() - n) / 1e3)) : null;
763
+ return /* @__PURE__ */ g("div", {
605
764
  className: t === "compact" ? "rounded-md border border-border/60 bg-surface/60 p-3" : "rounded-lg border border-border bg-surface overflow-hidden",
606
- children: [/* @__PURE__ */ h("div", {
765
+ children: [/* @__PURE__ */ g("div", {
607
766
  className: t === "compact" ? "flex items-center justify-between mb-2" : "border-b border-border px-4 py-2 flex items-center justify-between",
608
- children: [/* @__PURE__ */ m("h2", {
767
+ children: [/* @__PURE__ */ h("h2", {
609
768
  className: "text-xs font-semibold text-foreground uppercase tracking-wider",
610
769
  children: e
611
- }), i !== null && /* @__PURE__ */ m("span", {
770
+ }), a !== null && /* @__PURE__ */ h("span", {
612
771
  className: "text-[10px] text-foreground-subtle",
613
- children: i === 0 ? "just now" : `${i}s ago`
772
+ children: a === 0 ? i("common.justNow") : i("common.secondsAgo", { seconds: a })
614
773
  })]
615
- }), /* @__PURE__ */ m("div", {
774
+ }), /* @__PURE__ */ h("div", {
616
775
  className: t === "compact" ? "" : "p-3",
617
776
  children: r
618
777
  })]
619
778
  });
620
779
  }
621
780
  function be({ icon: e, message: t }) {
622
- return /* @__PURE__ */ h("div", {
781
+ return /* @__PURE__ */ g("div", {
623
782
  className: "px-4 py-6 flex flex-col items-center text-center text-foreground-subtle",
624
- children: [e, /* @__PURE__ */ m("p", {
783
+ children: [e, /* @__PURE__ */ h("p", {
625
784
  className: "text-[11px]",
626
785
  children: t
627
786
  })]
628
787
  });
629
788
  }
630
789
  function xe({ snapshot: e }) {
631
- let { dbfs: t } = e.level, n = Math.max(-80, Math.min(0, Number.isFinite(t) ? t : -80)), r = (n + 80) / 80 * 100, i = n > -10 ? "bg-danger" : n > -25 ? "bg-warning" : "bg-primary";
632
- return /* @__PURE__ */ h("div", {
790
+ let { t } = P(), { dbfs: n } = e.level, r = Math.max(-80, Math.min(0, Number.isFinite(n) ? n : -80)), i = (r + 80) / 80 * 100, a = r > -10 ? "bg-danger" : r > -25 ? "bg-warning" : "bg-primary";
791
+ return /* @__PURE__ */ g("div", {
633
792
  className: "rounded-md border border-border/60 bg-background/40 px-3 py-2",
634
793
  children: [
635
- /* @__PURE__ */ h("div", {
794
+ /* @__PURE__ */ g("div", {
636
795
  className: "flex items-center gap-1.5 mb-1.5 text-[11px] uppercase tracking-wider text-foreground-subtle",
637
796
  children: [
638
- /* @__PURE__ */ m(E, { className: "h-3.5 w-3.5" }),
639
- /* @__PURE__ */ m("span", { children: "Level" }),
640
- /* @__PURE__ */ m("span", {
797
+ /* @__PURE__ */ h(D, { className: "h-3.5 w-3.5" }),
798
+ /* @__PURE__ */ h("span", { children: t("audioMetrics.level") }),
799
+ /* @__PURE__ */ h("span", {
641
800
  className: "ml-auto text-base font-semibold text-foreground tabular-nums normal-case tracking-normal",
642
- children: Number.isFinite(t) ? `${t.toFixed(1)} dB` : "silent"
801
+ children: Number.isFinite(n) ? `${n.toFixed(1)} dB` : t("audioMetrics.silent")
643
802
  })
644
803
  ]
645
804
  }),
646
- /* @__PURE__ */ m("div", {
805
+ /* @__PURE__ */ h("div", {
647
806
  className: "h-1.5 rounded-full bg-foreground-subtle/15 overflow-hidden",
648
- children: /* @__PURE__ */ m("div", {
649
- className: `h-full ${i} transition-all`,
650
- style: { width: `${r}%` }
807
+ children: /* @__PURE__ */ h("div", {
808
+ className: `h-full ${a} transition-all`,
809
+ style: { width: `${i}%` }
651
810
  })
652
811
  }),
653
- /* @__PURE__ */ h("div", {
812
+ /* @__PURE__ */ g("div", {
654
813
  className: "flex justify-between text-[9px] text-foreground-subtle mt-1 tabular-nums",
655
814
  children: [
656
- /* @__PURE__ */ h("span", { children: [
657
- "peak ",
658
- Number.isFinite(e.peakDbfs) ? e.peakDbfs.toFixed(1) : "—",
659
- " dB"
660
- ] }),
661
- /* @__PURE__ */ h("span", { children: [
662
- "avg ",
663
- e.avgDbfs.toFixed(1),
664
- " dB"
665
- ] }),
666
- /* @__PURE__ */ h("span", { children: [_e(e.windowSec), "s window"] })
815
+ /* @__PURE__ */ h("span", { children: t("audioMetrics.peak", { value: Number.isFinite(e.peakDbfs) ? e.peakDbfs.toFixed(1) : "—" }) }),
816
+ /* @__PURE__ */ h("span", { children: t("audioMetrics.avg", { value: e.avgDbfs.toFixed(1) }) }),
817
+ /* @__PURE__ */ h("span", { children: t("audioMetrics.window", { seconds: _e(e.windowSec) }) })
667
818
  ]
668
819
  })
669
820
  ]
670
821
  });
671
822
  }
672
823
  function Se({ snapshot: e }) {
673
- let { current: t } = e;
674
- return /* @__PURE__ */ h("div", {
824
+ let { t } = P(), { current: n } = e;
825
+ return /* @__PURE__ */ g("div", {
675
826
  className: "rounded-md border border-border/60 bg-background/40 px-3 py-2",
676
- children: [/* @__PURE__ */ h("div", {
827
+ children: [/* @__PURE__ */ g("div", {
677
828
  className: "flex items-center gap-1.5 mb-1.5 text-[11px] uppercase tracking-wider text-foreground-subtle",
678
- children: [/* @__PURE__ */ m(M, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ m("span", { children: "Now" })]
679
- }), t ? /* @__PURE__ */ h("div", {
829
+ children: [/* @__PURE__ */ h(N, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ h("span", { children: t("audioMetrics.now") })]
830
+ }), n ? /* @__PURE__ */ g("div", {
680
831
  className: "flex flex-col gap-1",
681
- children: [/* @__PURE__ */ m("span", {
832
+ children: [/* @__PURE__ */ h("span", {
682
833
  className: "text-sm font-semibold text-foreground",
683
- children: t.className
834
+ children: n.className
684
835
  }), /* @__PURE__ */ h("span", {
685
836
  className: "text-[10px] text-foreground-subtle tabular-nums",
686
- children: [
687
- "score ",
688
- (t.score * 100).toFixed(0),
689
- "% —",
690
- " ",
691
- Math.max(0, Math.floor((Date.now() - t.timestamp) / 1e3)),
692
- "s ago"
693
- ]
837
+ children: t("audioMetrics.scoreAgo", {
838
+ score: (n.score * 100).toFixed(0),
839
+ seconds: Math.max(0, Math.floor((Date.now() - n.timestamp) / 1e3))
840
+ })
694
841
  })]
695
- }) : /* @__PURE__ */ m("span", {
842
+ }) : /* @__PURE__ */ h("span", {
696
843
  className: "text-[10px] text-foreground-subtle italic",
697
- children: "silence / unclassified"
844
+ children: t("audioMetrics.unclassified")
698
845
  })]
699
846
  });
700
847
  }
701
848
  function Ce({ snapshot: e }) {
702
- return e.byClass.length === 0 ? /* @__PURE__ */ h("div", {
849
+ let { t } = P();
850
+ return e.byClass.length === 0 ? /* @__PURE__ */ g("div", {
703
851
  className: "rounded-md border border-border/40 bg-background/20 px-3 py-2",
704
- children: [/* @__PURE__ */ h("div", {
852
+ children: [/* @__PURE__ */ g("div", {
705
853
  className: "flex items-center gap-1.5 mb-1.5 text-[11px] uppercase tracking-wider text-foreground-subtle",
706
- children: [/* @__PURE__ */ m(E, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ h("span", { children: [
707
- "Last ",
708
- _e(e.windowSec),
709
- "s"
710
- ] })]
711
- }), /* @__PURE__ */ m("span", {
854
+ children: [/* @__PURE__ */ h(D, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ h("span", { children: t("audioMetrics.last", { seconds: _e(e.windowSec) }) })]
855
+ }), /* @__PURE__ */ h("span", {
712
856
  className: "text-[10px] text-foreground-subtle italic",
713
- children: "no classified audio"
857
+ children: t("audioMetrics.noClassified")
714
858
  })]
715
- }) : /* @__PURE__ */ h("div", {
859
+ }) : /* @__PURE__ */ g("div", {
716
860
  className: "rounded-md border border-border/60 bg-background/40",
717
- children: [/* @__PURE__ */ h("div", {
861
+ children: [/* @__PURE__ */ g("div", {
718
862
  className: "px-3 py-1.5 border-b border-border/40 flex items-center gap-1.5 text-[11px] uppercase tracking-wider text-foreground-subtle",
719
863
  children: [
720
- /* @__PURE__ */ m(E, { className: "h-3.5 w-3.5" }),
721
- /* @__PURE__ */ h("span", { children: [
722
- "Last ",
723
- _e(e.windowSec),
724
- "s"
725
- ] }),
726
- /* @__PURE__ */ m("span", {
864
+ /* @__PURE__ */ h(D, { className: "h-3.5 w-3.5" }),
865
+ /* @__PURE__ */ h("span", { children: t("audioMetrics.last", { seconds: _e(e.windowSec) }) }),
866
+ /* @__PURE__ */ h("span", {
727
867
  className: "ml-auto text-[10px] normal-case tracking-normal",
728
868
  children: e.byClass.length
729
869
  })
730
870
  ]
731
- }), /* @__PURE__ */ m("div", {
871
+ }), /* @__PURE__ */ h("div", {
732
872
  className: "divide-y divide-border/30",
733
- children: e.byClass.slice(0, 8).map((e) => /* @__PURE__ */ h("div", {
873
+ children: e.byClass.slice(0, 8).map((e) => /* @__PURE__ */ g("div", {
734
874
  className: "px-3 py-1.5 flex items-center justify-between text-xs",
735
- children: [/* @__PURE__ */ m("span", {
875
+ children: [/* @__PURE__ */ h("span", {
736
876
  className: "font-medium text-foreground truncate",
737
877
  children: e.className
738
- }), /* @__PURE__ */ h("span", {
878
+ }), /* @__PURE__ */ g("span", {
739
879
  className: "flex items-center gap-2 tabular-nums text-foreground-subtle",
740
- children: [/* @__PURE__ */ h("span", { children: [e.hits, "× hits"] }), /* @__PURE__ */ h("span", {
880
+ children: [/* @__PURE__ */ h("span", { children: t("audioMetrics.hits", { count: e.hits }) }), /* @__PURE__ */ g("span", {
741
881
  className: "rounded-full px-1.5 py-0.5 text-[10px] bg-primary/10 text-primary border border-primary/20",
742
882
  children: [(e.peakScore * 100).toFixed(0), "%"]
743
883
  })]
@@ -748,7 +888,7 @@ function Ce({ snapshot: e }) {
748
888
  }
749
889
  //#endregion
750
890
  //#region src/pipeline-analytics/widgets/OccupancyHistoryChart.tsx
751
- var we = 5 * 6e4, V = {
891
+ var we = 5 * 6e4, U = {
752
892
  "1h": {
753
893
  label: "1 h",
754
894
  windowMs: 60 * 6e4,
@@ -772,55 +912,55 @@ var we = 5 * 6e4, V = {
772
912
  }, Te = [
773
913
  {
774
914
  id: "1h",
775
- label: V["1h"].label
915
+ label: U["1h"].label
776
916
  },
777
917
  {
778
918
  id: "6h",
779
- label: V["6h"].label
919
+ label: U["6h"].label
780
920
  },
781
921
  {
782
922
  id: "24h",
783
- label: V["24h"].label
923
+ label: U["24h"].label
784
924
  },
785
925
  {
786
926
  id: "7d",
787
- label: V["7d"].label
927
+ label: U["7d"].label
788
928
  }
789
- ], H = 140, U = {
929
+ ], W = 140, G = {
790
930
  top: 14,
791
931
  right: 12,
792
932
  bottom: 24,
793
933
  left: 32
794
- }, W = "__all__";
934
+ }, K = "__all__";
795
935
  function Ee({ deviceId: n }) {
796
- let a = p(c().trpcClient, n), [s, l] = r("24h"), [u, f] = r(W), v = V[s], [y, b] = P(), x = I(), S = e(null), C = (e) => {
797
- let t = S.current;
936
+ let { t: a } = P(), s = m(l().trpcClient, n), [c, u] = r("24h"), [d, p] = r(K), y = U[c], [b, x] = I(), S = ie(), C = e(null), w = (e) => {
937
+ let t = C.current;
798
938
  if (!t) return e;
799
939
  let n = t.getBoundingClientRect();
800
- return n.width === 0 ? e : e / b * n.width;
801
- }, w = d(a?.state.zoneAnalytics), T = t(() => {
940
+ return n.width === 0 ? e : e / x * n.width;
941
+ }, T = f(s?.state.zoneAnalytics), E = t(() => {
802
942
  let e = /* @__PURE__ */ new Set();
803
- if (w?.frame.byClass) for (let t of Object.keys(w.frame.byClass)) e.add(t);
804
- if (w?.zones) for (let t of w.zones) for (let n of Object.keys(t.byClass)) e.add(n);
943
+ if (T?.frame.byClass) for (let t of Object.keys(T.frame.byClass)) e.add(t);
944
+ if (T?.zones) for (let t of T.zones) for (let n of Object.keys(t.byClass)) e.add(n);
805
945
  return [...e].toSorted();
806
- }, [w]);
946
+ }, [T]);
807
947
  i(() => {
808
- u !== W && !T.includes(u) && f(W);
809
- }, [u, T]);
810
- let E = o({
948
+ d !== K && !E.includes(d) && p(K);
949
+ }, [d, E]);
950
+ let D = o({
811
951
  queryKey: [
812
952
  "pipeline-analytics",
813
953
  n,
814
954
  "occupancyLts",
815
- s,
816
- u
955
+ c,
956
+ d
817
957
  ],
818
958
  queryFn: async () => {
819
- if (!a) return [];
820
- let e = Date.now(), t = Math.floor((e - v.windowMs) / we) * we;
821
- return (await a.pipelineAnalytics?.readLongTermSeries({
959
+ if (!s) return [];
960
+ let e = Date.now(), t = Math.floor((e - y.windowMs) / we) * we;
961
+ return (await s.pipelineAnalytics?.readLongTermSeries({
822
962
  series: "occupancy",
823
- scope: u === W ? _() : _(void 0, u),
963
+ scope: d === K ? v() : v(void 0, d),
824
964
  from: t,
825
965
  to: e
826
966
  }) ?? []).map((e) => ({
@@ -828,122 +968,122 @@ function Ee({ deviceId: n }) {
828
968
  count: e.max
829
969
  }));
830
970
  },
831
- enabled: !!a,
832
- refetchInterval: v.pollIntervalMs,
833
- staleTime: Math.max(1e3, v.pollIntervalMs / 2)
834
- }), D = E.data ?? [], O = E.dataUpdatedAt > 0 ? E.dataUpdatedAt : Date.now(), A = O - v.windowMs, j = t(() => {
835
- if (D.length === 0) return 1;
836
- let e = D.reduce((e, t) => Math.max(e, t.count), 0);
971
+ enabled: !!s,
972
+ refetchInterval: y.pollIntervalMs,
973
+ staleTime: Math.max(1e3, y.pollIntervalMs / 2)
974
+ }), O = D.data ?? [], k = D.dataUpdatedAt > 0 ? D.dataUpdatedAt : Date.now(), j = k - y.windowMs, M = t(() => {
975
+ if (O.length === 0) return 1;
976
+ let e = O.reduce((e, t) => Math.max(e, t.count), 0);
837
977
  return Math.max(1, Math.ceil(e * 1.15));
838
- }, [D]), M = t(() => Oe(D, b, j), [
839
- D,
840
- b,
841
- j
842
- ]), F = t(() => te(A, O, b, U.left, U.right, 5), [
843
- A,
978
+ }, [O]), N = t(() => Oe(O, x, M), [
844
979
  O,
845
- b
846
- ]), ne = t(() => ke(j), [j]);
847
- return /* @__PURE__ */ h("div", {
980
+ x,
981
+ M
982
+ ]), L = t(() => te(j, k, x, G.left, G.right, 5), [
983
+ j,
984
+ k,
985
+ x
986
+ ]), ne = t(() => ke(M), [M]);
987
+ return /* @__PURE__ */ g("div", {
848
988
  className: "rounded-lg border border-border bg-surface overflow-hidden",
849
- children: [/* @__PURE__ */ h("div", {
989
+ children: [/* @__PURE__ */ g("div", {
850
990
  className: "border-b border-border px-4 py-2 flex items-center justify-between gap-3",
851
- children: [/* @__PURE__ */ h("div", {
991
+ children: [/* @__PURE__ */ g("div", {
852
992
  className: "flex items-center gap-1.5",
853
- children: [/* @__PURE__ */ m(k, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ m("h2", {
993
+ children: [/* @__PURE__ */ h(A, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ h("h2", {
854
994
  className: "text-xs font-semibold text-foreground uppercase tracking-wider",
855
- children: "Occupancy History"
995
+ children: a("occupancyHistory.title")
856
996
  })]
857
- }), /* @__PURE__ */ h("div", {
997
+ }), /* @__PURE__ */ g("div", {
858
998
  className: "flex items-center gap-2",
859
- children: [T.length > 0 && /* @__PURE__ */ h("select", {
860
- value: u,
861
- onChange: (e) => f(e.target.value),
999
+ children: [E.length > 0 && /* @__PURE__ */ g("select", {
1000
+ value: d,
1001
+ onChange: (e) => p(e.target.value),
862
1002
  className: "text-[10px] px-1.5 py-0.5 rounded border border-border bg-background text-foreground focus:outline-none focus:ring-1 focus:ring-primary/40",
863
- title: "Filter by detected class",
864
- children: [/* @__PURE__ */ m("option", {
865
- value: W,
866
- children: "All classes"
867
- }), T.map((e) => /* @__PURE__ */ m("option", {
1003
+ title: a("occupancyHistory.filterByClass"),
1004
+ children: [/* @__PURE__ */ h("option", {
1005
+ value: K,
1006
+ children: a("occupancyHistory.allClasses")
1007
+ }), E.map((e) => /* @__PURE__ */ h("option", {
868
1008
  value: e,
869
1009
  children: e
870
1010
  }, e))]
871
- }), /* @__PURE__ */ m(N, {
1011
+ }), /* @__PURE__ */ h(F, {
872
1012
  presets: Te,
873
- value: s,
874
- onChange: l
1013
+ value: c,
1014
+ onChange: u
875
1015
  })]
876
1016
  })]
877
- }), /* @__PURE__ */ h("div", {
878
- ref: y,
1017
+ }), /* @__PURE__ */ g("div", {
1018
+ ref: b,
879
1019
  className: "p-3 min-w-0 relative",
880
- children: [D.length === 0 ? /* @__PURE__ */ m("div", {
1020
+ children: [O.length === 0 ? /* @__PURE__ */ h("div", {
881
1021
  className: "flex items-center justify-center h-32 text-[11px] text-foreground-subtle italic",
882
- children: E.isLoading ? "Loading…" : "No occupancy history yet — analytics pipeline must be active."
883
- }) : b === 0 ? /* @__PURE__ */ m("div", { className: "h-32" }) : /* @__PURE__ */ h(g, { children: [/* @__PURE__ */ h("svg", {
884
- ref: S,
1022
+ children: D.isLoading ? a("common.loading") : a("occupancyHistory.empty")
1023
+ }) : x === 0 ? /* @__PURE__ */ h("div", { className: "h-32" }) : /* @__PURE__ */ g(_, { children: [/* @__PURE__ */ g("svg", {
1024
+ ref: C,
885
1025
  role: "img",
886
- "aria-label": "Frame occupancy history",
1026
+ "aria-label": a("occupancyHistory.ariaLabel"),
887
1027
  width: "100%",
888
- height: H,
889
- viewBox: `0 0 ${b} ${H}`,
1028
+ height: W,
1029
+ viewBox: `0 0 ${x} ${W}`,
890
1030
  preserveAspectRatio: "none",
891
1031
  className: "block",
892
- onMouseLeave: () => x.bindHover(null),
1032
+ onMouseLeave: () => S.bindHover(null),
893
1033
  children: [
894
- ne.map(({ y: e, label: t }, n) => /* @__PURE__ */ h("g", { children: [/* @__PURE__ */ m("line", {
895
- x1: U.left,
896
- x2: b - U.right,
1034
+ ne.map(({ y: e, label: t }, n) => /* @__PURE__ */ g("g", { children: [/* @__PURE__ */ h("line", {
1035
+ x1: G.left,
1036
+ x2: x - G.right,
897
1037
  y1: e,
898
1038
  y2: e,
899
1039
  stroke: "currentColor",
900
1040
  strokeOpacity: .08,
901
1041
  strokeWidth: .5
902
- }), /* @__PURE__ */ m("text", {
903
- x: U.left - 6,
1042
+ }), /* @__PURE__ */ h("text", {
1043
+ x: G.left - 6,
904
1044
  y: e + 3,
905
1045
  textAnchor: "end",
906
1046
  className: "text-[9px] fill-foreground-subtle",
907
1047
  children: t
908
1048
  })] }, `y-${n}`)),
909
- F.map(({ x: e, label: t }, n) => /* @__PURE__ */ m("text", {
1049
+ L.map(({ x: e, label: t }, n) => /* @__PURE__ */ h("text", {
910
1050
  x: e,
911
- y: H - U.bottom + 12,
1051
+ y: W - G.bottom + 12,
912
1052
  textAnchor: "middle",
913
1053
  className: "text-[9px] fill-foreground-subtle",
914
1054
  children: t
915
1055
  }, `x-${n}`)),
916
- M && /* @__PURE__ */ m("path", {
917
- d: M,
1056
+ N && /* @__PURE__ */ h("path", {
1057
+ d: N,
918
1058
  fill: "none",
919
1059
  stroke: "currentColor",
920
1060
  className: "text-primary",
921
1061
  strokeWidth: 1.5
922
1062
  }),
923
- D.map((e, t) => {
924
- let n = ee(t, D.length, b, U.left, U.right), r = De(e.count, j), i = H - U.top - U.bottom, a = D.length > 1 ? (b - U.left - U.right) / (D.length - 1) : 24;
925
- return /* @__PURE__ */ h("g", { children: [/* @__PURE__ */ m("circle", {
1063
+ O.map((e, t) => {
1064
+ let n = ee(t, O.length, x, G.left, G.right), r = De(e.count, M), i = W - G.top - G.bottom, o = O.length > 1 ? (x - G.left - G.right) / (O.length - 1) : 24;
1065
+ return /* @__PURE__ */ g("g", { children: [/* @__PURE__ */ h("circle", {
926
1066
  cx: n,
927
1067
  cy: r,
928
1068
  r: 2,
929
1069
  fill: "currentColor",
930
1070
  className: "text-primary"
931
- }), /* @__PURE__ */ m("rect", {
932
- x: n - a / 2,
933
- y: U.top,
934
- width: Math.max(2, a),
1071
+ }), /* @__PURE__ */ h("rect", {
1072
+ x: n - o / 2,
1073
+ y: G.top,
1074
+ width: Math.max(2, o),
935
1075
  height: i,
936
1076
  fill: "transparent",
937
1077
  onMouseEnter: () => {
938
- x.bindHover({
939
- anchorX: C(n),
1078
+ S.bindHover({
1079
+ anchorX: w(n),
940
1080
  anchorY: r,
941
- title: `${Ae(e.ts)} · ${e.count} object${e.count === 1 ? "" : "s"}`,
1081
+ title: `${Ae(e.ts)} · ${a("occupancyHistory.objects", { count: e.count })}`,
942
1082
  rows: [{
943
- label: "Class",
944
- value: u === W ? "all" : u
1083
+ label: a("occupancyHistory.class"),
1084
+ value: d === K ? a("occupancyHistory.all") : d
945
1085
  }, {
946
- label: "Bucket",
1086
+ label: a("occupancyHistory.bucket"),
947
1087
  value: "5 min"
948
1088
  }]
949
1089
  });
@@ -951,34 +1091,25 @@ function Ee({ deviceId: n }) {
951
1091
  })] }, `${e.ts}-${t}`);
952
1092
  })
953
1093
  ]
954
- }), /* @__PURE__ */ m(ie, {
955
- state: x.state,
956
- containerWidth: b
957
- })] }), D.length > 0 && /* @__PURE__ */ h("div", {
1094
+ }), /* @__PURE__ */ h(R, {
1095
+ state: S.state,
1096
+ containerWidth: x
1097
+ })] }), O.length > 0 && /* @__PURE__ */ g("div", {
958
1098
  className: "flex items-center justify-between text-[10px] text-foreground-subtle mt-1",
959
- children: [/* @__PURE__ */ h("span", { children: [
960
- D.length,
961
- " bucket",
962
- D.length === 1 ? "" : "s",
963
- " · 5 min resolution"
964
- ] }), /* @__PURE__ */ h("span", { children: [
965
- "peak ",
966
- D.reduce((e, t) => Math.max(e, t.count), 0),
967
- " obj"
968
- ] })]
1099
+ children: [/* @__PURE__ */ h("span", { children: a("occupancyHistory.buckets", { count: O.length }) }), /* @__PURE__ */ h("span", { children: a("occupancyHistory.peak", { value: O.reduce((e, t) => Math.max(e, t.count), 0) }) })]
969
1100
  })]
970
1101
  })]
971
1102
  });
972
1103
  }
973
1104
  function De(e, t) {
974
- let n = H - U.top - U.bottom, r = Math.min(1, e / t);
975
- return U.top + (1 - r) * n;
1105
+ let n = W - G.top - G.bottom, r = Math.min(1, e / t);
1106
+ return G.top + (1 - r) * n;
976
1107
  }
977
1108
  function Oe(e, t, n) {
978
1109
  if (e.length === 0) return null;
979
1110
  let r = [];
980
1111
  for (let i = 0; i < e.length; i++) {
981
- let a = ee(i, e.length, t, U.left, U.right), o = De(e[i].count, n);
1112
+ let a = ee(i, e.length, t, G.left, G.right), o = De(e[i].count, n);
982
1113
  r.push(`${i === 0 ? "M" : "L"} ${a.toFixed(1)} ${o.toFixed(1)}`);
983
1114
  }
984
1115
  return r.join(" ");
@@ -986,9 +1117,9 @@ function Oe(e, t, n) {
986
1117
  function ke(e) {
987
1118
  let t = [];
988
1119
  for (let n = 0; n < 4; n++) {
989
- let r = n / 3, i = Math.round(e * r), a = H - U.top - U.bottom;
1120
+ let r = n / 3, i = Math.round(e * r), a = W - G.top - G.bottom;
990
1121
  t.push({
991
- y: U.top + (1 - r) * a,
1122
+ y: G.top + (1 - r) * a,
992
1123
  label: `${i}`
993
1124
  });
994
1125
  }
@@ -1000,7 +1131,7 @@ function Ae(e) {
1000
1131
  }
1001
1132
  //#endregion
1002
1133
  //#region src/pipeline-analytics/widgets/MotionHistoryChart.tsx
1003
- var G = {
1134
+ var je = {
1004
1135
  "1h": {
1005
1136
  label: "1 h",
1006
1137
  windowMs: 60 * 6e4,
@@ -1019,143 +1150,143 @@ var G = {
1019
1150
  bucketMs: 15 * 6e4,
1020
1151
  pollIntervalMs: 3e5
1021
1152
  }
1022
- }, je = [
1153
+ }, Me = [
1023
1154
  {
1024
1155
  id: "1h",
1025
- label: G["1h"].label
1156
+ label: je["1h"].label
1026
1157
  },
1027
1158
  {
1028
1159
  id: "6h",
1029
- label: G["6h"].label
1160
+ label: je["6h"].label
1030
1161
  },
1031
1162
  {
1032
1163
  id: "24h",
1033
- label: G["24h"].label
1164
+ label: je["24h"].label
1034
1165
  }
1035
- ], Me = 5e3, K = 140, q = {
1166
+ ], Ne = 5e3, q = 140, J = {
1036
1167
  top: 14,
1037
1168
  right: 12,
1038
1169
  bottom: 24,
1039
1170
  left: 32
1040
1171
  };
1041
- function Ne({ deviceId: n }) {
1042
- let i = p(c().trpcClient, n), [a, s] = r("1h"), l = G[a], [u, d] = P(), f = I(), _ = e(null), v = (e) => {
1043
- let t = _.current;
1172
+ function Pe({ deviceId: n }) {
1173
+ let { t: i } = P(), a = m(l().trpcClient, n), [s, c] = r("1h"), u = je[s], [d, f] = I(), p = ie(), v = e(null), y = (e) => {
1174
+ let t = v.current;
1044
1175
  if (!t) return e;
1045
1176
  let n = t.getBoundingClientRect();
1046
- return n.width === 0 ? e : e / d * n.width;
1047
- }, y = o({
1177
+ return n.width === 0 ? e : e / f * n.width;
1178
+ }, b = o({
1048
1179
  queryKey: [
1049
1180
  "pipeline-analytics",
1050
1181
  n,
1051
1182
  "motionEvents",
1052
- a
1183
+ s
1053
1184
  ],
1054
1185
  queryFn: async () => {
1055
- if (!i) return [];
1056
- let e = Date.now() - l.windowMs;
1057
- return await i.pipelineAnalytics?.getMotionEvents({
1186
+ if (!a) return [];
1187
+ let e = Date.now() - u.windowMs;
1188
+ return await a.pipelineAnalytics?.getMotionEvents({
1058
1189
  since: e,
1059
- limit: Me
1190
+ limit: Ne
1060
1191
  }) ?? [];
1061
1192
  },
1062
- enabled: !!i,
1063
- refetchInterval: l.pollIntervalMs,
1064
- staleTime: Math.max(1e3, l.pollIntervalMs / 2)
1065
- }), b = y.data ?? [], x = y.dataUpdatedAt > 0 ? y.dataUpdatedAt : Date.now(), S = x - l.windowMs, C = t(() => Pe(b, S, x, l.bucketMs), [
1066
- b,
1067
- S,
1193
+ enabled: !!a,
1194
+ refetchInterval: u.pollIntervalMs,
1195
+ staleTime: Math.max(1e3, u.pollIntervalMs / 2)
1196
+ }), x = b.data ?? [], S = b.dataUpdatedAt > 0 ? b.dataUpdatedAt : Date.now(), C = S - u.windowMs, w = t(() => Fe(x, C, S, u.bucketMs), [
1068
1197
  x,
1069
- l.bucketMs
1070
- ]), w = t(() => {
1071
- if (C.length === 0) return 1;
1072
- let e = C.reduce((e, t) => Math.max(e, t.count), 0);
1198
+ C,
1199
+ S,
1200
+ u.bucketMs
1201
+ ]), T = t(() => {
1202
+ if (w.length === 0) return 1;
1203
+ let e = w.reduce((e, t) => Math.max(e, t.count), 0);
1073
1204
  return Math.max(1, Math.ceil(e * 1.15));
1074
- }, [C]), T = t(() => te(S, x, d, q.left, q.right, 5), [
1205
+ }, [w]), E = t(() => te(C, S, f, J.left, J.right, 5), [
1206
+ C,
1075
1207
  S,
1076
- x,
1077
- d
1078
- ]), D = t(() => Ie(w), [w]), O = b.length;
1079
- return /* @__PURE__ */ h("div", {
1208
+ f
1209
+ ]), O = t(() => Le(T), [T]), k = x.length;
1210
+ return /* @__PURE__ */ g("div", {
1080
1211
  className: "rounded-lg border border-border bg-surface overflow-hidden",
1081
- children: [/* @__PURE__ */ h("div", {
1212
+ children: [/* @__PURE__ */ g("div", {
1082
1213
  className: "border-b border-border px-4 py-2 flex items-center justify-between gap-3",
1083
- children: [/* @__PURE__ */ h("div", {
1214
+ children: [/* @__PURE__ */ g("div", {
1084
1215
  className: "flex items-center gap-1.5",
1085
- children: [/* @__PURE__ */ m(E, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ m("h2", {
1216
+ children: [/* @__PURE__ */ h(D, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ h("h2", {
1086
1217
  className: "text-xs font-semibold text-foreground uppercase tracking-wider",
1087
- children: "Motion History"
1218
+ children: i("motionHistory.title")
1088
1219
  })]
1089
- }), /* @__PURE__ */ m(N, {
1090
- presets: je,
1091
- value: a,
1092
- onChange: s
1220
+ }), /* @__PURE__ */ h(F, {
1221
+ presets: Me,
1222
+ value: s,
1223
+ onChange: c
1093
1224
  })]
1094
- }), /* @__PURE__ */ h("div", {
1095
- ref: u,
1225
+ }), /* @__PURE__ */ g("div", {
1226
+ ref: d,
1096
1227
  className: "p-3 min-w-0 relative",
1097
- children: [O === 0 ? /* @__PURE__ */ m("div", {
1228
+ children: [k === 0 ? /* @__PURE__ */ h("div", {
1098
1229
  className: "flex items-center justify-center h-32 text-[11px] text-foreground-subtle italic",
1099
- children: y.isLoading ? "Loading…" : "No motion events in the selected window."
1100
- }) : d === 0 ? /* @__PURE__ */ m("div", { className: "h-32" }) : /* @__PURE__ */ h(g, { children: [/* @__PURE__ */ h("svg", {
1101
- ref: _,
1230
+ children: b.isLoading ? i("common.loading") : i("motionHistory.empty")
1231
+ }) : f === 0 ? /* @__PURE__ */ h("div", { className: "h-32" }) : /* @__PURE__ */ g(_, { children: [/* @__PURE__ */ g("svg", {
1232
+ ref: v,
1102
1233
  role: "img",
1103
- "aria-label": "Motion event histogram",
1234
+ "aria-label": i("motionHistory.ariaLabel"),
1104
1235
  width: "100%",
1105
- height: K,
1106
- viewBox: `0 0 ${d} ${K}`,
1236
+ height: q,
1237
+ viewBox: `0 0 ${f} ${q}`,
1107
1238
  preserveAspectRatio: "none",
1108
1239
  className: "block",
1109
- onMouseLeave: () => f.bindHover(null),
1240
+ onMouseLeave: () => p.bindHover(null),
1110
1241
  children: [
1111
- D.map(({ y: e, label: t }, n) => /* @__PURE__ */ h("g", { children: [/* @__PURE__ */ m("line", {
1112
- x1: q.left,
1113
- x2: d - q.right,
1242
+ O.map(({ y: e, label: t }, n) => /* @__PURE__ */ g("g", { children: [/* @__PURE__ */ h("line", {
1243
+ x1: J.left,
1244
+ x2: f - J.right,
1114
1245
  y1: e,
1115
1246
  y2: e,
1116
1247
  stroke: "currentColor",
1117
1248
  strokeOpacity: .08,
1118
1249
  strokeWidth: .5
1119
- }), /* @__PURE__ */ m("text", {
1120
- x: q.left - 6,
1250
+ }), /* @__PURE__ */ h("text", {
1251
+ x: J.left - 6,
1121
1252
  y: e + 3,
1122
1253
  textAnchor: "end",
1123
1254
  className: "text-[9px] fill-foreground-subtle",
1124
1255
  children: t
1125
1256
  })] }, `y-${n}`)),
1126
- T.map(({ x: e, label: t }, n) => /* @__PURE__ */ m("text", {
1257
+ E.map(({ x: e, label: t }, n) => /* @__PURE__ */ h("text", {
1127
1258
  x: e,
1128
- y: K - q.bottom + 12,
1259
+ y: q - J.bottom + 12,
1129
1260
  textAnchor: "middle",
1130
1261
  className: "text-[9px] fill-foreground-subtle",
1131
1262
  children: t
1132
1263
  }, `x-${n}`)),
1133
- C.map((e, t) => {
1134
- let { x: n, w: r } = Fe(e.bucketStart, l.bucketMs, S, x, d), i = K - q.top - q.bottom, a = e.count / w * i, o = q.top + (i - a), s = e.bucketStart + l.bucketMs;
1135
- return /* @__PURE__ */ h("g", { children: [e.count > 0 && /* @__PURE__ */ m("rect", {
1264
+ w.map((e, t) => {
1265
+ let { x: n, w: r } = Ie(e.bucketStart, u.bucketMs, C, S, f), a = q - J.top - J.bottom, o = e.count / T * a, s = J.top + (a - o), c = e.bucketStart + u.bucketMs;
1266
+ return /* @__PURE__ */ g("g", { children: [e.count > 0 && /* @__PURE__ */ h("rect", {
1136
1267
  x: n,
1137
- y: o,
1268
+ y: s,
1138
1269
  width: Math.max(1, r - 1),
1139
- height: Math.max(1, a),
1270
+ height: Math.max(1, o),
1140
1271
  fill: "currentColor",
1141
1272
  className: "text-primary",
1142
1273
  opacity: .85
1143
- }), /* @__PURE__ */ m("rect", {
1274
+ }), /* @__PURE__ */ h("rect", {
1144
1275
  x: n,
1145
- y: q.top,
1276
+ y: J.top,
1146
1277
  width: Math.max(2, r),
1147
- height: i,
1278
+ height: a,
1148
1279
  fill: "transparent",
1149
1280
  onMouseEnter: () => {
1150
- f.bindHover({
1151
- anchorX: v(n + r / 2),
1152
- anchorY: o,
1153
- title: `${Le(e.bucketStart, s)} · ${e.count} event${e.count === 1 ? "" : "s"}`,
1281
+ p.bindHover({
1282
+ anchorX: y(n + r / 2),
1283
+ anchorY: s,
1284
+ title: `${Re(e.bucketStart, c)} · ${i("motionHistory.events", { count: e.count })}`,
1154
1285
  rows: [{
1155
- label: "Bucket",
1156
- value: Re(l.bucketMs)
1286
+ label: i("motionHistory.bucket"),
1287
+ value: ze(u.bucketMs)
1157
1288
  }, {
1158
- label: "Count",
1289
+ label: i("motionHistory.count"),
1159
1290
  value: `${e.count}`
1160
1291
  }]
1161
1292
  });
@@ -1163,29 +1294,20 @@ function Ne({ deviceId: n }) {
1163
1294
  })] }, `${e.bucketStart}-${t}`);
1164
1295
  })
1165
1296
  ]
1166
- }), /* @__PURE__ */ m(ie, {
1167
- state: f.state,
1168
- containerWidth: d
1169
- })] }), O > 0 && /* @__PURE__ */ h("div", {
1297
+ }), /* @__PURE__ */ h(R, {
1298
+ state: p.state,
1299
+ containerWidth: f
1300
+ })] }), k > 0 && /* @__PURE__ */ g("div", {
1170
1301
  className: "flex items-center justify-between text-[10px] text-foreground-subtle mt-1",
1171
- children: [/* @__PURE__ */ h("span", { children: [
1172
- O,
1173
- " event",
1174
- O === 1 ? "" : "s",
1175
- " · ",
1176
- Re(l.bucketMs),
1177
- " ",
1178
- "buckets"
1179
- ] }), /* @__PURE__ */ h("span", { children: [
1180
- "peak ",
1181
- C.reduce((e, t) => Math.max(e, t.count), 0),
1182
- "/bucket"
1183
- ] })]
1302
+ children: [/* @__PURE__ */ h("span", { children: i("motionHistory.summary", {
1303
+ count: k,
1304
+ bucket: ze(u.bucketMs)
1305
+ }) }), /* @__PURE__ */ h("span", { children: i("motionHistory.peak", { value: w.reduce((e, t) => Math.max(e, t.count), 0) }) })]
1184
1306
  })]
1185
1307
  })]
1186
1308
  });
1187
1309
  }
1188
- function Pe(e, t, n, r) {
1310
+ function Fe(e, t, n, r) {
1189
1311
  if (n <= t) return [];
1190
1312
  let i = Math.floor(t / r) * r, a = Math.floor(n / r) * r, o = /* @__PURE__ */ new Map();
1191
1313
  for (let e = i; e <= a; e += r) o.set(e, 0);
@@ -1199,37 +1321,37 @@ function Pe(e, t, n, r) {
1199
1321
  count: t
1200
1322
  }));
1201
1323
  }
1202
- function Fe(e, t, n, r, i) {
1203
- let a = Math.max(1, r - n), o = i - q.left - q.right;
1324
+ function Ie(e, t, n, r, i) {
1325
+ let a = Math.max(1, r - n), o = i - J.left - J.right;
1204
1326
  return {
1205
- x: q.left + (e - n) / a * o,
1327
+ x: J.left + (e - n) / a * o,
1206
1328
  w: t / a * o
1207
1329
  };
1208
1330
  }
1209
- function Ie(e) {
1331
+ function Le(e) {
1210
1332
  let t = [];
1211
1333
  for (let n = 0; n < 4; n++) {
1212
- let r = n / 3, i = Math.round(e * r), a = K - q.top - q.bottom;
1334
+ let r = n / 3, i = Math.round(e * r), a = q - J.top - J.bottom;
1213
1335
  t.push({
1214
- y: q.top + (1 - r) * a,
1336
+ y: J.top + (1 - r) * a,
1215
1337
  label: `${i}`
1216
1338
  });
1217
1339
  }
1218
1340
  return t;
1219
1341
  }
1220
- function Le(e, t) {
1342
+ function Re(e, t) {
1221
1343
  let n = (e) => {
1222
1344
  let t = new Date(e);
1223
1345
  return `${String(t.getHours()).padStart(2, "0")}:${String(t.getMinutes()).padStart(2, "0")}`;
1224
1346
  };
1225
1347
  return `${n(e)}–${n(t)}`;
1226
1348
  }
1227
- function Re(e) {
1349
+ function ze(e) {
1228
1350
  return e >= 60 * 6e4 ? `${Math.round(e / 6e4 / 60)}h` : e >= 6e4 ? `${Math.round(e / 6e4)}m` : `${Math.round(e / 1e3)}s`;
1229
1351
  }
1230
1352
  //#endregion
1231
1353
  //#region src/pipeline-analytics/widgets/DetectionHistoryChart.tsx
1232
- var J = {
1354
+ var Be = {
1233
1355
  "1h": {
1234
1356
  label: "1 h",
1235
1357
  windowMs: 60 * 6e4,
@@ -1248,181 +1370,181 @@ var J = {
1248
1370
  bucketMs: 15 * 6e4,
1249
1371
  pollIntervalMs: 3e5
1250
1372
  }
1251
- }, ze = [
1373
+ }, Ve = [
1252
1374
  {
1253
1375
  id: "1h",
1254
- label: J["1h"].label
1376
+ label: Be["1h"].label
1255
1377
  },
1256
1378
  {
1257
1379
  id: "6h",
1258
- label: J["6h"].label
1380
+ label: Be["6h"].label
1259
1381
  },
1260
1382
  {
1261
1383
  id: "24h",
1262
- label: J["24h"].label
1384
+ label: Be["24h"].label
1263
1385
  }
1264
- ], Be = 5e3, Ve = 4, Y = "__other__", X = "__all__", Z = 160, Q = {
1386
+ ], He = 5e3, Ue = 4, Y = "__other__", X = "__all__", Z = 160, Q = {
1265
1387
  top: 14,
1266
1388
  right: 12,
1267
1389
  bottom: 24,
1268
1390
  left: 32
1269
1391
  };
1270
- function He({ deviceId: n }) {
1271
- let a = p(c().trpcClient, n), [s, l] = r("1h"), [u, d] = r(X), f = J[s], [_, v] = P(), y = I(), b = e(null), x = o({
1392
+ function We({ deviceId: n }) {
1393
+ let { t: a } = P(), s = m(l().trpcClient, n), [c, u] = r("1h"), [d, f] = r(X), p = Be[c], [v, y] = I(), b = ie(), x = e(null), S = o({
1272
1394
  queryKey: [
1273
1395
  "pipeline-analytics",
1274
1396
  n,
1275
1397
  "objectEvents",
1276
- s
1398
+ c
1277
1399
  ],
1278
1400
  queryFn: async () => {
1279
- if (!a) return [];
1280
- let e = Date.now() - f.windowMs;
1281
- return await a.pipelineAnalytics?.getObjectEvents({
1401
+ if (!s) return [];
1402
+ let e = Date.now() - p.windowMs;
1403
+ return await s.pipelineAnalytics?.getObjectEvents({
1282
1404
  since: e,
1283
- limit: Be
1405
+ limit: He
1284
1406
  }) ?? [];
1285
1407
  },
1286
- enabled: !!a,
1287
- refetchInterval: f.pollIntervalMs,
1288
- staleTime: Math.max(1e3, f.pollIntervalMs / 2)
1289
- }), S = x.data ?? [], C = t(() => u === X ? S : S.filter((e) => e.className === u), [S, u]), w = x.dataUpdatedAt > 0 ? x.dataUpdatedAt : Date.now(), T = w - f.windowMs, E = t(() => {
1408
+ enabled: !!s,
1409
+ refetchInterval: p.pollIntervalMs,
1410
+ staleTime: Math.max(1e3, p.pollIntervalMs / 2)
1411
+ }), C = S.data ?? [], w = t(() => d === X ? C : C.filter((e) => e.className === d), [C, d]), T = S.dataUpdatedAt > 0 ? S.dataUpdatedAt : Date.now(), E = T - p.windowMs, D = t(() => {
1290
1412
  let e = /* @__PURE__ */ new Set();
1291
- for (let t of S) e.add(t.className);
1292
- return u !== X && e.add(u), [...e].toSorted();
1293
- }, [S, u]);
1413
+ for (let t of C) e.add(t.className);
1414
+ return d !== X && e.add(d), [...e].toSorted();
1415
+ }, [C, d]);
1294
1416
  i(() => {
1295
- u !== X && S.length > 0 && !E.includes(u) && d(X);
1417
+ d !== X && C.length > 0 && !D.includes(d) && f(X);
1296
1418
  }, [
1297
- u,
1298
- S,
1299
- E
1300
- ]);
1301
- let D = t(() => Ue(C, Ve), [C]), k = t(() => We(C, T, w, f.bucketMs, D), [
1419
+ d,
1302
1420
  C,
1303
- T,
1304
- w,
1305
- f.bucketMs,
1306
1421
  D
1307
- ]), A = t(() => {
1308
- if (k.length === 0) return 1;
1309
- let e = k.reduce((e, t) => Math.max(e, t.total), 0);
1422
+ ]);
1423
+ let O = t(() => Ge(w, Ue), [w]), A = t(() => Ke(w, E, T, p.bucketMs, O), [
1424
+ w,
1425
+ E,
1426
+ T,
1427
+ p.bucketMs,
1428
+ O
1429
+ ]), j = t(() => {
1430
+ if (A.length === 0) return 1;
1431
+ let e = A.reduce((e, t) => Math.max(e, t.total), 0);
1310
1432
  return Math.max(1, Math.ceil(e * 1.15));
1311
- }, [k]), j = t(() => te(T, w, v, Q.left, Q.right, 5), [
1433
+ }, [A]), M = t(() => te(E, T, y, Q.left, Q.right, 5), [
1434
+ E,
1312
1435
  T,
1313
- w,
1314
- v
1315
- ]), M = t(() => Ke(A), [A]), F = t(() => {
1316
- let e = D.map((e) => e.className);
1317
- return C.some((e) => !D.some((t) => t.className === e.className)) && e.push(Y), e;
1318
- }, [C, D]), ee = (e) => {
1319
- let t = b.current;
1436
+ y
1437
+ ]), N = t(() => Je(j), [j]), L = t(() => {
1438
+ let e = O.map((e) => e.className);
1439
+ return w.some((e) => !O.some((t) => t.className === e.className)) && e.push(Y), e;
1440
+ }, [w, O]), ee = (e) => {
1441
+ let t = x.current;
1320
1442
  if (!t) return e;
1321
1443
  let n = t.getBoundingClientRect();
1322
- return n.width === 0 ? e : e / v * n.width;
1444
+ return n.width === 0 ? e : e / y * n.width;
1323
1445
  };
1324
- return /* @__PURE__ */ h("div", {
1446
+ return /* @__PURE__ */ g("div", {
1325
1447
  className: "rounded-lg border border-border bg-surface overflow-hidden",
1326
- children: [/* @__PURE__ */ h("div", {
1448
+ children: [/* @__PURE__ */ g("div", {
1327
1449
  className: "border-b border-border px-4 py-2 flex items-center justify-between gap-3",
1328
- children: [/* @__PURE__ */ h("div", {
1450
+ children: [/* @__PURE__ */ g("div", {
1329
1451
  className: "flex items-center gap-1.5",
1330
- children: [/* @__PURE__ */ m(O, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ m("h2", {
1452
+ children: [/* @__PURE__ */ h(k, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ h("h2", {
1331
1453
  className: "text-xs font-semibold text-foreground uppercase tracking-wider",
1332
- children: "Detection History"
1454
+ children: a("detectionHistory.title")
1333
1455
  })]
1334
- }), /* @__PURE__ */ h("div", {
1456
+ }), /* @__PURE__ */ g("div", {
1335
1457
  className: "flex items-center gap-2",
1336
- children: [E.length > 0 && /* @__PURE__ */ h("select", {
1337
- value: u,
1338
- onChange: (e) => d(e.target.value),
1458
+ children: [D.length > 0 && /* @__PURE__ */ g("select", {
1459
+ value: d,
1460
+ onChange: (e) => f(e.target.value),
1339
1461
  className: "text-[10px] px-1.5 py-0.5 rounded border border-border bg-background text-foreground focus:outline-none focus:ring-1 focus:ring-primary/40",
1340
- title: "Filter by detected class",
1341
- children: [/* @__PURE__ */ m("option", {
1462
+ title: a("detectionHistory.filterByClass"),
1463
+ children: [/* @__PURE__ */ h("option", {
1342
1464
  value: X,
1343
- children: "All classes"
1344
- }), E.map((e) => /* @__PURE__ */ m("option", {
1465
+ children: a("detectionHistory.allClasses")
1466
+ }), D.map((e) => /* @__PURE__ */ h("option", {
1345
1467
  value: e,
1346
1468
  children: e
1347
1469
  }, e))]
1348
- }), /* @__PURE__ */ m(N, {
1349
- presets: ze,
1350
- value: s,
1351
- onChange: l
1470
+ }), /* @__PURE__ */ h(F, {
1471
+ presets: Ve,
1472
+ value: c,
1473
+ onChange: u
1352
1474
  })]
1353
1475
  })]
1354
- }), /* @__PURE__ */ h("div", {
1355
- ref: _,
1476
+ }), /* @__PURE__ */ g("div", {
1477
+ ref: v,
1356
1478
  className: "p-3 min-w-0 relative",
1357
- children: [C.length === 0 ? /* @__PURE__ */ m("div", {
1479
+ children: [w.length === 0 ? /* @__PURE__ */ h("div", {
1358
1480
  className: "flex items-center justify-center h-32 text-[11px] text-foreground-subtle italic",
1359
- children: x.isLoading ? "Loading…" : "No detection events in the selected window."
1360
- }) : v === 0 ? /* @__PURE__ */ m("div", { className: "h-32" }) : /* @__PURE__ */ h(g, { children: [
1361
- /* @__PURE__ */ h("svg", {
1362
- ref: b,
1481
+ children: S.isLoading ? a("common.loading") : a("detectionHistory.empty")
1482
+ }) : y === 0 ? /* @__PURE__ */ h("div", { className: "h-32" }) : /* @__PURE__ */ g(_, { children: [
1483
+ /* @__PURE__ */ g("svg", {
1484
+ ref: x,
1363
1485
  role: "img",
1364
- "aria-label": "Detection event histogram",
1486
+ "aria-label": a("detectionHistory.ariaLabel"),
1365
1487
  width: "100%",
1366
1488
  height: Z,
1367
- viewBox: `0 0 ${v} ${Z}`,
1489
+ viewBox: `0 0 ${y} ${Z}`,
1368
1490
  preserveAspectRatio: "none",
1369
1491
  className: "block",
1370
- onMouseLeave: () => y.bindHover(null),
1492
+ onMouseLeave: () => b.bindHover(null),
1371
1493
  children: [
1372
- M.map(({ y: e, label: t }, n) => /* @__PURE__ */ h("g", { children: [/* @__PURE__ */ m("line", {
1494
+ N.map(({ y: e, label: t }, n) => /* @__PURE__ */ g("g", { children: [/* @__PURE__ */ h("line", {
1373
1495
  x1: Q.left,
1374
- x2: v - Q.right,
1496
+ x2: y - Q.right,
1375
1497
  y1: e,
1376
1498
  y2: e,
1377
1499
  stroke: "currentColor",
1378
1500
  strokeOpacity: .08,
1379
1501
  strokeWidth: .5
1380
- }), /* @__PURE__ */ m("text", {
1502
+ }), /* @__PURE__ */ h("text", {
1381
1503
  x: Q.left - 6,
1382
1504
  y: e + 3,
1383
1505
  textAnchor: "end",
1384
1506
  className: "text-[9px] fill-foreground-subtle",
1385
1507
  children: t
1386
1508
  })] }, `y-${n}`)),
1387
- j.map(({ x: e, label: t }, n) => /* @__PURE__ */ m("text", {
1509
+ M.map(({ x: e, label: t }, n) => /* @__PURE__ */ h("text", {
1388
1510
  x: e,
1389
1511
  y: Z - Q.bottom + 12,
1390
1512
  textAnchor: "middle",
1391
1513
  className: "text-[9px] fill-foreground-subtle",
1392
1514
  children: t
1393
1515
  }, `x-${n}`)),
1394
- k.map((e, t) => {
1516
+ A.map((e, t) => {
1395
1517
  if (e.total === 0) return null;
1396
- let { x: n, w: r } = Ge(e.bucketStart, f.bucketMs, T, w, v), i = Z - Q.top - Q.bottom, a = e.total / A * i, o = Q.top + (i - a), s = 0, c = F.map((t, a) => {
1518
+ let { x: n, w: r } = qe(e.bucketStart, p.bucketMs, E, T, y), i = Z - Q.top - Q.bottom, o = e.total / j * i, s = Q.top + (i - o), c = 0, l = L.map((t, a) => {
1397
1519
  let o = e.byClass[t] ?? 0;
1398
1520
  if (o === 0) return null;
1399
- let c = o / A * i, l = Q.top + (i - s - c);
1400
- s += c;
1521
+ let s = o / j * i, l = Q.top + (i - c - s);
1522
+ c += s;
1401
1523
  let u = t === Y ? "#94a3b8" : re(a);
1402
- return /* @__PURE__ */ m("rect", {
1524
+ return /* @__PURE__ */ h("rect", {
1403
1525
  x: n,
1404
1526
  y: l,
1405
1527
  width: Math.max(1, r - 1),
1406
- height: Math.max(1, c),
1528
+ height: Math.max(1, s),
1407
1529
  fill: u,
1408
1530
  opacity: .9
1409
1531
  }, `${e.bucketStart}-${t}`);
1410
- }).filter((e) => e !== null), l = e.bucketStart + f.bucketMs;
1411
- return /* @__PURE__ */ h("g", { children: [c, /* @__PURE__ */ m("rect", {
1532
+ }).filter((e) => e !== null), u = e.bucketStart + p.bucketMs;
1533
+ return /* @__PURE__ */ g("g", { children: [l, /* @__PURE__ */ h("rect", {
1412
1534
  x: n,
1413
1535
  y: Q.top,
1414
1536
  width: Math.max(2, r),
1415
1537
  height: i,
1416
1538
  fill: "transparent",
1417
1539
  onMouseEnter: () => {
1418
- y.bindHover({
1540
+ b.bindHover({
1419
1541
  anchorX: ee(n + r / 2),
1420
- anchorY: o,
1421
- title: `${qe(e.bucketStart, l, f.bucketMs)} · ${e.total} detection${e.total === 1 ? "" : "s"}`,
1422
- rows: F.map((t, n) => {
1542
+ anchorY: s,
1543
+ title: `${Ye(e.bucketStart, u, p.bucketMs)} · ${a("detectionHistory.detections", { count: e.total })}`,
1544
+ rows: L.map((t, n) => {
1423
1545
  let r = e.byClass[t] ?? 0;
1424
1546
  return r === 0 ? null : {
1425
- label: t === Y ? "other" : t,
1547
+ label: t === Y ? a("detectionHistory.other") : t,
1426
1548
  value: `${r}`,
1427
1549
  colour: t === Y ? "#94a3b8" : re(n)
1428
1550
  };
@@ -1433,31 +1555,22 @@ function He({ deviceId: n }) {
1433
1555
  })
1434
1556
  ]
1435
1557
  }),
1436
- /* @__PURE__ */ m(ie, {
1437
- state: y.state,
1438
- containerWidth: v
1558
+ /* @__PURE__ */ h(R, {
1559
+ state: b.state,
1560
+ containerWidth: y
1439
1561
  }),
1440
- /* @__PURE__ */ m(Ye, { stackOrder: F })
1441
- ] }), C.length > 0 && /* @__PURE__ */ h("div", {
1562
+ /* @__PURE__ */ h(Ze, { stackOrder: L })
1563
+ ] }), w.length > 0 && /* @__PURE__ */ g("div", {
1442
1564
  className: "flex items-center justify-between text-[10px] text-foreground-subtle mt-1",
1443
- children: [/* @__PURE__ */ h("span", { children: [
1444
- C.length,
1445
- " detection",
1446
- C.length === 1 ? "" : "s",
1447
- " ·",
1448
- " ",
1449
- Je(f.bucketMs),
1450
- " buckets"
1451
- ] }), /* @__PURE__ */ h("span", { children: [
1452
- "peak ",
1453
- k.reduce((e, t) => Math.max(e, t.total), 0),
1454
- "/bucket"
1455
- ] })]
1565
+ children: [/* @__PURE__ */ h("span", { children: a("detectionHistory.summary", {
1566
+ count: w.length,
1567
+ bucket: Xe(p.bucketMs)
1568
+ }) }), /* @__PURE__ */ h("span", { children: a("detectionHistory.peak", { value: A.reduce((e, t) => Math.max(e, t.total), 0) }) })]
1456
1569
  })]
1457
1570
  })]
1458
1571
  });
1459
1572
  }
1460
- function Ue(e, t) {
1573
+ function Ge(e, t) {
1461
1574
  let n = /* @__PURE__ */ new Map();
1462
1575
  for (let t of e) n.set(t.className, (n.get(t.className) ?? 0) + 1);
1463
1576
  return [...n.entries()].toSorted(([, e], [, t]) => t - e).slice(0, t).map(([e, t]) => ({
@@ -1465,7 +1578,7 @@ function Ue(e, t) {
1465
1578
  count: t
1466
1579
  }));
1467
1580
  }
1468
- function We(e, t, n, r, i) {
1581
+ function Ke(e, t, n, r, i) {
1469
1582
  if (n <= t) return [];
1470
1583
  let a = new Set(i.map((e) => e.className)), o = Math.floor(t / r) * r, s = Math.floor(n / r) * r, c = /* @__PURE__ */ new Map();
1471
1584
  for (let e = o; e <= s; e += r) c.set(e, {
@@ -1486,14 +1599,14 @@ function We(e, t, n, r, i) {
1486
1599
  byClass: t.byClass
1487
1600
  }));
1488
1601
  }
1489
- function Ge(e, t, n, r, i) {
1602
+ function qe(e, t, n, r, i) {
1490
1603
  let a = Math.max(1, r - n), o = i - Q.left - Q.right;
1491
1604
  return {
1492
1605
  x: Q.left + (e - n) / a * o,
1493
1606
  w: t / a * o
1494
1607
  };
1495
1608
  }
1496
- function Ke(e) {
1609
+ function Je(e) {
1497
1610
  let t = [];
1498
1611
  for (let n = 0; n < 4; n++) {
1499
1612
  let r = n / 3, i = Math.round(e * r), a = Z - Q.top - Q.bottom;
@@ -1504,161 +1617,168 @@ function Ke(e) {
1504
1617
  }
1505
1618
  return t;
1506
1619
  }
1507
- function qe(e, t, n) {
1620
+ function Ye(e, t, n) {
1508
1621
  let r = (e) => `${String(e.getHours()).padStart(2, "0")}:${String(e.getMinutes()).padStart(2, "0")}`;
1509
1622
  return `${r(new Date(e))}–${r(new Date(t))}`;
1510
1623
  }
1511
- function Je(e) {
1624
+ function Xe(e) {
1512
1625
  return e >= 60 * 6e4 ? `${Math.round(e / 6e4 / 60)}h` : e >= 6e4 ? `${Math.round(e / 6e4)}m` : `${Math.round(e / 1e3)}s`;
1513
1626
  }
1514
- function Ye({ stackOrder: e }) {
1515
- return e.length === 0 ? null : /* @__PURE__ */ m("div", {
1627
+ function Ze({ stackOrder: e }) {
1628
+ let { t } = P();
1629
+ return e.length === 0 ? null : /* @__PURE__ */ h("div", {
1516
1630
  className: "flex flex-wrap gap-2 mt-2 px-1",
1517
- children: e.map((e, t) => /* @__PURE__ */ h("span", {
1518
- className: "inline-flex items-center gap-1 text-[10px] text-foreground-subtle",
1519
- children: [/* @__PURE__ */ m("span", {
1520
- className: "inline-block h-2 w-2 rounded-sm",
1521
- style: { backgroundColor: e === Y ? "#94a3b8" : re(t) }
1522
- }), /* @__PURE__ */ m("span", { children: e === Y ? "other" : e })]
1523
- }, e))
1631
+ children: e.map((e, n) => {
1632
+ let r = e === Y ? "#94a3b8" : re(n), i = e === Y ? t("detectionHistory.other") : e;
1633
+ return /* @__PURE__ */ g("span", {
1634
+ className: "inline-flex items-center gap-1 text-[10px] text-foreground-subtle",
1635
+ children: [/* @__PURE__ */ h("span", {
1636
+ className: "inline-block h-2 w-2 rounded-sm",
1637
+ style: { backgroundColor: r }
1638
+ }), /* @__PURE__ */ h("span", { children: i })]
1639
+ }, e);
1640
+ })
1524
1641
  });
1525
1642
  }
1526
1643
  //#endregion
1527
1644
  //#region src/pipeline-analytics/widgets/OccupancyPanel.tsx
1528
- function Xe({ dev: e, deviceId: t, title: n = "Live Occupancy", variant: r = "full" }) {
1529
- let i = p(c().trpcClient, e === void 0 && t !== void 0 ? t : null), a = e ?? i, o = d(a?.state.zoneAnalytics);
1530
- return o ? /* @__PURE__ */ m(Ze, {
1531
- title: n,
1645
+ function Qe({ dev: e, deviceId: t, title: n, variant: r = "full" }) {
1646
+ let { t: i } = P(), a = n ?? i("occupancy.title"), o = m(l().trpcClient, e === void 0 && t !== void 0 ? t : null), s = e ?? o, c = f(s?.state.zoneAnalytics);
1647
+ return c ? /* @__PURE__ */ h($e, {
1648
+ title: a,
1532
1649
  variant: r,
1533
- ts: o.ts,
1534
- children: /* @__PURE__ */ h("div", {
1650
+ ts: c.ts,
1651
+ children: /* @__PURE__ */ g("div", {
1535
1652
  className: r === "compact" ? "space-y-2" : "grid grid-cols-1 2xl:grid-cols-3 gap-3",
1536
1653
  children: [
1537
- /* @__PURE__ */ m($e, { frame: o.frame }),
1538
- /* @__PURE__ */ m(tt, { snapshot: o }),
1539
- /* @__PURE__ */ m(et, { unzoned: o.unzoned })
1654
+ /* @__PURE__ */ h(tt, { frame: c.frame }),
1655
+ /* @__PURE__ */ h(rt, { snapshot: c }),
1656
+ /* @__PURE__ */ h(nt, { unzoned: c.unzoned })
1540
1657
  ]
1541
1658
  })
1542
- }) : /* @__PURE__ */ m(Ze, {
1543
- title: n,
1659
+ }) : /* @__PURE__ */ h($e, {
1660
+ title: a,
1544
1661
  variant: r,
1545
- children: /* @__PURE__ */ m(Qe, { message: a ? "No occupancy data yet — analytics pipeline must be active for this device." : "Resolving device…" })
1662
+ children: /* @__PURE__ */ h(et, { message: i(s ? "occupancy.noData" : "common.resolving") })
1546
1663
  });
1547
1664
  }
1548
- function Ze({ title: e, variant: t, ts: n, children: r }) {
1549
- let i = n ? Math.max(0, Math.floor((Date.now() - n) / 1e3)) : null;
1550
- return /* @__PURE__ */ h("div", {
1665
+ function $e({ title: e, variant: t, ts: n, children: r }) {
1666
+ let { t: i } = P(), a = n ? Math.max(0, Math.floor((Date.now() - n) / 1e3)) : null;
1667
+ return /* @__PURE__ */ g("div", {
1551
1668
  className: t === "compact" ? "rounded-md border border-border/60 bg-surface/60 p-3" : "rounded-lg border border-border bg-surface overflow-hidden",
1552
- children: [/* @__PURE__ */ h("div", {
1669
+ children: [/* @__PURE__ */ g("div", {
1553
1670
  className: t === "compact" ? "flex items-center justify-between mb-2" : "border-b border-border px-4 py-2 flex items-center justify-between",
1554
- children: [/* @__PURE__ */ m("h2", {
1671
+ children: [/* @__PURE__ */ h("h2", {
1555
1672
  className: "text-xs font-semibold text-foreground uppercase tracking-wider",
1556
1673
  children: e
1557
- }), i !== null && /* @__PURE__ */ m("span", {
1674
+ }), a !== null && /* @__PURE__ */ h("span", {
1558
1675
  className: "text-[10px] text-foreground-subtle",
1559
- children: i === 0 ? "just now" : `${i}s ago`
1676
+ children: a === 0 ? i("common.justNow") : i("common.secondsAgo", { seconds: a })
1560
1677
  })]
1561
- }), /* @__PURE__ */ m("div", {
1678
+ }), /* @__PURE__ */ h("div", {
1562
1679
  className: t === "compact" ? "" : "p-3",
1563
1680
  children: r
1564
1681
  })]
1565
1682
  });
1566
1683
  }
1567
- function Qe({ message: e }) {
1568
- return /* @__PURE__ */ h("div", {
1684
+ function et({ message: e }) {
1685
+ return /* @__PURE__ */ g("div", {
1569
1686
  className: "px-4 py-6 flex flex-col items-center text-center text-foreground-subtle",
1570
- children: [/* @__PURE__ */ m(k, { className: "h-5 w-5 mb-2 opacity-30" }), /* @__PURE__ */ m("p", {
1687
+ children: [/* @__PURE__ */ h(A, { className: "h-5 w-5 mb-2 opacity-30" }), /* @__PURE__ */ h("p", {
1571
1688
  className: "text-[11px]",
1572
1689
  children: e
1573
1690
  })]
1574
1691
  });
1575
1692
  }
1576
- function $e({ frame: e }) {
1577
- return /* @__PURE__ */ m(nt, {
1578
- icon: /* @__PURE__ */ m(D, { className: "h-3.5 w-3.5" }),
1579
- label: "Frame total",
1693
+ function tt({ frame: e }) {
1694
+ let { t } = P();
1695
+ return /* @__PURE__ */ h(it, {
1696
+ icon: /* @__PURE__ */ h(O, { className: "h-3.5 w-3.5" }),
1697
+ label: t("occupancy.frameTotal"),
1580
1698
  total: e.totalObjects,
1581
1699
  byClass: e.byClass,
1582
1700
  tone: "default"
1583
1701
  });
1584
1702
  }
1585
- function et({ unzoned: e }) {
1586
- return /* @__PURE__ */ m(nt, {
1587
- icon: /* @__PURE__ */ m(A, { className: "h-3.5 w-3.5" }),
1588
- label: "Outside any zone",
1703
+ function nt({ unzoned: e }) {
1704
+ let { t } = P();
1705
+ return /* @__PURE__ */ h(it, {
1706
+ icon: /* @__PURE__ */ h(j, { className: "h-3.5 w-3.5" }),
1707
+ label: t("occupancy.outsideZone"),
1589
1708
  total: e.totalObjects,
1590
1709
  byClass: e.byClass,
1591
1710
  tone: "muted"
1592
1711
  });
1593
1712
  }
1594
- function tt({ snapshot: e }) {
1595
- return e.zones.length === 0 ? /* @__PURE__ */ m(nt, {
1596
- icon: /* @__PURE__ */ m(k, { className: "h-3.5 w-3.5" }),
1597
- label: "Per-zone",
1713
+ function rt({ snapshot: e }) {
1714
+ let { t } = P();
1715
+ return e.zones.length === 0 ? /* @__PURE__ */ h(it, {
1716
+ icon: /* @__PURE__ */ h(A, { className: "h-3.5 w-3.5" }),
1717
+ label: t("occupancy.perZone"),
1598
1718
  total: 0,
1599
1719
  byClass: {},
1600
1720
  tone: "muted",
1601
- emptyMessage: "No zones defined for this camera."
1602
- }) : /* @__PURE__ */ h("div", {
1721
+ emptyMessage: t("occupancy.noZones")
1722
+ }) : /* @__PURE__ */ g("div", {
1603
1723
  className: "rounded-md border border-border/60 bg-background/40",
1604
- children: [/* @__PURE__ */ h("div", {
1724
+ children: [/* @__PURE__ */ g("div", {
1605
1725
  className: "px-3 py-1.5 border-b border-border/40 flex items-center gap-1.5 text-[11px] uppercase tracking-wider text-foreground-subtle",
1606
1726
  children: [
1607
- /* @__PURE__ */ m(k, { className: "h-3.5 w-3.5" }),
1608
- /* @__PURE__ */ m("span", { children: "Per-zone" }),
1609
- /* @__PURE__ */ m("span", {
1727
+ /* @__PURE__ */ h(A, { className: "h-3.5 w-3.5" }),
1728
+ /* @__PURE__ */ h("span", { children: t("occupancy.perZone") }),
1729
+ /* @__PURE__ */ h("span", {
1610
1730
  className: "ml-auto text-[10px] normal-case tracking-normal",
1611
1731
  children: e.zones.length
1612
1732
  })
1613
1733
  ]
1614
- }), /* @__PURE__ */ m("div", {
1734
+ }), /* @__PURE__ */ h("div", {
1615
1735
  className: "divide-y divide-border/30",
1616
- children: e.zones.map((e) => /* @__PURE__ */ h("div", {
1736
+ children: e.zones.map((e) => /* @__PURE__ */ g("div", {
1617
1737
  className: "px-3 py-2",
1618
- children: [/* @__PURE__ */ h("div", {
1738
+ children: [/* @__PURE__ */ g("div", {
1619
1739
  className: "flex items-center justify-between mb-1",
1620
- children: [/* @__PURE__ */ m("span", {
1740
+ children: [/* @__PURE__ */ h("span", {
1621
1741
  className: "text-xs font-medium text-foreground truncate",
1622
1742
  children: e.zoneName
1623
- }), /* @__PURE__ */ m("span", {
1743
+ }), /* @__PURE__ */ h("span", {
1624
1744
  className: "rounded-full px-2 py-0.5 text-[10px] font-medium bg-foreground-subtle/10 text-foreground-subtle border border-border",
1625
1745
  children: e.totalObjects
1626
1746
  })]
1627
- }), /* @__PURE__ */ m(rt, { byClass: e.byClass })]
1747
+ }), /* @__PURE__ */ h(at, { byClass: e.byClass })]
1628
1748
  }, e.zoneId))
1629
1749
  })]
1630
1750
  });
1631
1751
  }
1632
- function nt({ icon: e, label: t, total: n, byClass: r, tone: i, emptyMessage: a }) {
1633
- let o = Object.keys(r).length;
1634
- return /* @__PURE__ */ h("div", {
1752
+ function it({ icon: e, label: t, total: n, byClass: r, tone: i, emptyMessage: a }) {
1753
+ let { t: o } = P(), s = Object.keys(r).length;
1754
+ return /* @__PURE__ */ g("div", {
1635
1755
  className: i === "muted" ? "rounded-md border border-border/40 bg-background/20 px-3 py-2" : "rounded-md border border-border/60 bg-background/40 px-3 py-2",
1636
- children: [/* @__PURE__ */ h("div", {
1756
+ children: [/* @__PURE__ */ g("div", {
1637
1757
  className: "flex items-center gap-1.5 mb-1.5 text-[11px] uppercase tracking-wider text-foreground-subtle",
1638
1758
  children: [
1639
1759
  e,
1640
- /* @__PURE__ */ m("span", { children: t }),
1641
- /* @__PURE__ */ m("span", {
1760
+ /* @__PURE__ */ h("span", { children: t }),
1761
+ /* @__PURE__ */ h("span", {
1642
1762
  className: "ml-auto text-base font-semibold text-foreground tabular-nums normal-case tracking-normal",
1643
1763
  children: n
1644
1764
  })
1645
1765
  ]
1646
- }), o === 0 ? /* @__PURE__ */ m("span", {
1766
+ }), s === 0 ? /* @__PURE__ */ h("span", {
1647
1767
  className: "text-[10px] text-foreground-subtle italic",
1648
- children: a ?? "no objects"
1649
- }) : /* @__PURE__ */ m(rt, { byClass: r })]
1768
+ children: a ?? o("occupancy.noObjects")
1769
+ }) : /* @__PURE__ */ h(at, { byClass: r })]
1650
1770
  });
1651
1771
  }
1652
- function rt({ byClass: e }) {
1653
- let n = t(() => Object.entries(e).sort(([, e], [, t]) => t - e), [e]);
1654
- return n.length === 0 ? /* @__PURE__ */ m("span", {
1772
+ function at({ byClass: e }) {
1773
+ let { t: n } = P(), r = t(() => Object.entries(e).sort(([, e], [, t]) => t - e), [e]);
1774
+ return r.length === 0 ? /* @__PURE__ */ h("span", {
1655
1775
  className: "text-[10px] text-foreground-subtle italic",
1656
- children: "no objects"
1657
- }) : /* @__PURE__ */ m("div", {
1776
+ children: n("occupancy.noObjects")
1777
+ }) : /* @__PURE__ */ h("div", {
1658
1778
  className: "flex flex-wrap gap-1",
1659
- children: n.map(([e, t]) => /* @__PURE__ */ h("span", {
1779
+ children: r.map(([e, t]) => /* @__PURE__ */ g("span", {
1660
1780
  className: "inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium bg-primary/10 text-primary border border-primary/20",
1661
- children: [/* @__PURE__ */ m("span", { children: e }), /* @__PURE__ */ m("span", {
1781
+ children: [/* @__PURE__ */ h("span", { children: e }), /* @__PURE__ */ h("span", {
1662
1782
  className: "tabular-nums opacity-80",
1663
1783
  children: t
1664
1784
  })]
@@ -1667,39 +1787,39 @@ function rt({ byClass: e }) {
1667
1787
  }
1668
1788
  //#endregion
1669
1789
  //#region src/pipeline-analytics/widgets/LiveStatsTab.tsx
1670
- function it({ deviceId: e }) {
1671
- return /* @__PURE__ */ h("div", {
1672
- className: u,
1790
+ function ot({ deviceId: e }) {
1791
+ return /* @__PURE__ */ g("div", {
1792
+ className: d,
1673
1793
  children: [
1674
- /* @__PURE__ */ h("div", {
1794
+ /* @__PURE__ */ g("div", {
1675
1795
  className: `grid ${s}`,
1676
1796
  style: { gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 340px), 1fr))" },
1677
- children: [/* @__PURE__ */ m(f, {
1797
+ children: [/* @__PURE__ */ h(p, {
1678
1798
  widgetId: "pipeline-analytics/live-occupancy-panel",
1679
1799
  host: "device-tab",
1680
1800
  deviceId: e
1681
- }), /* @__PURE__ */ m(f, {
1801
+ }), /* @__PURE__ */ h(p, {
1682
1802
  widgetId: "pipeline-analytics/audio-metrics-panel",
1683
1803
  host: "device-tab",
1684
1804
  deviceId: e
1685
1805
  })]
1686
1806
  }),
1687
- /* @__PURE__ */ m(f, {
1807
+ /* @__PURE__ */ h(p, {
1688
1808
  widgetId: "pipeline-analytics/audio-history-chart",
1689
1809
  host: "device-tab",
1690
1810
  deviceId: e
1691
1811
  }),
1692
- /* @__PURE__ */ m(f, {
1812
+ /* @__PURE__ */ h(p, {
1693
1813
  widgetId: "pipeline-analytics/occupancy-history-chart",
1694
1814
  host: "device-tab",
1695
1815
  deviceId: e
1696
1816
  }),
1697
- /* @__PURE__ */ m(f, {
1817
+ /* @__PURE__ */ h(p, {
1698
1818
  widgetId: "pipeline-analytics/motion-history-chart",
1699
1819
  host: "device-tab",
1700
1820
  deviceId: e
1701
1821
  }),
1702
- /* @__PURE__ */ m(f, {
1822
+ /* @__PURE__ */ h(p, {
1703
1823
  widgetId: "pipeline-analytics/detection-history-chart",
1704
1824
  host: "device-tab",
1705
1825
  deviceId: e
@@ -1710,40 +1830,41 @@ function it({ deviceId: e }) {
1710
1830
  //#endregion
1711
1831
  //#region src/pipeline-analytics/widgets/index.tsx
1712
1832
  function $({ name: e }) {
1833
+ let { t } = P();
1713
1834
  return /* @__PURE__ */ h("div", {
1714
1835
  className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning",
1715
- children: [e, " requires a deviceId"]
1836
+ children: t("missingDevice", { name: e })
1716
1837
  });
1717
1838
  }
1718
- function at(e) {
1719
- return e.deviceId === void 0 ? /* @__PURE__ */ m($, { name: "AudioHistoryChart" }) : /* @__PURE__ */ m(ce, { deviceId: e.deviceId });
1720
- }
1721
- function ot(e) {
1722
- return e.deviceId === void 0 ? /* @__PURE__ */ m($, { name: "AudioMetricsPanel" }) : /* @__PURE__ */ m(ve, { deviceId: e.deviceId });
1723
- }
1724
1839
  function st(e) {
1725
- return e.deviceId === void 0 ? /* @__PURE__ */ m($, { name: "OccupancyHistoryChart" }) : /* @__PURE__ */ m(Ee, { deviceId: e.deviceId });
1840
+ return e.deviceId === void 0 ? /* @__PURE__ */ h($, { name: "AudioHistoryChart" }) : /* @__PURE__ */ h(ce, { deviceId: e.deviceId });
1726
1841
  }
1727
1842
  function ct(e) {
1728
- return e.deviceId === void 0 ? /* @__PURE__ */ m($, { name: "MotionHistoryChart" }) : /* @__PURE__ */ m(Ne, { deviceId: e.deviceId });
1843
+ return e.deviceId === void 0 ? /* @__PURE__ */ h($, { name: "AudioMetricsPanel" }) : /* @__PURE__ */ h(ve, { deviceId: e.deviceId });
1729
1844
  }
1730
1845
  function lt(e) {
1731
- return e.deviceId === void 0 ? /* @__PURE__ */ m($, { name: "DetectionHistoryChart" }) : /* @__PURE__ */ m(He, { deviceId: e.deviceId });
1846
+ return e.deviceId === void 0 ? /* @__PURE__ */ h($, { name: "OccupancyHistoryChart" }) : /* @__PURE__ */ h(Ee, { deviceId: e.deviceId });
1732
1847
  }
1733
1848
  function ut(e) {
1734
- return e.deviceId === void 0 ? /* @__PURE__ */ m($, { name: "LiveOccupancyPanel" }) : /* @__PURE__ */ m(Xe, { deviceId: e.deviceId });
1849
+ return e.deviceId === void 0 ? /* @__PURE__ */ h($, { name: "MotionHistoryChart" }) : /* @__PURE__ */ h(Pe, { deviceId: e.deviceId });
1735
1850
  }
1736
1851
  function dt(e) {
1737
- return e.deviceId === void 0 ? /* @__PURE__ */ m($, { name: "LiveStats" }) : /* @__PURE__ */ m(it, { deviceId: e.deviceId });
1852
+ return e.deviceId === void 0 ? /* @__PURE__ */ h($, { name: "DetectionHistoryChart" }) : /* @__PURE__ */ h(We, { deviceId: e.deviceId });
1853
+ }
1854
+ function ft(e) {
1855
+ return e.deviceId === void 0 ? /* @__PURE__ */ h($, { name: "LiveOccupancyPanel" }) : /* @__PURE__ */ h(Qe, { deviceId: e.deviceId });
1856
+ }
1857
+ function pt(e) {
1858
+ return e.deviceId === void 0 ? /* @__PURE__ */ h($, { name: "LiveStats" }) : /* @__PURE__ */ h(ot, { deviceId: e.deviceId });
1738
1859
  }
1739
- var ft = {
1740
- "audio-history-chart": at,
1741
- "audio-metrics-panel": ot,
1742
- "occupancy-history-chart": st,
1743
- "motion-history-chart": ct,
1744
- "detection-history-chart": lt,
1745
- "live-occupancy-panel": ut,
1746
- "live-stats": dt
1860
+ var mt = {
1861
+ "audio-history-chart": st,
1862
+ "audio-metrics-panel": ct,
1863
+ "occupancy-history-chart": lt,
1864
+ "motion-history-chart": ut,
1865
+ "detection-history-chart": dt,
1866
+ "live-occupancy-panel": ft,
1867
+ "live-stats": pt
1747
1868
  };
1748
1869
  //#endregion
1749
- export { ft as default };
1870
+ export { mt as default };