@camstack/types 1.1.47 → 1.1.49

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-BkhAiFKX.js");
3
- const require_event_category = require("./event-category-AkBNxg_X.js");
2
+ const require_sleep = require("./sleep-BfvNtyu8.js");
3
+ const require_event_category = require("./event-category-CGj9fI4L.js");
4
4
  const require_enums = require("./enums.js");
5
5
  const require_err_msg = require("./err-msg-COpsHMw2.js");
6
6
  let zod = require("zod");
@@ -870,6 +870,83 @@ var RecordingRetentionSchema = zod.z.object({
870
870
  maxSizeGb: zod.z.number().min(0).optional()
871
871
  });
872
872
  /**
873
+ * Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
874
+ * sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
875
+ * previews at. Five graduated steps; absent on a config = `standard` (the
876
+ * shipped default, matching `sheet-geometry`/`sheet-composer`).
877
+ *
878
+ * Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
879
+ * Each window's index sidecar carries its own tile dims, so a camera whose
880
+ * preset changed over time renders every historical window at the dims it was
881
+ * written with.
882
+ */
883
+ var ScrubThumbnailPresetSchema = zod.z.enum([
884
+ "minimal",
885
+ "low",
886
+ "standard",
887
+ "high",
888
+ "max"
889
+ ]);
890
+ /** The default preset when a config omits `scrubThumbnails`. */
891
+ var DEFAULT_SCRUB_THUMBNAIL_PRESET = "standard";
892
+ /**
893
+ * Preset → tile geometry + JPEG quality. Every step is 16:9; the graduated
894
+ * ladder trades sheet size (and remote fetch cost) for scrub crispness.
895
+ * `standard` matches the shipped `sheet-geometry`/`sheet-composer` defaults
896
+ * (480×270 q72), so an unset config is byte-identical to today. The map is
897
+ * strictly monotone in resolution AND quality across the ordered steps.
898
+ */
899
+ var SCRUB_THUMBNAIL_PRESETS = {
900
+ minimal: {
901
+ tileWidth: 240,
902
+ tileHeight: 135,
903
+ quality: 55
904
+ },
905
+ low: {
906
+ tileWidth: 320,
907
+ tileHeight: 180,
908
+ quality: 60
909
+ },
910
+ standard: {
911
+ tileWidth: 480,
912
+ tileHeight: 270,
913
+ quality: 72
914
+ },
915
+ high: {
916
+ tileWidth: 640,
917
+ tileHeight: 360,
918
+ quality: 80
919
+ },
920
+ max: {
921
+ tileWidth: 960,
922
+ tileHeight: 540,
923
+ quality: 85
924
+ }
925
+ };
926
+ /** Human labels for each preset (resolution-tagged), for settings UIs. */
927
+ var SCRUB_THUMBNAIL_PRESET_LABELS = {
928
+ minimal: "Minimal (240p)",
929
+ low: "Low (320p)",
930
+ standard: "Standard (480p)",
931
+ high: "High (640p)",
932
+ max: "Max (960p)"
933
+ };
934
+ /** Ordered low→high so a UI can render the ladder in graduated order. */
935
+ var SCRUB_THUMBNAIL_PRESET_ORDER = [
936
+ "minimal",
937
+ "low",
938
+ "standard",
939
+ "high",
940
+ "max"
941
+ ];
942
+ /**
943
+ * Resolve the geometry for a recording config's scrub-thumbnail preset,
944
+ * defaulting to `standard` when unset. Pure — no I/O.
945
+ */
946
+ function resolveScrubThumbnailGeometry(preset) {
947
+ return SCRUB_THUMBNAIL_PRESETS[preset ?? "standard"];
948
+ }
949
+ /**
873
950
  * The full per-camera recording intent — the wire shape of a RecordingTarget.
874
951
  *
875
952
  * `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
@@ -906,7 +983,14 @@ var RecordingConfigSchema = zod.z.object({
906
983
  * derived into bands once via `migrateConfigToBands`.
907
984
  */
908
985
  bands: zod.z.array(RecordingBandSchema).optional(),
909
- retention: RecordingRetentionSchema.optional()
986
+ retention: RecordingRetentionSchema.optional(),
987
+ /**
988
+ * Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
989
+ * timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
990
+ * windows only — existing sheets are immutable, and each window's index
991
+ * carries its own tile dims so mixed-preset history renders correctly.
992
+ */
993
+ scrubThumbnails: ScrubThumbnailPresetSchema.optional()
910
994
  });
911
995
  //#endregion
912
996
  //#region src/interfaces/recording-config-migrate.ts
@@ -2187,6 +2271,10 @@ var MACRO_LABELS = [
2187
2271
  {
2188
2272
  id: "animal",
2189
2273
  name: "Animal"
2274
+ },
2275
+ {
2276
+ id: "package",
2277
+ name: "Package"
2190
2278
  }
2191
2279
  ];
2192
2280
  var COCO_TO_MACRO = {
@@ -2209,7 +2297,10 @@ var COCO_TO_MACRO = {
2209
2297
  elephant: "animal",
2210
2298
  bear: "animal",
2211
2299
  zebra: "animal",
2212
- giraffe: "animal"
2300
+ giraffe: "animal",
2301
+ suitcase: "package",
2302
+ backpack: "package",
2303
+ handbag: "package"
2213
2304
  },
2214
2305
  preserveOriginal: false
2215
2306
  };
@@ -10917,7 +11008,11 @@ var ZoneRulesArraySchema = zod.z.array(ZoneRuleSchema).readonly();
10917
11008
  * Extend the enum here when a new gating consumer comes online (audio
10918
11009
  * gating, alert filtering, …) — no other surface needs to change.
10919
11010
  */
10920
- var ZoneRuleStageEnum = zod.z.enum(["motion", "detection"]);
11011
+ var ZoneRuleStageEnum = zod.z.enum([
11012
+ "motion",
11013
+ "detection",
11014
+ "package"
11015
+ ]);
10921
11016
  /**
10922
11017
  * Zone rules capability — per-camera CRUD over the {@link ZoneRule}
10923
11018
  * arrays that decide how each pipeline stage uses the polygon zones.
@@ -10961,16 +11056,24 @@ var zoneRulesCapability = {
10961
11056
  })
10962
11057
  },
10963
11058
  /**
10964
- * Runtime-state slice — both stages mirrored together so consumers
11059
+ * Runtime-state slice — every stage mirrored together so consumers
10965
11060
  * see one reactive handle (`device.state.zoneRules.value`) instead
10966
- * of two. Bulk-replace mutations on either stage write the full
10967
- * `{motion, detection}` shape, so subscribers always get the
11061
+ * of one per stage. Bulk-replace mutations on any stage write the full
11062
+ * `{motion, detection, package}` shape, so subscribers always get the
10968
11063
  * complete current set. Consumers that only care about one stage
10969
11064
  * just read the matching property.
11065
+ *
11066
+ * `package` backs the package-drop detector — a package zone is a
11067
+ * `ZoneRule` on the `'package'` stage referencing drawn polygons
11068
+ * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
11069
+ * The orchestrator provider that writes this stage lands in a later
11070
+ * slice; until then the mirror carries only `{motion, detection}` and
11071
+ * consumers read `package` as absent (treat as `[]`).
10970
11072
  */
10971
11073
  runtimeState: zod.z.object({
10972
11074
  motion: zod.z.array(ZoneRuleSchema).readonly(),
10973
- detection: zod.z.array(ZoneRuleSchema).readonly()
11075
+ detection: zod.z.array(ZoneRuleSchema).readonly(),
11076
+ package: zod.z.array(ZoneRuleSchema).readonly()
10974
11077
  })
10975
11078
  };
10976
11079
  //#endregion
@@ -12971,6 +13074,12 @@ function createSystemProxy(api) {
12971
13074
  unassignPlates: (input) => dispatch("plateGallery", "unassignPlates", "mutation", input)
12972
13075
  },
12973
13076
  recording: { getStorageUsage: (input) => dispatch("recording", "getStorageUsage", "query", input) },
13077
+ recordingExport: {
13078
+ getExport: (input) => dispatch("recordingExport", "getExport", "query", input),
13079
+ cancelExport: (input) => dispatch("recordingExport", "cancelExport", "mutation", input),
13080
+ deleteExport: (input) => dispatch("recordingExport", "deleteExport", "mutation", input),
13081
+ getDownloadUrl: (input) => dispatch("recordingExport", "getDownloadUrl", "query", input)
13082
+ },
12974
13083
  serverManagement: {
12975
13084
  getServerPackageStatus: (input) => dispatch("serverManagement", "getServerPackageStatus", "query", input),
12976
13085
  checkServerUpdate: (input) => dispatch("serverManagement", "checkServerUpdate", "mutation", input),
@@ -18235,6 +18344,7 @@ var EventKindIconSchema = zod.z.enum([
18235
18344
  "smoke",
18236
18345
  "water",
18237
18346
  "button",
18347
+ "package",
18238
18348
  "generic"
18239
18349
  ]);
18240
18350
  var EventKindCategorySchema = zod.z.enum([
@@ -18242,7 +18352,8 @@ var EventKindCategorySchema = zod.z.enum([
18242
18352
  "audio",
18243
18353
  "detection",
18244
18354
  "sensor",
18245
- "custom"
18355
+ "custom",
18356
+ "package"
18246
18357
  ]);
18247
18358
  var EventKindDescriptorSchema = zod.z.object({
18248
18359
  /** Stable kind id (e.g. 'motion', 'person', 'contact'). */
@@ -23493,6 +23604,127 @@ var recordingCapability = {
23493
23604
  }
23494
23605
  };
23495
23606
  //#endregion
23607
+ //#region src/capabilities/recording-export.cap.ts
23608
+ /**
23609
+ * `recordingExport` cap — render a footage time range into a single downloadable
23610
+ * MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
23611
+ * bounded lifetime with a durable history, auto-expiry, and optional
23612
+ * delete-after-download.
23613
+ *
23614
+ * Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
23615
+ * recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
23616
+ * default `hub`) registers it. Device-scoped methods carry `deviceId` in their
23617
+ * input and dispatch to that single provider; the render runs on the node that
23618
+ * owns the footage (no cross-node segment transfer). Download rides the
23619
+ * framework addon data-plane. State persists in a DurableState blob (NOT
23620
+ * SQLite); history rows survive file deletion for audit.
23621
+ */
23622
+ /** Playback-speed multiplier for the render (1 = realtime). */
23623
+ var ExportSpeedSchema = zod.z.number().min(.25).max(32);
23624
+ /** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
23625
+ var ExportTimelapseSchema = zod.z.object({
23626
+ everyMs: zod.z.number().int().positive(),
23627
+ outputFps: zod.z.number().int().min(1).max(60).optional()
23628
+ });
23629
+ /**
23630
+ * Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
23631
+ * is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
23632
+ * silent. `maxLifeMs` bounds how long the finished file is kept;
23633
+ * `deleteAfterDownload` removes it shortly after the first complete download.
23634
+ */
23635
+ var ExportOptionsSchema = zod.z.object({
23636
+ speed: ExportSpeedSchema.optional(),
23637
+ timelapse: ExportTimelapseSchema.optional(),
23638
+ includeAudio: zod.z.boolean(),
23639
+ maxLifeMs: zod.z.number().int().positive(),
23640
+ deleteAfterDownload: zod.z.boolean(),
23641
+ title: zod.z.string().max(200).optional()
23642
+ }).superRefine((v, ctx) => {
23643
+ if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
23644
+ code: zod.z.ZodIssueCode.custom,
23645
+ message: "speed and timelapse are mutually exclusive",
23646
+ path: ["timelapse"]
23647
+ });
23648
+ });
23649
+ var ExportStateSchema = zod.z.enum([
23650
+ "queued",
23651
+ "rendering",
23652
+ "ready",
23653
+ "failed",
23654
+ "expired",
23655
+ "deleted"
23656
+ ]);
23657
+ /** One export job / history row. */
23658
+ var ExportRecordSchema = zod.z.object({
23659
+ id: zod.z.string(),
23660
+ deviceId: zod.z.number(),
23661
+ profile: zod.z.string(),
23662
+ fromMs: zod.z.number(),
23663
+ toMs: zod.z.number(),
23664
+ options: ExportOptionsSchema,
23665
+ state: ExportStateSchema,
23666
+ /** 0–100 while rendering; null otherwise. */
23667
+ progressPct: zod.z.number().nullable(),
23668
+ /** File size once ready; null before. */
23669
+ fileBytes: zod.z.number().nullable(),
23670
+ expiresAt: zod.z.number(),
23671
+ deleteAfterDownload: zod.z.boolean(),
23672
+ /** Epoch of the first complete download; null until then. */
23673
+ downloadedAt: zod.z.number().nullable(),
23674
+ createdAt: zod.z.number(),
23675
+ /** User id/name that requested the export. */
23676
+ createdBy: zod.z.string(),
23677
+ /** Failure reason when state is 'failed'; null otherwise. */
23678
+ error: zod.z.string().nullable()
23679
+ });
23680
+ /** Candidate download URLs (LAN first, then operator extra hosts). */
23681
+ var ExportDownloadSchema = zod.z.object({
23682
+ url: zod.z.string(),
23683
+ endpoints: zod.z.array(zod.z.string())
23684
+ });
23685
+ var recordingExportCapability = {
23686
+ name: "recordingExport",
23687
+ scope: "system",
23688
+ mode: "singleton",
23689
+ methods: {
23690
+ /** Queue a render of `[fromMs,toMs)` for `deviceId`/`profile`. Fails fast
23691
+ * when no footage covers the range. Returns the queued record. */
23692
+ createExport: require_sleep.method(zod.z.object({
23693
+ deviceId: zod.z.number(),
23694
+ profile: zod.z.string(),
23695
+ fromMs: zod.z.number(),
23696
+ toMs: zod.z.number(),
23697
+ options: ExportOptionsSchema
23698
+ }), ExportRecordSchema, {
23699
+ kind: "mutation",
23700
+ auth: "protected"
23701
+ }),
23702
+ /** All export rows (history included), optionally scoped to one device. */
23703
+ listExports: require_sleep.method(zod.z.object({ deviceId: zod.z.number().optional() }), zod.z.array(ExportRecordSchema), {
23704
+ kind: "query",
23705
+ auth: "protected"
23706
+ }),
23707
+ getExport: require_sleep.method(zod.z.object({ exportId: zod.z.string() }), ExportRecordSchema, {
23708
+ kind: "query",
23709
+ auth: "protected"
23710
+ }),
23711
+ /** Abort a queued/rendering export; the partial file is removed. */
23712
+ cancelExport: require_sleep.method(zod.z.object({ exportId: zod.z.string() }), ExportRecordSchema, {
23713
+ kind: "mutation",
23714
+ auth: "protected"
23715
+ }),
23716
+ /** Remove the file but keep the history row (state → 'deleted'). */
23717
+ deleteExport: require_sleep.method(zod.z.object({ exportId: zod.z.string() }), ExportRecordSchema, {
23718
+ kind: "mutation",
23719
+ auth: "protected"
23720
+ }),
23721
+ getDownloadUrl: require_sleep.method(zod.z.object({ exportId: zod.z.string() }), ExportDownloadSchema, {
23722
+ kind: "query",
23723
+ auth: "protected"
23724
+ })
23725
+ }
23726
+ };
23727
+ //#endregion
23496
23728
  //#region src/capabilities/stream-catalog.cap.ts
23497
23729
  /**
23498
23730
  * One publishable camera stream as its OWNING PROVIDER describes it — the same
@@ -24284,6 +24516,7 @@ var CAPABILITY_NAMES = {
24284
24516
  ptzAutotrack: "ptz-autotrack",
24285
24517
  reboot: "reboot",
24286
24518
  recording: "recording",
24519
+ recordingExport: "recordingExport",
24287
24520
  sceneMonitor: "scene-monitor",
24288
24521
  scriptRunner: "script-runner",
24289
24522
  serverManagement: "server-management",
@@ -24749,6 +24982,10 @@ var CAPABILITY_ROUTER_KEYS = [
24749
24982
  key: "recording",
24750
24983
  name: "recording"
24751
24984
  },
24985
+ {
24986
+ key: "recordingExport",
24987
+ name: "recordingExport"
24988
+ },
24752
24989
  {
24753
24990
  key: "sceneMonitor",
24754
24991
  name: "scene-monitor"
@@ -25003,6 +25240,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
25003
25240
  ptzAutotrackCapability,
25004
25241
  rebootCapability,
25005
25242
  recordingCapability,
25243
+ recordingExportCapability,
25006
25244
  sceneMonitorCapability,
25007
25245
  scriptRunnerCapability,
25008
25246
  serverManagementCapability,
@@ -28730,6 +28968,42 @@ var METHOD_ACCESS_MAP = Object.freeze({
28730
28968
  addonId: null,
28731
28969
  access: "create"
28732
28970
  },
28971
+ "recordingExport.cancelExport": {
28972
+ capName: "recordingExport",
28973
+ capScope: "system",
28974
+ addonId: null,
28975
+ access: "create"
28976
+ },
28977
+ "recordingExport.createExport": {
28978
+ capName: "recordingExport",
28979
+ capScope: "system",
28980
+ addonId: null,
28981
+ access: "create"
28982
+ },
28983
+ "recordingExport.deleteExport": {
28984
+ capName: "recordingExport",
28985
+ capScope: "system",
28986
+ addonId: null,
28987
+ access: "delete"
28988
+ },
28989
+ "recordingExport.getDownloadUrl": {
28990
+ capName: "recordingExport",
28991
+ capScope: "system",
28992
+ addonId: null,
28993
+ access: "view"
28994
+ },
28995
+ "recordingExport.getExport": {
28996
+ capName: "recordingExport",
28997
+ capScope: "system",
28998
+ addonId: null,
28999
+ access: "view"
29000
+ },
29001
+ "recordingExport.listExports": {
29002
+ capName: "recordingExport",
29003
+ capScope: "system",
29004
+ addonId: null,
29005
+ access: "view"
29006
+ },
28733
29007
  "sceneMonitor.captureReference": {
28734
29008
  capName: "scene-monitor",
28735
29009
  capScope: "device",
@@ -29941,6 +30215,7 @@ var KNOWN_CAP_NAMES = [
29941
30215
  "ptz-autotrack",
29942
30216
  "reboot",
29943
30217
  "recording",
30218
+ "recordingExport",
29944
30219
  "scene-monitor",
29945
30220
  "script-runner",
29946
30221
  "server-management",
@@ -30077,6 +30352,7 @@ var SYSTEM_CAP_NAMES = [
30077
30352
  "plate-gallery",
30078
30353
  "platform-probe",
30079
30354
  "recording",
30355
+ "recordingExport",
30080
30356
  "server-management",
30081
30357
  "settings-store",
30082
30358
  "smtp-provider",
@@ -30825,6 +31101,7 @@ exports.DEFAULT_AUDIO_ANALYZER_CONFIG = DEFAULT_AUDIO_ANALYZER_CONFIG;
30825
31101
  exports.DEFAULT_DECODER_HWACCEL_CONFIG = DEFAULT_DECODER_HWACCEL_CONFIG;
30826
31102
  exports.DEFAULT_FEATURES = DEFAULT_FEATURES;
30827
31103
  exports.DEFAULT_RETENTION = DEFAULT_RETENTION;
31104
+ exports.DEFAULT_SCRUB_THUMBNAIL_PRESET = DEFAULT_SCRUB_THUMBNAIL_PRESET;
30828
31105
  exports.DEVICE_CAP_NAMES = DEVICE_CAP_NAMES;
30829
31106
  exports.DEVICE_PROFILES = DEVICE_PROFILES;
30830
31107
  exports.DEVICE_SETTINGS_CONTRIBUTION_METHODS = require_sleep.DEVICE_SETTINGS_CONTRIBUTION_METHODS;
@@ -30885,8 +31162,14 @@ exports.EventKindDescriptorSchema = EventKindDescriptorSchema;
30885
31162
  exports.EventKindIconSchema = EventKindIconSchema;
30886
31163
  exports.EventKindSchema = EventKindSchema;
30887
31164
  exports.EventSourceType = require_enums.EventSourceType$1;
31165
+ exports.ExportDownloadSchema = ExportDownloadSchema;
31166
+ exports.ExportOptionsSchema = ExportOptionsSchema;
31167
+ exports.ExportRecordSchema = ExportRecordSchema;
30888
31168
  exports.ExportSetupFieldSchema = ExportSetupFieldSchema;
30889
31169
  exports.ExportSetupSchema = ExportSetupSchema;
31170
+ exports.ExportSpeedSchema = ExportSpeedSchema;
31171
+ exports.ExportStateSchema = ExportStateSchema;
31172
+ exports.ExportTimelapseSchema = ExportTimelapseSchema;
30890
31173
  exports.ExposedDeviceSchema = ExposedDeviceSchema;
30891
31174
  exports.ExposureModeSchema = ExposureModeSchema;
30892
31175
  exports.ExpressionEvalError = ExpressionEvalError;
@@ -31118,6 +31401,9 @@ exports.RunnerFrameSourceSchema = RunnerFrameSourceSchema;
31118
31401
  exports.RunnerLocalLoadSchema = RunnerLocalLoadSchema;
31119
31402
  exports.RunnerLocalMetricsSchema = RunnerLocalMetricsSchema;
31120
31403
  exports.SCOPE_PRESETS = SCOPE_PRESETS;
31404
+ exports.SCRUB_THUMBNAIL_PRESETS = SCRUB_THUMBNAIL_PRESETS;
31405
+ exports.SCRUB_THUMBNAIL_PRESET_LABELS = SCRUB_THUMBNAIL_PRESET_LABELS;
31406
+ exports.SCRUB_THUMBNAIL_PRESET_ORDER = SCRUB_THUMBNAIL_PRESET_ORDER;
31121
31407
  exports.SOURCE_INFO_METADATA_KEY = SOURCE_INFO_METADATA_KEY;
31122
31408
  exports.STREAM_PROFILE_META = STREAM_PROFILE_META;
31123
31409
  exports.STREAM_QUALITY_LABELS = STREAM_QUALITY_LABELS;
@@ -31133,6 +31419,7 @@ exports.ScopedTokenSchema = ScopedTokenSchema;
31133
31419
  exports.ScopedTokenSummarySchema = ScopedTokenSummarySchema;
31134
31420
  exports.ScoredObjectEventSchema = ScoredObjectEventSchema;
31135
31421
  exports.ScriptRunnerStatusSchema = ScriptRunnerStatusSchema;
31422
+ exports.ScrubThumbnailPresetSchema = ScrubThumbnailPresetSchema;
31136
31423
  exports.SearchResultSchema = SearchResultSchema;
31137
31424
  exports.SendEmailInputSchema = SendEmailInputSchema;
31138
31425
  exports.SendEmailResultSchema = SendEmailResultSchema;
@@ -31460,6 +31747,7 @@ exports.readNodePin = readNodePin;
31460
31747
  exports.readinessKey = require_sleep.readinessKey;
31461
31748
  exports.rebootCapability = rebootCapability;
31462
31749
  exports.recordingCapability = recordingCapability;
31750
+ exports.recordingExportCapability = recordingExportCapability;
31463
31751
  exports.rectsToCells = rectsToCells;
31464
31752
  exports.requiresPython = requiresPython;
31465
31753
  exports.resolveAddonExecution = resolveAddonExecution;
@@ -31473,6 +31761,7 @@ exports.resolveFormat = resolveFormat;
31473
31761
  exports.resolveHydratedFieldValue = require_sleep.resolveHydratedFieldValue;
31474
31762
  exports.resolveModelFormat = resolveModelFormat;
31475
31763
  exports.resolveRunnerId = resolveRunnerId;
31764
+ exports.resolveScrubThumbnailGeometry = resolveScrubThumbnailGeometry;
31476
31765
  exports.resolveVariantModelId = resolveVariantModelId;
31477
31766
  exports.runInferenceStep = runInferenceStep;
31478
31767
  exports.runtimeDevices = runtimeDevices;