@camstack/addon-model-studio 1.1.201 → 1.1.202

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. package/THIRD_PARTY_MODELS.md +34 -26
  2. package/dist/{MotionZonesSettings-C5XCa2RN.mjs → MotionZonesSettings-qabihnVu.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-Byby1Qnl.mjs → PrivacyMaskSettings-CGVI9EVl.mjs} +4 -4
  4. package/dist/{SceneMonitorEditor-BehD1iD6.mjs → SceneMonitorEditor-BcAVb1c7.mjs} +3 -3
  5. package/dist/_stub.js +3927 -3903
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BYPEJjop.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CZVL55Bi.mjs} +3 -3
  7. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DMrwYkbN.mjs +26 -0
  8. package/dist/{hostInit-Ds4oKb79.mjs → hostInit-D_0AEBSS.mjs} +2 -2
  9. package/dist/model-studio.addon.js +586 -46
  10. package/dist/model-studio.addon.mjs +586 -46
  11. package/dist/{player-overlays-BdsADMdm.mjs → player-overlays-CgZQeBdy.mjs} +1 -1
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-orJ4AkQR.mjs → responsive-dgrtmGP7.mjs} +1 -1
  14. package/dist/{scene-monitor-copy-CRMa4vtd.mjs → scene-monitor-copy-CWuj3twx.mjs} +1 -1
  15. package/dist/{square-CgcW-Db-.mjs → square-U1jjwP1Q.mjs} +1 -1
  16. package/dist/{trash-2-Di341FuZ.mjs → trash-2-B3hyZ06m.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CHD2bVBg.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-Rw5qHN1M.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CX_tb6VB.mjs +0 -26
@@ -10900,6 +10900,478 @@ var ClipSearchStrictnessSchema = _enum([
10900
10900
  "balanced",
10901
10901
  "strict"
10902
10902
  ]);
10903
+ var COCO_80_LABELS = [
10904
+ {
10905
+ id: "person",
10906
+ name: "Person"
10907
+ },
10908
+ {
10909
+ id: "bicycle",
10910
+ name: "Bicycle"
10911
+ },
10912
+ {
10913
+ id: "car",
10914
+ name: "Car"
10915
+ },
10916
+ {
10917
+ id: "motorcycle",
10918
+ name: "Motorcycle"
10919
+ },
10920
+ {
10921
+ id: "airplane",
10922
+ name: "Airplane"
10923
+ },
10924
+ {
10925
+ id: "bus",
10926
+ name: "Bus"
10927
+ },
10928
+ {
10929
+ id: "train",
10930
+ name: "Train"
10931
+ },
10932
+ {
10933
+ id: "truck",
10934
+ name: "Truck"
10935
+ },
10936
+ {
10937
+ id: "boat",
10938
+ name: "Boat"
10939
+ },
10940
+ {
10941
+ id: "traffic light",
10942
+ name: "Traffic Light"
10943
+ },
10944
+ {
10945
+ id: "fire hydrant",
10946
+ name: "Fire Hydrant"
10947
+ },
10948
+ {
10949
+ id: "stop sign",
10950
+ name: "Stop Sign"
10951
+ },
10952
+ {
10953
+ id: "parking meter",
10954
+ name: "Parking Meter"
10955
+ },
10956
+ {
10957
+ id: "bench",
10958
+ name: "Bench"
10959
+ },
10960
+ {
10961
+ id: "bird",
10962
+ name: "Bird"
10963
+ },
10964
+ {
10965
+ id: "cat",
10966
+ name: "Cat"
10967
+ },
10968
+ {
10969
+ id: "dog",
10970
+ name: "Dog"
10971
+ },
10972
+ {
10973
+ id: "horse",
10974
+ name: "Horse"
10975
+ },
10976
+ {
10977
+ id: "sheep",
10978
+ name: "Sheep"
10979
+ },
10980
+ {
10981
+ id: "cow",
10982
+ name: "Cow"
10983
+ },
10984
+ {
10985
+ id: "elephant",
10986
+ name: "Elephant"
10987
+ },
10988
+ {
10989
+ id: "bear",
10990
+ name: "Bear"
10991
+ },
10992
+ {
10993
+ id: "zebra",
10994
+ name: "Zebra"
10995
+ },
10996
+ {
10997
+ id: "giraffe",
10998
+ name: "Giraffe"
10999
+ },
11000
+ {
11001
+ id: "backpack",
11002
+ name: "Backpack"
11003
+ },
11004
+ {
11005
+ id: "umbrella",
11006
+ name: "Umbrella"
11007
+ },
11008
+ {
11009
+ id: "handbag",
11010
+ name: "Handbag"
11011
+ },
11012
+ {
11013
+ id: "tie",
11014
+ name: "Tie"
11015
+ },
11016
+ {
11017
+ id: "suitcase",
11018
+ name: "Suitcase"
11019
+ },
11020
+ {
11021
+ id: "frisbee",
11022
+ name: "Frisbee"
11023
+ },
11024
+ {
11025
+ id: "skis",
11026
+ name: "Skis"
11027
+ },
11028
+ {
11029
+ id: "snowboard",
11030
+ name: "Snowboard"
11031
+ },
11032
+ {
11033
+ id: "sports ball",
11034
+ name: "Sports Ball"
11035
+ },
11036
+ {
11037
+ id: "kite",
11038
+ name: "Kite"
11039
+ },
11040
+ {
11041
+ id: "baseball bat",
11042
+ name: "Baseball Bat"
11043
+ },
11044
+ {
11045
+ id: "baseball glove",
11046
+ name: "Baseball Glove"
11047
+ },
11048
+ {
11049
+ id: "skateboard",
11050
+ name: "Skateboard"
11051
+ },
11052
+ {
11053
+ id: "surfboard",
11054
+ name: "Surfboard"
11055
+ },
11056
+ {
11057
+ id: "tennis racket",
11058
+ name: "Tennis Racket"
11059
+ },
11060
+ {
11061
+ id: "bottle",
11062
+ name: "Bottle"
11063
+ },
11064
+ {
11065
+ id: "wine glass",
11066
+ name: "Wine Glass"
11067
+ },
11068
+ {
11069
+ id: "cup",
11070
+ name: "Cup"
11071
+ },
11072
+ {
11073
+ id: "fork",
11074
+ name: "Fork"
11075
+ },
11076
+ {
11077
+ id: "knife",
11078
+ name: "Knife"
11079
+ },
11080
+ {
11081
+ id: "spoon",
11082
+ name: "Spoon"
11083
+ },
11084
+ {
11085
+ id: "bowl",
11086
+ name: "Bowl"
11087
+ },
11088
+ {
11089
+ id: "banana",
11090
+ name: "Banana"
11091
+ },
11092
+ {
11093
+ id: "apple",
11094
+ name: "Apple"
11095
+ },
11096
+ {
11097
+ id: "sandwich",
11098
+ name: "Sandwich"
11099
+ },
11100
+ {
11101
+ id: "orange",
11102
+ name: "Orange"
11103
+ },
11104
+ {
11105
+ id: "broccoli",
11106
+ name: "Broccoli"
11107
+ },
11108
+ {
11109
+ id: "carrot",
11110
+ name: "Carrot"
11111
+ },
11112
+ {
11113
+ id: "hot dog",
11114
+ name: "Hot Dog"
11115
+ },
11116
+ {
11117
+ id: "pizza",
11118
+ name: "Pizza"
11119
+ },
11120
+ {
11121
+ id: "donut",
11122
+ name: "Donut"
11123
+ },
11124
+ {
11125
+ id: "cake",
11126
+ name: "Cake"
11127
+ },
11128
+ {
11129
+ id: "chair",
11130
+ name: "Chair"
11131
+ },
11132
+ {
11133
+ id: "couch",
11134
+ name: "Couch"
11135
+ },
11136
+ {
11137
+ id: "potted plant",
11138
+ name: "Potted Plant"
11139
+ },
11140
+ {
11141
+ id: "bed",
11142
+ name: "Bed"
11143
+ },
11144
+ {
11145
+ id: "dining table",
11146
+ name: "Dining Table"
11147
+ },
11148
+ {
11149
+ id: "toilet",
11150
+ name: "Toilet"
11151
+ },
11152
+ {
11153
+ id: "tv",
11154
+ name: "TV"
11155
+ },
11156
+ {
11157
+ id: "laptop",
11158
+ name: "Laptop"
11159
+ },
11160
+ {
11161
+ id: "mouse",
11162
+ name: "Mouse"
11163
+ },
11164
+ {
11165
+ id: "remote",
11166
+ name: "Remote"
11167
+ },
11168
+ {
11169
+ id: "keyboard",
11170
+ name: "Keyboard"
11171
+ },
11172
+ {
11173
+ id: "cell phone",
11174
+ name: "Cell Phone"
11175
+ },
11176
+ {
11177
+ id: "microwave",
11178
+ name: "Microwave"
11179
+ },
11180
+ {
11181
+ id: "oven",
11182
+ name: "Oven"
11183
+ },
11184
+ {
11185
+ id: "toaster",
11186
+ name: "Toaster"
11187
+ },
11188
+ {
11189
+ id: "sink",
11190
+ name: "Sink"
11191
+ },
11192
+ {
11193
+ id: "refrigerator",
11194
+ name: "Refrigerator"
11195
+ },
11196
+ {
11197
+ id: "book",
11198
+ name: "Book"
11199
+ },
11200
+ {
11201
+ id: "clock",
11202
+ name: "Clock"
11203
+ },
11204
+ {
11205
+ id: "vase",
11206
+ name: "Vase"
11207
+ },
11208
+ {
11209
+ id: "scissors",
11210
+ name: "Scissors"
11211
+ },
11212
+ {
11213
+ id: "teddy bear",
11214
+ name: "Teddy Bear"
11215
+ },
11216
+ {
11217
+ id: "hair drier",
11218
+ name: "Hair Drier"
11219
+ },
11220
+ {
11221
+ id: "toothbrush",
11222
+ name: "Toothbrush"
11223
+ }
11224
+ ];
11225
+ new Set([
11226
+ {
11227
+ id: "person",
11228
+ name: "Person"
11229
+ },
11230
+ {
11231
+ id: "vehicle",
11232
+ name: "Vehicle"
11233
+ },
11234
+ {
11235
+ id: "animal",
11236
+ name: "Animal"
11237
+ },
11238
+ {
11239
+ id: "package",
11240
+ name: "Package"
11241
+ }
11242
+ ].map((l) => l.id));
11243
+ var COCO_TO_MACRO = {
11244
+ mapping: {
11245
+ person: "person",
11246
+ bicycle: "vehicle",
11247
+ car: "vehicle",
11248
+ motorcycle: "vehicle",
11249
+ airplane: "vehicle",
11250
+ bus: "vehicle",
11251
+ train: "vehicle",
11252
+ truck: "vehicle",
11253
+ boat: "vehicle",
11254
+ bird: "animal",
11255
+ cat: "animal",
11256
+ dog: "animal",
11257
+ horse: "animal",
11258
+ sheep: "animal",
11259
+ cow: "animal",
11260
+ elephant: "animal",
11261
+ bear: "animal",
11262
+ zebra: "animal",
11263
+ giraffe: "animal",
11264
+ suitcase: "package",
11265
+ backpack: "package",
11266
+ handbag: "package"
11267
+ },
11268
+ preserveOriginal: false
11269
+ };
11270
+ /** Steps a root detector may declare it fills. */
11271
+ var FILLABLE_STEP_IDS = [
11272
+ "animal-classifier",
11273
+ "vehicle-classifier",
11274
+ "package-detection"
11275
+ ];
11276
+ /**
11277
+ * The EFFECT vocabulary of each fillable step: exactly the strings the step
11278
+ * itself emits, in its own spelling. A linked label is one of these and nothing
11279
+ * else, so a tier-1 value means the same thing whichever writer produced it.
11280
+ *
11281
+ * - `animal-classifier`: the PRIMARY model's `-labels.json` (Open Images V7,
11282
+ * 8 classes) — also the species allow-list the step offers.
11283
+ * - `vehicle-classifier`: `vehicle-type-v1-labels.json`, capitalised as the
11284
+ * model emits them (the classifier writes `winner.class` verbatim).
11285
+ * - `package-detection`: its one output class.
11286
+ *
11287
+ * `scripts/check-label-link-vocabulary.ts` fails the build if a model entry's
11288
+ * `labelToEffect` names anything outside this table.
11289
+ */
11290
+ var FILLABLE_STEP_VOCABULARIES = {
11291
+ "animal-classifier": [
11292
+ "bird",
11293
+ "cat",
11294
+ "cow",
11295
+ "deer",
11296
+ "dog",
11297
+ "horse",
11298
+ "sheep",
11299
+ "squirrel"
11300
+ ],
11301
+ "vehicle-classifier": [
11302
+ "Ambulance",
11303
+ "Bicycle",
11304
+ "Bus",
11305
+ "Car",
11306
+ "Motorcycle",
11307
+ "Taxi",
11308
+ "Truck",
11309
+ "Van"
11310
+ ],
11311
+ "package-detection": ["package"]
11312
+ };
11313
+ /** The macro a detection must carry for the step to apply to it. */
11314
+ var FILLABLE_STEP_MACRO = {
11315
+ "animal-classifier": "animal",
11316
+ "vehicle-classifier": "vehicle",
11317
+ "package-detection": "package"
11318
+ };
11319
+ /**
11320
+ * Raw detector labels that name a vocabulary entry under another spelling.
11321
+ * Case-insensitive equality covers the rest (`car` → `Car`).
11322
+ */
11323
+ var EFFECT_ALIASES = {
11324
+ "animal-classifier": {},
11325
+ "vehicle-classifier": {
11326
+ school_bus: "Bus",
11327
+ garbage_truck: "Truck"
11328
+ },
11329
+ "package-detection": {}
11330
+ };
11331
+ /**
11332
+ * A labelmap is COCO when it carries at least half of the COCO-80 classes. A
11333
+ * COCO detector NEVER fills a step (operator decision, D715): its `dog` / `car`
11334
+ * is the generic class the classifier exists to refine, and its six animal
11335
+ * classes would otherwise read as "fills animal-classifier 6/8". Frigate+
11336
+ * shares about a dozen COCO names; a COCO-80 or COCO-91 labelmap carries ~80.
11337
+ */
11338
+ function isCocoLabelmap(labels) {
11339
+ const present = new Set(labels);
11340
+ return COCO_80_LABELS.filter((l) => present.has(l.id)).length * 2 >= COCO_80_LABELS.length;
11341
+ }
11342
+ function effectFor(stepId, label) {
11343
+ const alias = EFFECT_ALIASES[stepId][label];
11344
+ if (alias !== void 0) return alias;
11345
+ const folded = label.toLowerCase();
11346
+ return FILLABLE_STEP_VOCABULARIES[stepId].find((v) => v.toLowerCase() === folded);
11347
+ }
11348
+ /**
11349
+ * Which steps a root detector fills, from its labelmap and classMap. A label
11350
+ * counts for a step only when the model's classMap sends it to that step's
11351
+ * macro AND it names a vocabulary entry. A step none of the labels reach is
11352
+ * not declared; a COCO labelmap declares nothing.
11353
+ */
11354
+ function deriveClassifierFills(labels, classMap) {
11355
+ if (classMap === void 0 || isCocoLabelmap(labels)) return [];
11356
+ const fills = [];
11357
+ for (const stepId of FILLABLE_STEP_IDS) {
11358
+ const labelToEffect = {};
11359
+ for (const label of labels) {
11360
+ if (classMap.mapping[label] !== FILLABLE_STEP_MACRO[stepId]) continue;
11361
+ const effect = effectFor(stepId, label);
11362
+ if (effect !== void 0) labelToEffect[label] = effect;
11363
+ }
11364
+ const covered = new Set(Object.values(labelToEffect));
11365
+ if (covered.size === 0) continue;
11366
+ const uncovered = FILLABLE_STEP_VOCABULARIES[stepId].filter((v) => !covered.has(v));
11367
+ fills.push({
11368
+ stepId,
11369
+ labelToEffect,
11370
+ uncovered
11371
+ });
11372
+ }
11373
+ return fills;
11374
+ }
10903
11375
  var MODEL_FORMATS = [
10904
11376
  "onnx",
10905
11377
  "coreml",
@@ -11032,6 +11504,12 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
11032
11504
  /** True when the weights or their data forbid commercial use. */
11033
11505
  nonCommercial: boolean().optional()
11034
11506
  }));
11507
+ /** One `fillsClassifierEffects` entry — see `ModelCatalogEntry.fillsClassifierEffects`. */
11508
+ var FillsClassifierEffectSchema = object({
11509
+ stepId: _enum(FILLABLE_STEP_IDS),
11510
+ labelToEffect: record(string(), string()),
11511
+ uncovered: array(string()).readonly()
11512
+ });
11035
11513
  var ModelCatalogEntrySchema = object({
11036
11514
  id: string(),
11037
11515
  name: string(),
@@ -11158,6 +11636,16 @@ var ModelCatalogEntrySchema = object({
11158
11636
  */
11159
11637
  classMap: DetectionCatalogClassMapSchema.optional(),
11160
11638
  /**
11639
+ * The pipeline steps this ROOT detector already does the work of (D715):
11640
+ * its labels name the effect the step exists to produce (`deer` for
11641
+ * `animal-classifier`, `package` for `package-detection`). Derived from the
11642
+ * labelmap by `deriveClassifierFills`, never hand-written; a COCO model
11643
+ * declares none. Whether a declaration is honoured is the step's own
11644
+ * `labelLink` policy (`resolveLabelLink`). `labelToEffect` values are in
11645
+ * `FILLABLE_STEP_VOCABULARIES` (guard `check-label-link-vocabulary`).
11646
+ */
11647
+ fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional(),
11648
+ /**
11161
11649
  * The model's CLIP feature-space contract (text encoder, dimension, vector
11162
11650
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
11163
11651
  * CLIP image encoder; its absence is what "not a CLIP model" means to the
@@ -18118,51 +18606,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
18118
18606
  kind: "mutation",
18119
18607
  auth: "admin"
18120
18608
  });
18121
- new Set([
18122
- {
18123
- id: "person",
18124
- name: "Person"
18125
- },
18126
- {
18127
- id: "vehicle",
18128
- name: "Vehicle"
18129
- },
18130
- {
18131
- id: "animal",
18132
- name: "Animal"
18133
- },
18134
- {
18135
- id: "package",
18136
- name: "Package"
18137
- }
18138
- ].map((l) => l.id));
18139
- var COCO_TO_MACRO = {
18140
- mapping: {
18141
- person: "person",
18142
- bicycle: "vehicle",
18143
- car: "vehicle",
18144
- motorcycle: "vehicle",
18145
- airplane: "vehicle",
18146
- bus: "vehicle",
18147
- train: "vehicle",
18148
- truck: "vehicle",
18149
- boat: "vehicle",
18150
- bird: "animal",
18151
- cat: "animal",
18152
- dog: "animal",
18153
- horse: "animal",
18154
- sheep: "animal",
18155
- cow: "animal",
18156
- elephant: "animal",
18157
- bear: "animal",
18158
- zebra: "animal",
18159
- giraffe: "animal",
18160
- suitcase: "package",
18161
- backpack: "package",
18162
- handbag: "package"
18163
- },
18164
- preserveOriginal: false
18165
- };
18166
18609
  var AUDIO_MACRO_LABELS = [
18167
18610
  {
18168
18611
  id: "speech",
@@ -23566,7 +24009,8 @@ var PipelineModelOptionSchema = object({
23566
24009
  group: ModelVariantGroupSchema.optional(),
23567
24010
  legacy: boolean().optional(),
23568
24011
  provider: ModelProviderIdSchema.optional(),
23569
- defaultConfidence: number().optional()
24012
+ defaultConfidence: number().optional(),
24013
+ fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional()
23570
24014
  });
23571
24015
  var ConfigFieldBridge = custom();
23572
24016
  var PipelineAddonSchemaSchema = object({
@@ -36581,6 +37025,82 @@ DeviceType.Camera, method(object({
36581
37025
  package: array(ZoneRuleSchema).readonly()
36582
37026
  });
36583
37027
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
37028
+ function isClassMapMacroTarget(value) {
37029
+ return CLASS_MAP_MACRO_TARGETS.some((target) => target === value);
37030
+ }
37031
+ /**
37032
+ * Raw Frigate+ label → detection macro. Every label of the documented
37033
+ * Frigate+ base set (docs.frigate.video/plus, verified 2026-08-21) is either
37034
+ * here or in {@link FRIGATE_PLUS_UNMAPPED_LABELS}, with the reason it is not.
37035
+ *
37036
+ * Why this exists: a Frigate+ import used to carry NO classMap, so it inherited
37037
+ * the step's `COCO_TO_MACRO` (`preserveOriginal: false`) and the executor
37038
+ * dropped every label COCO does not name — deer, raccoon, fox, squirrel, goat,
37039
+ * rabbit, skunk, kangaroo, possum, rodent, school_bus, garbage_truck and even
37040
+ * `package` vanished as `class-filter` discards. The executor keeps the raw
37041
+ * label as `originalClass` whenever the map resolves it, so the fine identity
37042
+ * survives under the macro.
37043
+ */
37044
+ var FRIGATE_PLUS_TO_MACRO = {
37045
+ person: "person",
37046
+ baby: "person",
37047
+ car: "vehicle",
37048
+ motorcycle: "vehicle",
37049
+ bicycle: "vehicle",
37050
+ boat: "vehicle",
37051
+ school_bus: "vehicle",
37052
+ garbage_truck: "vehicle",
37053
+ dog: "animal",
37054
+ cat: "animal",
37055
+ deer: "animal",
37056
+ horse: "animal",
37057
+ bird: "animal",
37058
+ raccoon: "animal",
37059
+ fox: "animal",
37060
+ bear: "animal",
37061
+ cow: "animal",
37062
+ squirrel: "animal",
37063
+ goat: "animal",
37064
+ rabbit: "animal",
37065
+ skunk: "animal",
37066
+ kangaroo: "animal",
37067
+ possum: "animal",
37068
+ rodent: "animal",
37069
+ package: "package"
37070
+ };
37071
+ /**
37072
+ * The per-model classMap for a Frigate / Frigate+ detector, derived from ITS
37073
+ * labelmap: each label resolves through {@link FRIGATE_PLUS_TO_MACRO} first,
37074
+ * then `COCO_TO_MACRO` (Frigate's default model ships the COCO-91 labelmap, so
37075
+ * a preset import may carry either vocabulary). A label neither knows is left
37076
+ * out, and `preserveOriginal: false` drops it in the executor — the same
37077
+ * contract as the COCO map, now with the Frigate+ vocabulary in it.
37078
+ */
37079
+ function buildFrigateClassMap(labels) {
37080
+ const mapping = {};
37081
+ for (const label of labels) {
37082
+ const target = FRIGATE_PLUS_TO_MACRO[label] ?? COCO_TO_MACRO.mapping[label];
37083
+ if (target !== void 0 && isClassMapMacroTarget(target)) mapping[label] = target;
37084
+ }
37085
+ return {
37086
+ mapping,
37087
+ preserveOriginal: false
37088
+ };
37089
+ }
37090
+ /**
37091
+ * Everything a Frigate / Frigate+ entry derives from its labelmap: the classMap
37092
+ * and the steps it fills (D715). Every Frigate builder spreads this, so the two
37093
+ * cannot be derived from different label lists. A COCO labelmap gets its map
37094
+ * and no fill.
37095
+ */
37096
+ function frigateLabelFields(labels) {
37097
+ const classMap = buildFrigateClassMap(labels);
37098
+ const fills = deriveClassifierFills(labels, classMap);
37099
+ return fills.length > 0 ? {
37100
+ classMap,
37101
+ fillsClassifierEffects: fills
37102
+ } : { classMap };
37103
+ }
36584
37104
  /**
36585
37105
  * Accessory device helpers — shared across drivers.
36586
37106
  *
@@ -49329,6 +49849,7 @@ function buildFrigateCatalogDescriptor(catalogId, overrides) {
49329
49849
  id: name,
49330
49850
  name
49331
49851
  })),
49852
+ ...frigateLabelFields(cat.labels),
49332
49853
  preprocessMode: "letterbox",
49333
49854
  provider: "frigate",
49334
49855
  license: cat.license,
@@ -49478,6 +49999,24 @@ async function ensureFormatsThenDistribute(modelId, deps) {
49478
49999
  }
49479
50000
  //#endregion
49480
50001
  //#region src/frigate/frigate-plus.ts
50002
+ /**
50003
+ * Frigate+ API client — the REAL api.frigate.video contract, verified against
50004
+ * frigate/plus.py (dev branch, 2026-08-21):
50005
+ *
50006
+ * - key format: `[uuid]:[40 hex]` (Frigate validates
50007
+ * `[a-z0-9]{8}-…-[a-z0-9]{12}:[a-z0-9]{40}`)
50008
+ * - GET /v1/auth/token with HTTP basic auth (key split on `:`) →
50009
+ * `{ accessToken, expires }`
50010
+ * - GET /v1/model/list with `Authorization: Bearer <accessToken>` → model list
50011
+ * - GET /v1/model/{id} → model info (`type`, `width`, `height`, `labelMap`,
50012
+ * `supportedDetectors`, …)
50013
+ * - GET /v1/model/{id}/signed_url → `{ url }` (presigned, plain GET)
50014
+ *
50015
+ * SECURITY: everything here runs SERVER-SIDE on the hub. The key comes from
50016
+ * the addon's settings store, is sent only to api.frigate.video, and is never
50017
+ * logged, never echoed in errors, never shipped to the browser. The fetch
50018
+ * function is injected so the contract is unit-testable offline.
50019
+ */
49481
50020
  var PLUS_API_HOST = "https://api.frigate.video";
49482
50021
  var PLUS_KEY_RE = /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}:[a-z0-9]{40}$/;
49483
50022
  function isValidPlusApiKey(key) {
@@ -49652,6 +50191,7 @@ function plusInfoToDescriptor(info, opts) {
49652
50191
  id: name,
49653
50192
  name
49654
50193
  })),
50194
+ ...frigateLabelFields(labels),
49655
50195
  preprocessMode: "letterbox",
49656
50196
  provider: "frigate",
49657
50197
  group: frigateVariantGroup(info.type, info.width),
@@ -1,5 +1,5 @@
1
1
  import { h as e, l as t, u as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { o as i, s as a } from "./responsive-orJ4AkQR.mjs";
2
+ import { o as i, s as a } from "./responsive-dgrtmGP7.mjs";
3
3
  import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
4
4
  var l = a("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-CHD2bVBg.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-Rw5qHN1M.mjs";
2
2
  export { t as get, e as init };
@@ -1,6 +1,6 @@
1
1
  import { c as e, g as t, h as n, l as r, n as i, p as a, r as o, t as s, u as c, y as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
2
  import "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
- import { s as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CX_tb6VB.mjs";
3
+ import { s as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DMrwYkbN.mjs";
4
4
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
5
5
  l();
6
6
  var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), f = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), p = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), m = (e) => {
@@ -1,5 +1,5 @@
1
1
  import { c as e, h as t, p as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { s as i } from "./responsive-orJ4AkQR.mjs";
2
+ import { s as i } from "./responsive-dgrtmGP7.mjs";
3
3
  var a = i("camera", [["path", {
4
4
  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",
5
5
  key: "18u6gg"