@camstack/addon-benchmark 1.2.236 → 1.2.237

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 (25) hide show
  1. package/dist/{MaskShapeCanvas-7LKD4bOR.mjs → MaskShapeCanvas-rvnAWD46.mjs} +2330 -2329
  2. package/dist/MotionZonesSettings-CLUkWpK0.mjs +309 -0
  3. package/dist/PrivacyMaskSettings-CO253ssl.mjs +368 -0
  4. package/dist/SceneMonitorEditor-CokHHuc7.mjs +846 -0
  5. package/dist/_stub.js +7108 -6531
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_benchmark_page-ChxR9kPt.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_benchmark_page-nmDNRQ49.mjs} +4 -4
  7. package/dist/_virtual_mf___mfe_internal__addon_benchmark_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BMVDowC4.mjs +26 -0
  8. package/dist/{_virtual_mf___mfe_internal__addon_benchmark_page__loadShare__react__loadShare__.js-BLRSn-wJ.mjs → _virtual_mf___mfe_internal__addon_benchmark_page__loadShare__react__loadShare__.js-BSWOsmOl.mjs} +1 -1
  9. package/dist/addon-benchmark.css +1 -1
  10. package/dist/{hostInit-CEx6N0CU.mjs → hostInit-CIr6lznC.mjs} +3 -3
  11. package/dist/player-overlays-CSPcduAF.mjs +44 -0
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-BEYSc24p.mjs → responsive-D-VpyylT.mjs} +35 -35
  14. package/dist/scene-monitor-copy-BJy41PVw.mjs +227 -0
  15. package/dist/{square-DEGbSYoK.mjs → square-ZwSCZFNX.mjs} +1 -1
  16. package/dist/{trash-2-CCLSWdWD.mjs → trash-2-BJm2vmez.mjs} +1 -1
  17. package/dist/ui-text-D2tfpVFx.mjs +34 -0
  18. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_benchmark_page__remoteEntry_js-Dm8qg1pv.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_benchmark_page__remoteEntry_js-DWgrEAbS.mjs} +1 -1
  19. package/package.json +1 -1
  20. package/dist/MotionZonesSettings-WETj-Fnx.mjs +0 -310
  21. package/dist/PrivacyMaskSettings-CuZnKVIY.mjs +0 -377
  22. package/dist/SceneMonitorEditor-zpag-Gn2.mjs +0 -831
  23. package/dist/_virtual_mf___mfe_internal__addon_benchmark_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-bKs8C0v5.mjs +0 -26
  24. package/dist/player-overlays-D5Bao9IZ.mjs +0 -44
  25. package/dist/scene-monitor-copy-9bafcJ0k.mjs +0 -187
@@ -0,0 +1,309 @@
1
+ import { S as e, _ as t, d as n, g as r, l as i, v as a } from "./_virtual_mf___mfe_internal__addon_benchmark_page__loadShare__react__loadShare__.js-BSWOsmOl.mjs";
2
+ import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_benchmark_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-Dh0XkFx5.mjs";
3
+ import { r as l, t as ee } from "./ui-text-D2tfpVFx.mjs";
4
+ import { f as u, l as d, m as f, s as p, u as te } from "./responsive-D-VpyylT.mjs";
5
+ import { n as ne, t as m } from "./player-overlays-CSPcduAF.mjs";
6
+ import { MaskShapeCanvas as h } from "./MaskShapeCanvas-rvnAWD46.mjs";
7
+ var g = f("grid-2x2", [
8
+ ["path", {
9
+ d: "M12 3v18",
10
+ key: "108xh3"
11
+ }],
12
+ ["path", {
13
+ d: "M3 12h18",
14
+ key: "1i2n21"
15
+ }],
16
+ ["rect", {
17
+ x: "3",
18
+ y: "3",
19
+ width: "18",
20
+ height: "18",
21
+ rx: "2",
22
+ key: "h1oib"
23
+ }]
24
+ ]);
25
+ //#endregion
26
+ //#region ../ui-library/src/composites/cap-settings/MotionZonesSettings.tsx
27
+ e();
28
+ var _ = 110, v = "motion-zones", y = 0, re = [
29
+ 1,
30
+ 2,
31
+ 3
32
+ ], b = 1, x = "rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors", S = "rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors";
33
+ function C(e, t, n) {
34
+ let r = t * n, i = Array.from({ length: r });
35
+ for (let t = 0; t < r; t += 1) i[t] = e[t] === !0;
36
+ return i;
37
+ }
38
+ function w(e, t) {
39
+ if (e.length !== t.length) return !1;
40
+ for (let n = 0; n < e.length; n += 1) if (e[n] !== t[n]) return !1;
41
+ return !0;
42
+ }
43
+ function T(e, t) {
44
+ return Math.ceil(e / t);
45
+ }
46
+ function E(e, t, n) {
47
+ return Math.min(n - 1, Math.floor((e + .5) / t * n));
48
+ }
49
+ function D(e, t, n, r) {
50
+ let i = T(t, r), a = T(n, r), o = Array.from({ length: i * a }, () => !1);
51
+ for (let r = 0; r < n; r += 1) {
52
+ let s = E(r, n, a);
53
+ for (let n = 0; n < t; n += 1) e[r * t + n] === !0 && (o[s * i + E(n, t, i)] = !0);
54
+ }
55
+ return o;
56
+ }
57
+ function O(e, t, n, r) {
58
+ let i = T(t, r), a = T(n, r), o = Array.from({ length: t * n }, () => !1);
59
+ for (let r = 0; r < n; r += 1) {
60
+ let s = E(r, n, a);
61
+ for (let n = 0; n < t; n += 1) o[r * t + n] = e[s * i + E(n, t, i)] === !0;
62
+ }
63
+ return o;
64
+ }
65
+ function k({ deviceId: e }) {
66
+ let f = l(), E = te(u().trpcClient, e), [k, A] = a(null), [j, M] = a(!1), [N, P] = a(null), [F, I] = a(null), [L, R] = a(b), [z, B] = a(!1), [V, H] = a(!1), U = t(!1);
67
+ n(() => {
68
+ if (!E) return;
69
+ let e = !1;
70
+ return U.current = !1, A(null), M(!1), P(null), I(null), R(b), H(!1), (async () => {
71
+ try {
72
+ let t = await E.motionZones?.getOptions({});
73
+ if (e) return;
74
+ if (!t) throw Error("device proxy not ready");
75
+ if (A(t), U.current) return;
76
+ let n = await E.motionZones?.getStatus({});
77
+ if (e) return;
78
+ if (!n) throw Error("device proxy not ready");
79
+ U.current = !0;
80
+ let r = n.regions.find((e) => e.shape.kind === "grid"), i = C(r ? r.shape.cells : [], t.grid.width, t.grid.height);
81
+ I(i), P(D(i, t.grid.width, t.grid.height, b));
82
+ } catch (t) {
83
+ if (e) return;
84
+ d(t) ? M(!0) : console.error("Motion Zones load failed", t);
85
+ }
86
+ })(), () => {
87
+ e = !0;
88
+ };
89
+ }, [E]);
90
+ let W = k ? k.grid.width : 0, G = k ? k.grid.height : 0, K = T(W, L), q = T(G, L), J = r(() => N && k ? O(N, W, G, L) : null, [
91
+ N,
92
+ k,
93
+ W,
94
+ G,
95
+ L
96
+ ]), Y = r(() => J !== null && F !== null && !w(J, F), [J, F]), ie = r(() => J ? J.reduce((e, t) => t ? e + 1 : e, 0) : 0, [J]), ae = W * G, X = K * q, Z = i((e) => {
97
+ X > 0 && P(Array.from({ length: X }, () => e));
98
+ }, [X]), oe = i(() => {
99
+ P((e) => e && e.map((e) => !e));
100
+ }, []), se = i(() => {
101
+ F && k && P(D(F, W, G, L));
102
+ }, [
103
+ F,
104
+ k,
105
+ W,
106
+ G,
107
+ L
108
+ ]), ce = i((e) => {
109
+ e === L || !k || P((t) => {
110
+ if (!t) return R(e), t;
111
+ let n = D(O(t, W, G, L), W, G, e);
112
+ return R(e), n;
113
+ });
114
+ }, [
115
+ L,
116
+ k,
117
+ W,
118
+ G
119
+ ]), Q = r(() => k && N ? [{
120
+ id: y,
121
+ shape: {
122
+ kind: "grid",
123
+ gridWidth: K,
124
+ gridHeight: q,
125
+ cells: [...N]
126
+ }
127
+ }] : [], [
128
+ k,
129
+ N,
130
+ K,
131
+ q
132
+ ]), $ = i((e, t) => {
133
+ t.kind === "grid" && P(t.cells);
134
+ }, []), le = i(async () => {
135
+ if (!(!E || !N || !k)) {
136
+ B(!0);
137
+ try {
138
+ let e = O(N, k.grid.width, k.grid.height, L), t = {
139
+ kind: "grid",
140
+ gridWidth: k.grid.width,
141
+ gridHeight: k.grid.height,
142
+ cells: e
143
+ };
144
+ await E.motionZones?.setZone({ patch: { regions: [{
145
+ id: y,
146
+ enabled: !0,
147
+ shape: t
148
+ }] } });
149
+ let n = await E.motionZones?.getStatus({});
150
+ if (n) {
151
+ let e = n.regions.find((e) => e.shape.kind === "grid"), t = C(e ? e.shape.cells : [], k.grid.width, k.grid.height);
152
+ I(t), P(D(t, k.grid.width, k.grid.height, L));
153
+ }
154
+ } catch (e) {
155
+ console.error("Motion Zones save failed", e);
156
+ } finally {
157
+ B(!1);
158
+ }
159
+ }
160
+ }, [
161
+ E,
162
+ N,
163
+ k,
164
+ L
165
+ ]);
166
+ m(r(() => V && !j && k && N ? {
167
+ id: v,
168
+ order: _,
169
+ node: /* @__PURE__ */ o(h, {
170
+ transparent: !0,
171
+ items: Q,
172
+ supportedShapes: ["grid"],
173
+ grid: {
174
+ width: K,
175
+ height: q
176
+ },
177
+ selectedId: y,
178
+ onSelect: () => {},
179
+ onShapeChange: $,
180
+ onDrawComplete: () => {},
181
+ drawingKind: null
182
+ })
183
+ } : null, [
184
+ V,
185
+ j,
186
+ k,
187
+ N,
188
+ Q,
189
+ $,
190
+ K,
191
+ q
192
+ ]));
193
+ let ue = !j && k !== null && N !== null;
194
+ return E ? /* @__PURE__ */ o(ne, {
195
+ title: f("uiLibrary.motionZones.title", "Motion Zones"),
196
+ icon: /* @__PURE__ */ o(g, { className: "h-3.5 w-3.5 text-foreground-subtle" }),
197
+ children: /* @__PURE__ */ o("div", {
198
+ className: "flex flex-col gap-3",
199
+ children: j ? /* @__PURE__ */ o("p", {
200
+ className: `${p} leading-relaxed`,
201
+ children: f("uiLibrary.motionZones.unsupported", "This camera doesn't expose an on-board motion zones grid.")
202
+ }) : ue ? /* @__PURE__ */ s(c, { children: [/* @__PURE__ */ o("p", {
203
+ className: `${p} leading-relaxed`,
204
+ children: /* @__PURE__ */ o(ee, {
205
+ uiKey: "uiLibrary.motionZones.intro",
206
+ fallback: "Toggle <0>Edit grid</0> to paint the region directly on the live frame, then <1>Save</1> to push the mask to the camera. Pick a bigger <2>Cell size</2> for quicker, broad-stroke painting — it's resampled to the camera's native {{width}}×{{height}} grid on save (×1 is the finest).",
207
+ components: [
208
+ /* @__PURE__ */ o("strong", { className: "text-foreground" }, "e"),
209
+ /* @__PURE__ */ o("strong", { className: "text-foreground" }, "s"),
210
+ /* @__PURE__ */ o("strong", { className: "text-foreground" }, "c")
211
+ ],
212
+ values: {
213
+ width: k.grid.width,
214
+ height: k.grid.height
215
+ }
216
+ })
217
+ }), /* @__PURE__ */ s("div", {
218
+ className: "flex items-center gap-2 flex-wrap",
219
+ children: [
220
+ /* @__PURE__ */ o("button", {
221
+ type: "button",
222
+ onClick: () => H((e) => !e),
223
+ disabled: z,
224
+ "aria-pressed": V,
225
+ className: V ? S : x,
226
+ children: V ? f("uiLibrary.motionZones.doneEditing", "Done editing") : f("uiLibrary.motionZones.editGrid", "Edit grid")
227
+ }),
228
+ /* @__PURE__ */ o("button", {
229
+ type: "button",
230
+ onClick: () => Z(!0),
231
+ disabled: z,
232
+ className: x,
233
+ children: f("uiLibrary.motionZones.allOn", "All on")
234
+ }),
235
+ /* @__PURE__ */ o("button", {
236
+ type: "button",
237
+ onClick: () => Z(!1),
238
+ disabled: z,
239
+ className: x,
240
+ children: f("uiLibrary.motionZones.allOff", "All off")
241
+ }),
242
+ /* @__PURE__ */ o("button", {
243
+ type: "button",
244
+ onClick: oe,
245
+ disabled: z,
246
+ className: x,
247
+ children: f("uiLibrary.motionZones.invert", "Invert")
248
+ }),
249
+ /* @__PURE__ */ s("div", {
250
+ className: "flex items-center gap-1 ml-1",
251
+ role: "group",
252
+ "aria-label": f("uiLibrary.motionZones.cellSize", "Cell size"),
253
+ children: [/* @__PURE__ */ o("span", {
254
+ className: `${p} mr-0.5`,
255
+ children: f("uiLibrary.motionZones.cellSize", "Cell size")
256
+ }), re.map((e) => /* @__PURE__ */ s("button", {
257
+ type: "button",
258
+ onClick: () => ce(e),
259
+ disabled: z,
260
+ "aria-pressed": L === e,
261
+ title: e === 1 ? f("uiLibrary.motionZones.cameraGrid", "Camera grid {{width}}×{{height}} (finest)", {
262
+ width: W,
263
+ height: G
264
+ }) : f("uiLibrary.motionZones.paintingGrid", "{{width}}×{{height}} painting grid · cells ×{{factor}} bigger", {
265
+ width: T(W, e),
266
+ height: T(G, e),
267
+ factor: e
268
+ }),
269
+ className: L === e ? S : x,
270
+ children: ["×", e]
271
+ }, e))]
272
+ }),
273
+ /* @__PURE__ */ s("span", {
274
+ className: `${p} ml-1 tabular-nums`,
275
+ children: [f("uiLibrary.motionZones.cells", "{{active}} / {{total}} cells · {{width}}×{{height}}", {
276
+ active: ie,
277
+ total: ae,
278
+ width: k.grid.width,
279
+ height: k.grid.height
280
+ }), L === 1 ? "" : f("uiLibrary.motionZones.paintSuffix", " · paint {{width}}×{{height}}", {
281
+ width: K,
282
+ height: q
283
+ })]
284
+ }),
285
+ /* @__PURE__ */ o("span", { className: "flex-1" }),
286
+ /* @__PURE__ */ o("button", {
287
+ type: "button",
288
+ onClick: se,
289
+ disabled: z || !Y,
290
+ className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
291
+ children: f("uiLibrary.motionZones.revert", "Revert")
292
+ }),
293
+ /* @__PURE__ */ o("button", {
294
+ type: "button",
295
+ onClick: () => void le(),
296
+ disabled: z || !Y,
297
+ className: S,
298
+ children: z ? f("uiLibrary.motionZones.saving", "Saving…") : f("uiLibrary.motionZones.save", "Save")
299
+ })
300
+ ]
301
+ })] }) : /* @__PURE__ */ o("p", {
302
+ className: `${p} leading-relaxed`,
303
+ children: f("uiLibrary.motionZones.loading", "Loading the camera's grid…")
304
+ })
305
+ })
306
+ }) : null;
307
+ }
308
+ //#endregion
309
+ export { k as MotionZonesSettings };
@@ -0,0 +1,368 @@
1
+ import { S as e, _ as t, d as n, g as r, l as i, v as a } from "./_virtual_mf___mfe_internal__addon_benchmark_page__loadShare__react__loadShare__.js-BSWOsmOl.mjs";
2
+ import { n as o, r as s, t as ee } from "./_virtual_mf___mfe_internal__addon_benchmark_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-Dh0XkFx5.mjs";
3
+ import { r as te, t as ne } from "./ui-text-D2tfpVFx.mjs";
4
+ import { f as re, l as ie, m as c, s as l, u as ae } from "./responsive-D-VpyylT.mjs";
5
+ import { n as oe, t as se } from "./player-overlays-CSPcduAF.mjs";
6
+ import { n as ce, r as le, t as ue } from "./square-ZwSCZFNX.mjs";
7
+ import { t as de } from "./trash-2-BJm2vmez.mjs";
8
+ import { MaskShapeCanvas as fe } from "./MaskShapeCanvas-rvnAWD46.mjs";
9
+ var pe = c("hexagon", [["path", {
10
+ d: "M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z",
11
+ key: "yt0hxn"
12
+ }]]), me = c("mic-off", [
13
+ ["path", {
14
+ d: "M12 19v3",
15
+ key: "npa21l"
16
+ }],
17
+ ["path", {
18
+ d: "M15 9.34V5a3 3 0 0 0-5.68-1.33",
19
+ key: "1gzdoj"
20
+ }],
21
+ ["path", {
22
+ d: "M16.95 16.95A7 7 0 0 1 5 12v-2",
23
+ key: "cqa7eg"
24
+ }],
25
+ ["path", {
26
+ d: "M18.89 13.23A7 7 0 0 0 19 12v-2",
27
+ key: "16hl24"
28
+ }],
29
+ ["path", {
30
+ d: "m2 2 20 20",
31
+ key: "1ooewy"
32
+ }],
33
+ ["path", {
34
+ d: "M9 9v3a3 3 0 0 0 5.12 2.12",
35
+ key: "r2i35w"
36
+ }]
37
+ ]);
38
+ //#endregion
39
+ //#region ../ui-library/src/composites/cap-settings/privacy-mask-audio.ts
40
+ e();
41
+ var u = "Microphone", d = "The camera encodes no audio at all — live view, recordings, exports and the audio analyzer are all silent.";
42
+ function he(e) {
43
+ let t = e.supportsAudioMute === !0, n = t ? e.audioEnabled : null, r = e.pendingOn ?? null;
44
+ return {
45
+ label: u,
46
+ supported: t,
47
+ on: n === null ? null : r ?? n,
48
+ available: t && n !== null,
49
+ costWhenOff: d
50
+ };
51
+ }
52
+ function ge(e) {
53
+ return !e.available || e.on === null ? null : { enabled: !e.on };
54
+ }
55
+ //#endregion
56
+ //#region ../ui-library/src/composites/cap-settings/PrivacyMaskSettings.tsx
57
+ var f = 120, p = "privacy-mask", m = "rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors", h = "rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors";
58
+ function g(e) {
59
+ return e.kind === "rect" || e.kind === "polygon" ? e : null;
60
+ }
61
+ function _e(e) {
62
+ let t = new Set(e.map((e) => e.id)), n = 0;
63
+ for (; t.has(n);) n += 1;
64
+ return n;
65
+ }
66
+ function ve(e, t) {
67
+ if (e.length !== t.length) return !1;
68
+ for (let n = 0; n < e.length; n += 1) if (JSON.stringify(e[n]) !== JSON.stringify(t[n])) return !1;
69
+ return !0;
70
+ }
71
+ function _({ deviceId: e }) {
72
+ let c = te(), u = ae(re().trpcClient, e), [d, _] = a(null), [v, y] = a(!1), [b, x] = a(!1), [S, C] = a(null), [w, T] = a(null), [E, D] = a(!1), [O, k] = a(!1), [A, j] = a(null), [M, N] = a(null), [P, F] = a(null), [I, L] = a(null), [R, z] = a(null), B = t(!1);
73
+ n(() => {
74
+ if (!u) return;
75
+ let e = !1;
76
+ return B.current = !1, _(null), y(!1), x(!1), C(null), T(null), k(!1), j(null), N(null), F(null), L(null), z(null), (async () => {
77
+ try {
78
+ let t = await u.privacyMask?.getOptions({});
79
+ if (e) return;
80
+ if (!t) throw Error("device proxy not ready");
81
+ if (_(t), B.current) return;
82
+ let n = await u.privacyMask?.getStatus({});
83
+ if (e) return;
84
+ if (!n) throw Error("device proxy not ready");
85
+ if (n.regions === null) {
86
+ x(!0), F(n.audioEnabled);
87
+ return;
88
+ }
89
+ B.current = !0;
90
+ let r = {
91
+ enabled: n.enabled,
92
+ regions: n.regions
93
+ };
94
+ T(r), C(r), F(n.audioEnabled);
95
+ } catch (t) {
96
+ if (e) return;
97
+ ie(t) ? y(!0) : console.error("Privacy Mask load failed", t);
98
+ }
99
+ })(), () => {
100
+ e = !0;
101
+ };
102
+ }, [u]);
103
+ let V = r(() => S !== null && w !== null && (S.enabled !== w.enabled || !ve(S.regions, w.regions)), [S, w]), H = S ? S.regions.length : 0, U = d ? d.maxRegions : 0, W = t(0);
104
+ n(() => {
105
+ W.current = U;
106
+ }, [U]);
107
+ let G = U > 0 && H >= U, ye = i(() => {
108
+ C((e) => e && {
109
+ ...e,
110
+ enabled: !e.enabled
111
+ });
112
+ }, []), K = i((e) => {
113
+ j(typeof e == "number" ? e : null);
114
+ }, []), q = r(() => S ? S.regions.map((e) => ({
115
+ id: e.id,
116
+ shape: e.shape,
117
+ enabled: e.enabled,
118
+ label: c("uiLibrary.privacyMaskSettings.zoneN", "Zone {{id}}", { id: e.id })
119
+ })) : [], [S, c]), J = i((e, t) => {
120
+ let n = g(t);
121
+ n && C((t) => t && {
122
+ ...t,
123
+ regions: t.regions.map((t) => t.id === e ? {
124
+ ...t,
125
+ shape: n
126
+ } : t)
127
+ });
128
+ }, []), Y = i((e) => {
129
+ let t = g(e);
130
+ t && (N(null), C((e) => {
131
+ if (!e) return e;
132
+ let n = W.current;
133
+ if (n > 0 && e.regions.length >= n) return e;
134
+ let r = _e(e.regions), i = {
135
+ id: r,
136
+ enabled: !0,
137
+ shape: t
138
+ };
139
+ return j(r), {
140
+ ...e,
141
+ regions: [...e.regions, i]
142
+ };
143
+ }));
144
+ }, []), X = i((e) => {
145
+ k(!0), j(null), N(e);
146
+ }, []), be = i((e) => {
147
+ k(!0), N(null), j(e);
148
+ }, []), xe = i((e) => {
149
+ j((t) => t === e ? null : t), C((t) => t && {
150
+ ...t,
151
+ regions: t.regions.filter((t) => t.id !== e)
152
+ });
153
+ }, []), Se = i(() => {
154
+ N(null), j(null), w && C({
155
+ enabled: w.enabled,
156
+ regions: w.regions
157
+ });
158
+ }, [w]), Ce = i(async () => {
159
+ if (!(!u || !S)) {
160
+ D(!0);
161
+ try {
162
+ await u.privacyMask?.setMask({ patch: {
163
+ enabled: S.enabled,
164
+ regions: [...S.regions]
165
+ } });
166
+ let e = await u.privacyMask?.getStatus({});
167
+ if (e && e.regions !== null) {
168
+ let t = {
169
+ enabled: e.enabled,
170
+ regions: e.regions
171
+ };
172
+ T(t), C(t);
173
+ }
174
+ } catch (e) {
175
+ console.error("Privacy Mask save failed", e);
176
+ } finally {
177
+ D(!1);
178
+ }
179
+ }
180
+ }, [u, S]), Z = he({
181
+ supportsAudioMute: d === null ? null : d.supportsAudioMute,
182
+ audioEnabled: P,
183
+ pendingOn: I
184
+ }), we = i(async () => {
185
+ let e = ge(Z);
186
+ if (!(!u || e === null)) {
187
+ L(e.enabled), z(null);
188
+ try {
189
+ await u.privacyMask?.setAudioEnabled(e);
190
+ let t = await u.privacyMask?.getStatus({});
191
+ t && F(t.audioEnabled);
192
+ } catch (e) {
193
+ console.error("Privacy microphone write failed — reverting", e), z(e instanceof Error ? e.message : String(e));
194
+ } finally {
195
+ L(null);
196
+ }
197
+ }
198
+ }, [u, Z]), Te = i(() => {
199
+ k((e) => (e && (N(null), j(null)), !e));
200
+ }, []), Q = d?.supportedShapes ?? [];
201
+ se(r(() => O && !v && d && S ? {
202
+ id: p,
203
+ order: f,
204
+ node: /* @__PURE__ */ o(fe, {
205
+ transparent: !0,
206
+ items: q,
207
+ supportedShapes: Q,
208
+ polygonVertices: d.polygonVertices,
209
+ selectedId: A,
210
+ onSelect: K,
211
+ onShapeChange: J,
212
+ onDrawComplete: Y,
213
+ drawingKind: M
214
+ })
215
+ } : null, [
216
+ O,
217
+ v,
218
+ d,
219
+ S,
220
+ q,
221
+ Q,
222
+ A,
223
+ K,
224
+ J,
225
+ Y,
226
+ M
227
+ ]));
228
+ let Ee = d?.supportedShapes.includes("rect") ?? !1, De = d?.supportedShapes.includes("polygon") ?? !1, $ = d !== null && (d.maxRegions <= 0 || d.supportedShapes.length === 0), Oe = !v && !$ && !b && d !== null && S !== null;
229
+ return u ? /* @__PURE__ */ o(oe, {
230
+ title: c("uiLibrary.privacyMaskSettings.title", "Privacy Mask"),
231
+ icon: /* @__PURE__ */ o(le, { className: "h-3.5 w-3.5 text-foreground-subtle" }),
232
+ children: /* @__PURE__ */ s("div", {
233
+ className: "flex flex-col gap-3",
234
+ children: [v || $ ? /* @__PURE__ */ o("p", {
235
+ className: `${l} leading-relaxed`,
236
+ children: c("uiLibrary.privacyMaskSettings.unsupported", "This camera doesn't support an on-board privacy mask.")
237
+ }) : b ? /* @__PURE__ */ o("p", {
238
+ className: `${l} leading-relaxed`,
239
+ children: c("uiLibrary.privacyMaskSettings.unreadable", "This camera hasn't answered, so what it currently masks is unknown — the editor stays closed rather than showing an empty frame you could save over. A battery camera answers once it wakes; otherwise check that it is reachable.")
240
+ }) : Oe ? /* @__PURE__ */ s(ee, { children: [
241
+ /* @__PURE__ */ o("p", {
242
+ className: `${l} leading-relaxed`,
243
+ children: /* @__PURE__ */ o(ne, {
244
+ uiKey: "uiLibrary.privacyMaskSettings.help",
245
+ fallback: "Toggle <0>Edit mask</0> to draw blanked-out zones on the live frame, then <1>Save</1> to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.",
246
+ components: [/* @__PURE__ */ o("strong", { className: "text-foreground" }, "edit"), /* @__PURE__ */ o("strong", { className: "text-foreground" }, "save")]
247
+ })
248
+ }),
249
+ /* @__PURE__ */ s("div", {
250
+ className: "flex items-center gap-2 flex-wrap",
251
+ children: [
252
+ /* @__PURE__ */ o("button", {
253
+ type: "button",
254
+ onClick: Te,
255
+ disabled: E,
256
+ "aria-pressed": O,
257
+ className: O ? h : m,
258
+ children: O ? c("uiLibrary.privacyMaskSettings.doneEditing", "Done editing") : c("uiLibrary.privacyMaskSettings.editMask", "Edit mask")
259
+ }),
260
+ /* @__PURE__ */ o("button", {
261
+ type: "button",
262
+ onClick: ye,
263
+ disabled: E,
264
+ "aria-pressed": S.enabled,
265
+ className: S.enabled ? h : m,
266
+ children: S.enabled ? c("uiLibrary.privacyMaskSettings.maskOn", "Mask on") : c("uiLibrary.privacyMaskSettings.maskOff", "Mask off")
267
+ }),
268
+ Ee && /* @__PURE__ */ o("button", {
269
+ type: "button",
270
+ onClick: () => X("rect"),
271
+ disabled: E || G,
272
+ "aria-pressed": M === "rect",
273
+ className: M === "rect" ? h : m,
274
+ title: G ? c("uiLibrary.privacyMaskSettings.maxZones", "Maximum zones reached") : c("uiLibrary.privacyMaskSettings.addRect", "Add a rectangle zone"),
275
+ children: c("uiLibrary.privacyMaskSettings.rectButton", "+ Rect")
276
+ }),
277
+ De && /* @__PURE__ */ o("button", {
278
+ type: "button",
279
+ onClick: () => X("polygon"),
280
+ disabled: E || G,
281
+ "aria-pressed": M === "polygon",
282
+ className: M === "polygon" ? h : m,
283
+ title: G ? c("uiLibrary.privacyMaskSettings.maxZones", "Maximum zones reached") : c("uiLibrary.privacyMaskSettings.addPolygon", "Add a polygon zone"),
284
+ children: c("uiLibrary.privacyMaskSettings.polygonButton", "+ Polygon")
285
+ }),
286
+ /* @__PURE__ */ o("span", {
287
+ className: `${l} ml-1 tabular-nums`,
288
+ children: c("uiLibrary.privacyMaskSettings.zoneCount", "{{active}} / {{max}} zones", {
289
+ active: H,
290
+ max: U
291
+ })
292
+ }),
293
+ /* @__PURE__ */ o("span", { className: "flex-1" }),
294
+ /* @__PURE__ */ o("button", {
295
+ type: "button",
296
+ onClick: Se,
297
+ disabled: E || !V,
298
+ className: "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors",
299
+ children: c("uiLibrary.privacyMaskSettings.revert", "Revert")
300
+ }),
301
+ /* @__PURE__ */ o("button", {
302
+ type: "button",
303
+ onClick: () => void Ce(),
304
+ disabled: E || !V,
305
+ className: h,
306
+ children: E ? c("uiLibrary.privacyMaskSettings.saving", "Saving…") : c("uiLibrary.privacyMaskSettings.save", "Save")
307
+ })
308
+ ]
309
+ }),
310
+ H > 0 ? /* @__PURE__ */ o("div", {
311
+ className: "flex flex-col gap-1",
312
+ children: S.regions.map((e) => {
313
+ let t = A === e.id, n = e.shape.kind === "polygon" ? pe : ue;
314
+ return /* @__PURE__ */ s("div", {
315
+ className: `flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t ? "border-primary/50 bg-primary/10" : "border-border bg-surface"}`,
316
+ children: [/* @__PURE__ */ s("button", {
317
+ type: "button",
318
+ onClick: () => be(e.id),
319
+ disabled: E,
320
+ className: "flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors",
321
+ children: [
322
+ /* @__PURE__ */ o(n, { className: "h-3.5 w-3.5 shrink-0" }),
323
+ /* @__PURE__ */ o("span", { children: c("uiLibrary.privacyMaskSettings.zoneN", "Zone {{id}}", { id: e.id }) }),
324
+ /* @__PURE__ */ o("span", {
325
+ className: "text-foreground-faint capitalize",
326
+ children: e.shape.kind
327
+ })
328
+ ]
329
+ }), /* @__PURE__ */ o("button", {
330
+ type: "button",
331
+ onClick: () => xe(e.id),
332
+ disabled: E,
333
+ "aria-label": c("uiLibrary.privacyMaskSettings.deleteZoneN", "Delete zone {{id}}", { id: e.id }),
334
+ title: c("uiLibrary.privacyMaskSettings.deleteZone", "Delete zone"),
335
+ className: "inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors",
336
+ children: /* @__PURE__ */ o(de, { className: "h-3.5 w-3.5" })
337
+ })]
338
+ }, e.id);
339
+ })
340
+ }) : null
341
+ ] }) : /* @__PURE__ */ o("p", {
342
+ className: `${l} leading-relaxed`,
343
+ children: c("uiLibrary.privacyMaskSettings.loading", "Loading the camera's privacy mask…")
344
+ }), Z.supported && /* @__PURE__ */ s("div", {
345
+ className: "flex items-start gap-3 rounded-md border border-border bg-surface px-2 py-2",
346
+ children: [/* @__PURE__ */ o("button", {
347
+ type: "button",
348
+ role: "switch",
349
+ "aria-label": Z.label,
350
+ "aria-checked": Z.on === !0,
351
+ disabled: !Z.available || I !== null,
352
+ onClick: () => void we(),
353
+ title: Z.on === null ? c("uiLibrary.privacyMaskSettings.micTitleUnknown", "Microphone — state unknown; the camera did not answer.") : Z.on ? c("uiLibrary.privacyMaskSettings.micTitleOn", "The camera is capturing sound. Turning it off: {{cost}}", { cost: Z.costWhenOff }) : c("uiLibrary.privacyMaskSettings.micTitleOff", "The camera is silent. {{cost}}", { cost: Z.costWhenOff }),
354
+ className: Z.on === !1 || Z.on === null ? m : h,
355
+ children: /* @__PURE__ */ s("span", {
356
+ className: "inline-flex items-center gap-1.5",
357
+ children: [Z.on === !1 ? /* @__PURE__ */ o(me, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ o(ce, { className: "h-3.5 w-3.5" }), Z.on === null ? c("uiLibrary.privacyMaskSettings.micUnknown", "Microphone unknown") : Z.on ? c("uiLibrary.privacyMaskSettings.micOn", "Microphone on") : c("uiLibrary.privacyMaskSettings.micOff", "Microphone off")]
358
+ })
359
+ }), /* @__PURE__ */ o("p", {
360
+ className: "text-[10px] text-foreground-subtle flex-1 leading-relaxed",
361
+ children: R === null ? Z.on === null ? c("uiLibrary.privacyMaskSettings.micNotReported", "The camera did not report its microphone, so this state is unknown.") : Z.costWhenOff : c("uiLibrary.privacyMaskSettings.writeFailed", "Write failed: {{reason}}", { reason: R })
362
+ })]
363
+ })]
364
+ })
365
+ }) : null;
366
+ }
367
+ //#endregion
368
+ export { _ as PrivacyMaskSettings };