@camstack/addon-osd-manager 0.1.69 → 0.1.70

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.
@@ -1,10 +1,10 @@
1
1
  import { c as e, h as t, m as n, p as r, u as i, y as a } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react__loadShare__.js-Bs1t18EM.mjs";
2
2
  import { a as o, i as s, n as c, r as l, s as u, t as d } from "./responsive-DgE6uJQL.mjs";
3
- import { a as f, c as p, i as ee, l as m, n as h, o as g, r as _, s as v, t as y, u as b } from "./use-device-snapshot-pxGFFbiL.mjs";
4
- import { t as x } from "./trash-2-C1RIMmGl.mjs";
5
- import { n as S, r as C, t as w } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DalfdIDw.mjs";
6
- import { MaskShapeCanvas as te } from "./MaskShapeCanvas-BEVxAjNq.mjs";
7
- var ne = u("settings-2", [
3
+ import { a as f, c as p, d as ee, i as m, l as te, n as h, o as ne, r as g, s as _, t as re, u as v } from "./use-device-snapshot-Bs7H8rkB.mjs";
4
+ import { t as y } from "./trash-2-C1RIMmGl.mjs";
5
+ import { n as b, r as x, t as S } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DalfdIDw.mjs";
6
+ import { MaskShapeCanvas as C } from "./MaskShapeCanvas-BEVxAjNq.mjs";
7
+ var ie = u("settings-2", [
8
8
  ["path", {
9
9
  d: "M14 17H5",
10
10
  key: "gfn3mx"
@@ -29,8 +29,8 @@ var ne = u("settings-2", [
29
29
  //#endregion
30
30
  //#region ../ui-library/src/composites/cap-settings/SceneReferenceGallery.tsx
31
31
  a();
32
- var T = "/addon/pipeline-analytics/event-media";
33
- function E(e) {
32
+ var w = p("/addon/pipeline-analytics/event-media");
33
+ function T(e) {
34
34
  let t = /* @__PURE__ */ new Map();
35
35
  for (let n of e.states) n.references.forEach((e, r) => {
36
36
  let i = t.get(e.condition) ?? [];
@@ -45,43 +45,43 @@ function E(e) {
45
45
  tiles: [...t].sort((e, t) => t.reference.capturedAt - e.reference.capturedAt)
46
46
  })).sort((e, t) => e.condition.localeCompare(t.condition));
47
47
  }
48
- function D(e) {
48
+ function E(e) {
49
49
  return e.states.reduce((e, t) => e + t.references.length, 0);
50
50
  }
51
- var O = "rounded border border-danger/50 bg-danger/10 px-1 py-0.5 text-[10px] font-medium text-danger hover:bg-danger/20 disabled:opacity-40 transition-colors";
52
- function k({ monitor: e, disabled: n, onDelete: r }) {
53
- let i = E(e), a = D(e), [o, s] = t(null);
54
- return i.length === 0 ? /* @__PURE__ */ S("p", {
51
+ var D = "rounded border border-danger/50 bg-danger/10 px-1 py-0.5 text-[10px] font-medium text-danger hover:bg-danger/20 disabled:opacity-40 transition-colors";
52
+ function O({ monitor: e, disabled: n, onDelete: r }) {
53
+ let i = T(e), a = E(e), [o, s] = t(null);
54
+ return i.length === 0 ? /* @__PURE__ */ b("p", {
55
55
  className: `${d} leading-relaxed`,
56
56
  children: "No photographs captured yet. Press “Capture daylight” to take the one this scene will judge everything against."
57
- }) : /* @__PURE__ */ S("div", {
57
+ }) : /* @__PURE__ */ b("div", {
58
58
  className: "flex flex-col gap-2",
59
- children: i.map((e) => /* @__PURE__ */ C("div", {
59
+ children: i.map((e) => /* @__PURE__ */ x("div", {
60
60
  className: "flex flex-col gap-1",
61
- children: [/* @__PURE__ */ C("p", {
61
+ children: [/* @__PURE__ */ x("p", {
62
62
  className: "text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle",
63
63
  children: [
64
- v(e.condition),
64
+ _(e.condition),
65
65
  " · ",
66
66
  e.tiles.length
67
67
  ]
68
- }), /* @__PURE__ */ S("ul", {
68
+ }), /* @__PURE__ */ b("ul", {
69
69
  className: "flex flex-wrap gap-1.5",
70
70
  children: e.tiles.map((t) => {
71
71
  let i = `${t.stateId}:${String(t.index)}`, c = a === 1, l = o === i;
72
- return /* @__PURE__ */ C("li", {
72
+ return /* @__PURE__ */ x("li", {
73
73
  className: "flex w-24 flex-col gap-1 rounded-md border border-border p-1",
74
74
  children: [
75
- /* @__PURE__ */ S(A, { reference: t.reference }),
76
- /* @__PURE__ */ S("span", {
75
+ /* @__PURE__ */ b(k, { reference: t.reference }),
76
+ /* @__PURE__ */ b("span", {
77
77
  className: `${d} tabular-nums`,
78
- children: j(t.reference.capturedAt)
78
+ children: A(t.reference.capturedAt)
79
79
  }),
80
- /* @__PURE__ */ C("button", {
80
+ /* @__PURE__ */ x("button", {
81
81
  type: "button",
82
- className: O,
82
+ className: D,
83
83
  disabled: n,
84
- "aria-label": `Delete the ${v(e.condition).toLowerCase()} photograph from ${j(t.reference.capturedAt)}`,
84
+ "aria-label": `Delete the ${_(e.condition).toLowerCase()} photograph from ${A(t.reference.capturedAt)}`,
85
85
  onClick: () => {
86
86
  if (c && !l) {
87
87
  s(i);
@@ -92,9 +92,9 @@ function k({ monitor: e, disabled: n, onDelete: r }) {
92
92
  index: t.index
93
93
  });
94
94
  },
95
- children: [/* @__PURE__ */ S(x, { className: "mr-1 inline h-3 w-3" }), l ? "Confirm" : "Delete"]
95
+ children: [/* @__PURE__ */ b(y, { className: "mr-1 inline h-3 w-3" }), l ? "Confirm" : "Delete"]
96
96
  }),
97
- l && /* @__PURE__ */ S("p", {
97
+ l && /* @__PURE__ */ b("p", {
98
98
  className: "text-[10px] leading-snug text-warning",
99
99
  children: "This is the only photograph this scene has. Delete it and the scene no longer knows what normal looks like — it stops judging until you capture again."
100
100
  })
@@ -105,24 +105,24 @@ function k({ monitor: e, disabled: n, onDelete: r }) {
105
105
  }, e.condition))
106
106
  });
107
107
  }
108
- function A({ reference: e }) {
108
+ function k({ reference: e }) {
109
109
  let [n, r] = t(!1), i = e.thumbnailMediaId;
110
- return i === void 0 || n ? /* @__PURE__ */ C("div", {
110
+ return i === void 0 || n ? /* @__PURE__ */ x("div", {
111
111
  className: "flex h-16 w-full flex-col items-center justify-center gap-0.5 rounded bg-surface text-foreground-subtle",
112
112
  title: "The picture for this reference is no longer stored. The reference itself is intact and still being scored against.",
113
- children: [/* @__PURE__ */ S(m, { className: "h-4 w-4" }), /* @__PURE__ */ S("span", {
113
+ children: [/* @__PURE__ */ b(v, { className: "h-4 w-4" }), /* @__PURE__ */ b("span", {
114
114
  className: "text-[9px]",
115
115
  children: "no picture"
116
116
  })]
117
- }) : /* @__PURE__ */ S("img", {
118
- src: `${T}/${encodeURIComponent(i)}`,
117
+ }) : /* @__PURE__ */ b("img", {
118
+ src: `${w}/${encodeURIComponent(i)}`,
119
119
  alt: "",
120
120
  loading: "lazy",
121
121
  className: "h-16 w-full rounded object-cover",
122
122
  onError: () => r(!0)
123
123
  });
124
124
  }
125
- function j(e) {
125
+ function A(e) {
126
126
  let t = new Date(e);
127
127
  return `${t.toLocaleDateString()} ${t.toLocaleTimeString([], {
128
128
  hour: "2-digit",
@@ -132,15 +132,15 @@ function j(e) {
132
132
  //#endregion
133
133
  //#region ../ui-library/src/composites/cap-settings/SceneSettingsForm.tsx
134
134
  a();
135
- var M = "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:border-primary focus:outline-none disabled:opacity-50", N = "text-[10px] font-medium text-foreground-subtle", P = "flex flex-col gap-2 rounded-md border border-border bg-surface/40 p-2", F = "text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle", I = 5, L = 3600, R = {
135
+ var j = "rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:border-primary focus:outline-none disabled:opacity-50", M = "text-[10px] font-medium text-foreground-subtle", N = "flex flex-col gap-2 rounded-md border border-border bg-surface/40 p-2", P = "text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle", F = 5, I = 3600, L = {
136
136
  periodic: "Only on the clock. Predictable, and it notices a change even on a camera nothing ever moves in front of.",
137
137
  "on-motion": "Only after the camera has been still again for the quiet window below. Cheapest, but a change nobody walks past is never seen.",
138
138
  both: "Both — the clock is the safety net that lets the motion path miss. This is the right answer for almost every scene."
139
- }, z = {
139
+ }, R = {
140
140
  skip: "Sit that light out. No verdict, no alarm, no flag touched — it picks itself back up when a light it knows returns. This is why the night capture is optional.",
141
141
  "judge-anyway": "Compare against the references you do have. Only correct when the two lights genuinely look alike (a floodlit driveway, an indoor lamp) — against a real infrared frame it will report a change that did not happen."
142
142
  };
143
- function B(e) {
143
+ function z(e) {
144
144
  return {
145
145
  label: e.label,
146
146
  checkIntervalSec: e.checkIntervalSec ?? 60,
@@ -151,10 +151,10 @@ function B(e) {
151
151
  confirmPrompt: e.confirm?.prompt ?? ""
152
152
  };
153
153
  }
154
- function V({ monitor: e, disabled: n, onPatch: r }) {
155
- let [a, o] = t(() => B(e)), [s, c] = t(!1);
154
+ function B({ monitor: e, disabled: n, onPatch: r }) {
155
+ let [a, o] = t(() => z(e)), [s, c] = t(!1);
156
156
  i(() => {
157
- s || o(B(e));
157
+ s || o(z(e));
158
158
  }, [e, s]);
159
159
  let l = (e) => {
160
160
  c(!1), r(e);
@@ -166,26 +166,26 @@ function V({ monitor: e, disabled: n, onPatch: r }) {
166
166
  ...e.check,
167
167
  hysteresisCount: t.hysteresisCount ?? e.check.hysteresisCount
168
168
  }, f = e.confirm?.enabled === !0, p = e.check.mode === "similarity" ? e.check.threshold : null;
169
- return /* @__PURE__ */ C("div", {
169
+ return /* @__PURE__ */ x("div", {
170
170
  className: "flex flex-col gap-2",
171
171
  children: [
172
- /* @__PURE__ */ C("div", {
173
- className: P,
172
+ /* @__PURE__ */ x("div", {
173
+ className: N,
174
174
  children: [
175
- /* @__PURE__ */ S("p", {
176
- className: F,
175
+ /* @__PURE__ */ b("p", {
176
+ className: P,
177
177
  children: "What it watches"
178
178
  }),
179
- /* @__PURE__ */ C("label", {
179
+ /* @__PURE__ */ x("label", {
180
180
  className: "flex flex-col gap-1",
181
- children: [/* @__PURE__ */ S("span", {
182
- className: N,
181
+ children: [/* @__PURE__ */ b("span", {
182
+ className: M,
183
183
  children: "Name"
184
- }), /* @__PURE__ */ S("input", {
184
+ }), /* @__PURE__ */ b("input", {
185
185
  type: "text",
186
186
  value: a.label,
187
187
  disabled: n,
188
- className: M,
188
+ className: j,
189
189
  onFocus: () => c(!0),
190
190
  onChange: (e) => o((t) => ({
191
191
  ...t,
@@ -197,100 +197,100 @@ function V({ monitor: e, disabled: n, onPatch: r }) {
197
197
  }
198
198
  })]
199
199
  }),
200
- /* @__PURE__ */ C("label", {
200
+ /* @__PURE__ */ x("label", {
201
201
  className: "flex items-center gap-2",
202
- children: [/* @__PURE__ */ S("input", {
202
+ children: [/* @__PURE__ */ b("input", {
203
203
  type: "checkbox",
204
204
  checked: e.enabled,
205
205
  disabled: n,
206
206
  onChange: (e) => l({ enabled: e.target.checked })
207
- }), /* @__PURE__ */ S("span", {
208
- className: N,
207
+ }), /* @__PURE__ */ b("span", {
208
+ className: M,
209
209
  children: "Watching"
210
210
  })]
211
211
  }),
212
- /* @__PURE__ */ S("p", {
212
+ /* @__PURE__ */ b("p", {
213
213
  className: d,
214
214
  children: "Turned off, the scene keeps its region, its references and its flag — it simply stops checking. Nothing is lost by pausing one for a while."
215
215
  }),
216
- /* @__PURE__ */ C("label", {
216
+ /* @__PURE__ */ x("label", {
217
217
  className: "flex flex-col gap-1",
218
- children: [/* @__PURE__ */ S("span", {
219
- className: N,
218
+ children: [/* @__PURE__ */ b("span", {
219
+ className: M,
220
220
  children: "When to look"
221
- }), /* @__PURE__ */ C("select", {
221
+ }), /* @__PURE__ */ x("select", {
222
222
  value: e.triggerMode,
223
223
  disabled: n,
224
- className: M,
224
+ className: j,
225
225
  onChange: (e) => {
226
226
  let t = e.target.value;
227
227
  (t === "periodic" || t === "on-motion" || t === "both") && l({ triggerMode: t });
228
228
  },
229
229
  children: [
230
- /* @__PURE__ */ S("option", {
230
+ /* @__PURE__ */ b("option", {
231
231
  value: "both",
232
232
  children: "On the clock and after motion settles"
233
233
  }),
234
- /* @__PURE__ */ S("option", {
234
+ /* @__PURE__ */ b("option", {
235
235
  value: "periodic",
236
236
  children: "On the clock only"
237
237
  }),
238
- /* @__PURE__ */ S("option", {
238
+ /* @__PURE__ */ b("option", {
239
239
  value: "on-motion",
240
240
  children: "After motion settles only"
241
241
  })
242
242
  ]
243
243
  })]
244
244
  }),
245
- /* @__PURE__ */ S("p", {
245
+ /* @__PURE__ */ b("p", {
246
246
  className: d,
247
- children: R[e.triggerMode]
247
+ children: L[e.triggerMode]
248
248
  }),
249
- /* @__PURE__ */ C("label", {
249
+ /* @__PURE__ */ x("label", {
250
250
  className: "flex flex-col gap-1",
251
- children: [/* @__PURE__ */ S("span", {
252
- className: N,
251
+ children: [/* @__PURE__ */ b("span", {
252
+ className: M,
253
253
  children: "Check every (seconds)"
254
- }), /* @__PURE__ */ S("input", {
254
+ }), /* @__PURE__ */ b("input", {
255
255
  type: "number",
256
- min: I,
257
- max: L,
256
+ min: F,
257
+ max: I,
258
258
  value: a.checkIntervalSec,
259
259
  disabled: n,
260
- className: M,
260
+ className: j,
261
261
  onFocus: () => c(!0),
262
262
  onChange: (e) => o((t) => ({
263
263
  ...t,
264
264
  checkIntervalSec: Number(e.target.value) || 0
265
265
  })),
266
266
  onBlur: () => {
267
- let t = H(a.checkIntervalSec, I, L);
267
+ let t = V(a.checkIntervalSec, F, I);
268
268
  t === e.checkIntervalSec ? c(!1) : l({ checkIntervalSec: t });
269
269
  }
270
270
  })]
271
271
  }),
272
- /* @__PURE__ */ S("p", {
272
+ /* @__PURE__ */ b("p", {
273
273
  className: d,
274
274
  children: "60 s suits “is the bin still out”. Every check costs one photograph and one encode, so going below about 30 s buys latency you almost never need and multiplies the cost by the number of scenes you own."
275
275
  })
276
276
  ]
277
277
  }),
278
- /* @__PURE__ */ C("div", {
279
- className: P,
278
+ /* @__PURE__ */ x("div", {
279
+ className: N,
280
280
  children: [
281
- /* @__PURE__ */ S("p", {
282
- className: F,
281
+ /* @__PURE__ */ b("p", {
282
+ className: P,
283
283
  children: "How sure it has to be"
284
284
  }),
285
- e.check.mode === "similarity" && /* @__PURE__ */ C(w, { children: [/* @__PURE__ */ C("label", {
285
+ e.check.mode === "similarity" && /* @__PURE__ */ x(S, { children: [/* @__PURE__ */ x("label", {
286
286
  className: "flex flex-col gap-1",
287
- children: [/* @__PURE__ */ C("span", {
288
- className: N,
289
- children: ["Match threshold — ", /* @__PURE__ */ S("span", {
287
+ children: [/* @__PURE__ */ x("span", {
288
+ className: M,
289
+ children: ["Match threshold — ", /* @__PURE__ */ b("span", {
290
290
  className: "tabular-nums",
291
291
  children: a.threshold.toFixed(2)
292
292
  })]
293
- }), /* @__PURE__ */ S("input", {
293
+ }), /* @__PURE__ */ b("input", {
294
294
  type: "range",
295
295
  min: .3,
296
296
  max: .99,
@@ -309,212 +309,212 @@ function V({ monitor: e, disabled: n, onPatch: r }) {
309
309
  a.threshold === p ? c(!1) : l({ check: u({ threshold: a.threshold }) });
310
310
  }
311
311
  })]
312
- }), /* @__PURE__ */ S("p", {
312
+ }), /* @__PURE__ */ b("p", {
313
313
  className: "text-[10px] text-foreground-subtle",
314
314
  children: "How closely the region still has to resemble the photograph to count as unchanged. Higher means fussier: at 0.95 a passing cloud can read as a change; at 0.60 the bin can be taken and the scene will shrug. 0.80 is a sensible start — if it cries wolf, lower it; if it misses the thing you care about, raise it."
315
315
  })] }),
316
- /* @__PURE__ */ C("label", {
316
+ /* @__PURE__ */ x("label", {
317
317
  className: "flex flex-col gap-1",
318
- children: [/* @__PURE__ */ S("span", {
319
- className: N,
318
+ children: [/* @__PURE__ */ b("span", {
319
+ className: M,
320
320
  children: "Agreeing checks before it changes its mind"
321
- }), /* @__PURE__ */ S("input", {
321
+ }), /* @__PURE__ */ b("input", {
322
322
  type: "number",
323
323
  min: 1,
324
324
  max: 10,
325
325
  value: a.hysteresisCount,
326
326
  disabled: n,
327
- className: M,
327
+ className: j,
328
328
  onFocus: () => c(!0),
329
329
  onChange: (e) => o((t) => ({
330
330
  ...t,
331
331
  hysteresisCount: Number(e.target.value) || 1
332
332
  })),
333
333
  onBlur: () => {
334
- let t = H(a.hysteresisCount, 1, 10);
334
+ let t = V(a.hysteresisCount, 1, 10);
335
335
  t === e.check.hysteresisCount ? c(!1) : l({ check: u({ hysteresisCount: t }) });
336
336
  }
337
337
  })]
338
338
  }),
339
- /* @__PURE__ */ S("p", {
339
+ /* @__PURE__ */ b("p", {
340
340
  className: d,
341
341
  children: "One bad photograph must never be able to flip a scene. 3 agreeing checks at 60 s is about four minutes of latency and is what makes the answer trustworthy — leaving a state costs exactly the same as entering one."
342
342
  }),
343
- /* @__PURE__ */ C("label", {
343
+ /* @__PURE__ */ x("label", {
344
344
  className: "flex flex-col gap-1",
345
- children: [/* @__PURE__ */ S("span", {
346
- className: N,
345
+ children: [/* @__PURE__ */ b("span", {
346
+ className: M,
347
347
  children: "Quiet for (seconds) before a check counts"
348
- }), /* @__PURE__ */ S("input", {
348
+ }), /* @__PURE__ */ b("input", {
349
349
  type: "number",
350
350
  min: 0,
351
351
  max: 3600,
352
352
  value: a.quietSeconds,
353
353
  disabled: n,
354
- className: M,
354
+ className: j,
355
355
  onFocus: () => c(!0),
356
356
  onChange: (e) => o((t) => ({
357
357
  ...t,
358
358
  quietSeconds: Number(e.target.value) || 0
359
359
  })),
360
360
  onBlur: () => {
361
- let t = H(a.quietSeconds, 0, 3600);
361
+ let t = V(a.quietSeconds, 0, 3600);
362
362
  t === e.quietSeconds ? c(!1) : l({ quietSeconds: t });
363
363
  }
364
364
  })]
365
365
  }),
366
- /* @__PURE__ */ S("p", {
366
+ /* @__PURE__ */ b("p", {
367
367
  className: d,
368
368
  children: "A check taken while something is moving is a photograph of the van parked in front of the bin, so it is discarded rather than merely delayed. 0 disables the gate."
369
369
  }),
370
- /* @__PURE__ */ C("label", {
370
+ /* @__PURE__ */ x("label", {
371
371
  className: "flex flex-col gap-1",
372
- children: [/* @__PURE__ */ S("span", {
373
- className: N,
372
+ children: [/* @__PURE__ */ b("span", {
373
+ className: M,
374
374
  children: "Minimum gap between counted checks (seconds)"
375
- }), /* @__PURE__ */ S("input", {
375
+ }), /* @__PURE__ */ b("input", {
376
376
  type: "number",
377
377
  min: 0,
378
378
  max: 3600,
379
379
  value: a.minObservationSpacingSec,
380
380
  disabled: n,
381
- className: M,
381
+ className: j,
382
382
  onFocus: () => c(!0),
383
383
  onChange: (e) => o((t) => ({
384
384
  ...t,
385
385
  minObservationSpacingSec: Number(e.target.value) || 0
386
386
  })),
387
387
  onBlur: () => {
388
- let t = H(a.minObservationSpacingSec, 0, 3600);
388
+ let t = V(a.minObservationSpacingSec, 0, 3600);
389
389
  t === e.minObservationSpacingSec ? c(!1) : l({ minObservationSpacingSec: t });
390
390
  }
391
391
  })]
392
392
  }),
393
- /* @__PURE__ */ S("p", {
393
+ /* @__PURE__ */ b("p", {
394
394
  className: d,
395
395
  children: "Spreads the agreeing checks over real time instead of letting three adjacent polls inside one long occlusion be mistaken for three independent opinions."
396
396
  })
397
397
  ]
398
398
  }),
399
- /* @__PURE__ */ C("div", {
400
- className: P,
399
+ /* @__PURE__ */ x("div", {
400
+ className: N,
401
401
  children: [
402
- /* @__PURE__ */ S("p", {
403
- className: F,
402
+ /* @__PURE__ */ b("p", {
403
+ className: P,
404
404
  children: "Lighting"
405
405
  }),
406
- /* @__PURE__ */ C("label", {
406
+ /* @__PURE__ */ x("label", {
407
407
  className: "flex flex-col gap-1",
408
- children: [/* @__PURE__ */ S("span", {
409
- className: N,
408
+ children: [/* @__PURE__ */ b("span", {
409
+ className: M,
410
410
  children: "When a light has no reference of its own"
411
- }), /* @__PURE__ */ C("select", {
411
+ }), /* @__PURE__ */ x("select", {
412
412
  value: e.onUncoveredCondition,
413
413
  disabled: n,
414
- className: M,
414
+ className: j,
415
415
  onChange: (e) => {
416
416
  let t = e.target.value;
417
417
  (t === "skip" || t === "judge-anyway") && l({ onUncoveredCondition: t });
418
418
  },
419
- children: [/* @__PURE__ */ S("option", {
419
+ children: [/* @__PURE__ */ b("option", {
420
420
  value: "skip",
421
421
  children: "Skip the check (recommended)"
422
- }), /* @__PURE__ */ S("option", {
422
+ }), /* @__PURE__ */ b("option", {
423
423
  value: "judge-anyway",
424
424
  children: "Judge against the other light anyway"
425
425
  })]
426
426
  })]
427
427
  }),
428
- /* @__PURE__ */ S("p", {
428
+ /* @__PURE__ */ b("p", {
429
429
  className: d,
430
- children: z[e.onUncoveredCondition]
430
+ children: R[e.onUncoveredCondition]
431
431
  })
432
432
  ]
433
433
  }),
434
- /* @__PURE__ */ C("div", {
435
- className: P,
434
+ /* @__PURE__ */ x("div", {
435
+ className: N,
436
436
  children: [
437
- /* @__PURE__ */ S("p", {
438
- className: F,
437
+ /* @__PURE__ */ b("p", {
438
+ className: P,
439
439
  children: "What you get told"
440
440
  }),
441
- /* @__PURE__ */ C("label", {
441
+ /* @__PURE__ */ x("label", {
442
442
  className: "flex flex-col gap-1",
443
- children: [/* @__PURE__ */ S("span", {
444
- className: N,
443
+ children: [/* @__PURE__ */ b("span", {
444
+ className: M,
445
445
  children: "Notifications follow"
446
- }), /* @__PURE__ */ C("select", {
446
+ }), /* @__PURE__ */ x("select", {
447
447
  value: e.emit,
448
448
  disabled: n,
449
- className: M,
449
+ className: j,
450
450
  onChange: (e) => {
451
451
  let t = e.target.value;
452
452
  (t === "latched" || t === "live") && l({ emit: t });
453
453
  },
454
- children: [/* @__PURE__ */ S("option", {
454
+ children: [/* @__PURE__ */ b("option", {
455
455
  value: "latched",
456
456
  children: "The flag — told once, still visible at breakfast"
457
- }), /* @__PURE__ */ S("option", {
457
+ }), /* @__PURE__ */ b("option", {
458
458
  value: "live",
459
459
  children: "The live state — follows the region as it changes"
460
460
  })]
461
461
  })]
462
462
  }),
463
- /* @__PURE__ */ S("p", {
463
+ /* @__PURE__ */ b("p", {
464
464
  className: d,
465
465
  children: "“Is the bin gone” is a flag: you want to be told once and still see it later. “Is the gate open” is a live state."
466
466
  }),
467
- /* @__PURE__ */ C("label", {
467
+ /* @__PURE__ */ x("label", {
468
468
  className: "flex items-center gap-2",
469
- children: [/* @__PURE__ */ S("input", {
469
+ children: [/* @__PURE__ */ b("input", {
470
470
  type: "checkbox",
471
471
  checked: e.autoRestore,
472
472
  disabled: n,
473
473
  onChange: (e) => l({ autoRestore: e.target.checked })
474
- }), /* @__PURE__ */ S("span", {
475
- className: N,
474
+ }), /* @__PURE__ */ b("span", {
475
+ className: M,
476
476
  children: "Clear the flag by itself when things look normal again"
477
477
  })]
478
478
  }),
479
- /* @__PURE__ */ S("p", {
479
+ /* @__PURE__ */ b("p", {
480
480
  className: d,
481
481
  children: "Off by default, so an alarm never silently clears itself. The “back to normal” moment is recorded either way, so an automation can still react to it."
482
482
  })
483
483
  ]
484
484
  }),
485
- /* @__PURE__ */ C("div", {
486
- className: P,
485
+ /* @__PURE__ */ x("div", {
486
+ className: N,
487
487
  children: [
488
- /* @__PURE__ */ S("p", {
489
- className: F,
488
+ /* @__PURE__ */ b("p", {
489
+ className: P,
490
490
  children: "AI double-check"
491
491
  }),
492
- /* @__PURE__ */ C("label", {
492
+ /* @__PURE__ */ x("label", {
493
493
  className: "flex items-center gap-2",
494
- children: [/* @__PURE__ */ S("input", {
494
+ children: [/* @__PURE__ */ b("input", {
495
495
  type: "checkbox",
496
496
  checked: f,
497
497
  disabled: n || a.confirmPrompt.trim().length === 0,
498
498
  onChange: (e) => l(e.target.checked ? { confirm: {
499
- ...U(a.confirmPrompt.trim()),
499
+ ...H(a.confirmPrompt.trim()),
500
500
  enabled: !0
501
501
  } } : { confirm: null })
502
- }), /* @__PURE__ */ S("span", {
503
- className: N,
502
+ }), /* @__PURE__ */ b("span", {
503
+ className: M,
504
504
  children: "Ask a vision model before changing the answer"
505
505
  })]
506
506
  }),
507
- /* @__PURE__ */ C("label", {
507
+ /* @__PURE__ */ x("label", {
508
508
  className: "flex flex-col gap-1",
509
- children: [/* @__PURE__ */ S("span", {
510
- className: N,
509
+ children: [/* @__PURE__ */ b("span", {
510
+ className: M,
511
511
  children: "The question to ask"
512
- }), /* @__PURE__ */ S("input", {
512
+ }), /* @__PURE__ */ b("input", {
513
513
  type: "text",
514
514
  value: a.confirmPrompt,
515
515
  placeholder: "e.g. Is the wheelie bin still there?",
516
516
  disabled: n,
517
- className: M,
517
+ className: j,
518
518
  onFocus: () => c(!0),
519
519
  onChange: (e) => o((t) => ({
520
520
  ...t,
@@ -523,17 +523,17 @@ function V({ monitor: e, disabled: n, onPatch: r }) {
523
523
  onBlur: () => {
524
524
  let t = a.confirmPrompt.trim();
525
525
  t.length > 0 && t !== e.confirm?.prompt ? l({ confirm: {
526
- ...U(t),
526
+ ...H(t),
527
527
  enabled: f
528
528
  } }) : c(!1);
529
529
  }
530
530
  })]
531
531
  }),
532
- /* @__PURE__ */ C("p", {
532
+ /* @__PURE__ */ x("p", {
533
533
  className: d,
534
534
  children: [
535
535
  "The model is asked ",
536
- /* @__PURE__ */ S("strong", { children: "only" }),
536
+ /* @__PURE__ */ b("strong", { children: "only" }),
537
537
  " when the region has already changed enough to flip the answer — roughly twice a week for a bin, not once a minute. It reasons about the object rather than the pixels, so rain, shadows and a repositioned bin stop counting as the thing being taken. If it cannot be reached, the change is held rather than announced."
538
538
  ]
539
539
  })
@@ -542,10 +542,10 @@ function V({ monitor: e, disabled: n, onPatch: r }) {
542
542
  ]
543
543
  });
544
544
  }
545
- function H(e, t, n) {
545
+ function V(e, t, n) {
546
546
  return Math.min(n, Math.max(t, e));
547
547
  }
548
- function U(e) {
548
+ function H(e) {
549
549
  return {
550
550
  enabled: !1,
551
551
  prompt: e,
@@ -557,13 +557,13 @@ function U(e) {
557
557
  //#endregion
558
558
  //#region ../ui-library/src/composites/cap-settings/SceneMonitorEditor.tsx
559
559
  a();
560
- var W = "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", G = "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", K = "rounded-md border border-danger/50 bg-danger/10 px-2 py-1 text-[11px] font-medium text-danger hover:bg-danger/20 disabled:opacity-40 transition-colors", q = {
560
+ var U = "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", W = "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", G = "rounded-md border border-danger/50 bg-danger/10 px-2 py-1 text-[11px] font-medium text-danger hover:bg-danger/20 disabled:opacity-40 transition-colors", K = {
561
561
  alarm: "border-danger/50 bg-danger/15 text-danger",
562
562
  ok: "border-success/50 bg-success/15 text-success",
563
563
  unknown: "border-border bg-surface text-foreground-subtle"
564
- }, re = .8, ie = 3;
565
- function J({ deviceId: a }) {
566
- let u = l(o().trpcClient, a), m = s(u?.state.sceneMonitor), T = y(a, { width: 640 }), [E, D] = t(null), [O, A] = t(!1), [j, M] = t(null), [N, P] = t(null), [F, I] = t(null), [L, R] = t(null), [z, B] = t(!1), [H, U] = t(null), [J, Y] = t(""), X = n(!0);
564
+ }, q = .8, J = 3;
565
+ function Y({ deviceId: a }) {
566
+ let u = l(o().trpcClient, a), p = s(u?.state.sceneMonitor), v = re(a, { width: 640 }), [w, T] = t(null), [E, D] = t(!1), [k, A] = t(null), [j, M] = t(null), [N, P] = t(null), [F, I] = t(null), [L, R] = t(!1), [z, V] = t(null), [H, Y] = t(""), X = n(!0);
567
567
  i(() => (X.current = !0, () => {
568
568
  X.current = !1;
569
569
  }), []);
@@ -571,23 +571,23 @@ function J({ deviceId: a }) {
571
571
  if (u) try {
572
572
  let e = await u.sceneMonitor?.listScenes({});
573
573
  if (!X.current) return;
574
- e && D(e);
574
+ e && T(e);
575
575
  } catch (e) {
576
576
  if (!X.current) return;
577
- c(e) ? A(!0) : P(e instanceof Error ? e.message : String(e));
577
+ c(e) ? D(!0) : M(e instanceof Error ? e.message : String(e));
578
578
  }
579
579
  }, [u]);
580
580
  i(() => {
581
- D(null), A(!1), P(null), Z();
581
+ T(null), D(!1), M(null), Z();
582
582
  }, [Z]);
583
- let Q = m?.monitors ?? E?.monitors ?? [], ae = Date.now(), $ = e(async (e, t) => {
584
- M(e), P(null);
583
+ let Q = p?.monitors ?? w?.monitors ?? [], ae = Date.now(), $ = e(async (e, t) => {
584
+ A(e), M(null);
585
585
  try {
586
586
  await t(), await Z();
587
587
  } catch (e) {
588
- X.current && P(e instanceof Error ? e.message : String(e));
588
+ X.current && M(e instanceof Error ? e.message : String(e));
589
589
  } finally {
590
- X.current && M(null);
590
+ X.current && A(null);
591
591
  }
592
592
  }, [Z]), oe = r(() => {
593
593
  let e = Q.map((e) => ({
@@ -596,15 +596,15 @@ function J({ deviceId: a }) {
596
596
  label: e.label,
597
597
  enabled: e.enabled
598
598
  }));
599
- return H === null ? e : [...e, {
599
+ return z === null ? e : [...e, {
600
600
  id: "__draft__",
601
- shape: H,
601
+ shape: z,
602
602
  label: "New scene"
603
603
  }];
604
- }, [Q, H]), se = e((e, t) => {
604
+ }, [Q, z]), se = e((e, t) => {
605
605
  if (t.kind === "rect") {
606
606
  if (e === "__draft__") {
607
- U(t);
607
+ V(t);
608
608
  return;
609
609
  }
610
610
  $(`roi-${String(e)}`, async () => u?.sceneMonitor?.updateScene({
@@ -613,205 +613,205 @@ function J({ deviceId: a }) {
613
613
  }));
614
614
  }
615
615
  }, [u, $]), ce = e((e) => {
616
- e.kind === "rect" && U(e);
616
+ e.kind === "rect" && V(e);
617
617
  }, []), le = e(async () => {
618
- H === null || J.trim().length === 0 || (await $("create", async () => {
618
+ z === null || H.trim().length === 0 || (await $("create", async () => {
619
619
  await u?.sceneMonitor?.createScene({
620
- label: J.trim(),
621
- roi: H,
620
+ label: H.trim(),
621
+ roi: z,
622
622
  check: {
623
623
  mode: "similarity",
624
- threshold: re,
625
- hysteresisCount: ie
624
+ threshold: q,
625
+ hysteresisCount: J
626
626
  }
627
627
  });
628
- }), U(null), Y(""), B(!1));
628
+ }), V(null), Y(""), R(!1));
629
629
  }, [
630
630
  u,
631
+ z,
631
632
  H,
632
- J,
633
633
  $
634
634
  ]);
635
- return u ? /* @__PURE__ */ S("div", {
635
+ return u ? /* @__PURE__ */ b("div", {
636
636
  className: "flex flex-col gap-3",
637
- children: O ? /* @__PURE__ */ S("p", {
637
+ children: E ? /* @__PURE__ */ b("p", {
638
638
  className: `${d} leading-relaxed`,
639
639
  children: "Scene monitoring is not available for this camera."
640
- }) : /* @__PURE__ */ C(w, { children: [
641
- /* @__PURE__ */ S("p", {
640
+ }) : /* @__PURE__ */ x(S, { children: [
641
+ /* @__PURE__ */ b("p", {
642
642
  className: `${d} leading-relaxed`,
643
643
  children: "A scene watches one region of this camera and tells you when it stops looking like the picture you captured. Draw a box around the thing you care about — a wheelie bin, a gate, a parking space — then capture what “normal” looks like. Daylight is enough to start: the night reference is optional, and without it the scene simply sits the infrared hours out instead of reporting a problem."
644
644
  }),
645
- /* @__PURE__ */ S("div", {
645
+ /* @__PURE__ */ b("div", {
646
646
  className: "relative overflow-hidden rounded-md border border-border",
647
- children: /* @__PURE__ */ S(te, {
647
+ children: /* @__PURE__ */ b(C, {
648
648
  items: oe,
649
649
  supportedShapes: ["rect"],
650
- selectedId: F ?? (H === null ? null : "__draft__"),
651
- onSelect: (e) => I(e === null ? null : String(e)),
650
+ selectedId: N ?? (z === null ? null : "__draft__"),
651
+ onSelect: (e) => P(e === null ? null : String(e)),
652
652
  onShapeChange: se,
653
653
  onDrawComplete: ce,
654
- drawingKind: z && H === null ? "rect" : null,
655
- backdrop: T.src === null ? null : /* @__PURE__ */ S("img", {
656
- src: T.src,
654
+ drawingKind: L && z === null ? "rect" : null,
655
+ backdrop: v.src === null ? null : /* @__PURE__ */ b("img", {
656
+ src: v.src,
657
657
  alt: "",
658
658
  className: "h-full w-full object-contain",
659
659
  draggable: !1
660
660
  })
661
661
  })
662
662
  }),
663
- /* @__PURE__ */ C("div", {
663
+ /* @__PURE__ */ x("div", {
664
664
  className: "flex flex-wrap items-center gap-2",
665
- children: [/* @__PURE__ */ S("button", {
665
+ children: [/* @__PURE__ */ b("button", {
666
666
  type: "button",
667
- className: z ? G : W,
668
- "aria-pressed": z,
667
+ className: L ? W : U,
668
+ "aria-pressed": L,
669
669
  onClick: () => {
670
- B((e) => !e), U(null);
670
+ R((e) => !e), V(null);
671
671
  },
672
- disabled: j !== null,
673
- children: z ? "Cancel" : "+ New scene"
674
- }), /* @__PURE__ */ S("button", {
672
+ disabled: k !== null,
673
+ children: L ? "Cancel" : "+ New scene"
674
+ }), /* @__PURE__ */ b("button", {
675
675
  type: "button",
676
- className: W,
677
- onClick: T.refresh,
678
- disabled: j !== null,
676
+ className: U,
677
+ onClick: v.refresh,
678
+ disabled: k !== null,
679
679
  children: "Refresh frame"
680
680
  })]
681
681
  }),
682
- z && /* @__PURE__ */ C("div", {
682
+ L && /* @__PURE__ */ x("div", {
683
683
  className: "flex flex-col gap-2 rounded-md border border-border bg-surface p-2",
684
684
  children: [
685
- /* @__PURE__ */ S("p", {
685
+ /* @__PURE__ */ b("p", {
686
686
  className: "text-[10px] text-foreground-subtle",
687
- children: H === null ? "Click on the frame to drop a box, then drag its corner to fit it around the thing you want watched." : "Name it, then create. You capture what “normal” looks like next."
687
+ children: z === null ? "Click on the frame to drop a box, then drag its corner to fit it around the thing you want watched." : "Name it, then create. You capture what “normal” looks like next."
688
688
  }),
689
- H !== null && f(H) && /* @__PURE__ */ S("p", {
689
+ z !== null && f(z) && /* @__PURE__ */ b("p", {
690
690
  className: "text-[11px] leading-relaxed text-warning",
691
691
  children: "That box covers most of the frame. A scene that big is dominated by the weather, the sky and passing cars — it will quietly stop noticing the thing you actually care about. Draw it tighter."
692
692
  }),
693
- /* @__PURE__ */ C("div", {
693
+ /* @__PURE__ */ x("div", {
694
694
  className: "flex items-center gap-2",
695
- children: [/* @__PURE__ */ S("input", {
695
+ children: [/* @__PURE__ */ b("input", {
696
696
  type: "text",
697
- value: J,
697
+ value: H,
698
698
  onChange: (e) => Y(e.target.value),
699
699
  placeholder: "e.g. Immondizia prelevata",
700
700
  className: "flex-1 rounded-md border border-border bg-surface px-2 py-1 text-[12px] text-foreground"
701
- }), /* @__PURE__ */ S("button", {
701
+ }), /* @__PURE__ */ b("button", {
702
702
  type: "button",
703
- className: G,
703
+ className: W,
704
704
  onClick: () => void le(),
705
- disabled: H === null || J.trim().length === 0 || j !== null,
705
+ disabled: z === null || H.trim().length === 0 || k !== null,
706
706
  children: "Create"
707
707
  })]
708
708
  })
709
709
  ]
710
710
  }),
711
- N !== null && /* @__PURE__ */ S("p", {
711
+ j !== null && /* @__PURE__ */ b("p", {
712
712
  className: "text-[11px] leading-relaxed text-danger",
713
- children: N
713
+ children: j
714
714
  }),
715
- Q.length === 0 ? /* @__PURE__ */ S("p", {
715
+ Q.length === 0 ? /* @__PURE__ */ b("p", {
716
716
  className: `${d} leading-relaxed`,
717
717
  children: "No scenes on this camera yet."
718
- }) : /* @__PURE__ */ S("ul", {
718
+ }) : /* @__PURE__ */ b("ul", {
719
719
  className: "flex flex-col gap-2",
720
720
  children: Q.map((e) => {
721
- let t = _(e);
722
- return /* @__PURE__ */ C("li", {
723
- className: `flex flex-col gap-1.5 rounded-md border p-2 ${F === e.id ? "border-primary/50" : "border-border"}`,
721
+ let t = g(e);
722
+ return /* @__PURE__ */ x("li", {
723
+ className: `flex flex-col gap-1.5 rounded-md border p-2 ${N === e.id ? "border-primary/50" : "border-border"}`,
724
724
  children: [
725
- /* @__PURE__ */ C("div", {
725
+ /* @__PURE__ */ x("div", {
726
726
  className: "flex items-center gap-2",
727
- children: [/* @__PURE__ */ S("button", {
727
+ children: [/* @__PURE__ */ b("button", {
728
728
  type: "button",
729
729
  className: "flex-1 text-left text-[12px] font-medium text-foreground",
730
- onClick: () => I(e.id),
730
+ onClick: () => P(e.id),
731
731
  children: e.label
732
- }), /* @__PURE__ */ S("span", {
733
- className: `rounded border px-1.5 py-0.5 text-[10px] font-medium ${q[t.tone]}`,
732
+ }), /* @__PURE__ */ b("span", {
733
+ className: `rounded border px-1.5 py-0.5 text-[10px] font-medium ${K[t.tone]}`,
734
734
  children: t.text
735
735
  })]
736
736
  }),
737
- /* @__PURE__ */ S("p", {
737
+ /* @__PURE__ */ b("p", {
738
738
  className: `${d} leading-relaxed`,
739
- children: g(e, ae)
739
+ children: ne(e, ae)
740
740
  }),
741
- /* @__PURE__ */ S("p", {
741
+ /* @__PURE__ */ b("p", {
742
742
  className: `${d} tabular-nums`,
743
- children: ee(e)
743
+ children: m(e)
744
744
  }),
745
- /* @__PURE__ */ S(k, {
745
+ /* @__PURE__ */ b(O, {
746
746
  monitor: e,
747
- disabled: j !== null,
747
+ disabled: k !== null,
748
748
  onDelete: ({ stateId: t, index: n }) => void $(`refdel-${e.id}-${t}-${String(n)}`, async () => u.sceneMonitor?.deleteReference({
749
749
  monitorId: e.id,
750
750
  stateId: t,
751
751
  index: n
752
752
  }))
753
753
  }),
754
- /* @__PURE__ */ C("div", {
754
+ /* @__PURE__ */ x("div", {
755
755
  className: "flex flex-wrap items-center gap-1.5",
756
756
  children: [
757
757
  h.map((t) => {
758
758
  let n = t === "ir";
759
- return /* @__PURE__ */ C("button", {
759
+ return /* @__PURE__ */ x("button", {
760
760
  type: "button",
761
- className: W,
762
- disabled: j !== null,
763
- title: n ? "Optional. Without a night reference the checks in infrared are simply skipped — the scene keeps working in daylight and nothing is reported as broken." : `Take a fresh photo now and store it as the ${v(t).toLowerCase()} reference`,
761
+ className: U,
762
+ disabled: k !== null,
763
+ title: n ? "Optional. Without a night reference the checks in infrared are simply skipped — the scene keeps working in daylight and nothing is reported as broken." : `Take a fresh photo now and store it as the ${_(t).toLowerCase()} reference`,
764
764
  onClick: () => void $(`cap-${e.id}-${t}`, async () => u.sceneMonitor?.captureReference({
765
765
  monitorId: e.id,
766
766
  condition: t
767
767
  })),
768
768
  children: [
769
- /* @__PURE__ */ S(b, { className: "mr-1 inline h-3 w-3" }),
769
+ /* @__PURE__ */ b(ee, { className: "mr-1 inline h-3 w-3" }),
770
770
  "Capture ",
771
- v(t).toLowerCase(),
772
- n && /* @__PURE__ */ S("span", {
771
+ _(t).toLowerCase(),
772
+ n && /* @__PURE__ */ b("span", {
773
773
  className: "ml-1 text-foreground-subtle/70",
774
774
  children: "(optional)"
775
775
  })
776
776
  ]
777
777
  }, t);
778
778
  }),
779
- /* @__PURE__ */ C("button", {
779
+ /* @__PURE__ */ x("button", {
780
780
  type: "button",
781
- className: G,
782
- disabled: j !== null || e.states.length === 0,
781
+ className: W,
782
+ disabled: k !== null || e.states.length === 0,
783
783
  title: "Clear the flag and re-photograph what normal looks like right now",
784
784
  onClick: () => void $(`reset-${e.id}`, async () => u.sceneMonitor?.resetScene({ monitorId: e.id })),
785
- children: [/* @__PURE__ */ S(p, { className: "mr-1 inline h-3 w-3" }), "Reset"]
785
+ children: [/* @__PURE__ */ b(te, { className: "mr-1 inline h-3 w-3" }), "Reset"]
786
786
  }),
787
- /* @__PURE__ */ S("button", {
787
+ /* @__PURE__ */ b("button", {
788
788
  type: "button",
789
- className: W,
790
- disabled: j !== null,
789
+ className: U,
790
+ disabled: k !== null,
791
791
  onClick: () => void $(`check-${e.id}`, async () => u.sceneMonitor?.recheckNow({ monitorId: e.id })),
792
792
  children: "Check now"
793
793
  }),
794
- /* @__PURE__ */ C("button", {
794
+ /* @__PURE__ */ x("button", {
795
795
  type: "button",
796
- className: L === e.id ? G : W,
797
- "aria-pressed": L === e.id,
796
+ className: F === e.id ? W : U,
797
+ "aria-pressed": F === e.id,
798
798
  "aria-label": `Settings for ${e.label}`,
799
- disabled: j !== null,
800
- onClick: () => R((t) => t === e.id ? null : e.id),
801
- children: [/* @__PURE__ */ S(ne, { className: "mr-1 inline h-3 w-3" }), "Settings"]
799
+ disabled: k !== null,
800
+ onClick: () => I((t) => t === e.id ? null : e.id),
801
+ children: [/* @__PURE__ */ b(ie, { className: "mr-1 inline h-3 w-3" }), "Settings"]
802
802
  }),
803
- /* @__PURE__ */ S("button", {
803
+ /* @__PURE__ */ b("button", {
804
804
  type: "button",
805
- className: K,
806
- disabled: j !== null,
805
+ className: G,
806
+ disabled: k !== null,
807
807
  onClick: () => void $(`del-${e.id}`, async () => u.sceneMonitor?.deleteScene({ monitorId: e.id })),
808
- children: /* @__PURE__ */ S(x, { className: "h-3 w-3" })
808
+ children: /* @__PURE__ */ b(y, { className: "h-3 w-3" })
809
809
  })
810
810
  ]
811
811
  }),
812
- L === e.id && /* @__PURE__ */ S(V, {
812
+ F === e.id && /* @__PURE__ */ b(B, {
813
813
  monitor: e,
814
- disabled: j !== null,
814
+ disabled: k !== null,
815
815
  onPatch: (t) => void $(`tune-${e.id}`, async () => u.sceneMonitor?.updateScene({
816
816
  monitorId: e.id,
817
817
  patch: t
@@ -825,4 +825,4 @@ function J({ deviceId: a }) {
825
825
  }) : null;
826
826
  }
827
827
  //#endregion
828
- export { J as SceneMonitorEditor };
828
+ export { Y as SceneMonitorEditor };
package/dist/_stub.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import "./virtualExposes-BgZ5Cn7S.mjs";
2
- import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-BNPFHalU.mjs";
2
+ import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-B3aCdsuR.mjs";
3
3
  import { _ as e, c as t, d as n, h as r, i, l as a, m as o, n as s, p as c, r as l, t as u, u as d, y as f } from "./_virtual_mf___mfe_internal__addon_osd_manager_page__loadShare__react__loadShare__.js-Bs1t18EM.mjs";
4
4
  import { i as p, o as m, r as h, s as g } from "./responsive-DgE6uJQL.mjs";
5
- import { c as _, l as v, u as y } from "./use-device-snapshot-pxGFFbiL.mjs";
5
+ import { d as _, l as v, u as y } from "./use-device-snapshot-Bs7H8rkB.mjs";
6
6
  import { r as b } from "./player-overlays-C16Fbveg.mjs";
7
7
  import { r as ee, t as te } from "./square-fdvKDCKB.mjs";
8
8
  import { t as ne } from "./trash-2-C1RIMmGl.mjs";
@@ -9765,7 +9765,7 @@ function Yc({ url: e, alt: n, open: i, onOpenChange: a }) {
9765
9765
  label: "Reset zoom",
9766
9766
  disabled: o === 1,
9767
9767
  onClick: u,
9768
- children: /* @__PURE__ */ S(_, { className: "h-4 w-4" })
9768
+ children: /* @__PURE__ */ S(v, { className: "h-4 w-4" })
9769
9769
  }),
9770
9770
  /* @__PURE__ */ S(Xc, {
9771
9771
  label: "Close",
@@ -9807,7 +9807,7 @@ function Zc({ trpc: e, deviceId: t }) {
9807
9807
  return o === null ? /* @__PURE__ */ S("span", {
9808
9808
  className: "inline-flex h-7 w-7 items-center justify-center rounded bg-surface-hover text-foreground-subtle",
9809
9809
  title: "No image",
9810
- children: /* @__PURE__ */ S(v, {
9810
+ children: /* @__PURE__ */ S(y, {
9811
9811
  className: "h-4 w-4",
9812
9812
  "aria-hidden": "true"
9813
9813
  })
@@ -9852,7 +9852,7 @@ function Qc({ trpc: e, deviceId: t, deviceName: n }) {
9852
9852
  }) : /* @__PURE__ */ C("div", {
9853
9853
  "data-testid": "image-placeholder",
9854
9854
  className: "flex h-48 w-full flex-col items-center justify-center gap-2 text-foreground-subtle",
9855
- children: [/* @__PURE__ */ S(v, {
9855
+ children: [/* @__PURE__ */ S(y, {
9856
9856
  className: "h-8 w-8",
9857
9857
  "aria-hidden": "true"
9858
9858
  }), /* @__PURE__ */ S("span", {
@@ -15272,7 +15272,7 @@ f(), f();
15272
15272
  //#region ../ui-library/src/composites/device-meta.ts
15273
15273
  var C_ = {
15274
15274
  [T.Camera]: {
15275
- icon: y,
15275
+ icon: _,
15276
15276
  label: "Camera"
15277
15277
  },
15278
15278
  [T.Hub]: {
@@ -15698,7 +15698,7 @@ var P_ = class {
15698
15698
  } catch {}
15699
15699
  }
15700
15700
  };
15701
- f(), new P_(), f(), f(), f(), f(), i(() => import("./MaskShapeCanvas-BEVxAjNq.mjs").then((e) => ({ default: e.MaskShapeCanvas }))), i(() => import("./MotionZonesSettings-v7mdWSJz.mjs").then((e) => ({ default: e.MotionZonesSettings }))), i(() => import("./SceneMonitorEditor-C3lJW1yB.mjs").then((e) => ({ default: e.SceneMonitorEditor }))), i(() => import("./PrivacyMaskSettings-BMx0poHF.mjs").then((e) => ({ default: e.PrivacyMaskSettings })));
15701
+ f(), new P_(), f(), f(), f(), f(), i(() => import("./MaskShapeCanvas-BEVxAjNq.mjs").then((e) => ({ default: e.MaskShapeCanvas }))), i(() => import("./MotionZonesSettings-v7mdWSJz.mjs").then((e) => ({ default: e.MotionZonesSettings }))), i(() => import("./SceneMonitorEditor-D8YJqooy.mjs").then((e) => ({ default: e.SceneMonitorEditor }))), i(() => import("./PrivacyMaskSettings-BMx0poHF.mjs").then((e) => ({ default: e.PrivacyMaskSettings })));
15702
15702
  //#endregion
15703
15703
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils.js
15704
15704
  var F_ = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), I_ = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), L_ = (e) => {
@@ -1,4 +1,4 @@
1
- import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-BNPFHalU.mjs";
1
+ import "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-B3aCdsuR.mjs";
2
2
  //#region \0virtual:mf-localSharedImportMap:__mfe_internal__addon_osd_manager_page
3
3
  var e = {
4
4
  "@camstack/sdk": {
@@ -33,7 +33,7 @@ var e = {
33
33
  },
34
34
  "@camstack/ui-library": {
35
35
  name: "@camstack/ui-library",
36
- version: "1.2.123",
36
+ version: "1.2.124",
37
37
  scope: ["default"],
38
38
  loaded: !1,
39
39
  from: "addon_osd_manager_page",
@@ -81,7 +81,7 @@ async function r() {
81
81
  }
82
82
  },
83
83
  "@camstack/ui-library": {
84
- version: "1.2.123",
84
+ version: "1.2.124",
85
85
  scope: "default",
86
86
  shareConfig: {
87
87
  singleton: !0,
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-BNPFHalU.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_osd_manager_page__remoteEntry_js-B3aCdsuR.mjs";
2
2
  export { t as get, e as init };
@@ -48,46 +48,85 @@ var a = i("camera", [["path", {
48
48
  }], ["path", {
49
49
  d: "M3 3v5h5",
50
50
  key: "1xhq8a"
51
- }]]), c = ["day", "ir"], l = {
51
+ }]]);
52
+ //#endregion
53
+ //#region ../ui-library/src/lib/hub-mount.ts
54
+ r();
55
+ var c = "camstack-mount", l = /^\/(?:[A-Za-z0-9_\-.]+\/)*$/, u = null;
56
+ function d(e) {
57
+ if (e == null || e === "") return null;
58
+ let t = e.endsWith("/") ? e : `${e}/`;
59
+ return !l.test(t) || t.includes("/../") || t.includes("/./") ? null : t;
60
+ }
61
+ function f() {
62
+ if (typeof document > "u") return "/";
63
+ let e = d(document.querySelector(`meta[name="${c}"]`)?.getAttribute("content"));
64
+ if (e !== null) return e;
65
+ if (document.querySelector("base[href]") !== null) try {
66
+ let e = new URL(document.baseURI);
67
+ if (e.origin === window.location.origin) {
68
+ let t = d(e.pathname);
69
+ if (t !== null) return t;
70
+ }
71
+ } catch {}
72
+ return "/";
73
+ }
74
+ function p() {
75
+ return u === null && (u = f()), u;
76
+ }
77
+ function m() {
78
+ return p().replace(/\/$/, "");
79
+ }
80
+ function h(e) {
81
+ return /^[a-z][a-z0-9+.-]*:/i.test(e) || e.startsWith("//");
82
+ }
83
+ function g(e) {
84
+ if (h(e)) return e;
85
+ let t = p(), n = e.replace(/^\/+/, "");
86
+ return t !== "/" && (e === m() || e.startsWith(t)) ? e : `${t}${n}`;
87
+ }
88
+ //#endregion
89
+ //#region ../ui-library/src/composites/cap-settings/scene-monitor-copy.ts
90
+ var _ = ["day", "ir"], v = {
52
91
  day: "Daylight",
53
92
  ir: "Night (IR)",
54
93
  night: "Night",
55
94
  dawn: "Dawn",
56
95
  dusk: "Dusk"
57
96
  };
58
- function u(e) {
59
- return l[e] ?? e;
97
+ function y(e) {
98
+ return v[e] ?? e;
60
99
  }
61
- function d(e) {
62
- let t = new Set(e.coveredConditions), n = c.map((e) => `${u(e)} ${t.has(e) ? "✓" : "✗"}`), r = [...t].filter((e) => !c.some((t) => t === e));
63
- for (let e of r) n.push(`${u(e)} ✓`);
64
- let i = c.filter((e) => !t.has(e));
100
+ function b(e) {
101
+ let t = new Set(e.coveredConditions), n = _.map((e) => `${y(e)} ${t.has(e) ? "✓" : "✗"}`), r = [...t].filter((e) => !_.some((t) => t === e));
102
+ for (let e of r) n.push(`${y(e)} ✓`);
103
+ let i = _.filter((e) => !t.has(e));
65
104
  if (i.length === 0) return n.join(" · ");
66
105
  if (t.size === 0) return `${n.join(" · ")} — nothing captured yet, so this scene is not watching.`;
67
- let a = i.map((e) => u(e).toLowerCase()).join(" and ");
106
+ let a = i.map((e) => y(e).toLowerCase()).join(" and ");
68
107
  return e.onUncoveredCondition === "judge-anyway" ? `${n.join(" · ")} — ${a} judged against the references you do have.` : `${n.join(" · ")} — optional; checks in ${a} are skipped.`;
69
108
  }
70
- function f(e) {
109
+ function x(e) {
71
110
  if (e.suspendedCondition === null) return null;
72
- let t = u(e.suspendedCondition).toLowerCase();
111
+ let t = y(e.suspendedCondition).toLowerCase();
73
112
  return `Paused — nothing was captured in ${t}, so checks are on hold until the light changes back. Capture ${t} if you want it watched around the clock.`;
74
113
  }
75
- var p = {
114
+ var S = {
76
115
  "no-reference-for-condition": "can’t tell — nothing has been captured for this scene yet. Press “Capture daylight” to photograph what normal looks like.",
77
116
  "view-shifted": "can’t tell — the camera view has moved since the reference was captured. Re-capture it.",
78
117
  "no-vision-profile": "can’t tell — the vision model is unreachable, so the change is on hold.",
79
118
  "encoder-model-changed": "can’t tell — the embedding model changed, so the stored references are unreadable. Re-capture them.",
80
119
  "no-snapshot": "can’t tell — this camera did not return a frame."
81
120
  };
82
- function m(e, t) {
121
+ function C(e, t) {
83
122
  if (e.states.length === 0) return "Not armed yet — capture the initial state to start watching.";
84
- if (e.verdict === "unknown") return e.unavailable === null ? "can’t tell right now." : p[e.unavailable];
85
- let n = e.verdict === "diverged" ? e.divergedAt : e.armedAt, r = n === null ? "" : ` for ${v(Math.max(0, t - n))}`;
123
+ if (e.verdict === "unknown") return e.unavailable === null ? "can’t tell right now." : S[e.unavailable];
124
+ let n = e.verdict === "diverged" ? e.divergedAt : e.armedAt, r = n === null ? "" : ` for ${D(Math.max(0, t - n))}`;
86
125
  if (e.latched) return e.verdict === "diverged" ? `CHANGED${r} — press Reset when you have dealt with it.` : `Back to normal, but still flagged as changed${r}. Press Reset to clear it.`;
87
- let i = f(e);
126
+ let i = x(e);
88
127
  return i === null ? e.verdict === "diverged" ? `CHANGED${r}` : `Normal${r}` : i;
89
128
  }
90
- function h(e) {
129
+ function w(e) {
91
130
  return e.states.length === 0 ? {
92
131
  text: "Not armed",
93
132
  tone: "unknown"
@@ -108,11 +147,11 @@ function h(e) {
108
147
  tone: "unknown"
109
148
  };
110
149
  }
111
- var g = .4;
112
- function _(e) {
113
- return e.width * e.height > g;
150
+ var T = .4;
151
+ function E(e) {
152
+ return e.width * e.height > T;
114
153
  }
115
- function v(e) {
154
+ function D(e) {
116
155
  let t = Math.floor(e / 1e3);
117
156
  if (t < 60) return `${t}s`;
118
157
  let n = Math.floor(t / 60);
@@ -122,17 +161,16 @@ function v(e) {
122
161
  }
123
162
  //#endregion
124
163
  //#region ../ui-library/src/hooks/use-device-snapshot.ts
125
- r();
126
- var y = "/addon/snapshot/media";
127
- function b(r, i = {}) {
164
+ var O = "/addon/snapshot/media";
165
+ function k(r, i = {}) {
128
166
  let { width: a, baseUrl: o } = i, [s, c] = t(0);
129
167
  return {
130
168
  src: n(() => {
131
169
  if (r === null || r <= 0) return null;
132
- let e = o === void 0 ? "" : o.replace(/\/+$/, ""), t = new URLSearchParams();
170
+ let e = o === void 0 ? m() : o.replace(/\/+$/, ""), t = new URLSearchParams();
133
171
  a !== void 0 && Number.isInteger(a) && a > 0 && t.set("w", String(a)), s > 0 && (t.set("force", "1"), t.set("r", String(s)));
134
172
  let n = t.toString();
135
- return `${e}${y}/${String(r)}.jpg${n.length > 0 ? `?${n}` : ""}`;
173
+ return `${e}${O}/${String(r)}.jpg${n.length > 0 ? `?${n}` : ""}`;
136
174
  }, [
137
175
  r,
138
176
  a,
@@ -146,4 +184,4 @@ function b(r, i = {}) {
146
184
  };
147
185
  }
148
186
  //#endregion
149
- export { _ as a, s as c, d as i, o as l, c as n, m as o, h as r, u as s, b as t, a as u };
187
+ export { E as a, g as c, a as d, b as i, s as l, _ as n, C as o, w as r, y as s, k as t, o as u };
@@ -2753,7 +2753,7 @@ async function rr(e) {
2753
2753
  }
2754
2754
  }
2755
2755
  async function ir() {
2756
- return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-5Q6_pbgt.mjs")).catch((e) => {
2756
+ return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_osd_manager_page-DDGVZgEx.mjs")).catch((e) => {
2757
2757
  throw tr = void 0, e;
2758
2758
  }), tr;
2759
2759
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-osd-manager",
3
- "version": "0.1.69",
3
+ "version": "0.1.70",
4
4
  "description": "Binds camera on-screen-display slots to live state and recognitions",
5
5
  "keywords": [
6
6
  "camstack",