@camstack/ui-library 1.1.41 → 1.1.43
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.
- package/dist/composites/camera-stream-player.d.ts +2 -2
- package/dist/composites/detection-colors.d.ts +6 -7
- package/dist/composites/device-select-field.d.ts +16 -0
- package/dist/composites/device-select-filter.d.ts +53 -0
- package/dist/composites/event-kind-visuals.d.ts +26 -0
- package/dist/composites/index.d.ts +5 -0
- package/dist/generated/system-hooks.d.ts +0 -2
- package/dist/hooks/use-device-webrtc.d.ts +2 -1
- package/dist/index.cjs +1035 -37
- package/dist/index.js +1026 -38
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8249,6 +8249,30 @@ var ArrowUp = createLucideIcon("arrow-up", [["path", {
|
|
|
8249
8249
|
* This source code is licensed under the ISC license.
|
|
8250
8250
|
* See the LICENSE file in the root directory of this source tree.
|
|
8251
8251
|
*/
|
|
8252
|
+
var Baby = createLucideIcon("baby", [
|
|
8253
|
+
["path", {
|
|
8254
|
+
d: "M10 16c.5.3 1.2.5 2 .5s1.5-.2 2-.5",
|
|
8255
|
+
key: "1u7htd"
|
|
8256
|
+
}],
|
|
8257
|
+
["path", {
|
|
8258
|
+
d: "M15 12h.01",
|
|
8259
|
+
key: "1k8ypt"
|
|
8260
|
+
}],
|
|
8261
|
+
["path", {
|
|
8262
|
+
d: "M19.38 6.813A9 9 0 0 1 20.8 10.2a2 2 0 0 1 0 3.6 9 9 0 0 1-17.6 0 2 2 0 0 1 0-3.6A9 9 0 0 1 12 3c2 0 3.5 1.1 3.5 2.5s-.9 2.5-2 2.5c-.8 0-1.5-.4-1.5-1",
|
|
8263
|
+
key: "11xh7x"
|
|
8264
|
+
}],
|
|
8265
|
+
["path", {
|
|
8266
|
+
d: "M9 12h.01",
|
|
8267
|
+
key: "157uk2"
|
|
8268
|
+
}]
|
|
8269
|
+
]);
|
|
8270
|
+
/**
|
|
8271
|
+
* @license lucide-react v0.576.0 - ISC
|
|
8272
|
+
*
|
|
8273
|
+
* This source code is licensed under the ISC license.
|
|
8274
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
8275
|
+
*/
|
|
8252
8276
|
var Ban = createLucideIcon("ban", [["circle", {
|
|
8253
8277
|
cx: "12",
|
|
8254
8278
|
cy: "12",
|
|
@@ -8458,6 +8482,68 @@ var Bell = createLucideIcon("bell", [["path", {
|
|
|
8458
8482
|
* This source code is licensed under the ISC license.
|
|
8459
8483
|
* See the LICENSE file in the root directory of this source tree.
|
|
8460
8484
|
*/
|
|
8485
|
+
var Bike = createLucideIcon("bike", [
|
|
8486
|
+
["circle", {
|
|
8487
|
+
cx: "18.5",
|
|
8488
|
+
cy: "17.5",
|
|
8489
|
+
r: "3.5",
|
|
8490
|
+
key: "15x4ox"
|
|
8491
|
+
}],
|
|
8492
|
+
["circle", {
|
|
8493
|
+
cx: "5.5",
|
|
8494
|
+
cy: "17.5",
|
|
8495
|
+
r: "3.5",
|
|
8496
|
+
key: "1noe27"
|
|
8497
|
+
}],
|
|
8498
|
+
["circle", {
|
|
8499
|
+
cx: "15",
|
|
8500
|
+
cy: "5",
|
|
8501
|
+
r: "1",
|
|
8502
|
+
key: "19l28e"
|
|
8503
|
+
}],
|
|
8504
|
+
["path", {
|
|
8505
|
+
d: "M12 17.5V14l-3-3 4-3 2 3h2",
|
|
8506
|
+
key: "1npguv"
|
|
8507
|
+
}]
|
|
8508
|
+
]);
|
|
8509
|
+
/**
|
|
8510
|
+
* @license lucide-react v0.576.0 - ISC
|
|
8511
|
+
*
|
|
8512
|
+
* This source code is licensed under the ISC license.
|
|
8513
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
8514
|
+
*/
|
|
8515
|
+
var Bird = createLucideIcon("bird", [
|
|
8516
|
+
["path", {
|
|
8517
|
+
d: "M16 7h.01",
|
|
8518
|
+
key: "1kdx03"
|
|
8519
|
+
}],
|
|
8520
|
+
["path", {
|
|
8521
|
+
d: "M3.4 18H12a8 8 0 0 0 8-8V7a4 4 0 0 0-7.28-2.3L2 20",
|
|
8522
|
+
key: "oj1oa8"
|
|
8523
|
+
}],
|
|
8524
|
+
["path", {
|
|
8525
|
+
d: "m20 7 2 .5-2 .5",
|
|
8526
|
+
key: "12nv4d"
|
|
8527
|
+
}],
|
|
8528
|
+
["path", {
|
|
8529
|
+
d: "M10 18v3",
|
|
8530
|
+
key: "1yea0a"
|
|
8531
|
+
}],
|
|
8532
|
+
["path", {
|
|
8533
|
+
d: "M14 17.75V21",
|
|
8534
|
+
key: "1pymcb"
|
|
8535
|
+
}],
|
|
8536
|
+
["path", {
|
|
8537
|
+
d: "M7 18a6 6 0 0 0 3.84-10.61",
|
|
8538
|
+
key: "1npnn0"
|
|
8539
|
+
}]
|
|
8540
|
+
]);
|
|
8541
|
+
/**
|
|
8542
|
+
* @license lucide-react v0.576.0 - ISC
|
|
8543
|
+
*
|
|
8544
|
+
* This source code is licensed under the ISC license.
|
|
8545
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
8546
|
+
*/
|
|
8461
8547
|
var Blinds = createLucideIcon("blinds", [
|
|
8462
8548
|
["path", {
|
|
8463
8549
|
d: "M3 3h18",
|
|
@@ -8614,6 +8700,46 @@ var Bug = createLucideIcon("bug", [
|
|
|
8614
8700
|
* This source code is licensed under the ISC license.
|
|
8615
8701
|
* See the LICENSE file in the root directory of this source tree.
|
|
8616
8702
|
*/
|
|
8703
|
+
var Bus = createLucideIcon("bus", [
|
|
8704
|
+
["path", {
|
|
8705
|
+
d: "M8 6v6",
|
|
8706
|
+
key: "18i7km"
|
|
8707
|
+
}],
|
|
8708
|
+
["path", {
|
|
8709
|
+
d: "M15 6v6",
|
|
8710
|
+
key: "1sg6z9"
|
|
8711
|
+
}],
|
|
8712
|
+
["path", {
|
|
8713
|
+
d: "M2 12h19.6",
|
|
8714
|
+
key: "de5uta"
|
|
8715
|
+
}],
|
|
8716
|
+
["path", {
|
|
8717
|
+
d: "M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3",
|
|
8718
|
+
key: "1wwztk"
|
|
8719
|
+
}],
|
|
8720
|
+
["circle", {
|
|
8721
|
+
cx: "7",
|
|
8722
|
+
cy: "18",
|
|
8723
|
+
r: "2",
|
|
8724
|
+
key: "19iecd"
|
|
8725
|
+
}],
|
|
8726
|
+
["path", {
|
|
8727
|
+
d: "M9 18h5",
|
|
8728
|
+
key: "lrx6i"
|
|
8729
|
+
}],
|
|
8730
|
+
["circle", {
|
|
8731
|
+
cx: "16",
|
|
8732
|
+
cy: "18",
|
|
8733
|
+
r: "2",
|
|
8734
|
+
key: "1v4tcr"
|
|
8735
|
+
}]
|
|
8736
|
+
]);
|
|
8737
|
+
/**
|
|
8738
|
+
* @license lucide-react v0.576.0 - ISC
|
|
8739
|
+
*
|
|
8740
|
+
* This source code is licensed under the ISC license.
|
|
8741
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
8742
|
+
*/
|
|
8617
8743
|
var Camera = createLucideIcon("camera", [["path", {
|
|
8618
8744
|
d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",
|
|
8619
8745
|
key: "18u6gg"
|
|
@@ -8629,6 +8755,34 @@ var Camera = createLucideIcon("camera", [["path", {
|
|
|
8629
8755
|
* This source code is licensed under the ISC license.
|
|
8630
8756
|
* See the LICENSE file in the root directory of this source tree.
|
|
8631
8757
|
*/
|
|
8758
|
+
var Car = createLucideIcon("car", [
|
|
8759
|
+
["path", {
|
|
8760
|
+
d: "M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2",
|
|
8761
|
+
key: "5owen"
|
|
8762
|
+
}],
|
|
8763
|
+
["circle", {
|
|
8764
|
+
cx: "7",
|
|
8765
|
+
cy: "17",
|
|
8766
|
+
r: "2",
|
|
8767
|
+
key: "u2ysq9"
|
|
8768
|
+
}],
|
|
8769
|
+
["path", {
|
|
8770
|
+
d: "M9 17h6",
|
|
8771
|
+
key: "r8uit2"
|
|
8772
|
+
}],
|
|
8773
|
+
["circle", {
|
|
8774
|
+
cx: "17",
|
|
8775
|
+
cy: "17",
|
|
8776
|
+
r: "2",
|
|
8777
|
+
key: "axvx0g"
|
|
8778
|
+
}]
|
|
8779
|
+
]);
|
|
8780
|
+
/**
|
|
8781
|
+
* @license lucide-react v0.576.0 - ISC
|
|
8782
|
+
*
|
|
8783
|
+
* This source code is licensed under the ISC license.
|
|
8784
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
8785
|
+
*/
|
|
8632
8786
|
var Cast = createLucideIcon("cast", [
|
|
8633
8787
|
["path", {
|
|
8634
8788
|
d: "M2 8V6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6",
|
|
@@ -8656,6 +8810,30 @@ var Cast = createLucideIcon("cast", [
|
|
|
8656
8810
|
* This source code is licensed under the ISC license.
|
|
8657
8811
|
* See the LICENSE file in the root directory of this source tree.
|
|
8658
8812
|
*/
|
|
8813
|
+
var Cat = createLucideIcon("cat", [
|
|
8814
|
+
["path", {
|
|
8815
|
+
d: "M12 5c.67 0 1.35.09 2 .26 1.78-2 5.03-2.84 6.42-2.26 1.4.58-.42 7-.42 7 .57 1.07 1 2.24 1 3.44C21 17.9 16.97 21 12 21s-9-3-9-7.56c0-1.25.5-2.4 1-3.44 0 0-1.89-6.42-.5-7 1.39-.58 4.72.23 6.5 2.23A9.04 9.04 0 0 1 12 5Z",
|
|
8816
|
+
key: "x6xyqk"
|
|
8817
|
+
}],
|
|
8818
|
+
["path", {
|
|
8819
|
+
d: "M8 14v.5",
|
|
8820
|
+
key: "1nzgdb"
|
|
8821
|
+
}],
|
|
8822
|
+
["path", {
|
|
8823
|
+
d: "M16 14v.5",
|
|
8824
|
+
key: "1lajdz"
|
|
8825
|
+
}],
|
|
8826
|
+
["path", {
|
|
8827
|
+
d: "M11.25 16.25h1.5L12 17l-.75-.75Z",
|
|
8828
|
+
key: "12kq1m"
|
|
8829
|
+
}]
|
|
8830
|
+
]);
|
|
8831
|
+
/**
|
|
8832
|
+
* @license lucide-react v0.576.0 - ISC
|
|
8833
|
+
*
|
|
8834
|
+
* This source code is licensed under the ISC license.
|
|
8835
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
8836
|
+
*/
|
|
8659
8837
|
var Check = createLucideIcon("check", [["path", {
|
|
8660
8838
|
d: "M20 6 9 17l-5-5",
|
|
8661
8839
|
key: "1gmf2c"
|
|
@@ -9049,6 +9227,74 @@ var Cloud = createLucideIcon("cloud", [["path", {
|
|
|
9049
9227
|
* This source code is licensed under the ISC license.
|
|
9050
9228
|
* See the LICENSE file in the root directory of this source tree.
|
|
9051
9229
|
*/
|
|
9230
|
+
var Cog = createLucideIcon("cog", [
|
|
9231
|
+
["path", {
|
|
9232
|
+
d: "M11 10.27 7 3.34",
|
|
9233
|
+
key: "16pf9h"
|
|
9234
|
+
}],
|
|
9235
|
+
["path", {
|
|
9236
|
+
d: "m11 13.73-4 6.93",
|
|
9237
|
+
key: "794ttg"
|
|
9238
|
+
}],
|
|
9239
|
+
["path", {
|
|
9240
|
+
d: "M12 22v-2",
|
|
9241
|
+
key: "1osdcq"
|
|
9242
|
+
}],
|
|
9243
|
+
["path", {
|
|
9244
|
+
d: "M12 2v2",
|
|
9245
|
+
key: "tus03m"
|
|
9246
|
+
}],
|
|
9247
|
+
["path", {
|
|
9248
|
+
d: "M14 12h8",
|
|
9249
|
+
key: "4f43i9"
|
|
9250
|
+
}],
|
|
9251
|
+
["path", {
|
|
9252
|
+
d: "m17 20.66-1-1.73",
|
|
9253
|
+
key: "eq3orb"
|
|
9254
|
+
}],
|
|
9255
|
+
["path", {
|
|
9256
|
+
d: "m17 3.34-1 1.73",
|
|
9257
|
+
key: "2wel8s"
|
|
9258
|
+
}],
|
|
9259
|
+
["path", {
|
|
9260
|
+
d: "M2 12h2",
|
|
9261
|
+
key: "1t8f8n"
|
|
9262
|
+
}],
|
|
9263
|
+
["path", {
|
|
9264
|
+
d: "m20.66 17-1.73-1",
|
|
9265
|
+
key: "sg0v6f"
|
|
9266
|
+
}],
|
|
9267
|
+
["path", {
|
|
9268
|
+
d: "m20.66 7-1.73 1",
|
|
9269
|
+
key: "1ow05n"
|
|
9270
|
+
}],
|
|
9271
|
+
["path", {
|
|
9272
|
+
d: "m3.34 17 1.73-1",
|
|
9273
|
+
key: "nuk764"
|
|
9274
|
+
}],
|
|
9275
|
+
["path", {
|
|
9276
|
+
d: "m3.34 7 1.73 1",
|
|
9277
|
+
key: "1ulond"
|
|
9278
|
+
}],
|
|
9279
|
+
["circle", {
|
|
9280
|
+
cx: "12",
|
|
9281
|
+
cy: "12",
|
|
9282
|
+
r: "2",
|
|
9283
|
+
key: "1c9p78"
|
|
9284
|
+
}],
|
|
9285
|
+
["circle", {
|
|
9286
|
+
cx: "12",
|
|
9287
|
+
cy: "12",
|
|
9288
|
+
r: "8",
|
|
9289
|
+
key: "46899m"
|
|
9290
|
+
}]
|
|
9291
|
+
]);
|
|
9292
|
+
/**
|
|
9293
|
+
* @license lucide-react v0.576.0 - ISC
|
|
9294
|
+
*
|
|
9295
|
+
* This source code is licensed under the ISC license.
|
|
9296
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
9297
|
+
*/
|
|
9052
9298
|
var CopyPlus = createLucideIcon("copy-plus", [
|
|
9053
9299
|
["line", {
|
|
9054
9300
|
x1: "15",
|
|
@@ -9239,6 +9485,34 @@ var Database = createLucideIcon("database", [
|
|
|
9239
9485
|
* This source code is licensed under the ISC license.
|
|
9240
9486
|
* See the LICENSE file in the root directory of this source tree.
|
|
9241
9487
|
*/
|
|
9488
|
+
var Dog = createLucideIcon("dog", [
|
|
9489
|
+
["path", {
|
|
9490
|
+
d: "M11.25 16.25h1.5L12 17z",
|
|
9491
|
+
key: "w7jh35"
|
|
9492
|
+
}],
|
|
9493
|
+
["path", {
|
|
9494
|
+
d: "M16 14v.5",
|
|
9495
|
+
key: "1lajdz"
|
|
9496
|
+
}],
|
|
9497
|
+
["path", {
|
|
9498
|
+
d: "M4.42 11.247A13.152 13.152 0 0 0 4 14.556C4 18.728 7.582 21 12 21s8-2.272 8-6.444a11.702 11.702 0 0 0-.493-3.309",
|
|
9499
|
+
key: "u7s9ue"
|
|
9500
|
+
}],
|
|
9501
|
+
["path", {
|
|
9502
|
+
d: "M8 14v.5",
|
|
9503
|
+
key: "1nzgdb"
|
|
9504
|
+
}],
|
|
9505
|
+
["path", {
|
|
9506
|
+
d: "M8.5 8.5c-.384 1.05-1.083 2.028-2.344 2.5-1.931.722-3.576-.297-3.656-1-.113-.994 1.177-6.53 4-7 1.923-.321 3.651.845 3.651 2.235A7.497 7.497 0 0 1 14 5.277c0-1.39 1.844-2.598 3.767-2.277 2.823.47 4.113 6.006 4 7-.08.703-1.725 1.722-3.656 1-1.261-.472-1.855-1.45-2.239-2.5",
|
|
9507
|
+
key: "v8hric"
|
|
9508
|
+
}]
|
|
9509
|
+
]);
|
|
9510
|
+
/**
|
|
9511
|
+
* @license lucide-react v0.576.0 - ISC
|
|
9512
|
+
*
|
|
9513
|
+
* This source code is licensed under the ISC license.
|
|
9514
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
9515
|
+
*/
|
|
9242
9516
|
var DoorClosed = createLucideIcon("door-closed", [
|
|
9243
9517
|
["path", {
|
|
9244
9518
|
d: "M10 12h.01",
|
|
@@ -9673,6 +9947,26 @@ var GripHorizontal = createLucideIcon("grip-horizontal", [
|
|
|
9673
9947
|
* This source code is licensed under the ISC license.
|
|
9674
9948
|
* See the LICENSE file in the root directory of this source tree.
|
|
9675
9949
|
*/
|
|
9950
|
+
var Hammer = createLucideIcon("hammer", [
|
|
9951
|
+
["path", {
|
|
9952
|
+
d: "m15 12-9.373 9.373a1 1 0 0 1-3.001-3L12 9",
|
|
9953
|
+
key: "1hayfq"
|
|
9954
|
+
}],
|
|
9955
|
+
["path", {
|
|
9956
|
+
d: "m18 15 4-4",
|
|
9957
|
+
key: "16gjal"
|
|
9958
|
+
}],
|
|
9959
|
+
["path", {
|
|
9960
|
+
d: "m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172v-.344a2 2 0 0 0-.586-1.414l-1.657-1.657A6 6 0 0 0 12.516 3H9l1.243 1.243A6 6 0 0 1 12 8.485V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5",
|
|
9961
|
+
key: "15ts47"
|
|
9962
|
+
}]
|
|
9963
|
+
]);
|
|
9964
|
+
/**
|
|
9965
|
+
* @license lucide-react v0.576.0 - ISC
|
|
9966
|
+
*
|
|
9967
|
+
* This source code is licensed under the ISC license.
|
|
9968
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
9969
|
+
*/
|
|
9676
9970
|
var HardDrive = createLucideIcon("hard-drive", [
|
|
9677
9971
|
["path", {
|
|
9678
9972
|
d: "M10 16h.01",
|
|
@@ -9849,6 +10143,38 @@ var Info = createLucideIcon("info", [
|
|
|
9849
10143
|
* This source code is licensed under the ISC license.
|
|
9850
10144
|
* See the LICENSE file in the root directory of this source tree.
|
|
9851
10145
|
*/
|
|
10146
|
+
var Laugh = createLucideIcon("laugh", [
|
|
10147
|
+
["circle", {
|
|
10148
|
+
cx: "12",
|
|
10149
|
+
cy: "12",
|
|
10150
|
+
r: "10",
|
|
10151
|
+
key: "1mglay"
|
|
10152
|
+
}],
|
|
10153
|
+
["path", {
|
|
10154
|
+
d: "M18 13a6 6 0 0 1-6 5 6 6 0 0 1-6-5h12Z",
|
|
10155
|
+
key: "b2q4dd"
|
|
10156
|
+
}],
|
|
10157
|
+
["line", {
|
|
10158
|
+
x1: "9",
|
|
10159
|
+
x2: "9.01",
|
|
10160
|
+
y1: "9",
|
|
10161
|
+
y2: "9",
|
|
10162
|
+
key: "yxxnd0"
|
|
10163
|
+
}],
|
|
10164
|
+
["line", {
|
|
10165
|
+
x1: "15",
|
|
10166
|
+
x2: "15.01",
|
|
10167
|
+
y1: "9",
|
|
10168
|
+
y2: "9",
|
|
10169
|
+
key: "1p4y9e"
|
|
10170
|
+
}]
|
|
10171
|
+
]);
|
|
10172
|
+
/**
|
|
10173
|
+
* @license lucide-react v0.576.0 - ISC
|
|
10174
|
+
*
|
|
10175
|
+
* This source code is licensed under the ISC license.
|
|
10176
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
10177
|
+
*/
|
|
9852
10178
|
var LayoutGrid = createLucideIcon("layout-grid", [
|
|
9853
10179
|
["rect", {
|
|
9854
10180
|
width: "7",
|
|
@@ -10452,6 +10778,30 @@ var Network = createLucideIcon("network", [
|
|
|
10452
10778
|
* This source code is licensed under the ISC license.
|
|
10453
10779
|
* See the LICENSE file in the root directory of this source tree.
|
|
10454
10780
|
*/
|
|
10781
|
+
var Package = createLucideIcon("package", [
|
|
10782
|
+
["path", {
|
|
10783
|
+
d: "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 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.73z",
|
|
10784
|
+
key: "1a0edw"
|
|
10785
|
+
}],
|
|
10786
|
+
["path", {
|
|
10787
|
+
d: "M12 22V12",
|
|
10788
|
+
key: "d0xqtd"
|
|
10789
|
+
}],
|
|
10790
|
+
["polyline", {
|
|
10791
|
+
points: "3.29 7 12 12 20.71 7",
|
|
10792
|
+
key: "ousv84"
|
|
10793
|
+
}],
|
|
10794
|
+
["path", {
|
|
10795
|
+
d: "m7.5 4.27 9 5.15",
|
|
10796
|
+
key: "1c824w"
|
|
10797
|
+
}]
|
|
10798
|
+
]);
|
|
10799
|
+
/**
|
|
10800
|
+
* @license lucide-react v0.576.0 - ISC
|
|
10801
|
+
*
|
|
10802
|
+
* This source code is licensed under the ISC license.
|
|
10803
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
10804
|
+
*/
|
|
10455
10805
|
var Pause = createLucideIcon("pause", [["rect", {
|
|
10456
10806
|
x: "14",
|
|
10457
10807
|
y: "3",
|
|
@@ -10516,6 +10866,16 @@ var Pencil = createLucideIcon("pencil", [["path", {
|
|
|
10516
10866
|
* This source code is licensed under the ISC license.
|
|
10517
10867
|
* See the LICENSE file in the root directory of this source tree.
|
|
10518
10868
|
*/
|
|
10869
|
+
var Phone = createLucideIcon("phone", [["path", {
|
|
10870
|
+
d: "M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384",
|
|
10871
|
+
key: "9njp5v"
|
|
10872
|
+
}]]);
|
|
10873
|
+
/**
|
|
10874
|
+
* @license lucide-react v0.576.0 - ISC
|
|
10875
|
+
*
|
|
10876
|
+
* This source code is licensed under the ISC license.
|
|
10877
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
10878
|
+
*/
|
|
10519
10879
|
var Pipette = createLucideIcon("pipette", [
|
|
10520
10880
|
["path", {
|
|
10521
10881
|
d: "m12 9-8.414 8.414A2 2 0 0 0 3 18.828v1.344a2 2 0 0 1-.586 1.414A2 2 0 0 1 3.828 21h1.344a2 2 0 0 0 1.414-.586L15 12",
|
|
@@ -10536,6 +10896,16 @@ var Pipette = createLucideIcon("pipette", [
|
|
|
10536
10896
|
* This source code is licensed under the ISC license.
|
|
10537
10897
|
* See the LICENSE file in the root directory of this source tree.
|
|
10538
10898
|
*/
|
|
10899
|
+
var Plane = createLucideIcon("plane", [["path", {
|
|
10900
|
+
d: "M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z",
|
|
10901
|
+
key: "1v9wt8"
|
|
10902
|
+
}]]);
|
|
10903
|
+
/**
|
|
10904
|
+
* @license lucide-react v0.576.0 - ISC
|
|
10905
|
+
*
|
|
10906
|
+
* This source code is licensed under the ISC license.
|
|
10907
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
10908
|
+
*/
|
|
10539
10909
|
var Play = createLucideIcon("play", [["path", {
|
|
10540
10910
|
d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",
|
|
10541
10911
|
key: "10ikf1"
|
|
@@ -10810,6 +11180,26 @@ var RotateCw = createLucideIcon("rotate-cw", [["path", {
|
|
|
10810
11180
|
* This source code is licensed under the ISC license.
|
|
10811
11181
|
* See the LICENSE file in the root directory of this source tree.
|
|
10812
11182
|
*/
|
|
11183
|
+
var Sailboat = createLucideIcon("sailboat", [
|
|
11184
|
+
["path", {
|
|
11185
|
+
d: "M10 2v15",
|
|
11186
|
+
key: "1qf71f"
|
|
11187
|
+
}],
|
|
11188
|
+
["path", {
|
|
11189
|
+
d: "M7 22a4 4 0 0 1-4-4 1 1 0 0 1 1-1h16a1 1 0 0 1 1 1 4 4 0 0 1-4 4z",
|
|
11190
|
+
key: "1pxcvx"
|
|
11191
|
+
}],
|
|
11192
|
+
["path", {
|
|
11193
|
+
d: "M9.159 2.46a1 1 0 0 1 1.521-.193l9.977 8.98A1 1 0 0 1 20 13H4a1 1 0 0 1-.824-1.567z",
|
|
11194
|
+
key: "5oog16"
|
|
11195
|
+
}]
|
|
11196
|
+
]);
|
|
11197
|
+
/**
|
|
11198
|
+
* @license lucide-react v0.576.0 - ISC
|
|
11199
|
+
*
|
|
11200
|
+
* This source code is licensed under the ISC license.
|
|
11201
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11202
|
+
*/
|
|
10813
11203
|
var Save = createLucideIcon("save", [
|
|
10814
11204
|
["path", {
|
|
10815
11205
|
d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",
|
|
@@ -11475,6 +11865,22 @@ var Table2 = createLucideIcon("table-2", [["path", {
|
|
|
11475
11865
|
* This source code is licensed under the ISC license.
|
|
11476
11866
|
* See the LICENSE file in the root directory of this source tree.
|
|
11477
11867
|
*/
|
|
11868
|
+
var Tag = createLucideIcon("tag", [["path", {
|
|
11869
|
+
d: "M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z",
|
|
11870
|
+
key: "vktsd0"
|
|
11871
|
+
}], ["circle", {
|
|
11872
|
+
cx: "7.5",
|
|
11873
|
+
cy: "7.5",
|
|
11874
|
+
r: ".5",
|
|
11875
|
+
fill: "currentColor",
|
|
11876
|
+
key: "kqv944"
|
|
11877
|
+
}]]);
|
|
11878
|
+
/**
|
|
11879
|
+
* @license lucide-react v0.576.0 - ISC
|
|
11880
|
+
*
|
|
11881
|
+
* This source code is licensed under the ISC license.
|
|
11882
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11883
|
+
*/
|
|
11478
11884
|
var Target = createLucideIcon("target", [
|
|
11479
11885
|
["circle", {
|
|
11480
11886
|
cx: "12",
|
|
@@ -11530,6 +11936,25 @@ var ToggleLeft = createLucideIcon("toggle-left", [["circle", {
|
|
|
11530
11936
|
* This source code is licensed under the ISC license.
|
|
11531
11937
|
* See the LICENSE file in the root directory of this source tree.
|
|
11532
11938
|
*/
|
|
11939
|
+
var ToggleRight = createLucideIcon("toggle-right", [["circle", {
|
|
11940
|
+
cx: "15",
|
|
11941
|
+
cy: "12",
|
|
11942
|
+
r: "3",
|
|
11943
|
+
key: "1afu0r"
|
|
11944
|
+
}], ["rect", {
|
|
11945
|
+
width: "20",
|
|
11946
|
+
height: "14",
|
|
11947
|
+
x: "2",
|
|
11948
|
+
y: "5",
|
|
11949
|
+
rx: "7",
|
|
11950
|
+
key: "g7kal2"
|
|
11951
|
+
}]]);
|
|
11952
|
+
/**
|
|
11953
|
+
* @license lucide-react v0.576.0 - ISC
|
|
11954
|
+
*
|
|
11955
|
+
* This source code is licensed under the ISC license.
|
|
11956
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11957
|
+
*/
|
|
11533
11958
|
var Tractor = createLucideIcon("tractor", [
|
|
11534
11959
|
["path", {
|
|
11535
11960
|
d: "m10 11 11 .9a1 1 0 0 1 .8 1.1l-.665 4.158a1 1 0 0 1-.988.842H20",
|
|
@@ -11578,6 +12003,38 @@ var Tractor = createLucideIcon("tractor", [
|
|
|
11578
12003
|
* This source code is licensed under the ISC license.
|
|
11579
12004
|
* See the LICENSE file in the root directory of this source tree.
|
|
11580
12005
|
*/
|
|
12006
|
+
var TrainFront = createLucideIcon("train-front", [
|
|
12007
|
+
["path", {
|
|
12008
|
+
d: "M8 3.1V7a4 4 0 0 0 8 0V3.1",
|
|
12009
|
+
key: "1v71zp"
|
|
12010
|
+
}],
|
|
12011
|
+
["path", {
|
|
12012
|
+
d: "m9 15-1-1",
|
|
12013
|
+
key: "1yrq24"
|
|
12014
|
+
}],
|
|
12015
|
+
["path", {
|
|
12016
|
+
d: "m15 15 1-1",
|
|
12017
|
+
key: "1t0d6s"
|
|
12018
|
+
}],
|
|
12019
|
+
["path", {
|
|
12020
|
+
d: "M9 19c-2.8 0-5-2.2-5-5v-4a8 8 0 0 1 16 0v4c0 2.8-2.2 5-5 5Z",
|
|
12021
|
+
key: "1p0hjs"
|
|
12022
|
+
}],
|
|
12023
|
+
["path", {
|
|
12024
|
+
d: "m8 19-2 3",
|
|
12025
|
+
key: "13i0xs"
|
|
12026
|
+
}],
|
|
12027
|
+
["path", {
|
|
12028
|
+
d: "m16 19 2 3",
|
|
12029
|
+
key: "xo31yx"
|
|
12030
|
+
}]
|
|
12031
|
+
]);
|
|
12032
|
+
/**
|
|
12033
|
+
* @license lucide-react v0.576.0 - ISC
|
|
12034
|
+
*
|
|
12035
|
+
* This source code is licensed under the ISC license.
|
|
12036
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12037
|
+
*/
|
|
11581
12038
|
var Trash2 = createLucideIcon("trash-2", [
|
|
11582
12039
|
["path", {
|
|
11583
12040
|
d: "M10 11v6",
|
|
@@ -11652,6 +12109,38 @@ var TriangleAlert = createLucideIcon("triangle-alert", [
|
|
|
11652
12109
|
* This source code is licensed under the ISC license.
|
|
11653
12110
|
* See the LICENSE file in the root directory of this source tree.
|
|
11654
12111
|
*/
|
|
12112
|
+
var Truck = createLucideIcon("truck", [
|
|
12113
|
+
["path", {
|
|
12114
|
+
d: "M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2",
|
|
12115
|
+
key: "wrbu53"
|
|
12116
|
+
}],
|
|
12117
|
+
["path", {
|
|
12118
|
+
d: "M15 18H9",
|
|
12119
|
+
key: "1lyqi6"
|
|
12120
|
+
}],
|
|
12121
|
+
["path", {
|
|
12122
|
+
d: "M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14",
|
|
12123
|
+
key: "lysw3i"
|
|
12124
|
+
}],
|
|
12125
|
+
["circle", {
|
|
12126
|
+
cx: "17",
|
|
12127
|
+
cy: "18",
|
|
12128
|
+
r: "2",
|
|
12129
|
+
key: "332jqn"
|
|
12130
|
+
}],
|
|
12131
|
+
["circle", {
|
|
12132
|
+
cx: "7",
|
|
12133
|
+
cy: "18",
|
|
12134
|
+
r: "2",
|
|
12135
|
+
key: "19iecd"
|
|
12136
|
+
}]
|
|
12137
|
+
]);
|
|
12138
|
+
/**
|
|
12139
|
+
* @license lucide-react v0.576.0 - ISC
|
|
12140
|
+
*
|
|
12141
|
+
* This source code is licensed under the ISC license.
|
|
12142
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12143
|
+
*/
|
|
11655
12144
|
var Type = createLucideIcon("type", [
|
|
11656
12145
|
["path", {
|
|
11657
12146
|
d: "M12 4v16",
|
|
@@ -11702,6 +12191,69 @@ var Upload = createLucideIcon("upload", [
|
|
|
11702
12191
|
* This source code is licensed under the ISC license.
|
|
11703
12192
|
* See the LICENSE file in the root directory of this source tree.
|
|
11704
12193
|
*/
|
|
12194
|
+
var UserCheck = createLucideIcon("user-check", [
|
|
12195
|
+
["path", {
|
|
12196
|
+
d: "m16 11 2 2 4-4",
|
|
12197
|
+
key: "9rsbq5"
|
|
12198
|
+
}],
|
|
12199
|
+
["path", {
|
|
12200
|
+
d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",
|
|
12201
|
+
key: "1yyitq"
|
|
12202
|
+
}],
|
|
12203
|
+
["circle", {
|
|
12204
|
+
cx: "9",
|
|
12205
|
+
cy: "7",
|
|
12206
|
+
r: "4",
|
|
12207
|
+
key: "nufk8"
|
|
12208
|
+
}]
|
|
12209
|
+
]);
|
|
12210
|
+
/**
|
|
12211
|
+
* @license lucide-react v0.576.0 - ISC
|
|
12212
|
+
*
|
|
12213
|
+
* This source code is licensed under the ISC license.
|
|
12214
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12215
|
+
*/
|
|
12216
|
+
var User = createLucideIcon("user", [["path", {
|
|
12217
|
+
d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",
|
|
12218
|
+
key: "975kel"
|
|
12219
|
+
}], ["circle", {
|
|
12220
|
+
cx: "12",
|
|
12221
|
+
cy: "7",
|
|
12222
|
+
r: "4",
|
|
12223
|
+
key: "17ys0d"
|
|
12224
|
+
}]]);
|
|
12225
|
+
/**
|
|
12226
|
+
* @license lucide-react v0.576.0 - ISC
|
|
12227
|
+
*
|
|
12228
|
+
* This source code is licensed under the ISC license.
|
|
12229
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12230
|
+
*/
|
|
12231
|
+
var Users = createLucideIcon("users", [
|
|
12232
|
+
["path", {
|
|
12233
|
+
d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",
|
|
12234
|
+
key: "1yyitq"
|
|
12235
|
+
}],
|
|
12236
|
+
["path", {
|
|
12237
|
+
d: "M16 3.128a4 4 0 0 1 0 7.744",
|
|
12238
|
+
key: "16gr8j"
|
|
12239
|
+
}],
|
|
12240
|
+
["path", {
|
|
12241
|
+
d: "M22 21v-2a4 4 0 0 0-3-3.87",
|
|
12242
|
+
key: "kshegd"
|
|
12243
|
+
}],
|
|
12244
|
+
["circle", {
|
|
12245
|
+
cx: "9",
|
|
12246
|
+
cy: "7",
|
|
12247
|
+
r: "4",
|
|
12248
|
+
key: "nufk8"
|
|
12249
|
+
}]
|
|
12250
|
+
]);
|
|
12251
|
+
/**
|
|
12252
|
+
* @license lucide-react v0.576.0 - ISC
|
|
12253
|
+
*
|
|
12254
|
+
* This source code is licensed under the ISC license.
|
|
12255
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
12256
|
+
*/
|
|
11705
12257
|
var UtensilsCrossed = createLucideIcon("utensils-crossed", [
|
|
11706
12258
|
["path", {
|
|
11707
12259
|
d: "m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8",
|
|
@@ -17135,8 +17687,6 @@ var useAddonsListFrameworkPackages = trpc.addons.listFrameworkPackages.useQuery;
|
|
|
17135
17687
|
var useAddonsListCapabilityProviders = trpc.addons.listCapabilityProviders.useQuery;
|
|
17136
17688
|
/** Generated alias around `trpc.addons.setCapabilityProviderEnabled.useMutation`. */
|
|
17137
17689
|
var useAddonsSetCapabilityProviderEnabled = trpc.addons.setCapabilityProviderEnabled.useMutation;
|
|
17138
|
-
/** Generated alias around `trpc.addons.updateFrameworkPackage.useMutation`. */
|
|
17139
|
-
var useAddonsUpdateFrameworkPackage = trpc.addons.updateFrameworkPackage.useMutation;
|
|
17140
17690
|
/** Generated alias around `trpc.addons.getVersions.useQuery`. */
|
|
17141
17691
|
var useAddonsGetVersions = trpc.addons.getVersions.useQuery;
|
|
17142
17692
|
/** Generated alias around `trpc.addons.restartAddon.useMutation`. */
|
|
@@ -30827,28 +31377,28 @@ function PipelineBuilder({ schema, steps, onChange, templates, selectedTemplateI
|
|
|
30827
31377
|
//#endregion
|
|
30828
31378
|
//#region src/composites/detection-colors.ts
|
|
30829
31379
|
/**
|
|
30830
|
-
* Detection class colors —
|
|
31380
|
+
* Detection class colors — a thin adapter over the SINGLE event-kind
|
|
31381
|
+
* taxonomy dictionary in `@camstack/types` (`EVENT_TAXONOMY`). Colors are no
|
|
31382
|
+
* longer duplicated here; this module only adds the UI-only classes the
|
|
31383
|
+
* taxonomy doesn't model (face / plate) and the deterministic hash fallback.
|
|
30831
31384
|
*
|
|
30832
|
-
* Used by: DetectionCanvas
|
|
30833
|
-
*
|
|
31385
|
+
* Used by: DetectionCanvas / DetectionResultTree / DetectionOverlay (UI),
|
|
31386
|
+
* and any other place that visualizes detection classes.
|
|
30834
31387
|
*/
|
|
30835
|
-
/**
|
|
30836
|
-
var
|
|
30837
|
-
person: "#3b82f6",
|
|
30838
|
-
vehicle: "#f59e0b",
|
|
30839
|
-
animal: "#22c55e",
|
|
31388
|
+
/** UI-only classes not modelled in the event taxonomy (sub-detections). */
|
|
31389
|
+
var UI_ONLY_COLORS = {
|
|
30840
31390
|
face: "#a855f7",
|
|
30841
|
-
plate: "#ec4899"
|
|
30842
|
-
bird: "#14b8a6",
|
|
30843
|
-
dog: "#84cc16",
|
|
30844
|
-
cat: "#f97316",
|
|
30845
|
-
car: "#f59e0b",
|
|
30846
|
-
truck: "#d97706",
|
|
30847
|
-
bus: "#b45309",
|
|
30848
|
-
motorcycle: "#eab308",
|
|
30849
|
-
bicycle: "#ca8a04",
|
|
30850
|
-
motion: "#facc15"
|
|
31391
|
+
plate: "#ec4899"
|
|
30851
31392
|
};
|
|
31393
|
+
/**
|
|
31394
|
+
* Fixed colors for known detection classes — derived from the taxonomy
|
|
31395
|
+
* (every detection/motion kind) plus the UI-only face/plate classes. Kept as
|
|
31396
|
+
* a named export for back-compat with existing consumers.
|
|
31397
|
+
*/
|
|
31398
|
+
var CLASS_COLORS = Object.freeze({
|
|
31399
|
+
...Object.fromEntries(Object.values(_camstack_types.EVENT_TAXONOMY).filter((e) => e.category === "detection" || e.kind === "motion").map((e) => [e.kind, e.color])),
|
|
31400
|
+
...UI_ONLY_COLORS
|
|
31401
|
+
});
|
|
30852
31402
|
/** Fallback color palette for unknown classes (deterministic hash-based) */
|
|
30853
31403
|
var FALLBACK_PALETTE = [
|
|
30854
31404
|
"#ef4444",
|
|
@@ -30863,19 +31413,131 @@ var FALLBACK_PALETTE = [
|
|
|
30863
31413
|
"#059669"
|
|
30864
31414
|
];
|
|
30865
31415
|
/** Primary/default color when nothing else matches */
|
|
30866
|
-
var DEFAULT_COLOR =
|
|
31416
|
+
var DEFAULT_COLOR = _camstack_types.DEFAULT_EVENT_COLOR;
|
|
30867
31417
|
/**
|
|
30868
31418
|
* Get the color for a detection class name.
|
|
30869
|
-
*
|
|
31419
|
+
* Resolves: custom override → taxonomy/UI-only fixed color → deterministic
|
|
31420
|
+
* hash-based color for unknown classes.
|
|
30870
31421
|
*/
|
|
30871
31422
|
function getClassColor(className, customColors) {
|
|
30872
31423
|
if (customColors?.[className]) return customColors[className];
|
|
30873
31424
|
if (customColors?.[className.toLowerCase()]) return customColors[className.toLowerCase()];
|
|
31425
|
+
const fromTaxonomy = _camstack_types.EVENT_TAXONOMY[className] ?? _camstack_types.EVENT_TAXONOMY[className.toLowerCase()];
|
|
31426
|
+
if (fromTaxonomy !== void 0) return fromTaxonomy.color;
|
|
30874
31427
|
if (CLASS_COLORS[className]) return CLASS_COLORS[className];
|
|
30875
31428
|
if (CLASS_COLORS[className.toLowerCase()]) return CLASS_COLORS[className.toLowerCase()];
|
|
30876
31429
|
let hash = 0;
|
|
30877
31430
|
for (let i = 0; i < className.length; i++) hash = hash * 31 + (className.codePointAt(i) ?? 0) >>> 0;
|
|
30878
|
-
return FALLBACK_PALETTE[hash % FALLBACK_PALETTE.length] ??
|
|
31431
|
+
return FALLBACK_PALETTE[hash % FALLBACK_PALETTE.length] ?? DEFAULT_COLOR;
|
|
31432
|
+
}
|
|
31433
|
+
//#endregion
|
|
31434
|
+
//#region src/composites/event-kind-visuals.tsx
|
|
31435
|
+
/**
|
|
31436
|
+
* Event-kind VISUALS — the UI-side half of the unified taxonomy dictionary
|
|
31437
|
+
* (`@camstack/types` `EVENT_TAXONOMY` owns the serializable data:
|
|
31438
|
+
* color / iconId / labelKey; this owns `iconId → lucide component` and
|
|
31439
|
+
* `labelKey → t()`).
|
|
31440
|
+
*
|
|
31441
|
+
* Every UI that renders an event kind (timeline, events tree, chips,
|
|
31442
|
+
* detection canvas/tree) resolves its glyph + translated label here — no
|
|
31443
|
+
* per-component hardcoded icon or label.
|
|
31444
|
+
*/
|
|
31445
|
+
/**
|
|
31446
|
+
* `iconId` → lucide component. Built ONLY from statically-imported icons
|
|
31447
|
+
* (bundle-safe). Unknown ids resolve to the neutral `Tag` fallback.
|
|
31448
|
+
*/
|
|
31449
|
+
var EVENT_KIND_ICONS = {
|
|
31450
|
+
motion: Activity,
|
|
31451
|
+
audio: Volume2,
|
|
31452
|
+
person: User,
|
|
31453
|
+
vehicle: Car,
|
|
31454
|
+
animal: PawPrint,
|
|
31455
|
+
package: Package,
|
|
31456
|
+
sensor: Radio,
|
|
31457
|
+
control: SlidersHorizontal,
|
|
31458
|
+
car: Car,
|
|
31459
|
+
truck: Truck,
|
|
31460
|
+
bus: Bus,
|
|
31461
|
+
motorcycle: Bike,
|
|
31462
|
+
bicycle: Bike,
|
|
31463
|
+
airplane: Plane,
|
|
31464
|
+
boat: Sailboat,
|
|
31465
|
+
train: TrainFront,
|
|
31466
|
+
bird: Bird,
|
|
31467
|
+
cat: Cat,
|
|
31468
|
+
dog: Dog,
|
|
31469
|
+
horse: PawPrint,
|
|
31470
|
+
sheep: PawPrint,
|
|
31471
|
+
cow: PawPrint,
|
|
31472
|
+
elephant: PawPrint,
|
|
31473
|
+
bear: PawPrint,
|
|
31474
|
+
zebra: PawPrint,
|
|
31475
|
+
giraffe: PawPrint,
|
|
31476
|
+
door: DoorOpen,
|
|
31477
|
+
pir: Radar,
|
|
31478
|
+
smoke: Flame,
|
|
31479
|
+
water: Droplet,
|
|
31480
|
+
gas: Wind,
|
|
31481
|
+
vibration: Vibrate,
|
|
31482
|
+
tamper: ShieldAlert,
|
|
31483
|
+
presence: UserCheck,
|
|
31484
|
+
generic: Tag,
|
|
31485
|
+
lock: Lock,
|
|
31486
|
+
siren: Siren,
|
|
31487
|
+
switch: ToggleRight,
|
|
31488
|
+
doorbell: BellRing,
|
|
31489
|
+
button: CircleDot,
|
|
31490
|
+
"audio-speech": MessageSquare,
|
|
31491
|
+
"audio-scream": Megaphone,
|
|
31492
|
+
"audio-crying": Baby,
|
|
31493
|
+
"audio-laughter": Laugh,
|
|
31494
|
+
"audio-music": Music,
|
|
31495
|
+
"audio-dog": Dog,
|
|
31496
|
+
"audio-cat": Cat,
|
|
31497
|
+
"audio-bird": Bird,
|
|
31498
|
+
"audio-animal": PawPrint,
|
|
31499
|
+
"audio-alarm": BellRing,
|
|
31500
|
+
"audio-doorbell": BellRing,
|
|
31501
|
+
"audio-glass_breaking": TriangleAlert,
|
|
31502
|
+
"audio-gunshot": Crosshair,
|
|
31503
|
+
"audio-vehicle": Car,
|
|
31504
|
+
"audio-siren": Siren,
|
|
31505
|
+
"audio-fire": Flame,
|
|
31506
|
+
"audio-water": Droplets,
|
|
31507
|
+
"audio-wind": Wind,
|
|
31508
|
+
"audio-door": DoorOpen,
|
|
31509
|
+
"audio-footsteps": Footprints,
|
|
31510
|
+
"audio-crowd": Users,
|
|
31511
|
+
"audio-telephone": Phone,
|
|
31512
|
+
"audio-engine": Cog,
|
|
31513
|
+
"audio-tools": Hammer,
|
|
31514
|
+
"audio-silence": VolumeX
|
|
31515
|
+
};
|
|
31516
|
+
/** Resolve an `iconId` to a lucide component (falls back to `Tag`). */
|
|
31517
|
+
function resolveEventKindIcon(iconId) {
|
|
31518
|
+
if (Object.hasOwn(EVENT_KIND_ICONS, iconId)) return EVENT_KIND_ICONS[iconId];
|
|
31519
|
+
if (iconId.startsWith("audio-")) return Volume2;
|
|
31520
|
+
return Tag;
|
|
31521
|
+
}
|
|
31522
|
+
/**
|
|
31523
|
+
* Translated label for an event kind — `t(labelKey)` when a translation
|
|
31524
|
+
* exists, else the English `label` fallback. Robust to a missing key: an
|
|
31525
|
+
* i18n backend that echoes the key unchanged (react-i18next default) is
|
|
31526
|
+
* treated as "no translation" and the fallback label is returned, so the UI
|
|
31527
|
+
* never renders a raw `eventKind.*` key.
|
|
31528
|
+
*/
|
|
31529
|
+
function eventKindLabel(descriptor, t) {
|
|
31530
|
+
if (t === void 0) return descriptor.label;
|
|
31531
|
+
const translated = t(descriptor.labelKey);
|
|
31532
|
+
return translated === descriptor.labelKey || translated.length === 0 ? descriptor.label : translated;
|
|
31533
|
+
}
|
|
31534
|
+
/** Small convenience component: renders the lucide glyph for an `iconId`. */
|
|
31535
|
+
function EventKindGlyph({ iconId, size = 16, color, className }) {
|
|
31536
|
+
return (0, react$1.createElement)(resolveEventKindIcon(iconId), {
|
|
31537
|
+
size,
|
|
31538
|
+
color,
|
|
31539
|
+
className
|
|
31540
|
+
});
|
|
30879
31541
|
}
|
|
30880
31542
|
//#endregion
|
|
30881
31543
|
//#region src/composites/detection-canvas.tsx
|
|
@@ -32524,6 +33186,294 @@ function mountAddonPage(PageComponent, options = {}) {
|
|
|
32524
33186
|
}));
|
|
32525
33187
|
}
|
|
32526
33188
|
//#endregion
|
|
33189
|
+
//#region src/composites/device-select-filter.ts
|
|
33190
|
+
/** True when two string lists share at least one member. */
|
|
33191
|
+
function intersects(a, b) {
|
|
33192
|
+
if (a.length === 0 || b.length === 0) return false;
|
|
33193
|
+
const set = new Set(a);
|
|
33194
|
+
return b.some((v) => set.has(v));
|
|
33195
|
+
}
|
|
33196
|
+
/**
|
|
33197
|
+
* Does a device satisfy the filter?
|
|
33198
|
+
*
|
|
33199
|
+
* Union match: with an empty/absent filter every device passes; otherwise the
|
|
33200
|
+
* device passes when ANY provided clause matches — its `features` intersect
|
|
33201
|
+
* `caps`, OR its `type` is in `types`. `excludeDeviceId` is subtracted last
|
|
33202
|
+
* (it always drops the device regardless of the other clauses).
|
|
33203
|
+
*/
|
|
33204
|
+
function deviceMatchesFilter(device, filter) {
|
|
33205
|
+
if (filter?.excludeDeviceId !== void 0 && device.id === filter.excludeDeviceId) return false;
|
|
33206
|
+
const hasCaps = filter?.caps !== void 0 && filter.caps.length > 0;
|
|
33207
|
+
const hasTypes = filter?.types !== void 0 && filter.types.length > 0;
|
|
33208
|
+
if (!hasCaps && !hasTypes) return true;
|
|
33209
|
+
if (hasCaps && intersects(device.features ?? [], filter.caps)) return true;
|
|
33210
|
+
if (hasTypes && filter.types.includes(device.type)) return true;
|
|
33211
|
+
return false;
|
|
33212
|
+
}
|
|
33213
|
+
/** Human label for a device option: `Name (Location)` when a location is set. */
|
|
33214
|
+
function deviceOptionLabel(device) {
|
|
33215
|
+
return typeof device.location === "string" && device.location.length > 0 ? `${device.name} (${device.location})` : device.name;
|
|
33216
|
+
}
|
|
33217
|
+
/**
|
|
33218
|
+
* Filter a device list and project it into sorted `{ value, label }` options
|
|
33219
|
+
* (value = the device id as a string). Sorted case-insensitively by label so
|
|
33220
|
+
* the picker order is stable.
|
|
33221
|
+
*/
|
|
33222
|
+
function devicesToOptions(devices, filter) {
|
|
33223
|
+
return devices.filter((d) => deviceMatchesFilter(d, filter)).map((d) => ({
|
|
33224
|
+
value: String(d.id),
|
|
33225
|
+
label: deviceOptionLabel(d)
|
|
33226
|
+
})).toSorted((a, b) => a.label.localeCompare(b.label));
|
|
33227
|
+
}
|
|
33228
|
+
/**
|
|
33229
|
+
* Free-text option filter — case-insensitive AND over whitespace tokens, each
|
|
33230
|
+
* matched against the option's `value` + `label` (so a device is found by name,
|
|
33231
|
+
* id, or location). An empty query returns every option in order.
|
|
33232
|
+
*/
|
|
33233
|
+
function filterDeviceOptions(options, query) {
|
|
33234
|
+
const tokens = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
33235
|
+
if (tokens.length === 0) return [...options];
|
|
33236
|
+
return options.filter((opt) => {
|
|
33237
|
+
const hay = `${opt.value} ${opt.label}`.toLowerCase();
|
|
33238
|
+
return tokens.every((t) => hay.includes(t));
|
|
33239
|
+
});
|
|
33240
|
+
}
|
|
33241
|
+
/**
|
|
33242
|
+
* Resolve the currently-selected values into options IN SELECTION ORDER (so
|
|
33243
|
+
* chips stay stable while searching). A selected value with no matching option
|
|
33244
|
+
* becomes a synthetic `{ value, label: value }` — a stale id still shows as a
|
|
33245
|
+
* removable chip rather than silently vanishing.
|
|
33246
|
+
*/
|
|
33247
|
+
function selectedDeviceOptions(options, selected) {
|
|
33248
|
+
const byValue = new Map(options.map((o) => [o.value, o]));
|
|
33249
|
+
return selected.map((v) => byValue.get(v) ?? {
|
|
33250
|
+
value: v,
|
|
33251
|
+
label: v
|
|
33252
|
+
});
|
|
33253
|
+
}
|
|
33254
|
+
//#endregion
|
|
33255
|
+
//#region src/composites/device-select-field.tsx
|
|
33256
|
+
/**
|
|
33257
|
+
* `device-select` / `device-multiselect` renderers.
|
|
33258
|
+
*
|
|
33259
|
+
* Both fetch EVERY system device via `deviceManager.listAll` and narrow the
|
|
33260
|
+
* options CLIENT-SIDE with the field's declarative `deviceFilter` (see
|
|
33261
|
+
* `device-select-filter.ts`). No server-computed option list is involved —
|
|
33262
|
+
* the form field carries only the filter. Value(s) are device ids as strings.
|
|
33263
|
+
*
|
|
33264
|
+
* The multi variant mirrors the "Linked devices" searchable combobox UX
|
|
33265
|
+
* (removable chips + typeahead dropdown); the single variant is a native
|
|
33266
|
+
* select. Both are inline in ui-library (like `node-select`) so any host that
|
|
33267
|
+
* renders the shared form field gets them without extra registration.
|
|
33268
|
+
*/
|
|
33269
|
+
var INPUT_CLASS$1 = "w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-xs text-foreground focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none disabled:opacity-50 disabled:cursor-not-allowed";
|
|
33270
|
+
var INPUT_SHELL = "flex items-center gap-1.5 rounded-md border border-border bg-background px-2 py-1.5 focus-within:border-primary focus-within:ring-1 focus-within:ring-primary/30";
|
|
33271
|
+
var LABEL_CLASS$1 = "block text-[11px] font-medium text-foreground mb-1 break-words";
|
|
33272
|
+
var DESC_CLASS$1 = "text-[10px] text-foreground-subtle mt-0.5 break-words";
|
|
33273
|
+
/** The compact projection of the listAll rows the device fields consume. */
|
|
33274
|
+
function toCandidates(rows) {
|
|
33275
|
+
if (!Array.isArray(rows)) return [];
|
|
33276
|
+
const out = [];
|
|
33277
|
+
for (const row of rows) {
|
|
33278
|
+
if (typeof row !== "object" || row === null) continue;
|
|
33279
|
+
const r = row;
|
|
33280
|
+
if (typeof r.id !== "number" || typeof r.type !== "string" || typeof r.name !== "string") continue;
|
|
33281
|
+
out.push({
|
|
33282
|
+
id: r.id,
|
|
33283
|
+
type: r.type,
|
|
33284
|
+
name: r.name,
|
|
33285
|
+
location: typeof r.location === "string" ? r.location : null,
|
|
33286
|
+
features: Array.isArray(r.features) ? r.features.filter((f) => typeof f === "string") : []
|
|
33287
|
+
});
|
|
33288
|
+
}
|
|
33289
|
+
return out;
|
|
33290
|
+
}
|
|
33291
|
+
function FieldShell({ label, description, required, translationFn, children }) {
|
|
33292
|
+
const resolvedLabel = resolveLabel(label, translationFn);
|
|
33293
|
+
const resolvedDescription = resolveLabel(description, translationFn);
|
|
33294
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
33295
|
+
className: "min-w-0",
|
|
33296
|
+
children: [
|
|
33297
|
+
resolvedLabel !== void 0 && resolvedLabel !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
33298
|
+
className: LABEL_CLASS$1,
|
|
33299
|
+
children: [resolvedLabel, required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
33300
|
+
className: "text-danger ml-0.5",
|
|
33301
|
+
children: "*"
|
|
33302
|
+
})]
|
|
33303
|
+
}),
|
|
33304
|
+
children,
|
|
33305
|
+
resolvedDescription && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
33306
|
+
className: DESC_CLASS$1,
|
|
33307
|
+
children: resolvedDescription
|
|
33308
|
+
})
|
|
33309
|
+
]
|
|
33310
|
+
});
|
|
33311
|
+
}
|
|
33312
|
+
function DeviceSelectField({ field, value, onChange, disabled, translationFn }) {
|
|
33313
|
+
const { data } = useDeviceManagerListAll({});
|
|
33314
|
+
const options = (0, react$1.useMemo)(() => devicesToOptions(toCandidates(data), field.deviceFilter), [data, field.deviceFilter]);
|
|
33315
|
+
const current = value === void 0 || value === null ? "" : String(value);
|
|
33316
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FieldShell, {
|
|
33317
|
+
label: field.label,
|
|
33318
|
+
description: field.description,
|
|
33319
|
+
required: field.required,
|
|
33320
|
+
translationFn,
|
|
33321
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
33322
|
+
className: INPUT_CLASS$1,
|
|
33323
|
+
value: current,
|
|
33324
|
+
disabled: disabled || field.disabled,
|
|
33325
|
+
onChange: (e) => onChange(e.target.value),
|
|
33326
|
+
children: [!field.required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
33327
|
+
value: "",
|
|
33328
|
+
children: "— Select device —"
|
|
33329
|
+
}), options.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
33330
|
+
value: opt.value,
|
|
33331
|
+
children: opt.label
|
|
33332
|
+
}, opt.value))]
|
|
33333
|
+
})
|
|
33334
|
+
});
|
|
33335
|
+
}
|
|
33336
|
+
function DeviceMultiSelectField({ field, value, onChange, disabled, translationFn }) {
|
|
33337
|
+
const { data } = useDeviceManagerListAll({});
|
|
33338
|
+
const options = (0, react$1.useMemo)(() => devicesToOptions(toCandidates(data), field.deviceFilter), [data, field.deviceFilter]);
|
|
33339
|
+
const selected = Array.isArray(value) ? value.map(String) : [];
|
|
33340
|
+
const isDisabled = disabled === true || field.disabled === true;
|
|
33341
|
+
const atMax = field.maxItems !== void 0 && selected.length >= field.maxItems;
|
|
33342
|
+
const [query, setQuery] = (0, react$1.useState)("");
|
|
33343
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
33344
|
+
const [highlight, setHighlight] = (0, react$1.useState)(0);
|
|
33345
|
+
const inputRef = (0, react$1.useRef)(null);
|
|
33346
|
+
const blurTimer = (0, react$1.useRef)(null);
|
|
33347
|
+
const selectedOptions = (0, react$1.useMemo)(() => selectedDeviceOptions(options, selected), [options, selected]);
|
|
33348
|
+
const filtered = (0, react$1.useMemo)(() => filterDeviceOptions(options, query), [options, query]);
|
|
33349
|
+
const toggle = (optValue) => {
|
|
33350
|
+
if (isDisabled) return;
|
|
33351
|
+
if (selected.includes(optValue)) onChange(selected.filter((v) => v !== optValue));
|
|
33352
|
+
else {
|
|
33353
|
+
if (field.maxItems !== void 0 && selected.length >= field.maxItems) return;
|
|
33354
|
+
onChange([...selected, optValue]);
|
|
33355
|
+
}
|
|
33356
|
+
};
|
|
33357
|
+
const handleKeyDown = (e) => {
|
|
33358
|
+
if (e.key === "ArrowDown") {
|
|
33359
|
+
e.preventDefault();
|
|
33360
|
+
setOpen(true);
|
|
33361
|
+
setHighlight((h) => filtered.length === 0 ? 0 : (h + 1) % filtered.length);
|
|
33362
|
+
} else if (e.key === "ArrowUp") {
|
|
33363
|
+
e.preventDefault();
|
|
33364
|
+
setOpen(true);
|
|
33365
|
+
setHighlight((h) => filtered.length === 0 ? 0 : (h - 1 + filtered.length) % filtered.length);
|
|
33366
|
+
} else if (e.key === "Enter") {
|
|
33367
|
+
e.preventDefault();
|
|
33368
|
+
const opt = filtered[highlight];
|
|
33369
|
+
if (opt) toggle(opt.value);
|
|
33370
|
+
} else if (e.key === "Escape") setOpen(false);
|
|
33371
|
+
else if (e.key === "Backspace" && query === "" && selected.length > 0) onChange(selected.slice(0, -1));
|
|
33372
|
+
};
|
|
33373
|
+
const label = resolveLabel(field.label, translationFn);
|
|
33374
|
+
const description = resolveLabel(field.description, translationFn);
|
|
33375
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
33376
|
+
className: "min-w-0",
|
|
33377
|
+
children: [
|
|
33378
|
+
label !== void 0 && label !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
33379
|
+
className: LABEL_CLASS$1,
|
|
33380
|
+
children: label
|
|
33381
|
+
}),
|
|
33382
|
+
selectedOptions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
33383
|
+
className: "flex flex-wrap gap-1 mb-1.5",
|
|
33384
|
+
children: selectedOptions.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
33385
|
+
className: "inline-flex items-center gap-1 rounded-md bg-primary/10 px-1.5 py-0.5 text-[11px] text-primary max-w-full",
|
|
33386
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
33387
|
+
className: "truncate",
|
|
33388
|
+
children: opt.label
|
|
33389
|
+
}), !isDisabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
33390
|
+
type: "button",
|
|
33391
|
+
className: "shrink-0 hover:text-danger",
|
|
33392
|
+
"aria-label": `Remove ${opt.label}`,
|
|
33393
|
+
onClick: () => toggle(opt.value),
|
|
33394
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(X, { className: "h-2.5 w-2.5" })
|
|
33395
|
+
})]
|
|
33396
|
+
}, opt.value))
|
|
33397
|
+
}),
|
|
33398
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
33399
|
+
className: INPUT_SHELL + (isDisabled ? " opacity-50" : ""),
|
|
33400
|
+
children: [
|
|
33401
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, { className: "h-3.5 w-3.5 shrink-0 text-foreground-subtle" }),
|
|
33402
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
33403
|
+
ref: inputRef,
|
|
33404
|
+
type: "text",
|
|
33405
|
+
role: "combobox",
|
|
33406
|
+
"aria-expanded": open,
|
|
33407
|
+
"aria-controls": `dsel-${field.key}`,
|
|
33408
|
+
className: "min-w-0 flex-1 bg-transparent text-xs text-foreground outline-none placeholder:text-foreground-disabled",
|
|
33409
|
+
value: query,
|
|
33410
|
+
placeholder: atMax ? `Max ${field.maxItems} selected` : field.placeholder ?? "Search devices…",
|
|
33411
|
+
disabled: isDisabled,
|
|
33412
|
+
onChange: (e) => {
|
|
33413
|
+
setQuery(e.target.value);
|
|
33414
|
+
setOpen(true);
|
|
33415
|
+
setHighlight(0);
|
|
33416
|
+
},
|
|
33417
|
+
onFocus: () => setOpen(true),
|
|
33418
|
+
onBlur: () => {
|
|
33419
|
+
blurTimer.current = setTimeout(() => setOpen(false), 120);
|
|
33420
|
+
},
|
|
33421
|
+
onKeyDown: handleKeyDown
|
|
33422
|
+
}),
|
|
33423
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDown, {
|
|
33424
|
+
className: "h-3.5 w-3.5 shrink-0 cursor-pointer text-foreground-subtle",
|
|
33425
|
+
onMouseDown: (e) => {
|
|
33426
|
+
e.preventDefault();
|
|
33427
|
+
if (blurTimer.current) clearTimeout(blurTimer.current);
|
|
33428
|
+
setOpen((o) => !o);
|
|
33429
|
+
inputRef.current?.focus();
|
|
33430
|
+
}
|
|
33431
|
+
})
|
|
33432
|
+
]
|
|
33433
|
+
}),
|
|
33434
|
+
open && !isDisabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
33435
|
+
id: `dsel-${field.key}`,
|
|
33436
|
+
role: "listbox",
|
|
33437
|
+
className: "mt-1 max-h-56 overflow-y-auto rounded-md border border-border bg-surface shadow-lg",
|
|
33438
|
+
onMouseDown: (e) => {
|
|
33439
|
+
e.preventDefault();
|
|
33440
|
+
},
|
|
33441
|
+
children: filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
33442
|
+
className: "px-2.5 py-2 text-[11px] text-foreground-subtle italic",
|
|
33443
|
+
children: options.length === 0 ? "No matching devices" : `No matches for “${query}”`
|
|
33444
|
+
}) : filtered.map((opt, i) => {
|
|
33445
|
+
const checked = selected.includes(opt.value);
|
|
33446
|
+
const blockedByMax = !checked && atMax;
|
|
33447
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
33448
|
+
type: "button",
|
|
33449
|
+
role: "option",
|
|
33450
|
+
"aria-selected": checked,
|
|
33451
|
+
disabled: blockedByMax,
|
|
33452
|
+
className: [
|
|
33453
|
+
"flex w-full items-center gap-2 px-2.5 py-1.5 text-left text-xs transition-colors",
|
|
33454
|
+
i === highlight ? "bg-primary/10" : "hover:bg-surface-hover",
|
|
33455
|
+
blockedByMax ? "opacity-40 cursor-not-allowed" : "cursor-pointer"
|
|
33456
|
+
].join(" "),
|
|
33457
|
+
onMouseEnter: () => setHighlight(i),
|
|
33458
|
+
onClick: () => toggle(opt.value),
|
|
33459
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
33460
|
+
className: ["flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded border", checked ? "border-primary bg-primary text-white" : "border-border"].join(" "),
|
|
33461
|
+
children: checked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, { className: "h-2.5 w-2.5" })
|
|
33462
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
33463
|
+
className: "truncate text-foreground",
|
|
33464
|
+
children: opt.label
|
|
33465
|
+
})]
|
|
33466
|
+
}, opt.value);
|
|
33467
|
+
})
|
|
33468
|
+
}),
|
|
33469
|
+
description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
33470
|
+
className: DESC_CLASS$1,
|
|
33471
|
+
children: description
|
|
33472
|
+
})
|
|
33473
|
+
]
|
|
33474
|
+
});
|
|
33475
|
+
}
|
|
33476
|
+
//#endregion
|
|
32527
33477
|
//#region src/contexts/custom-field-renderers.tsx
|
|
32528
33478
|
/**
|
|
32529
33479
|
* Custom field renderer registry.
|
|
@@ -38506,6 +39456,20 @@ function FormField({ field, values, onChange, disabled, translationFn, onTestFie
|
|
|
38506
39456
|
disabled,
|
|
38507
39457
|
translationFn
|
|
38508
39458
|
});
|
|
39459
|
+
case "device-select": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceSelectField, {
|
|
39460
|
+
field,
|
|
39461
|
+
value,
|
|
39462
|
+
onChange: handleChange,
|
|
39463
|
+
disabled,
|
|
39464
|
+
translationFn
|
|
39465
|
+
});
|
|
39466
|
+
case "device-multiselect": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DeviceMultiSelectField, {
|
|
39467
|
+
field,
|
|
39468
|
+
value,
|
|
39469
|
+
onChange: handleChange,
|
|
39470
|
+
disabled,
|
|
39471
|
+
translationFn
|
|
39472
|
+
});
|
|
38509
39473
|
case "probe": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProbeField, {
|
|
38510
39474
|
field,
|
|
38511
39475
|
value,
|
|
@@ -39015,6 +39979,7 @@ function computeClientHints(container) {
|
|
|
39015
39979
|
var RECONNECT_BASE_DELAY_MS = 1500;
|
|
39016
39980
|
var RECONNECT_MAX_DELAY_MS = 15e3;
|
|
39017
39981
|
var MAX_RECONNECT_ATTEMPTS = 40;
|
|
39982
|
+
var FIRST_FRAME_TIMEOUT_MS = 8e3;
|
|
39018
39983
|
function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, muted: initialMuted = true, showControls = true, showStats = false, onPlaybackStats, onClientNetworkSample, onConnectTiming, className = "", onStateChange, onError, overlay, createSession, sendAnswer, handleOffer, getIceServers, addIceCandidate, getIceCandidates, closeSession, getSessionState, reoffer, posterUrl, hintsOverride, reconnectSignal, onControlChannel }) {
|
|
39019
39984
|
const videoRef = (0, react$1.useRef)(null);
|
|
39020
39985
|
const containerRef = (0, react$1.useRef)(null);
|
|
@@ -39391,14 +40356,26 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
39391
40356
|
});
|
|
39392
40357
|
onConnectTiming?.({ ...timing });
|
|
39393
40358
|
const v = videoRef.current;
|
|
39394
|
-
if (v && "requestVideoFrameCallback" in v)
|
|
39395
|
-
|
|
39396
|
-
|
|
39397
|
-
|
|
39398
|
-
|
|
40359
|
+
if (v && "requestVideoFrameCallback" in v) {
|
|
40360
|
+
v.requestVideoFrameCallback(() => {
|
|
40361
|
+
timing.firstFrameMs = ms();
|
|
40362
|
+
console.info("[WebRTC timing] first decoded frame", {
|
|
40363
|
+
streamKey,
|
|
40364
|
+
firstFrameMs: timing.firstFrameMs
|
|
40365
|
+
});
|
|
40366
|
+
onConnectTiming?.({ ...timing });
|
|
39399
40367
|
});
|
|
39400
|
-
|
|
39401
|
-
|
|
40368
|
+
setTimeout(() => {
|
|
40369
|
+
if (!mountedRef.current) return;
|
|
40370
|
+
if (timing.firstFrameMs !== void 0) return;
|
|
40371
|
+
console.warn("[WebRTC timing] NO decoded frame (stalled)", {
|
|
40372
|
+
streamKey,
|
|
40373
|
+
sinceIceConnectedMs: ms() - (timing.iceConnectedMs ?? 0),
|
|
40374
|
+
iceConnectedMs: timing.iceConnectedMs,
|
|
40375
|
+
firstTrackMs: timing.firstTrackMs
|
|
40376
|
+
});
|
|
40377
|
+
}, FIRST_FRAME_TIMEOUT_MS);
|
|
40378
|
+
}
|
|
39402
40379
|
}
|
|
39403
40380
|
reconnectAttemptsRef.current = 0;
|
|
39404
40381
|
if (seamless) swapInOnce();
|
|
@@ -39431,8 +40408,12 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
39431
40408
|
await pc.setLocalDescription(offer);
|
|
39432
40409
|
timing.localSetMs = ms();
|
|
39433
40410
|
if (!mountedRef.current || abort.signal.aborted) return;
|
|
40411
|
+
const clientOfferHints = {
|
|
40412
|
+
...computeClientHints(containerRef.current),
|
|
40413
|
+
...hintsOverride
|
|
40414
|
+
};
|
|
39434
40415
|
const signalingStart = ms();
|
|
39435
|
-
const { sessionId: sid, sdpAnswer } = await handleOffer(pc.localDescription?.sdp ?? offer.sdp ?? "");
|
|
40416
|
+
const { sessionId: sid, sdpAnswer } = await handleOffer(pc.localDescription?.sdp ?? offer.sdp ?? "", void 0, clientOfferHints);
|
|
39436
40417
|
timing.signalingRttMs = ms() - signalingStart;
|
|
39437
40418
|
sessionId = sid;
|
|
39438
40419
|
sessionIdsRef.current.add(sid);
|
|
@@ -39493,7 +40474,8 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
39493
40474
|
partialReconnectReset,
|
|
39494
40475
|
updateState,
|
|
39495
40476
|
onError,
|
|
39496
|
-
startSessionStatePoll
|
|
40477
|
+
startSessionStatePoll,
|
|
40478
|
+
hintsOverride
|
|
39497
40479
|
]);
|
|
39498
40480
|
renegotiateRef.current = (0, react$1.useCallback)(async (sessionId, target) => {
|
|
39499
40481
|
const reofferFn = reoffer;
|
|
@@ -39556,7 +40538,11 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
39556
40538
|
pc.close();
|
|
39557
40539
|
return;
|
|
39558
40540
|
}
|
|
39559
|
-
const
|
|
40541
|
+
const reofferHints = {
|
|
40542
|
+
...computeClientHints(containerRef.current),
|
|
40543
|
+
...hintsOverride
|
|
40544
|
+
};
|
|
40545
|
+
const { sessionId: sid, sdpAnswer } = await reofferFn(sessionId, pc.localDescription?.sdp ?? offer.sdp ?? "", target, reofferHints);
|
|
39560
40546
|
if (!mountedRef.current) {
|
|
39561
40547
|
pc.close();
|
|
39562
40548
|
return;
|
|
@@ -39607,7 +40593,8 @@ function CameraStreamPlayer({ serverUrl, streamKey, label, autoPlay = true, mute
|
|
|
39607
40593
|
addIceCandidate,
|
|
39608
40594
|
getIceCandidates,
|
|
39609
40595
|
updateState,
|
|
39610
|
-
startSessionStatePoll
|
|
40596
|
+
startSessionStatePoll,
|
|
40597
|
+
hintsOverride
|
|
39611
40598
|
]);
|
|
39612
40599
|
const connect = useClientOffer ? connectClientOffer : useServerOffer ? connectServerOffer : connectWhep;
|
|
39613
40600
|
const connectRef = (0, react$1.useRef)(() => {});
|
|
@@ -45320,13 +46307,14 @@ function useDeviceWebrtc(trpc, deviceId, pollIntervalMs = 5e3) {
|
|
|
45320
46307
|
deviceId,
|
|
45321
46308
|
getIceServers
|
|
45322
46309
|
]);
|
|
45323
|
-
const handleOffer = (0, react$1.useCallback)(async (target, sdpOffer, sessionId) => {
|
|
46310
|
+
const handleOffer = (0, react$1.useCallback)(async (target, sdpOffer, sessionId, hints) => {
|
|
45324
46311
|
if (deviceId === null) throw new Error("No device selected");
|
|
45325
46312
|
return trpc.webrtcSession.handleOffer.mutate({
|
|
45326
46313
|
deviceId,
|
|
45327
46314
|
target,
|
|
45328
46315
|
sdpOffer,
|
|
45329
|
-
...sessionId !== void 0 ? { sessionId } : {}
|
|
46316
|
+
...sessionId !== void 0 ? { sessionId } : {},
|
|
46317
|
+
...hints !== void 0 ? { hints } : {}
|
|
45330
46318
|
});
|
|
45331
46319
|
}, [trpc, deviceId]);
|
|
45332
46320
|
const sendAnswer = (0, react$1.useCallback)(async (sessionId, sdpAnswer) => {
|
|
@@ -45748,6 +46736,8 @@ exports.DeviceExportPanel = DeviceExportPanel;
|
|
|
45748
46736
|
exports.DeviceGrid = DeviceGrid;
|
|
45749
46737
|
exports.DeviceItem = DeviceItem;
|
|
45750
46738
|
exports.DeviceList = DeviceList;
|
|
46739
|
+
exports.DeviceMultiSelectField = DeviceMultiSelectField;
|
|
46740
|
+
exports.DeviceSelectField = DeviceSelectField;
|
|
45751
46741
|
exports.Dialog = Dialog;
|
|
45752
46742
|
exports.DialogContent = DialogContent;
|
|
45753
46743
|
exports.DialogDescription = DialogDescription;
|
|
@@ -45763,8 +46753,10 @@ exports.DropdownItem = DropdownItem;
|
|
|
45763
46753
|
exports.DropdownTrigger = DropdownTrigger;
|
|
45764
46754
|
exports.DummyHeroCard = DummyHeroCard;
|
|
45765
46755
|
exports.DummyInline = DummyInline;
|
|
46756
|
+
exports.EVENT_KIND_ICONS = EVENT_KIND_ICONS;
|
|
45766
46757
|
exports.EmptyState = EmptyState;
|
|
45767
46758
|
exports.ErrorBox = ErrorBox;
|
|
46759
|
+
exports.EventKindGlyph = EventKindGlyph;
|
|
45768
46760
|
exports.EventStream = EventStream;
|
|
45769
46761
|
exports.EyeOff = EyeOff;
|
|
45770
46762
|
exports.FILL = FILL;
|
|
@@ -45930,11 +46922,16 @@ exports.cursorFractionFor = cursorFractionFor;
|
|
|
45930
46922
|
exports.darkColors = require_theme_index.darkColors$1;
|
|
45931
46923
|
exports.defaultTheme = require_theme_index.defaultTheme$1;
|
|
45932
46924
|
exports.deriveDeviceKind = deriveDeviceKind;
|
|
46925
|
+
exports.deviceMatchesFilter = deviceMatchesFilter;
|
|
46926
|
+
exports.deviceOptionLabel = deviceOptionLabel;
|
|
45933
46927
|
exports.deviceRoleMeta = deviceRoleMeta;
|
|
45934
46928
|
exports.deviceRoleMetaOf = deviceRoleMetaOf;
|
|
45935
46929
|
exports.deviceTypeMeta = deviceTypeMeta;
|
|
45936
46930
|
exports.deviceTypeMetaOf = deviceTypeMetaOf;
|
|
46931
|
+
exports.devicesToOptions = devicesToOptions;
|
|
45937
46932
|
exports.ensureMfHostInit = ensureMfHostInit;
|
|
46933
|
+
exports.eventKindLabel = eventKindLabel;
|
|
46934
|
+
exports.filterDeviceOptions = filterDeviceOptions;
|
|
45938
46935
|
exports.findTimezone = _camstack_types.findTimezone;
|
|
45939
46936
|
exports.formatControlDateTime = formatControlDateTime;
|
|
45940
46937
|
exports.formatLastSeen = formatLastSeen;
|
|
@@ -45966,9 +46963,11 @@ exports.resolveContainerPrimary = resolveContainerPrimary;
|
|
|
45966
46963
|
exports.resolveControlAlign = resolveControlAlign;
|
|
45967
46964
|
exports.resolveDeviceControl = resolveDeviceControl;
|
|
45968
46965
|
exports.resolveDisplayIcon = resolveDisplayIcon;
|
|
46966
|
+
exports.resolveEventKindIcon = resolveEventKindIcon;
|
|
45969
46967
|
exports.resolvePrimaryChild = resolvePrimaryChild;
|
|
45970
46968
|
exports.resolveSensorDisplay = resolveSensorDisplay;
|
|
45971
46969
|
exports.scrubReducer = scrubReducer;
|
|
46970
|
+
exports.selectedDeviceOptions = selectedDeviceOptions;
|
|
45972
46971
|
exports.serializeRecordedCommand = serializeRecordedCommand;
|
|
45973
46972
|
exports.shouldCommit = shouldCommit;
|
|
45974
46973
|
exports.shouldEmit = shouldEmit;
|
|
@@ -46018,7 +47017,6 @@ exports.useAddonsSetAutoUpdateSettings = useAddonsSetAutoUpdateSettings;
|
|
|
46018
47017
|
exports.useAddonsSetCapabilityProviderEnabled = useAddonsSetCapabilityProviderEnabled;
|
|
46019
47018
|
exports.useAddonsStartJob = useAddonsStartJob;
|
|
46020
47019
|
exports.useAddonsUninstallPackage = useAddonsUninstallPackage;
|
|
46021
|
-
exports.useAddonsUpdateFrameworkPackage = useAddonsUpdateFrameworkPackage;
|
|
46022
47020
|
exports.useAddonsUpdatePackage = useAddonsUpdatePackage;
|
|
46023
47021
|
exports.useAirQualitySensorGetStatus = useAirQualitySensorGetStatus;
|
|
46024
47022
|
exports.useAlarmPanelArm = useAlarmPanelArm;
|