@happyvertical/smrt-video 0.35.0 → 0.35.2

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.d.ts CHANGED
@@ -1228,7 +1228,7 @@ export declare class VideoWorkflow extends SmrtObject {
1228
1228
  * @param params - Key-value pairs of parameters to inject
1229
1229
  * @returns Modified workflow JSON or null if no workflowJson set
1230
1230
  */
1231
- injectParameters(params: Record<string, any>): object | null;
1231
+ injectParameters(params: Record<string, unknown>): object | null;
1232
1232
  }
1233
1233
 
1234
1234
  /**
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ function getQueryRows(result) {
20
20
  if (Array.isArray(result)) {
21
21
  return result;
22
22
  }
23
- if (Array.isArray(result?.rows)) {
23
+ if (typeof result === "object" && result !== null && "rows" in result && Array.isArray(result.rows)) {
24
24
  return result.rows;
25
25
  }
26
26
  return [];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/__smrt-register__.ts","../src/owned-asset-utils.ts","../src/performer.ts","../src/scene.ts","../src/character.ts","../src/characters.ts","../src/composite-job.ts","../src/video-composition.ts","../src/video-compositions.ts","../src/video-sequence.ts","../src/video-sequences.ts","../src/video-shot.ts","../src/video-shot-character.ts","../src/video-shot-characters.ts","../src/video-shots.ts","../src/video-workflow.ts","../src/character-asset.ts","../src/character-owned-asset.ts","../src/character-assets.ts","../src/performer-asset.ts","../src/performer-owned-asset.ts","../src/performer-assets.ts","../src/scene-asset.ts","../src/scene-owned-asset.ts","../src/scene-assets.ts","../src/video-composition-asset.ts","../src/video-sequence-asset.ts","../src/video-shot-asset.ts"],"sourcesContent":["/**\n * Self-registers this package's build-time manifest before any @smrt() decorator\n * in the package fires. Fixes issue #1132: in consumer runtimes (tsx, SvelteKit\n * SSR, plain `vite dev`) the decorator's synchronous manifest lookup previously\n * missed because no step populated the global manifest cache — classes got\n * registered with zero fields and `save()` / `toJSON()` silently dropped every\n * declared property.\n *\n * Import this module as the first statement in `src/index.ts` so its top-level\n * side effect runs ahead of any class module's @smrt() decorator.\n *\n * Silent no-op in dev/test, where the vitest plugin already populates manifests\n * via a different path. Only needs to succeed in the published dist output.\n *\n * @see https://github.com/happyvertical/smrt/issues/1132\n */\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\n// `new URL('./manifest.json', import.meta.url)` resolves at runtime to the\n// manifest sitting next to this module's compiled output. Vite warns at build\n// time that it cannot pre-resolve the URL; that is the intended behavior —\n// the URL must resolve to dist/manifest.json at runtime, not be inlined.\nObjectRegistry.registerPackageManifest(\n new URL('./manifest.json', import.meta.url),\n);\n","import { type Asset, AssetCollection } from '@happyvertical/smrt-assets';\nimport { withSystemContext } from '@happyvertical/smrt-tenancy';\n\n// Video roles intentionally allow hyphens for legacy compatibility\n// (`seed-image`, `base-motion`, `env-map`, etc.).\nconst VIDEO_ASSET_ROLE_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_-]*$/;\nconst VIDEO_ASSET_OWNER_COLUMNS = [\n 'character_id',\n 'performer_id',\n 'scene_id',\n 'video_shot_id',\n 'video_sequence_id',\n 'video_composition_id',\n] as const;\n\nexport type VideoAssetOwnerColumn = (typeof VIDEO_ASSET_OWNER_COLUMNS)[number];\n\nfunction getQueryRows(result: any): Record<string, unknown>[] {\n if (Array.isArray(result)) {\n return result as Record<string, unknown>[];\n }\n\n if (Array.isArray(result?.rows)) {\n return result.rows as Record<string, unknown>[];\n }\n\n return [];\n}\n\nfunction isMissingSchemaError(error: unknown, target?: string): boolean {\n const message =\n error instanceof Error\n ? error.message.toLowerCase()\n : String(error).toLowerCase();\n\n const isMissing =\n message.includes('no such table') ||\n message.includes('no such column') ||\n message.includes('does not exist') ||\n message.includes('unknown column');\n\n if (!isMissing) {\n return false;\n }\n\n return !target || message.includes(target.toLowerCase());\n}\n\nfunction buildPlaceholders(count: number): string {\n return Array.from({ length: count }, () => '?').join(', ');\n}\n\nfunction uniqueAssetIds(\n assetIds: Iterable<string | null | undefined>,\n): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n\n for (const assetId of assetIds) {\n if (!assetId || seen.has(assetId)) {\n continue;\n }\n\n seen.add(assetId);\n result.push(assetId);\n }\n\n return result;\n}\n\nexport function mergeOwnedAssetIds(\n ...groups: Array<Iterable<string | null | undefined>>\n): string[] {\n const seen = new Set<string>();\n const merged: string[] = [];\n\n for (const group of groups) {\n for (const assetId of group) {\n if (!assetId || seen.has(assetId)) {\n continue;\n }\n\n seen.add(assetId);\n merged.push(assetId);\n }\n }\n\n return merged;\n}\n\nexport function assertValidVideoAssetRole(role: string): void {\n if (!VIDEO_ASSET_ROLE_PATTERN.test(role)) {\n throw new Error(\n `Invalid asset role \"${role}\"; must start with a letter or underscore and contain only letters, digits, underscores, and hyphens`,\n );\n }\n}\n\nexport function assertValidVideoAssetSortOrder(sortOrder: number): void {\n if (!Number.isInteger(sortOrder) || sortOrder < 0 || sortOrder > 2147483647) {\n throw new Error(\n `Invalid sortOrder \"${sortOrder}\"; must be a non-negative integer`,\n );\n }\n}\n\nexport async function resolveOwnedAssets(\n db: any,\n tenantId: string | null | undefined,\n assetIds: Iterable<string | null | undefined>,\n): Promise<Asset[]> {\n const orderedIds = uniqueAssetIds(assetIds);\n if (orderedIds.length === 0) {\n return [];\n }\n\n const assets = await AssetCollection.create({ db });\n let resolved: Asset[];\n try {\n resolved = tenantId\n ? await withSystemContext(async () => assets.listByIds(orderedIds))\n : await assets.listByIds(orderedIds);\n } catch (error) {\n if (isMissingSchemaError(error, 'assets')) {\n return [];\n }\n\n throw error;\n }\n\n const visibleAssets = tenantId\n ? resolved.filter(\n (asset) => asset.tenantId === tenantId || asset.tenantId === null,\n )\n : resolved;\n const assetsById = new Map(\n visibleAssets\n .filter((asset) => asset.id)\n .map((asset) => [asset.id as string, asset]),\n );\n\n return orderedIds\n .map((assetId) => assetsById.get(assetId))\n .filter(Boolean) as Asset[];\n}\n\nexport async function listCanonicalOwnedAssetIds<\n T extends { assetId: string },\n>(options: {\n tableName: string;\n loadLinks: () => Promise<T[]>;\n}): Promise<string[]> {\n try {\n return uniqueAssetIds(\n (await options.loadLinks()).map((link) => link.assetId),\n );\n } catch (error) {\n if (isMissingSchemaError(error, options.tableName)) {\n return [];\n }\n\n throw error;\n }\n}\n\nexport async function listLegacyOwnedAssetIds(options: {\n db: any;\n ownerColumn: VideoAssetOwnerColumn;\n ownerId: string;\n role?: string;\n metaTypes: string[];\n}): Promise<string[]> {\n const { db, ownerColumn, ownerId, role, metaTypes } = options;\n if (!ownerId || metaTypes.length === 0) {\n return [];\n }\n\n if (!VIDEO_ASSET_OWNER_COLUMNS.includes(ownerColumn)) {\n throw new Error(`Unsupported video asset owner column \"${ownerColumn}\"`);\n }\n\n const params: unknown[] = [ownerId, ...metaTypes];\n const clauses = [\n `${ownerColumn} = ?`,\n `_meta_type IN (${buildPlaceholders(metaTypes.length)})`,\n ];\n\n if (role) {\n clauses.push('role = ?');\n params.push(role);\n }\n\n try {\n const result = await db.query(\n `SELECT id\n FROM assets\n WHERE ${clauses.join(' AND ')}\n ORDER BY created_at ASC, id ASC`,\n ...params,\n );\n\n return uniqueAssetIds(\n getQueryRows(result).map((row) => String(row?.id || '')),\n );\n } catch (error) {\n if (isMissingSchemaError(error)) {\n return [];\n }\n\n throw error;\n }\n}\n\nexport function legacyVideoAssetMetaTypes(className: string): string[] {\n return [className, `@happyvertical/smrt-video:${className}`];\n}\n","/**\n * Performer Model\n *\n * Represents the physical likeness/face DNA for consistent face generation.\n * A Performer can play multiple Characters (PersonalityProfiles).\n * Ensures face consistency via IP-Adapter FaceID.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { crossPackageRef, SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n assertValidVideoAssetRole,\n assertValidVideoAssetSortOrder,\n legacyVideoAssetMetaTypes,\n listCanonicalOwnedAssetIds,\n listLegacyOwnedAssetIds,\n mergeOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { PerformerAssetRole } from './performer-asset.js';\n\n/**\n * Performer DNA for IP-Adapter FaceID consistency\n */\nexport interface PerformerDNA {\n /** Gender */\n gender: 'male' | 'female' | 'neutral';\n\n /** Age range */\n ageRange:\n | 'child'\n | 'teen'\n | 'young_adult'\n | 'adult'\n | 'middle_aged'\n | 'senior';\n\n /** Face embedding for IP-Adapter FaceID (512-dim vector) */\n faceEmbedding?: number[];\n\n /** Default clothing style (can be overridden per Character) */\n defaultClothing?: {\n style: 'business' | 'casual' | 'formal' | 'outdoor';\n colors?: string[];\n description?: string;\n };\n\n /** IP-Adapter weight for consistency (0.5-1.0) */\n ipAdapterWeight: number;\n\n /** FaceID weight for face consistency */\n faceIdWeight?: number;\n}\n\n/**\n * Performer status\n */\nexport type PerformerStatus = 'pending' | 'ready';\n\n/**\n * Performer creation options\n */\nexport interface PerformerOptions extends SmrtObjectOptions {\n /** Human-readable name */\n name?: string;\n\n /** Description */\n description?: string | null;\n\n /** Performer DNA for consistent face generation */\n dna?: PerformerDNA;\n\n /** Reference images for IP-Adapter (multiple angles/expressions) */\n referenceAssetIds?: string[];\n\n /** Generated seed image asset ID */\n seedImageAssetId?: string | null;\n\n /** Default voice profile for this performer */\n voiceProfileId?: string | null;\n\n /** Performer status */\n status?: PerformerStatus;\n\n /** 1-1 profile record for this performer */\n profileId?: string | null;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Performer - The physical likeness/face DNA\n *\n * A Performer represents a person's visual identity for consistent\n * face generation across multiple Characters. One Performer can play\n * many Characters (e.g., same face as \"Evening Anchor\" and \"Weekend Host\").\n *\n * @example\n * ```typescript\n * import { Performer } from '@happyvertical/smrt-video';\n *\n * const performer = new Performer({\n * name: 'Alex Bentley',\n * dna: {\n * gender: 'male',\n * ageRange: 'adult',\n * ipAdapterWeight: 0.75,\n * },\n * referenceAssetIds: ['ref-img-1', 'ref-img-2'],\n * });\n * await performer.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class Performer extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Human-readable name */\n name: string = '';\n\n /** Description */\n description: string | null = null;\n\n /** Performer DNA for consistent face generation */\n dna: PerformerDNA = {\n gender: 'neutral',\n ageRange: 'adult',\n ipAdapterWeight: 0.7,\n };\n\n /** Reference images for IP-Adapter (multiple angles/expressions) */\n referenceAssetIds: string[] = [];\n\n /** Generated seed image asset ID */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n seedImageAssetId: string | null = null;\n\n /** Default voice profile for this performer */\n @crossPackageRef('@happyvertical/smrt-voice:VoiceProfile')\n voiceProfileId: string | null = null;\n\n /** Performer status */\n status: PerformerStatus = 'pending';\n\n /** 1-1 profile record for this performer */\n @crossPackageRef('@happyvertical/smrt-profiles:Profile')\n profileId: string | null = null;\n\n constructor(options: PerformerOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.dna !== undefined) this.dna = options.dna;\n if (options.referenceAssetIds !== undefined)\n this.referenceAssetIds = options.referenceAssetIds;\n if (options.seedImageAssetId !== undefined)\n this.seedImageAssetId = options.seedImageAssetId;\n if (options.voiceProfileId !== undefined)\n this.voiceProfileId = options.voiceProfileId;\n if (options.status !== undefined) this.status = options.status;\n if (options.profileId !== undefined) this.profileId = options.profileId;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n private async getPerformerAssetCollection() {\n const { PerformerOwnedAssetCollection } = await import(\n './performer-assets.js'\n );\n return PerformerOwnedAssetCollection.create({ db: this.db });\n }\n\n private getLegacyFieldAssetIds(role?: PerformerAssetRole): string[] {\n if (role === 'reference') {\n return this.referenceAssetIds;\n }\n\n if (role === 'seed') {\n return this.seedImageAssetId ? [this.seedImageAssetId] : [];\n }\n\n return [...this.referenceAssetIds, this.seedImageAssetId].filter(\n (assetId): assetId is string => Boolean(assetId),\n );\n }\n\n private setLegacyFieldAssetId(\n role: PerformerAssetRole,\n assetId: string,\n ): boolean {\n if (role === 'seed') {\n if (this.seedImageAssetId === assetId) {\n return false;\n }\n\n this.seedImageAssetId = assetId;\n return true;\n }\n\n if (this.referenceAssetIds.includes(assetId)) {\n return false;\n }\n\n this.referenceAssetIds = [...this.referenceAssetIds, assetId];\n return true;\n }\n\n private clearLegacyFieldAssetId(\n assetId: string,\n role?: PerformerAssetRole,\n ): boolean {\n let changed = false;\n\n if ((!role || role === 'seed') && this.seedImageAssetId === assetId) {\n this.seedImageAssetId = null;\n changed = true;\n }\n\n if (!role || role === 'reference') {\n const remaining = this.referenceAssetIds.filter(\n (referenceAssetId) => referenceAssetId !== assetId,\n );\n\n if (remaining.length !== this.referenceAssetIds.length) {\n this.referenceAssetIds = remaining;\n changed = true;\n }\n }\n\n return changed;\n }\n\n async getAssets(role?: PerformerAssetRole): Promise<Asset[]> {\n const canonicalAssetIds = this.id\n ? await listCanonicalOwnedAssetIds({\n tableName: 'performer_assets',\n loadLinks: async () =>\n (await this.getPerformerAssetCollection()).byLeft(\n this.id as string,\n role ? { role } : {},\n ),\n })\n : [];\n const legacyFieldAssetIds = this.getLegacyFieldAssetIds(role);\n const legacyOwnedAssetIds = this.id\n ? await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'performer_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('PerformerAsset'),\n })\n : [];\n\n return resolveOwnedAssets(\n this.db,\n this.tenantId,\n mergeOwnedAssetIds(\n canonicalAssetIds,\n legacyFieldAssetIds,\n legacyOwnedAssetIds,\n ),\n );\n }\n\n async getAssetByRole(role: PerformerAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n async addAsset(\n asset: Asset,\n role: PerformerAssetRole = 'reference',\n sortOrder = 0,\n ): Promise<void> {\n if (!this.id || !asset.id) {\n throw new Error('Cannot associate unsaved performer or asset');\n }\n\n assertValidVideoAssetRole(role);\n assertValidVideoAssetSortOrder(sortOrder);\n\n const performerAssets = await this.getPerformerAssetCollection();\n await performerAssets.attach(this.id, asset.id, {\n role,\n sortOrder,\n tenantId: this.tenantId,\n });\n\n if (this.setLegacyFieldAssetId(role, asset.id)) {\n await this.save();\n }\n }\n\n async removeAsset(assetId: string, role?: PerformerAssetRole): Promise<void> {\n if (!this.id) {\n return;\n }\n\n const performerAssets = await this.getPerformerAssetCollection();\n await performerAssets.detach(this.id, assetId, role ? { role } : {});\n\n if (this.clearLegacyFieldAssetId(assetId, role)) {\n await this.save();\n }\n }\n\n /** Check if the performer has reference images */\n get hasReferences(): boolean {\n return this.referenceAssetIds.length > 0;\n }\n\n /** Check if the performer has a face embedding */\n get hasFaceEmbedding(): boolean {\n return (\n Array.isArray(this.dna.faceEmbedding) && this.dna.faceEmbedding.length > 0\n );\n }\n\n /** Check if the performer is ready for generation */\n get isReady(): boolean {\n return this.status === 'ready' && this.hasReferences;\n }\n}\n","/**\n * Scene Model\n *\n * Represents a virtual production scene (background environment).\n * Supports 360° panoramas, standard images, and video backgrounds.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { crossPackageRef, SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n assertValidVideoAssetRole,\n assertValidVideoAssetSortOrder,\n legacyVideoAssetMetaTypes,\n listCanonicalOwnedAssetIds,\n listLegacyOwnedAssetIds,\n mergeOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { SceneAssetRole } from './scene-asset.js';\n\n/**\n * Viewpoint extracted from 360° scene\n */\nexport interface SceneViewpoint {\n /** Viewpoint identifier */\n id: string;\n\n /** Human-readable name */\n name: string;\n\n /** Horizontal rotation (-180 to 180°) */\n pan: number;\n\n /** Vertical rotation (-90 to 90°) */\n tilt: number;\n\n /** Field of view (60-120°) */\n fov: number;\n\n /** Generated rectilinear image asset ID */\n extractedAssetId?: string;\n\n /** Viewpoint-specific lighting profile */\n lightingProfile?: LightingProfile;\n}\n\n/**\n * Lighting profile for IC-Light matching\n */\nexport interface LightingProfile {\n /** Dominant light direction (normalized vector) */\n direction?: { x: number; y: number; z: number };\n\n /** Light color temperature (Kelvin) */\n colorTemperature?: number;\n\n /** Ambient light intensity (0-1) */\n ambientIntensity?: number;\n\n /** Key light intensity (0-1) */\n keyLightIntensity?: number;\n\n /** Shadow softness (0-1) */\n shadowSoftness?: number;\n\n /** Environment map asset ID for reflections */\n envMapAssetId?: string;\n}\n\n/**\n * Anchor point for character placement in scene\n */\nexport interface AnchorPoint {\n /** Anchor point identifier */\n id: string;\n\n /** Human-readable name */\n name: string;\n\n /** Position as normalized coordinates (0-1) */\n position: { x: number; y: number };\n\n /** Suggested character scale at this point */\n suggestedScale: number;\n\n /** Ground plane Y coordinate for perspective */\n groundY: number;\n\n /** Optional viewpoint this anchor belongs to */\n viewpointId?: string;\n}\n\n/**\n * Scene source type\n */\nexport type SceneSourceType =\n | 'image'\n | 'video'\n | 'panorama_360'\n | 'panorama_180';\n\n/**\n * Scene projection type\n */\nexport type SceneProjection = 'equirectangular' | 'cubemap';\n\n/**\n * Scene status\n */\nexport type SceneStatus = 'pending' | 'processing' | 'ready' | 'failed';\n\n/**\n * Scene creation options\n */\nexport interface SceneOptions extends SmrtObjectOptions {\n /** Human-readable name */\n name?: string;\n\n /** Description */\n description?: string | null;\n\n /** Source media asset ID */\n sourceAssetId?: string | null;\n\n /** Type of source media */\n sourceType?: SceneSourceType;\n\n /** Projection type for panoramas */\n projection?: SceneProjection | null;\n\n /** Extracted camera angles from 360° panoramas */\n viewpoints?: SceneViewpoint[];\n\n /** Lighting analysis for IC-Light matching */\n lightingProfile?: LightingProfile | null;\n\n /** Location metadata */\n location?: {\n name: string;\n coordinates?: { lat: number; lng: number };\n } | null;\n\n /** Anchor points for character placement */\n anchorPoints?: AnchorPoint[];\n\n /** Scene status */\n status?: SceneStatus;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Scene for virtual production compositing\n *\n * Supports 360° panoramas, standard images, and video backgrounds\n * with viewpoint extraction, lighting analysis, and character placement.\n *\n * @example\n * ```typescript\n * import { Scene } from '@happyvertical/smrt-video';\n *\n * const scene = new Scene({\n * name: 'Town Hall Exterior',\n * sourceAssetId: 'asset-townhall-pano',\n * sourceType: 'panorama_360',\n * projection: 'equirectangular',\n * });\n * await scene.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class Scene extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Human-readable name */\n name: string = '';\n\n /** Description */\n description: string | null = null;\n\n /** Source media asset ID */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n sourceAssetId: string | null = null;\n\n /** Type of source media */\n sourceType: SceneSourceType = 'image';\n\n /** Projection type for panoramas */\n projection: SceneProjection | null = null;\n\n /** Extracted camera angles from 360° panoramas */\n viewpoints: SceneViewpoint[] = [];\n\n /** Lighting analysis for IC-Light matching */\n lightingProfile: LightingProfile | null = null;\n\n /** Location metadata */\n location: {\n name: string;\n coordinates?: { lat: number; lng: number };\n } | null = null;\n\n /** Anchor points for character placement */\n anchorPoints: AnchorPoint[] = [];\n\n /** Scene status */\n status: SceneStatus = 'pending';\n\n constructor(options: SceneOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.sourceAssetId !== undefined)\n this.sourceAssetId = options.sourceAssetId;\n if (options.sourceType !== undefined) this.sourceType = options.sourceType;\n if (options.projection !== undefined) this.projection = options.projection;\n if (options.viewpoints !== undefined) this.viewpoints = options.viewpoints;\n if (options.lightingProfile !== undefined)\n this.lightingProfile = options.lightingProfile;\n if (options.location !== undefined) this.location = options.location;\n if (options.anchorPoints !== undefined)\n this.anchorPoints = options.anchorPoints;\n if (options.status !== undefined) this.status = options.status;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n private async getSceneAssetCollection() {\n const { SceneOwnedAssetCollection } = await import('./scene-assets.js');\n return SceneOwnedAssetCollection.create({ db: this.db });\n }\n\n private getLegacyFieldAssetIds(role?: SceneAssetRole): string[] {\n if (role === 'source') {\n return this.sourceAssetId ? [this.sourceAssetId] : [];\n }\n\n if (role === 'env-map') {\n return this.lightingProfile?.envMapAssetId\n ? [this.lightingProfile.envMapAssetId]\n : [];\n }\n\n if (role === 'viewpoint-extract') {\n return this.viewpoints\n .map((viewpoint) => viewpoint.extractedAssetId || null)\n .filter((assetId): assetId is string => Boolean(assetId));\n }\n\n return [\n this.sourceAssetId,\n this.lightingProfile?.envMapAssetId || null,\n ...this.viewpoints.map((viewpoint) => viewpoint.extractedAssetId || null),\n ].filter((assetId): assetId is string => Boolean(assetId));\n }\n\n private setLegacyFieldAssetId(\n role: SceneAssetRole,\n assetId: string,\n ): boolean {\n if (role === 'source') {\n if (this.sourceAssetId === assetId) {\n return false;\n }\n\n this.sourceAssetId = assetId;\n return true;\n }\n\n if (role === 'env-map') {\n if ((this.lightingProfile?.envMapAssetId || null) === assetId) {\n return false;\n }\n\n this.lightingProfile = {\n ...(this.lightingProfile || {}),\n envMapAssetId: assetId,\n };\n return true;\n }\n\n return false;\n }\n\n private clearLegacyFieldAssetId(\n assetId: string,\n role?: SceneAssetRole,\n ): boolean {\n let changed = false;\n\n if ((!role || role === 'source') && this.sourceAssetId === assetId) {\n this.sourceAssetId = null;\n changed = true;\n }\n\n if (\n (!role || role === 'env-map') &&\n this.lightingProfile?.envMapAssetId === assetId\n ) {\n this.lightingProfile = {\n ...(this.lightingProfile || {}),\n envMapAssetId: undefined,\n };\n changed = true;\n }\n\n if (!role || role === 'viewpoint-extract') {\n let viewpointChanged = false;\n const nextViewpoints = this.viewpoints.map((viewpoint) => {\n if (viewpoint.extractedAssetId !== assetId) {\n return viewpoint;\n }\n\n viewpointChanged = true;\n return {\n ...viewpoint,\n extractedAssetId: undefined,\n };\n });\n\n if (viewpointChanged) {\n this.viewpoints = nextViewpoints;\n changed = true;\n }\n }\n\n return changed;\n }\n\n async getAssets(role?: SceneAssetRole): Promise<Asset[]> {\n const canonicalAssetIds = this.id\n ? await listCanonicalOwnedAssetIds({\n tableName: 'scene_assets',\n loadLinks: async () =>\n (await this.getSceneAssetCollection()).byLeft(\n this.id as string,\n role ? { role } : {},\n ),\n })\n : [];\n const legacyFieldAssetIds = this.getLegacyFieldAssetIds(role);\n const legacyOwnedAssetIds = this.id\n ? await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'scene_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('SceneAsset'),\n })\n : [];\n\n return resolveOwnedAssets(\n this.db,\n this.tenantId,\n mergeOwnedAssetIds(\n canonicalAssetIds,\n legacyFieldAssetIds,\n legacyOwnedAssetIds,\n ),\n );\n }\n\n async getAssetByRole(role: SceneAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n async addAsset(\n asset: Asset,\n role: SceneAssetRole = 'source',\n sortOrder = 0,\n ): Promise<void> {\n if (!this.id || !asset.id) {\n throw new Error('Cannot associate unsaved scene or asset');\n }\n\n assertValidVideoAssetRole(role);\n assertValidVideoAssetSortOrder(sortOrder);\n\n const sceneAssets = await this.getSceneAssetCollection();\n await sceneAssets.attach(this.id, asset.id, {\n role,\n sortOrder,\n tenantId: this.tenantId,\n });\n\n if (this.setLegacyFieldAssetId(role, asset.id)) {\n await this.save();\n }\n }\n\n async removeAsset(assetId: string, role?: SceneAssetRole): Promise<void> {\n if (!this.id) {\n return;\n }\n\n const sceneAssets = await this.getSceneAssetCollection();\n await sceneAssets.detach(this.id, assetId, role ? { role } : {});\n\n if (this.clearLegacyFieldAssetId(assetId, role)) {\n await this.save();\n }\n }\n\n /** Check if this is a 360° panorama */\n get isPanorama(): boolean {\n return (\n this.sourceType === 'panorama_360' || this.sourceType === 'panorama_180'\n );\n }\n\n /** Check if the scene has viewpoints extracted */\n get hasViewpoints(): boolean {\n return this.viewpoints.length > 0;\n }\n\n /** Check if the scene is ready for compositing */\n get isReady(): boolean {\n return this.status === 'ready' && this.sourceAssetId !== null;\n }\n}\n","/**\n * Character Model\n *\n * Manages virtual characters for AI-powered video production.\n * Each character combines a visual identity with a voice profile.\n *\n * Renamed from PersonalityProfile. A Character is the role being played\n * (outfit, voice, branding). A Performer is the physical likeness/face DNA.\n * \"A Performer plays Characters.\"\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport type { CharacterAssetRole } from './character-asset.js';\nimport {\n assertValidVideoAssetRole,\n assertValidVideoAssetSortOrder,\n legacyVideoAssetMetaTypes,\n listCanonicalOwnedAssetIds,\n listLegacyOwnedAssetIds,\n mergeOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport { Performer } from './performer.js';\nimport { Scene } from './scene.js';\n\n/**\n * Character status\n */\nexport type CharacterStatus = 'pending' | 'ready';\n\n/**\n * Scene-specific configuration for a character\n */\nexport interface CharacterSceneConfig {\n /** Scene ID */\n sceneId: string;\n\n /** Preferred viewpoint ID (for 360° scenes) */\n viewpointId?: string;\n\n /** Anchor point ID for placement */\n anchorPointId?: string;\n\n /** Character scale in this scene */\n scale: number;\n\n /** Character position in this scene (normalized 0-1) */\n position: { x: number; y: number };\n}\n\n/**\n * Branding configuration for video overlays\n */\nexport interface BrandingConfig {\n /** Asset ID for logo overlay */\n logoAssetId?: string | null;\n\n /** Primary brand color (hex) */\n primaryColor?: string | null;\n\n /** Background color (hex) */\n backgroundColor?: string | null;\n\n /** Lower-third template name */\n lowerThirdTemplate?: string | null;\n\n /** Font family for text overlays */\n fontFamily?: string | null;\n\n /** Whether to show news ticker */\n tickerEnabled?: boolean;\n}\n\n/**\n * Character creation options\n */\nexport interface CharacterOptions extends SmrtObjectOptions {\n /** Human-readable name for the character */\n name?: string;\n\n /** Description of the character persona */\n description?: string | null;\n\n /** Asset ID of the seed image for image-to-video generation */\n imageAssetId?: string | null;\n\n /** Asset ID of pre-baked base motion video */\n baseMotionAssetId?: string | null;\n\n /** Voice profile ID for speech synthesis */\n voiceProfileId?: string | null;\n\n /** Branding configuration for video overlays */\n brandingKit?: BrandingConfig;\n\n /** Character status */\n status?: CharacterStatus;\n\n /** Linked performer for IP-Adapter face consistency */\n performerId?: string | null;\n\n /** Default scene for this character */\n defaultSceneId?: string | null;\n\n /** Scene-specific configurations */\n sceneConfigs?: CharacterSceneConfig[];\n\n /** 1-1 profile record for this character */\n profileId?: string | null;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Virtual character for AI-powered video production\n *\n * Character represents a virtual persona combining:\n * - Visual identity: Seed image for I2V (image-to-video) generation\n * - Voice identity: Link to a VoiceProfile for TTS\n * - Branding: Logo overlays, lower-thirds, colors\n *\n * @example\n * ```typescript\n * import { Character } from '@happyvertical/smrt-video';\n *\n * const character = new Character({\n * name: 'Bentley News Anchor',\n * description: 'Professional news anchor for local broadcasts',\n * imageAssetId: 'asset-123',\n * voiceProfileId: 'voice-456',\n * brandingKit: {\n * logoAssetId: 'asset-789',\n * primaryColor: '#1a73e8',\n * lowerThirdTemplate: 'news-standard',\n * tickerEnabled: true,\n * },\n * });\n * await character.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class Character extends SmrtObject {\n /** Tenant ID for multi-tenant isolation */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Human-readable name for the character */\n name: string = '';\n\n /** Description of the character persona */\n description: string | null = null;\n\n /** Asset ID of the seed image for I2V generation */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n imageAssetId: string | null = null;\n\n /** Asset ID of pre-baked base motion video */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n baseMotionAssetId: string | null = null;\n\n /** Voice profile ID for speech synthesis */\n @crossPackageRef('@happyvertical/smrt-voice:VoiceProfile')\n voiceProfileId: string | null = null;\n\n /** Branding configuration for video overlays */\n brandingKit: BrandingConfig = {};\n\n /** Character status */\n status: CharacterStatus = 'pending';\n\n /** Linked performer for IP-Adapter face consistency */\n @foreignKey(() => Performer)\n performerId: string | null = null;\n\n /** Default scene for this character */\n @foreignKey(() => Scene)\n defaultSceneId: string | null = null;\n\n /** Scene-specific configurations */\n sceneConfigs: CharacterSceneConfig[] = [];\n\n /** 1-1 profile record for this character */\n @crossPackageRef('@happyvertical/smrt-profiles:Profile')\n profileId: string | null = null;\n\n constructor(options: CharacterOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.imageAssetId !== undefined)\n this.imageAssetId = options.imageAssetId;\n if (options.baseMotionAssetId !== undefined)\n this.baseMotionAssetId = options.baseMotionAssetId;\n if (options.voiceProfileId !== undefined)\n this.voiceProfileId = options.voiceProfileId;\n if (options.brandingKit !== undefined)\n this.brandingKit = options.brandingKit;\n if (options.status !== undefined) this.status = options.status;\n if (options.performerId !== undefined)\n this.performerId = options.performerId;\n if (options.defaultSceneId !== undefined)\n this.defaultSceneId = options.defaultSceneId;\n if (options.sceneConfigs !== undefined)\n this.sceneConfigs = options.sceneConfigs;\n if (options.profileId !== undefined) this.profileId = options.profileId;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n private async getCharacterAssetCollection() {\n const { CharacterOwnedAssetCollection } = await import(\n './character-assets.js'\n );\n return CharacterOwnedAssetCollection.create({ db: this.db });\n }\n\n private getLegacyFieldAssetIds(role?: CharacterAssetRole): string[] {\n if (role === 'seed-image') {\n return this.imageAssetId ? [this.imageAssetId] : [];\n }\n\n if (role === 'base-motion') {\n return this.baseMotionAssetId ? [this.baseMotionAssetId] : [];\n }\n\n if (role === 'logo') {\n return this.brandingKit.logoAssetId ? [this.brandingKit.logoAssetId] : [];\n }\n\n return [\n this.imageAssetId,\n this.baseMotionAssetId,\n this.brandingKit.logoAssetId || null,\n ].filter((assetId): assetId is string => Boolean(assetId));\n }\n\n private setLegacyFieldAssetId(\n role: CharacterAssetRole,\n assetId: string | null,\n ): boolean {\n if (role === 'seed-image') {\n if (this.imageAssetId === assetId) {\n return false;\n }\n\n this.imageAssetId = assetId;\n return true;\n }\n\n if (role === 'base-motion') {\n if (this.baseMotionAssetId === assetId) {\n return false;\n }\n\n this.baseMotionAssetId = assetId;\n return true;\n }\n\n if ((this.brandingKit.logoAssetId || null) === assetId) {\n return false;\n }\n\n this.brandingKit = {\n ...this.brandingKit,\n logoAssetId: assetId,\n };\n return true;\n }\n\n private clearLegacyFieldAssetId(\n assetId: string,\n role?: CharacterAssetRole,\n ): boolean {\n let changed = false;\n\n if ((!role || role === 'seed-image') && this.imageAssetId === assetId) {\n this.imageAssetId = null;\n changed = true;\n }\n\n if (\n (!role || role === 'base-motion') &&\n this.baseMotionAssetId === assetId\n ) {\n this.baseMotionAssetId = null;\n changed = true;\n }\n\n if (\n (!role || role === 'logo') &&\n this.brandingKit.logoAssetId === assetId\n ) {\n this.brandingKit = {\n ...this.brandingKit,\n logoAssetId: null,\n };\n changed = true;\n }\n\n return changed;\n }\n\n async getAssets(role?: CharacterAssetRole): Promise<Asset[]> {\n const canonicalAssetIds = this.id\n ? await listCanonicalOwnedAssetIds({\n tableName: 'character_assets',\n loadLinks: async () =>\n (await this.getCharacterAssetCollection()).byLeft(\n this.id as string,\n role ? { role } : {},\n ),\n })\n : [];\n const legacyFieldAssetIds = this.getLegacyFieldAssetIds(role);\n const legacyOwnedAssetIds = this.id\n ? await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'character_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('CharacterAsset'),\n })\n : [];\n\n return resolveOwnedAssets(\n this.db,\n this.tenantId,\n mergeOwnedAssetIds(\n canonicalAssetIds,\n legacyFieldAssetIds,\n legacyOwnedAssetIds,\n ),\n );\n }\n\n async getAssetByRole(role: CharacterAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n async addAsset(\n asset: Asset,\n role: CharacterAssetRole = 'seed-image',\n sortOrder = 0,\n ): Promise<void> {\n if (!this.id || !asset.id) {\n throw new Error('Cannot associate unsaved character or asset');\n }\n\n assertValidVideoAssetRole(role);\n assertValidVideoAssetSortOrder(sortOrder);\n\n const characterAssets = await this.getCharacterAssetCollection();\n await characterAssets.attach(this.id, asset.id, {\n role,\n sortOrder,\n tenantId: this.tenantId,\n });\n\n if (this.setLegacyFieldAssetId(role, asset.id)) {\n await this.save();\n }\n }\n\n async removeAsset(assetId: string, role?: CharacterAssetRole): Promise<void> {\n if (!this.id) {\n return;\n }\n\n const characterAssets = await this.getCharacterAssetCollection();\n await characterAssets.detach(this.id, assetId, role ? { role } : {});\n\n if (this.clearLegacyFieldAssetId(assetId, role)) {\n await this.save();\n }\n }\n\n /**\n * Check if the character has a pre-baked base motion video\n * @deprecated Use getAssetByRole('base-motion') instead\n */\n get hasBaseMotion(): boolean {\n return this.baseMotionAssetId !== null;\n }\n\n /** Check if the character is complete and ready for video generation */\n get isComplete(): boolean {\n return (\n this.imageAssetId !== null &&\n this.voiceProfileId !== null &&\n this.status === 'ready'\n );\n }\n}\n","/**\n * CharacterCollection - Collection manager for Character instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal } from '@happyvertical/smrt-tenancy';\nimport { Character } from './character.js';\n\nexport class CharacterCollection extends SmrtCollection<Character> {\n static readonly _itemClass = Character;\n\n /** Find all characters belonging to a specific tenant */\n async findByTenant(tenantId: string): Promise<Character[]> {\n return (await this.list({ where: { tenantId } })) as Character[];\n }\n\n /**\n * Find all global characters (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n */\n async findGlobal(): Promise<Character[]> {\n return queryGlobal<Character>(this);\n }\n\n /** Find characters by performer */\n async findByPerformer(performerId: string): Promise<Character[]> {\n return (await this.list({ where: { performerId } })) as Character[];\n }\n\n /** Find characters that are ready for video generation */\n async findReady(): Promise<Character[]> {\n return (await this.list({ where: { status: 'ready' } })) as Character[];\n }\n}\n","/**\n * CompositeJob Model\n *\n * Tracks the progress of compositing a character video onto a scene background.\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Scene } from './scene.js';\n\n/**\n * Composite job status\n */\nexport type CompositeJobStatus =\n | 'pending'\n | 'removing_bg'\n | 'analyzing_light'\n | 'compositing'\n | 'complete'\n | 'failed';\n\n/**\n * Composite job creation options\n */\nexport interface CompositeJobOptions extends SmrtObjectOptions {\n /** Character video asset ID (after lip-sync) */\n characterVideoAssetId?: string | null;\n\n /** Scene ID to composite onto */\n sceneId?: string | null;\n\n /** Viewpoint ID (for 360° scenes) */\n viewpointId?: string | null;\n\n /** Anchor point ID for placement */\n anchorPointId?: string | null;\n\n /** Character scale */\n scale?: number;\n\n /** Character position (normalized 0-1) */\n position?: { x: number; y: number };\n\n /** Job status */\n status?: CompositeJobStatus;\n\n /** Progress percentage (0-100) */\n progress?: number;\n\n /** Output video asset ID */\n outputAssetId?: string | null;\n\n /** Error message if failed */\n errorMessage?: string | null;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Composite job for tracking virtual production compositing\n *\n * @example\n * ```typescript\n * import { CompositeJob } from '@happyvertical/smrt-video';\n *\n * const job = new CompositeJob({\n * characterVideoAssetId: 'asset-video-123',\n * sceneId: 'scene-townhall',\n * scale: 0.8,\n * position: { x: 0.5, y: 0.7 },\n * });\n * await job.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class CompositeJob extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Character video asset ID (after lip-sync) */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n characterVideoAssetId: string | null = null;\n\n /** Scene ID to composite onto */\n @foreignKey(() => Scene)\n sceneId: string | null = null;\n\n /** Viewpoint ID (for 360° scenes) */\n viewpointId: string | null = null;\n\n /** Anchor point ID for placement */\n anchorPointId: string | null = null;\n\n /** Character scale */\n scale: number = 1.0;\n\n /** Character position (normalized 0-1) */\n position: { x: number; y: number } = { x: 0.5, y: 0.5 };\n\n /** Job status */\n status: CompositeJobStatus = 'pending';\n\n /** Progress percentage (0-100) */\n progress: number = 0;\n\n /** Output video asset ID */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n outputAssetId: string | null = null;\n\n /** Error message if failed */\n errorMessage: string | null = null;\n\n constructor(options: CompositeJobOptions = {}) {\n super(options);\n\n if (options.characterVideoAssetId !== undefined)\n this.characterVideoAssetId = options.characterVideoAssetId;\n if (options.sceneId !== undefined) this.sceneId = options.sceneId;\n if (options.viewpointId !== undefined)\n this.viewpointId = options.viewpointId;\n if (options.anchorPointId !== undefined)\n this.anchorPointId = options.anchorPointId;\n if (options.scale !== undefined) this.scale = options.scale;\n if (options.position !== undefined) this.position = options.position;\n if (options.status !== undefined) this.status = options.status;\n if (options.progress !== undefined) this.progress = options.progress;\n if (options.outputAssetId !== undefined)\n this.outputAssetId = options.outputAssetId;\n if (options.errorMessage !== undefined)\n this.errorMessage = options.errorMessage;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n /** Check if the job is complete */\n get isComplete(): boolean {\n return this.status === 'complete' && this.outputAssetId !== null;\n }\n\n /** Check if the job is in progress */\n get isProcessing(): boolean {\n return (\n this.status !== 'pending' &&\n this.status !== 'complete' &&\n this.status !== 'failed'\n );\n }\n}\n","/**\n * VideoComposition Model\n *\n * The publishable output. Defines render spec (fps, width, height).\n * Contains ordered sequences with optional transitions between them.\n * Maps to Remotion <Composition /> + <TransitionSeries>.\n *\n * Design principle: store frames, compute seconds. seconds = frames / fps.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport { Content, type ContentOptions } from '@happyvertical/smrt-content';\nimport { smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped } from '@happyvertical/smrt-tenancy';\nimport {\n legacyVideoAssetMetaTypes,\n listLegacyOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { VideoCompositionAssetRole } from './video-composition-asset.js';\n\n/**\n * Render status for the composition\n */\nexport type RenderStatus = 'draft' | 'rendering' | 'ready' | 'failed';\n\n/**\n * VideoComposition creation options\n */\nexport interface VideoCompositionOptions extends ContentOptions {\n /** Frames per second (e.g., 30) — everything downstream is in frames */\n fps?: number;\n\n /** Render width in pixels */\n width?: number;\n\n /** Render height in pixels */\n height?: number;\n\n /** Computed total: sum of sequences minus transition overlaps */\n durationInFrames?: number;\n\n /** Render status */\n renderStatus?: RenderStatus;\n\n /** Render progress (0-100) */\n renderProgress?: number;\n}\n\n/**\n * Publishable video composition\n *\n * VideoComposition is the top-level container for a rendered video.\n * It defines the render spec and contains ordered VideoSequences.\n *\n * @example\n * ```typescript\n * import { VideoComposition } from '@happyvertical/smrt-video';\n *\n * const composition = new VideoComposition({\n * title: 'Evening News - January 25, 2026',\n * fps: 30,\n * width: 1920,\n * height: 1080,\n * });\n * await composition.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoComposition extends Content {\n /** Frames per second — everything downstream is in frames */\n fps: number = 30;\n\n /** Render width in pixels */\n width: number = 1920;\n\n /** Render height in pixels */\n height: number = 1080;\n\n /** Computed total: sum of sequences minus transition overlaps */\n durationInFrames: number = 0;\n\n /** Render status */\n renderStatus: RenderStatus = 'draft';\n\n /** Render progress (0-100) */\n renderProgress: number = 0;\n\n constructor(options: VideoCompositionOptions = {}) {\n super({\n ...options,\n type: 'video-composition',\n });\n\n if (options.fps !== undefined) this.fps = options.fps;\n if (options.width !== undefined) this.width = options.width;\n if (options.height !== undefined) this.height = options.height;\n if (options.durationInFrames !== undefined)\n this.durationInFrames = options.durationInFrames;\n if (options.renderStatus !== undefined)\n this.renderStatus = options.renderStatus;\n if (options.renderProgress !== undefined)\n this.renderProgress = options.renderProgress;\n }\n\n /** Duration in seconds */\n get durationInSeconds(): number {\n if (this.fps === 0) return 0;\n return this.durationInFrames / this.fps;\n }\n\n /** Check if the composition is ready for publishing */\n get isReady(): boolean {\n return this.renderStatus === 'ready';\n }\n\n /** Check if the composition is currently rendering */\n get isRendering(): boolean {\n return this.renderStatus === 'rendering';\n }\n\n async getAssets(relationship?: string): Promise<Asset[]>;\n async getAssets(role?: VideoCompositionAssetRole): Promise<Asset[]>;\n async getAssets(relationship?: string): Promise<Asset[]> {\n const canonicalAssets = await super.getAssets(relationship);\n if (!this.id) {\n return canonicalAssets;\n }\n\n const role = relationship as VideoCompositionAssetRole | undefined;\n const legacyAssets = await resolveOwnedAssets(\n this.db,\n this.tenantId,\n await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'video_composition_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('VideoCompositionAsset'),\n }),\n );\n\n return [\n ...canonicalAssets,\n ...legacyAssets.filter(\n (asset) =>\n asset.id &&\n !canonicalAssets.some(\n (canonicalAsset) => canonicalAsset.id === asset.id,\n ),\n ),\n ];\n }\n\n async getAssetByRole(role: VideoCompositionAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n}\n","/**\n * VideoCompositionCollection - Collection manager for VideoComposition instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { type RenderStatus, VideoComposition } from './video-composition.js';\n\nexport class VideoCompositionCollection extends SmrtCollection<VideoComposition> {\n static readonly _itemClass = VideoComposition;\n\n /** Find compositions by render status */\n async findByRenderStatus(\n renderStatus: RenderStatus,\n ): Promise<VideoComposition[]> {\n return (await this.list({\n where: { renderStatus },\n })) as VideoComposition[];\n }\n\n /** Find compositions that are ready for publishing */\n async findReady(): Promise<VideoComposition[]> {\n return (await this.list({\n where: { renderStatus: 'ready' },\n })) as VideoComposition[];\n }\n}\n","/**\n * VideoSequence Model\n *\n * A thematic section of a video: \"top story\", \"weather\", \"interview\".\n * Groups VideoShots. Maps to Remotion <TransitionSeries.Sequence>.\n *\n * Design principle: store frames, compute seconds. seconds = frames / fps.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport { Content, type ContentOptions } from '@happyvertical/smrt-content';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped } from '@happyvertical/smrt-tenancy';\nimport {\n legacyVideoAssetMetaTypes,\n listLegacyOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { VideoSequenceAssetRole } from './video-sequence-asset.js';\n\n/**\n * Transition type to the next sequence\n */\nexport type TransitionType = 'none' | 'fade' | 'slide' | 'wipe';\n\n/**\n * VideoSequence creation options\n */\nexport interface VideoSequenceOptions extends ContentOptions {\n /** Composition this sequence belongs to (nullable — can exist standalone) */\n compositionId?: string | null;\n\n /** Order within composition */\n position?: number;\n\n /** Computed duration: sum of shot frames */\n durationInFrames?: number;\n\n /** Transition type to the next sequence */\n transitionType?: TransitionType;\n\n /** Overlap frames with next sequence for transition */\n transitionDurationFrames?: number;\n}\n\n/**\n * Thematic section of a video composition\n *\n * VideoSequence groups VideoShots into a logical section. It can belong\n * to a VideoComposition or exist standalone (e.g., during long-video generation).\n *\n * @example\n * ```typescript\n * import { VideoSequence } from '@happyvertical/smrt-video';\n *\n * const sequence = new VideoSequence({\n * title: 'Top Story',\n * position: 0,\n * transitionType: 'fade',\n * transitionDurationFrames: 15,\n * });\n * await sequence.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoSequence extends Content {\n /** Composition this sequence belongs to */\n @foreignKey('VideoComposition')\n compositionId: string | null = null;\n\n /** Order within composition */\n position: number = 0;\n\n /** Computed duration: sum of shot frames */\n durationInFrames: number = 0;\n\n /** Transition type to the next sequence */\n transitionType: TransitionType = 'none';\n\n /** Overlap frames with next sequence for transition */\n transitionDurationFrames: number = 0;\n\n constructor(options: VideoSequenceOptions = {}) {\n super({\n ...options,\n type: 'video-sequence',\n });\n\n if (options.compositionId !== undefined)\n this.compositionId = options.compositionId;\n if (options.position !== undefined) this.position = options.position;\n if (options.durationInFrames !== undefined)\n this.durationInFrames = options.durationInFrames;\n if (options.transitionType !== undefined)\n this.transitionType = options.transitionType;\n if (options.transitionDurationFrames !== undefined)\n this.transitionDurationFrames = options.transitionDurationFrames;\n }\n\n async getAssets(relationship?: string): Promise<Asset[]>;\n async getAssets(role?: VideoSequenceAssetRole): Promise<Asset[]>;\n async getAssets(relationship?: string): Promise<Asset[]> {\n const canonicalAssets = await super.getAssets(relationship);\n if (!this.id) {\n return canonicalAssets;\n }\n\n const role = relationship as VideoSequenceAssetRole | undefined;\n const legacyAssets = await resolveOwnedAssets(\n this.db,\n this.tenantId,\n await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'video_sequence_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('VideoSequenceAsset'),\n }),\n );\n\n return [\n ...canonicalAssets,\n ...legacyAssets.filter(\n (asset) =>\n asset.id &&\n !canonicalAssets.some(\n (canonicalAsset) => canonicalAsset.id === asset.id,\n ),\n ),\n ];\n }\n\n async getAssetByRole(role: VideoSequenceAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n}\n","/**\n * VideoSequenceCollection - Collection manager for VideoSequence instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { VideoSequence } from './video-sequence.js';\n\nexport class VideoSequenceCollection extends SmrtCollection<VideoSequence> {\n static readonly _itemClass = VideoSequence;\n\n /** Find sequences belonging to a composition, ordered by position */\n async findByComposition(compositionId: string): Promise<VideoSequence[]> {\n return (await this.list({\n where: { compositionId },\n orderBy: 'position ASC',\n })) as VideoSequence[];\n }\n\n /** Find standalone sequences (not in any composition) */\n async findStandalone(): Promise<VideoSequence[]> {\n return (await this.list({\n where: { compositionId: null },\n })) as VideoSequence[];\n }\n}\n","/**\n * VideoShot Model\n *\n * The atomic video generation unit. One or more characters + one scene + one pipeline run.\n * This is what ComfyUI produces. Maps to Remotion <Sequence><Video /></Sequence>.\n *\n * Design principle: store frames, compute seconds. seconds = frames / fps.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport { Content, type ContentOptions } from '@happyvertical/smrt-content';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped } from '@happyvertical/smrt-tenancy';\nimport type { WordTiming } from '@happyvertical/smrt-voice';\nimport {\n legacyVideoAssetMetaTypes,\n listLegacyOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport { Scene } from './scene.js';\nimport { VideoSequence } from './video-sequence.js';\nimport type { VideoShotAssetRole } from './video-shot-asset.js';\n\n/**\n * Video shot status\n */\nexport type VideoShotStatus =\n | 'draft'\n | 'queued'\n | 'processing'\n | 'ready'\n | 'failed'\n | 'published';\n\n/**\n * Video metadata\n */\nexport interface VideoMetadata {\n /** Actual duration in seconds */\n duration?: number;\n\n /** Video resolution (e.g., \"1920x1080\") */\n resolution?: string;\n\n /** Aspect ratio (e.g., \"16:9\", \"9:16\") */\n aspectRatio?: string;\n\n /** Video codec (e.g., \"h264\", \"h265\") */\n codec?: string;\n\n /** Frames per second */\n fps?: number;\n\n /** File size in bytes */\n fileSize?: number;\n\n /** Word timing data from TTS for lip-sync */\n wordTimings?: WordTiming[];\n\n /** ComfyUI prompt ID for tracking */\n comfyPromptId?: string;\n}\n\n/**\n * Video shot creation options\n */\nexport interface VideoShotOptions extends ContentOptions {\n /** Sequence this shot belongs to (nullable — shots can exist standalone) */\n sequenceId?: string | null;\n\n /** Scene for this shot (nullable) */\n sceneId?: string | null;\n\n /** Order within sequence */\n position?: number;\n\n /** Actual frame count of generated clip */\n durationInFrames?: number;\n\n /** Frames to skip at start (overlap handling) */\n trimBeforeFrames?: number;\n\n /** Frames to skip at end */\n trimAfterFrames?: number;\n\n /** Script text to be spoken */\n scriptText?: string;\n\n /** Word count in the script */\n scriptWordCount?: number;\n\n /** Target duration in seconds */\n targetDuration?: number;\n\n /** Video generation status */\n shotStatus?: VideoShotStatus;\n\n /** Generation progress (0-100) */\n progress?: number;\n\n /** Error message if status is 'failed' */\n errorMessage?: string | null;\n\n /** Detailed status message for progress tracking */\n statusMessage?: string | null;\n\n /** Video metadata */\n videoMetadata?: VideoMetadata;\n}\n\n/**\n * Atomic video generation unit\n *\n * VideoShot represents a single pipeline run producing one video clip.\n * It can belong to a VideoSequence (for multi-segment long videos) or\n * exist standalone. Characters are linked via the VideoShotCharacter join model.\n *\n * @example\n * ```typescript\n * import { VideoShot } from '@happyvertical/smrt-video';\n *\n * const shot = new VideoShot({\n * scriptText: 'Welcome to the evening news.',\n * targetDuration: 30,\n * title: 'Evening News - Opening',\n * });\n * await shot.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoShot extends Content {\n /** Sequence this shot belongs to */\n @foreignKey(() => VideoSequence)\n sequenceId: string | null = null;\n\n /** Scene for this shot */\n @foreignKey(() => Scene)\n sceneId: string | null = null;\n\n /** Order within sequence */\n position: number = 0;\n\n /** Actual frame count of generated clip */\n durationInFrames: number = 0;\n\n /** Frames to skip at start (overlap handling) */\n trimBeforeFrames: number = 0;\n\n /** Frames to skip at end */\n trimAfterFrames: number = 0;\n\n /** Script text to be spoken */\n scriptText: string = '';\n\n /** Word count in the script */\n scriptWordCount: number = 0;\n\n /** Target duration in seconds */\n targetDuration: number = 30;\n\n /** Video generation status */\n shotStatus: VideoShotStatus = 'draft';\n\n /** Generation progress (0-100) */\n progress: number = 0;\n\n /** Error message if status is 'failed' */\n errorMessage: string | null = null;\n\n /** Detailed status message for progress tracking */\n statusMessage: string | null = null;\n\n /** Video metadata (duration, resolution, etc.) */\n videoMetadata: VideoMetadata = {};\n\n constructor(options: VideoShotOptions = {}) {\n super({\n ...options,\n type: 'video-shot',\n });\n\n if (options.sequenceId !== undefined) this.sequenceId = options.sequenceId;\n if (options.sceneId !== undefined) this.sceneId = options.sceneId;\n if (options.position !== undefined) this.position = options.position;\n if (options.durationInFrames !== undefined)\n this.durationInFrames = options.durationInFrames;\n if (options.trimBeforeFrames !== undefined)\n this.trimBeforeFrames = options.trimBeforeFrames;\n if (options.trimAfterFrames !== undefined)\n this.trimAfterFrames = options.trimAfterFrames;\n if (options.scriptText !== undefined) {\n this.scriptText = options.scriptText;\n this.scriptWordCount = this.scriptText\n .split(/\\s+/)\n .filter(Boolean).length;\n }\n if (options.scriptWordCount !== undefined)\n this.scriptWordCount = options.scriptWordCount;\n if (options.targetDuration !== undefined)\n this.targetDuration = options.targetDuration;\n if (options.shotStatus !== undefined) this.shotStatus = options.shotStatus;\n if (options.progress !== undefined) this.progress = options.progress;\n if (options.errorMessage !== undefined)\n this.errorMessage = options.errorMessage;\n if (options.statusMessage !== undefined)\n this.statusMessage = options.statusMessage;\n if (options.videoMetadata !== undefined)\n this.videoMetadata = options.videoMetadata;\n }\n\n /** Estimate speech duration based on word count (2.7 words/sec) */\n get estimatedDuration(): number {\n return this.scriptWordCount / 2.7;\n }\n\n /** Check if the script length matches target duration (+/- 15%) */\n get isScriptLengthValid(): boolean {\n const estimated = this.estimatedDuration;\n const tolerance = this.targetDuration * 0.15;\n return (\n estimated >= this.targetDuration - tolerance &&\n estimated <= this.targetDuration + tolerance\n );\n }\n\n /** Get the recommended word count for target duration */\n get recommendedWordCount(): { min: number; max: number; target: number } {\n const wordsPerSecond = 2.7;\n const target = Math.round(this.targetDuration * wordsPerSecond);\n const tolerance = Math.round(target * 0.15);\n return {\n min: target - tolerance,\n max: target + tolerance,\n target,\n };\n }\n\n /** Effective frame count after trimming */\n get effectiveFrames(): number {\n return Math.max(\n 0,\n this.durationInFrames - this.trimBeforeFrames - this.trimAfterFrames,\n );\n }\n\n /** Check if video generation is in progress */\n get isGenerating(): boolean {\n return this.shotStatus === 'queued' || this.shotStatus === 'processing';\n }\n\n /** Check if video is ready for publishing */\n get isReady(): boolean {\n return this.shotStatus === 'ready';\n }\n\n async getAssets(relationship?: string): Promise<Asset[]>;\n async getAssets(role?: VideoShotAssetRole): Promise<Asset[]>;\n async getAssets(relationship?: string): Promise<Asset[]> {\n const canonicalAssets = await super.getAssets(relationship);\n if (!this.id) {\n return canonicalAssets;\n }\n\n const role = relationship as VideoShotAssetRole | undefined;\n const legacyAssets = await resolveOwnedAssets(\n this.db,\n this.tenantId,\n await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'video_shot_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('VideoShotAsset'),\n }),\n );\n\n return [\n ...canonicalAssets,\n ...legacyAssets.filter(\n (asset) =>\n asset.id &&\n !canonicalAssets.some(\n (canonicalAsset) => canonicalAsset.id === asset.id,\n ),\n ),\n ];\n }\n\n async getAssetByRole(role: VideoShotAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n /** Update script text and recalculate word count */\n setScript(text: string): void {\n this.scriptText = text;\n this.scriptWordCount = text.split(/\\s+/).filter(Boolean).length;\n }\n}\n","/**\n * VideoShotCharacter - Join model linking VideoShots to Characters\n *\n * Replaces the old single personalityProfileId FK on VideoContent.\n * Supports multiple characters per shot with role and ordering.\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { foreignKey, SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Character } from './character.js';\nimport { VideoShot } from './video-shot.js';\n\n/**\n * Character role within a shot\n */\nexport type VideoShotCharacterRole = 'primary' | 'secondary' | 'background';\n\n/**\n * VideoShotCharacter creation options\n */\nexport interface VideoShotCharacterOptions extends SmrtObjectOptions {\n /** Video shot ID */\n videoShotId: string;\n\n /** Character ID */\n characterId: string;\n\n /** Role of the character in this shot */\n role?: VideoShotCharacterRole;\n\n /** Order/layer position within the shot */\n position?: number;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Join model linking a VideoShot to a Character\n *\n * @example\n * ```typescript\n * import { VideoShotCharacter } from '@happyvertical/smrt-video';\n *\n * const link = new VideoShotCharacter({\n * videoShotId: 'shot-123',\n * characterId: 'char-456',\n * role: 'primary',\n * position: 0,\n * });\n * await link.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoShotCharacter extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Video shot ID */\n @foreignKey(() => VideoShot, { required: true })\n videoShotId: string = '';\n\n /** Character ID */\n @foreignKey(() => Character, { required: true })\n characterId: string = '';\n\n /** Role of the character in this shot */\n role: VideoShotCharacterRole = 'primary';\n\n /** Order/layer position within the shot */\n position: number = 0;\n\n constructor(options: VideoShotCharacterOptions) {\n super(options);\n\n this.videoShotId = options.videoShotId;\n this.characterId = options.characterId;\n if (options.role !== undefined) this.role = options.role;\n if (options.position !== undefined) this.position = options.position;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","/**\n * VideoShotCharacterCollection - Collection manager for VideoShotCharacter instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { VideoShotCharacter } from './video-shot-character.js';\n\nexport class VideoShotCharacterCollection extends SmrtCollection<VideoShotCharacter> {\n static readonly _itemClass = VideoShotCharacter;\n\n /** Find all character links for a shot, ordered by position */\n async findByShot(videoShotId: string): Promise<VideoShotCharacter[]> {\n return (await this.list({\n where: { videoShotId },\n orderBy: 'position ASC',\n })) as VideoShotCharacter[];\n }\n\n /** Find all shot links for a character */\n async findByCharacter(characterId: string): Promise<VideoShotCharacter[]> {\n return (await this.list({\n where: { characterId },\n })) as VideoShotCharacter[];\n }\n}\n","/**\n * VideoShotCollection - Collection manager for VideoShot instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { VideoShot, type VideoShotStatus } from './video-shot.js';\n\nexport class VideoShotCollection extends SmrtCollection<VideoShot> {\n static readonly _itemClass = VideoShot;\n\n /** Find shots belonging to a specific sequence, ordered by position */\n async findBySequence(sequenceId: string): Promise<VideoShot[]> {\n return (await this.list({\n where: { sequenceId },\n orderBy: 'position ASC',\n })) as VideoShot[];\n }\n\n /** Find shots by status */\n async findByStatus(shotStatus: VideoShotStatus): Promise<VideoShot[]> {\n return (await this.list({ where: { shotStatus } })) as VideoShot[];\n }\n\n /** Find standalone shots (not in any sequence) */\n async findStandalone(): Promise<VideoShot[]> {\n return (await this.list({ where: { sequenceId: null } })) as VideoShot[];\n }\n}\n","/**\n * Video Workflow Model\n *\n * Manages ComfyUI workflow templates for video generation.\n */\n\nimport { createLogger } from '@happyvertical/logger';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\n\nconst logger = createLogger({ level: 'info' });\n\n/**\n * Node mapping for dynamic parameter injection\n */\nexport interface NodeMapping {\n /**\n * Node ID for anchor seed image input\n */\n seedImage?: string;\n\n /**\n * Node ID for TTS audio input\n */\n audioFile?: string;\n\n /**\n * Node ID for base motion video input\n */\n baseVideo?: string;\n\n /**\n * Node ID for final video output\n */\n outputVideo?: string;\n\n /**\n * Node ID for text prompt input\n */\n prompt?: string;\n\n /**\n * Node ID for negative prompt input\n */\n negativePrompt?: string;\n\n /**\n * Node ID for sampler/scheduler settings\n */\n sampler?: string;\n\n /**\n * Node ID for video duration control\n */\n duration?: string;\n\n /**\n * Additional custom node mappings\n */\n [key: string]: string | undefined;\n}\n\n/**\n * Workflow type classification\n */\nexport type WorkflowType =\n | 'prebake'\n | 'broadcast'\n | 'lipsync'\n | 'postprod'\n | 'custom';\n\n/**\n * Video workflow creation options\n */\nexport interface VideoWorkflowOptions extends SmrtObjectOptions {\n /**\n * Human-readable name for the workflow\n */\n name?: string;\n\n /**\n * Description of what this workflow does\n */\n description?: string | null;\n\n /**\n * Workflow type classification\n * @default 'custom'\n */\n workflowType?: WorkflowType;\n\n /**\n * ComfyUI API format JSON\n */\n workflowJson?: object | null;\n\n /**\n * Node ID mappings for dynamic parameter injection\n */\n nodeMapping?: NodeMapping;\n\n /**\n * Estimated processing time in seconds\n */\n estimatedTime?: number;\n\n /**\n * Whether this workflow is active/usable\n * @default true\n */\n isActive?: boolean;\n\n /**\n * ComfyUI models required by this workflow\n */\n requiredModels?: string[];\n\n /**\n * Tenant ID for multi-tenant isolation\n */\n tenantId?: string | null;\n}\n\n/**\n * ComfyUI workflow template for video generation\n *\n * VideoWorkflow stores ComfyUI workflow definitions with node mappings\n * for dynamic parameter injection. This allows the Histrio agent to\n * inject anchor images, audio, and other inputs at runtime.\n *\n * @example\n * ```typescript\n * import { VideoWorkflow } from '@happyvertical/smrt-video';\n *\n * const workflow = new VideoWorkflow({\n * name: 'Wan 2.6 + EchoMimic',\n * description: 'Full broadcast generation with lip-sync',\n * workflowType: 'broadcast',\n * workflowJson: comfyuiWorkflowJson,\n * nodeMapping: {\n * seedImage: '1',\n * audioFile: '5',\n * outputVideo: '12',\n * },\n * estimatedTime: 600, // 10 minutes\n * requiredModels: ['wan_2.6_t2v_14b_fp8', 'echomimic_v2'],\n * });\n * await workflow.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoWorkflow extends SmrtObject {\n /**\n * Tenant ID for multi-tenant isolation\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Human-readable name for the workflow\n */\n name: string = '';\n\n /**\n * Description of what this workflow does\n */\n description: string | null = null;\n\n /**\n * Workflow type classification\n * - prebake: Pre-generate base motion from seed image\n * - broadcast: Full video generation pipeline\n * - lipsync: Lip-sync only (requires base video + audio)\n * - postprod: Post-production overlays and effects\n * - custom: User-defined workflow\n */\n workflowType: WorkflowType = 'custom';\n\n /**\n * ComfyUI API format JSON\n * This is the workflow definition that will be sent to ComfyUI\n */\n workflowJson: object | null = null;\n\n /**\n * Node ID mappings for dynamic parameter injection\n * Maps semantic names to ComfyUI node IDs\n */\n nodeMapping: NodeMapping = {};\n\n /**\n * Estimated processing time in seconds\n * Used for progress estimation\n */\n estimatedTime: number = 300;\n\n /**\n * Whether this workflow is active/usable\n */\n isActive: boolean = true;\n\n /**\n * ComfyUI models required by this workflow\n * Used for validation before queuing\n */\n requiredModels: string[] = [];\n\n constructor(options: VideoWorkflowOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.workflowType !== undefined)\n this.workflowType = options.workflowType;\n if (options.workflowJson !== undefined)\n this.workflowJson = options.workflowJson;\n if (options.nodeMapping !== undefined)\n this.nodeMapping = options.nodeMapping;\n if (options.estimatedTime !== undefined)\n this.estimatedTime = options.estimatedTime;\n if (options.isActive !== undefined) this.isActive = options.isActive;\n if (options.requiredModels !== undefined)\n this.requiredModels = options.requiredModels;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n /**\n * Check if the workflow has all required node mappings\n */\n get hasRequiredMappings(): boolean {\n const required = ['outputVideo'];\n return required.every((key) => this.nodeMapping[key] !== undefined);\n }\n\n /**\n * Get a copy of the workflow JSON with injected parameters\n *\n * Parameter injection follows ComfyUI node structure conventions:\n * - seedImage, audioFile, baseVideo → node.inputs.image (file path)\n * - prompt → node.inputs.text (string)\n * - Other parameters → node.inputs[paramKey]\n *\n * @param params - Key-value pairs of parameters to inject\n * @returns Modified workflow JSON or null if no workflowJson set\n */\n injectParameters(params: Record<string, any>): object | null {\n if (!this.workflowJson) return null;\n\n const workflow = JSON.parse(JSON.stringify(this.workflowJson));\n const warnings: string[] = [];\n\n for (const [paramKey, nodeId] of Object.entries(this.nodeMapping)) {\n if (nodeId && params[paramKey] !== undefined) {\n // Validate nodeId exists in workflow\n if (!workflow[nodeId]) {\n warnings.push(\n `Node mapping '${paramKey}' references node '${nodeId}' which does not exist in workflow`,\n );\n continue;\n }\n\n // Inject parameter into the node\n workflow[nodeId].inputs = workflow[nodeId].inputs || {};\n\n // Map parameters to ComfyUI node input field names\n if (\n paramKey === 'seedImage' ||\n paramKey === 'audioFile' ||\n paramKey === 'baseVideo'\n ) {\n workflow[nodeId].inputs.image = params[paramKey];\n } else if (paramKey === 'prompt') {\n workflow[nodeId].inputs.text = params[paramKey];\n } else {\n workflow[nodeId].inputs[paramKey] = params[paramKey];\n }\n }\n }\n\n // Log warnings if any (in development)\n if (warnings.length > 0 && process.env.NODE_ENV !== 'production') {\n logger.warn(\n `[VideoWorkflow] Parameter injection warnings:\\n${warnings.join('\\n')}`,\n );\n }\n\n return workflow;\n }\n}\n","/**\n * CharacterAsset - legacy STI asset subclass for Character-owned assets\n *\n * @deprecated Character owned assets are now modeled canonically through\n * `CharacterOwnedAsset` join rows in `character_assets`. This legacy subtype\n * remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { Character } from './character.js';\n\n/** Roles a character asset can play */\nexport type CharacterAssetRole = 'seed-image' | 'base-motion' | 'logo';\n\nexport interface CharacterAssetOptions extends AssetOptions {\n /** Character this asset belongs to */\n characterId?: string | null;\n /** Role of this asset for the character */\n role?: CharacterAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class CharacterAsset extends Asset {\n @foreignKey(() => Character)\n characterId: string | null = null;\n\n role: CharacterAssetRole = 'seed-image';\n\n constructor(options: CharacterAssetOptions = {}) {\n super(options);\n if (options.characterId !== undefined)\n this.characterId = options.characterId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Character } from './character.js';\nimport type { CharacterAssetRole } from './character-asset.js';\n\nexport interface CharacterOwnedAssetOptions extends SmrtObjectOptions {\n characterId?: string;\n assetId?: string;\n role?: CharacterAssetRole;\n sortOrder?: number;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n name: 'CharacterOwnedAsset',\n tableName: 'character_assets',\n conflictColumns: ['character_id', 'asset_id', 'role'],\n api: false,\n mcp: false,\n cli: false,\n})\nexport class CharacterOwnedAsset extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n @foreignKey(() => Character, { required: true })\n characterId = '';\n\n @crossPackageRef('@happyvertical/smrt-assets:Asset', { required: true })\n assetId = '';\n\n @field({ required: true })\n role: CharacterAssetRole = 'seed-image';\n\n @field()\n sortOrder = 0;\n\n constructor(options: CharacterOwnedAssetOptions = {}) {\n super(options);\n if (options.characterId) this.characterId = options.characterId;\n if (options.assetId) this.assetId = options.assetId;\n if (options.role !== undefined) this.role = options.role;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","import type { SmrtCollectionOptions } from '@happyvertical/smrt-core';\nimport { SmrtJunction, smrt } from '@happyvertical/smrt-core';\nimport { CharacterOwnedAsset } from './character-owned-asset.js';\n\nexport interface CharacterOwnedAssetCollectionOptions\n extends SmrtCollectionOptions {}\n\n@smrt({\n api: false,\n mcp: false,\n cli: false,\n})\nexport class CharacterOwnedAssetCollection extends SmrtJunction<CharacterOwnedAsset> {\n static readonly _itemClass = CharacterOwnedAsset;\n protected leftField = 'characterId';\n protected rightField = 'assetId';\n}\n","/**\n * PerformerAsset - legacy STI asset subclass for Performer-owned assets\n *\n * @deprecated Performer owned assets are now modeled canonically through\n * `PerformerOwnedAsset` join rows in `performer_assets`. This legacy subtype\n * remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { Performer } from './performer.js';\n\n/** Roles a performer asset can play */\nexport type PerformerAssetRole = 'reference' | 'seed';\n\nexport interface PerformerAssetOptions extends AssetOptions {\n /** Performer this asset belongs to */\n performerId?: string | null;\n /** Role of this asset for the performer */\n role?: PerformerAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class PerformerAsset extends Asset {\n @foreignKey(() => Performer)\n performerId: string | null = null;\n\n role: PerformerAssetRole = 'reference';\n\n constructor(options: PerformerAssetOptions = {}) {\n super(options);\n if (options.performerId !== undefined)\n this.performerId = options.performerId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Performer } from './performer.js';\nimport type { PerformerAssetRole } from './performer-asset.js';\n\nexport interface PerformerOwnedAssetOptions extends SmrtObjectOptions {\n performerId?: string;\n assetId?: string;\n role?: PerformerAssetRole;\n sortOrder?: number;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n name: 'PerformerOwnedAsset',\n tableName: 'performer_assets',\n conflictColumns: ['performer_id', 'asset_id', 'role'],\n api: false,\n mcp: false,\n cli: false,\n})\nexport class PerformerOwnedAsset extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n @foreignKey(() => Performer, { required: true })\n performerId = '';\n\n @crossPackageRef('@happyvertical/smrt-assets:Asset', { required: true })\n assetId = '';\n\n @field({ required: true })\n role: PerformerAssetRole = 'reference';\n\n @field()\n sortOrder = 0;\n\n constructor(options: PerformerOwnedAssetOptions = {}) {\n super(options);\n if (options.performerId) this.performerId = options.performerId;\n if (options.assetId) this.assetId = options.assetId;\n if (options.role !== undefined) this.role = options.role;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","import type { SmrtCollectionOptions } from '@happyvertical/smrt-core';\nimport { SmrtJunction, smrt } from '@happyvertical/smrt-core';\nimport { PerformerOwnedAsset } from './performer-owned-asset.js';\n\nexport interface PerformerOwnedAssetCollectionOptions\n extends SmrtCollectionOptions {}\n\n@smrt({\n api: false,\n mcp: false,\n cli: false,\n})\nexport class PerformerOwnedAssetCollection extends SmrtJunction<PerformerOwnedAsset> {\n static readonly _itemClass = PerformerOwnedAsset;\n protected leftField = 'performerId';\n protected rightField = 'assetId';\n}\n","/**\n * SceneAsset - legacy STI asset subclass for Scene-owned assets\n *\n * @deprecated Scene owned assets are now modeled canonically through\n * `SceneOwnedAsset` join rows in `scene_assets`. This legacy subtype remains\n * readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { Scene } from './scene.js';\n\n/** Roles a scene asset can play */\nexport type SceneAssetRole = 'source' | 'viewpoint-extract' | 'env-map';\n\nexport interface SceneAssetOptions extends AssetOptions {\n /** Scene this asset belongs to */\n sceneId?: string | null;\n /** Role of this asset for the scene */\n role?: SceneAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class SceneAsset extends Asset {\n @foreignKey(() => Scene)\n sceneId: string | null = null;\n\n role: SceneAssetRole = 'source';\n\n constructor(options: SceneAssetOptions = {}) {\n super(options);\n if (options.sceneId !== undefined) this.sceneId = options.sceneId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Scene } from './scene.js';\nimport type { SceneAssetRole } from './scene-asset.js';\n\nexport interface SceneOwnedAssetOptions extends SmrtObjectOptions {\n sceneId?: string;\n assetId?: string;\n role?: SceneAssetRole;\n sortOrder?: number;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n name: 'SceneOwnedAsset',\n tableName: 'scene_assets',\n conflictColumns: ['scene_id', 'asset_id', 'role'],\n api: false,\n mcp: false,\n cli: false,\n})\nexport class SceneOwnedAsset extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n @foreignKey(() => Scene, { required: true })\n sceneId = '';\n\n @crossPackageRef('@happyvertical/smrt-assets:Asset', { required: true })\n assetId = '';\n\n @field({ required: true })\n role: SceneAssetRole = 'source';\n\n @field()\n sortOrder = 0;\n\n constructor(options: SceneOwnedAssetOptions = {}) {\n super(options);\n if (options.sceneId) this.sceneId = options.sceneId;\n if (options.assetId) this.assetId = options.assetId;\n if (options.role !== undefined) this.role = options.role;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","import type { SmrtCollectionOptions } from '@happyvertical/smrt-core';\nimport { SmrtJunction, smrt } from '@happyvertical/smrt-core';\nimport { SceneOwnedAsset } from './scene-owned-asset.js';\n\nexport interface SceneOwnedAssetCollectionOptions\n extends SmrtCollectionOptions {}\n\n@smrt({\n api: false,\n mcp: false,\n cli: false,\n})\nexport class SceneOwnedAssetCollection extends SmrtJunction<SceneOwnedAsset> {\n static readonly _itemClass = SceneOwnedAsset;\n protected leftField = 'sceneId';\n protected rightField = 'assetId';\n}\n","/**\n * VideoCompositionAsset - legacy STI asset subclass for VideoComposition-owned assets\n *\n * @deprecated VideoComposition now uses inherited Content asset helpers backed\n * by `content_assets`. This legacy subtype remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { VideoComposition } from './video-composition.js';\n\n/** Roles a video composition asset can play */\nexport type VideoCompositionAssetRole = 'video' | 'audio' | 'thumbnail';\n\nexport interface VideoCompositionAssetOptions extends AssetOptions {\n /** VideoComposition this asset belongs to */\n videoCompositionId?: string | null;\n /** Role of this asset for the composition */\n role?: VideoCompositionAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class VideoCompositionAsset extends Asset {\n @foreignKey(() => VideoComposition)\n videoCompositionId: string | null = null;\n\n role: VideoCompositionAssetRole = 'video';\n\n constructor(options: VideoCompositionAssetOptions = {}) {\n super(options);\n if (options.videoCompositionId !== undefined)\n this.videoCompositionId = options.videoCompositionId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","/**\n * VideoSequenceAsset - legacy STI asset subclass for VideoSequence-owned assets\n *\n * @deprecated VideoSequence now uses inherited Content asset helpers backed by\n * `content_assets`. This legacy subtype remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { VideoSequence } from './video-sequence.js';\n\n/** Roles a video sequence asset can play */\nexport type VideoSequenceAssetRole = 'video' | 'audio' | 'thumbnail';\n\nexport interface VideoSequenceAssetOptions extends AssetOptions {\n /** VideoSequence this asset belongs to */\n videoSequenceId?: string | null;\n /** Role of this asset for the sequence */\n role?: VideoSequenceAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class VideoSequenceAsset extends Asset {\n @foreignKey(() => VideoSequence)\n videoSequenceId: string | null = null;\n\n role: VideoSequenceAssetRole = 'video';\n\n constructor(options: VideoSequenceAssetOptions = {}) {\n super(options);\n if (options.videoSequenceId !== undefined)\n this.videoSequenceId = options.videoSequenceId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","/**\n * VideoShotAsset - legacy STI asset subclass for VideoShot-owned assets\n *\n * @deprecated VideoShot now uses inherited Content asset helpers backed by\n * `content_assets`. This legacy subtype remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { VideoShot } from './video-shot.js';\n\n/** Roles a video shot asset can play */\nexport type VideoShotAssetRole = 'video' | 'audio' | 'thumbnail';\n\nexport interface VideoShotAssetOptions extends AssetOptions {\n /** VideoShot this asset belongs to */\n videoShotId?: string | null;\n /** Role of this asset for the shot */\n role?: VideoShotAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class VideoShotAsset extends Asset {\n @foreignKey(() => VideoShot)\n videoShotId: string | null = null;\n\n role: VideoShotAssetRole = 'video';\n\n constructor(options: VideoShotAssetOptions = {}) {\n super(options);\n if (options.videoShotId !== undefined)\n this.videoShotId = options.videoShotId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n"],"names":["tenantId","PerformerOwnedAssetCollection","performerAssets","__decorateClass","SceneOwnedAssetCollection","sceneAssets","CharacterOwnedAssetCollection","characterAssets","__publicField"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/__smrt-register__.ts","../src/owned-asset-utils.ts","../src/performer.ts","../src/scene.ts","../src/character.ts","../src/characters.ts","../src/composite-job.ts","../src/video-composition.ts","../src/video-compositions.ts","../src/video-sequence.ts","../src/video-sequences.ts","../src/video-shot.ts","../src/video-shot-character.ts","../src/video-shot-characters.ts","../src/video-shots.ts","../src/video-workflow.ts","../src/character-asset.ts","../src/character-owned-asset.ts","../src/character-assets.ts","../src/performer-asset.ts","../src/performer-owned-asset.ts","../src/performer-assets.ts","../src/scene-asset.ts","../src/scene-owned-asset.ts","../src/scene-assets.ts","../src/video-composition-asset.ts","../src/video-sequence-asset.ts","../src/video-shot-asset.ts"],"sourcesContent":["/**\n * Self-registers this package's build-time manifest before any @smrt() decorator\n * in the package fires. Fixes issue #1132: in consumer runtimes (tsx, SvelteKit\n * SSR, plain `vite dev`) the decorator's synchronous manifest lookup previously\n * missed because no step populated the global manifest cache — classes got\n * registered with zero fields and `save()` / `toJSON()` silently dropped every\n * declared property.\n *\n * Import this module as the first statement in `src/index.ts` so its top-level\n * side effect runs ahead of any class module's @smrt() decorator.\n *\n * Silent no-op in dev/test, where the vitest plugin already populates manifests\n * via a different path. Only needs to succeed in the published dist output.\n *\n * @see https://github.com/happyvertical/smrt/issues/1132\n */\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\n// `new URL('./manifest.json', import.meta.url)` resolves at runtime to the\n// manifest sitting next to this module's compiled output. Vite warns at build\n// time that it cannot pre-resolve the URL; that is the intended behavior —\n// the URL must resolve to dist/manifest.json at runtime, not be inlined.\nObjectRegistry.registerPackageManifest(\n new URL('./manifest.json', import.meta.url),\n);\n","import { type Asset, AssetCollection } from '@happyvertical/smrt-assets';\nimport { withSystemContext } from '@happyvertical/smrt-tenancy';\nimport type { DatabaseInterface } from '@happyvertical/sql';\n\n// Video roles intentionally allow hyphens for legacy compatibility\n// (`seed-image`, `base-motion`, `env-map`, etc.).\nconst VIDEO_ASSET_ROLE_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_-]*$/;\nconst VIDEO_ASSET_OWNER_COLUMNS = [\n 'character_id',\n 'performer_id',\n 'scene_id',\n 'video_shot_id',\n 'video_sequence_id',\n 'video_composition_id',\n] as const;\n\nexport type VideoAssetOwnerColumn = (typeof VIDEO_ASSET_OWNER_COLUMNS)[number];\n\nfunction getQueryRows(result: unknown): Record<string, unknown>[] {\n if (Array.isArray(result)) {\n return result as Record<string, unknown>[];\n }\n\n if (\n typeof result === 'object' &&\n result !== null &&\n 'rows' in result &&\n Array.isArray((result as { rows: unknown }).rows)\n ) {\n return (result as { rows: Record<string, unknown>[] }).rows;\n }\n\n return [];\n}\n\nfunction isMissingSchemaError(error: unknown, target?: string): boolean {\n const message =\n error instanceof Error\n ? error.message.toLowerCase()\n : String(error).toLowerCase();\n\n const isMissing =\n message.includes('no such table') ||\n message.includes('no such column') ||\n message.includes('does not exist') ||\n message.includes('unknown column');\n\n if (!isMissing) {\n return false;\n }\n\n return !target || message.includes(target.toLowerCase());\n}\n\nfunction buildPlaceholders(count: number): string {\n return Array.from({ length: count }, () => '?').join(', ');\n}\n\nfunction uniqueAssetIds(\n assetIds: Iterable<string | null | undefined>,\n): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n\n for (const assetId of assetIds) {\n if (!assetId || seen.has(assetId)) {\n continue;\n }\n\n seen.add(assetId);\n result.push(assetId);\n }\n\n return result;\n}\n\nexport function mergeOwnedAssetIds(\n ...groups: Array<Iterable<string | null | undefined>>\n): string[] {\n const seen = new Set<string>();\n const merged: string[] = [];\n\n for (const group of groups) {\n for (const assetId of group) {\n if (!assetId || seen.has(assetId)) {\n continue;\n }\n\n seen.add(assetId);\n merged.push(assetId);\n }\n }\n\n return merged;\n}\n\nexport function assertValidVideoAssetRole(role: string): void {\n if (!VIDEO_ASSET_ROLE_PATTERN.test(role)) {\n throw new Error(\n `Invalid asset role \"${role}\"; must start with a letter or underscore and contain only letters, digits, underscores, and hyphens`,\n );\n }\n}\n\nexport function assertValidVideoAssetSortOrder(sortOrder: number): void {\n if (!Number.isInteger(sortOrder) || sortOrder < 0 || sortOrder > 2147483647) {\n throw new Error(\n `Invalid sortOrder \"${sortOrder}\"; must be a non-negative integer`,\n );\n }\n}\n\nexport async function resolveOwnedAssets(\n db: DatabaseInterface,\n tenantId: string | null | undefined,\n assetIds: Iterable<string | null | undefined>,\n): Promise<Asset[]> {\n const orderedIds = uniqueAssetIds(assetIds);\n if (orderedIds.length === 0) {\n return [];\n }\n\n const assets = await AssetCollection.create({ db });\n let resolved: Asset[];\n try {\n resolved = tenantId\n ? await withSystemContext(async () => assets.listByIds(orderedIds))\n : await assets.listByIds(orderedIds);\n } catch (error) {\n if (isMissingSchemaError(error, 'assets')) {\n return [];\n }\n\n throw error;\n }\n\n const visibleAssets = tenantId\n ? resolved.filter(\n (asset) => asset.tenantId === tenantId || asset.tenantId === null,\n )\n : resolved;\n const assetsById = new Map(\n visibleAssets\n .filter((asset) => asset.id)\n .map((asset) => [asset.id as string, asset]),\n );\n\n return orderedIds\n .map((assetId) => assetsById.get(assetId))\n .filter(Boolean) as Asset[];\n}\n\nexport async function listCanonicalOwnedAssetIds<\n T extends { assetId: string },\n>(options: {\n tableName: string;\n loadLinks: () => Promise<T[]>;\n}): Promise<string[]> {\n try {\n return uniqueAssetIds(\n (await options.loadLinks()).map((link) => link.assetId),\n );\n } catch (error) {\n if (isMissingSchemaError(error, options.tableName)) {\n return [];\n }\n\n throw error;\n }\n}\n\nexport async function listLegacyOwnedAssetIds(options: {\n db: DatabaseInterface;\n ownerColumn: VideoAssetOwnerColumn;\n ownerId: string;\n role?: string;\n metaTypes: string[];\n}): Promise<string[]> {\n const { db, ownerColumn, ownerId, role, metaTypes } = options;\n if (!ownerId || metaTypes.length === 0) {\n return [];\n }\n\n if (!VIDEO_ASSET_OWNER_COLUMNS.includes(ownerColumn)) {\n throw new Error(`Unsupported video asset owner column \"${ownerColumn}\"`);\n }\n\n const params: unknown[] = [ownerId, ...metaTypes];\n const clauses = [\n `${ownerColumn} = ?`,\n `_meta_type IN (${buildPlaceholders(metaTypes.length)})`,\n ];\n\n if (role) {\n clauses.push('role = ?');\n params.push(role);\n }\n\n try {\n const result = await db.query(\n `SELECT id\n FROM assets\n WHERE ${clauses.join(' AND ')}\n ORDER BY created_at ASC, id ASC`,\n ...params,\n );\n\n return uniqueAssetIds(\n getQueryRows(result).map((row) => String(row?.id || '')),\n );\n } catch (error) {\n if (isMissingSchemaError(error)) {\n return [];\n }\n\n throw error;\n }\n}\n\nexport function legacyVideoAssetMetaTypes(className: string): string[] {\n return [className, `@happyvertical/smrt-video:${className}`];\n}\n","/**\n * Performer Model\n *\n * Represents the physical likeness/face DNA for consistent face generation.\n * A Performer can play multiple Characters (PersonalityProfiles).\n * Ensures face consistency via IP-Adapter FaceID.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { crossPackageRef, SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n assertValidVideoAssetRole,\n assertValidVideoAssetSortOrder,\n legacyVideoAssetMetaTypes,\n listCanonicalOwnedAssetIds,\n listLegacyOwnedAssetIds,\n mergeOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { PerformerAssetRole } from './performer-asset.js';\n\n/**\n * Performer DNA for IP-Adapter FaceID consistency\n */\nexport interface PerformerDNA {\n /** Gender */\n gender: 'male' | 'female' | 'neutral';\n\n /** Age range */\n ageRange:\n | 'child'\n | 'teen'\n | 'young_adult'\n | 'adult'\n | 'middle_aged'\n | 'senior';\n\n /** Face embedding for IP-Adapter FaceID (512-dim vector) */\n faceEmbedding?: number[];\n\n /** Default clothing style (can be overridden per Character) */\n defaultClothing?: {\n style: 'business' | 'casual' | 'formal' | 'outdoor';\n colors?: string[];\n description?: string;\n };\n\n /** IP-Adapter weight for consistency (0.5-1.0) */\n ipAdapterWeight: number;\n\n /** FaceID weight for face consistency */\n faceIdWeight?: number;\n}\n\n/**\n * Performer status\n */\nexport type PerformerStatus = 'pending' | 'ready';\n\n/**\n * Performer creation options\n */\nexport interface PerformerOptions extends SmrtObjectOptions {\n /** Human-readable name */\n name?: string;\n\n /** Description */\n description?: string | null;\n\n /** Performer DNA for consistent face generation */\n dna?: PerformerDNA;\n\n /** Reference images for IP-Adapter (multiple angles/expressions) */\n referenceAssetIds?: string[];\n\n /** Generated seed image asset ID */\n seedImageAssetId?: string | null;\n\n /** Default voice profile for this performer */\n voiceProfileId?: string | null;\n\n /** Performer status */\n status?: PerformerStatus;\n\n /** 1-1 profile record for this performer */\n profileId?: string | null;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Performer - The physical likeness/face DNA\n *\n * A Performer represents a person's visual identity for consistent\n * face generation across multiple Characters. One Performer can play\n * many Characters (e.g., same face as \"Evening Anchor\" and \"Weekend Host\").\n *\n * @example\n * ```typescript\n * import { Performer } from '@happyvertical/smrt-video';\n *\n * const performer = new Performer({\n * name: 'Alex Bentley',\n * dna: {\n * gender: 'male',\n * ageRange: 'adult',\n * ipAdapterWeight: 0.75,\n * },\n * referenceAssetIds: ['ref-img-1', 'ref-img-2'],\n * });\n * await performer.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class Performer extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Human-readable name */\n name: string = '';\n\n /** Description */\n description: string | null = null;\n\n /** Performer DNA for consistent face generation */\n dna: PerformerDNA = {\n gender: 'neutral',\n ageRange: 'adult',\n ipAdapterWeight: 0.7,\n };\n\n /** Reference images for IP-Adapter (multiple angles/expressions) */\n referenceAssetIds: string[] = [];\n\n /** Generated seed image asset ID */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n seedImageAssetId: string | null = null;\n\n /** Default voice profile for this performer */\n @crossPackageRef('@happyvertical/smrt-voice:VoiceProfile')\n voiceProfileId: string | null = null;\n\n /** Performer status */\n status: PerformerStatus = 'pending';\n\n /** 1-1 profile record for this performer */\n @crossPackageRef('@happyvertical/smrt-profiles:Profile')\n profileId: string | null = null;\n\n constructor(options: PerformerOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.dna !== undefined) this.dna = options.dna;\n if (options.referenceAssetIds !== undefined)\n this.referenceAssetIds = options.referenceAssetIds;\n if (options.seedImageAssetId !== undefined)\n this.seedImageAssetId = options.seedImageAssetId;\n if (options.voiceProfileId !== undefined)\n this.voiceProfileId = options.voiceProfileId;\n if (options.status !== undefined) this.status = options.status;\n if (options.profileId !== undefined) this.profileId = options.profileId;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n private async getPerformerAssetCollection() {\n const { PerformerOwnedAssetCollection } = await import(\n './performer-assets.js'\n );\n return PerformerOwnedAssetCollection.create({ db: this.db });\n }\n\n private getLegacyFieldAssetIds(role?: PerformerAssetRole): string[] {\n if (role === 'reference') {\n return this.referenceAssetIds;\n }\n\n if (role === 'seed') {\n return this.seedImageAssetId ? [this.seedImageAssetId] : [];\n }\n\n return [...this.referenceAssetIds, this.seedImageAssetId].filter(\n (assetId): assetId is string => Boolean(assetId),\n );\n }\n\n private setLegacyFieldAssetId(\n role: PerformerAssetRole,\n assetId: string,\n ): boolean {\n if (role === 'seed') {\n if (this.seedImageAssetId === assetId) {\n return false;\n }\n\n this.seedImageAssetId = assetId;\n return true;\n }\n\n if (this.referenceAssetIds.includes(assetId)) {\n return false;\n }\n\n this.referenceAssetIds = [...this.referenceAssetIds, assetId];\n return true;\n }\n\n private clearLegacyFieldAssetId(\n assetId: string,\n role?: PerformerAssetRole,\n ): boolean {\n let changed = false;\n\n if ((!role || role === 'seed') && this.seedImageAssetId === assetId) {\n this.seedImageAssetId = null;\n changed = true;\n }\n\n if (!role || role === 'reference') {\n const remaining = this.referenceAssetIds.filter(\n (referenceAssetId) => referenceAssetId !== assetId,\n );\n\n if (remaining.length !== this.referenceAssetIds.length) {\n this.referenceAssetIds = remaining;\n changed = true;\n }\n }\n\n return changed;\n }\n\n async getAssets(role?: PerformerAssetRole): Promise<Asset[]> {\n const canonicalAssetIds = this.id\n ? await listCanonicalOwnedAssetIds({\n tableName: 'performer_assets',\n loadLinks: async () =>\n (await this.getPerformerAssetCollection()).byLeft(\n this.id as string,\n role ? { role } : {},\n ),\n })\n : [];\n const legacyFieldAssetIds = this.getLegacyFieldAssetIds(role);\n const legacyOwnedAssetIds = this.id\n ? await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'performer_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('PerformerAsset'),\n })\n : [];\n\n return resolveOwnedAssets(\n this.db,\n this.tenantId,\n mergeOwnedAssetIds(\n canonicalAssetIds,\n legacyFieldAssetIds,\n legacyOwnedAssetIds,\n ),\n );\n }\n\n async getAssetByRole(role: PerformerAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n async addAsset(\n asset: Asset,\n role: PerformerAssetRole = 'reference',\n sortOrder = 0,\n ): Promise<void> {\n if (!this.id || !asset.id) {\n throw new Error('Cannot associate unsaved performer or asset');\n }\n\n assertValidVideoAssetRole(role);\n assertValidVideoAssetSortOrder(sortOrder);\n\n const performerAssets = await this.getPerformerAssetCollection();\n await performerAssets.attach(this.id, asset.id, {\n role,\n sortOrder,\n tenantId: this.tenantId,\n });\n\n if (this.setLegacyFieldAssetId(role, asset.id)) {\n await this.save();\n }\n }\n\n async removeAsset(assetId: string, role?: PerformerAssetRole): Promise<void> {\n if (!this.id) {\n return;\n }\n\n const performerAssets = await this.getPerformerAssetCollection();\n await performerAssets.detach(this.id, assetId, role ? { role } : {});\n\n if (this.clearLegacyFieldAssetId(assetId, role)) {\n await this.save();\n }\n }\n\n /** Check if the performer has reference images */\n get hasReferences(): boolean {\n return this.referenceAssetIds.length > 0;\n }\n\n /** Check if the performer has a face embedding */\n get hasFaceEmbedding(): boolean {\n return (\n Array.isArray(this.dna.faceEmbedding) && this.dna.faceEmbedding.length > 0\n );\n }\n\n /** Check if the performer is ready for generation */\n get isReady(): boolean {\n return this.status === 'ready' && this.hasReferences;\n }\n}\n","/**\n * Scene Model\n *\n * Represents a virtual production scene (background environment).\n * Supports 360° panoramas, standard images, and video backgrounds.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { crossPackageRef, SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport {\n assertValidVideoAssetRole,\n assertValidVideoAssetSortOrder,\n legacyVideoAssetMetaTypes,\n listCanonicalOwnedAssetIds,\n listLegacyOwnedAssetIds,\n mergeOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { SceneAssetRole } from './scene-asset.js';\n\n/**\n * Viewpoint extracted from 360° scene\n */\nexport interface SceneViewpoint {\n /** Viewpoint identifier */\n id: string;\n\n /** Human-readable name */\n name: string;\n\n /** Horizontal rotation (-180 to 180°) */\n pan: number;\n\n /** Vertical rotation (-90 to 90°) */\n tilt: number;\n\n /** Field of view (60-120°) */\n fov: number;\n\n /** Generated rectilinear image asset ID */\n extractedAssetId?: string;\n\n /** Viewpoint-specific lighting profile */\n lightingProfile?: LightingProfile;\n}\n\n/**\n * Lighting profile for IC-Light matching\n */\nexport interface LightingProfile {\n /** Dominant light direction (normalized vector) */\n direction?: { x: number; y: number; z: number };\n\n /** Light color temperature (Kelvin) */\n colorTemperature?: number;\n\n /** Ambient light intensity (0-1) */\n ambientIntensity?: number;\n\n /** Key light intensity (0-1) */\n keyLightIntensity?: number;\n\n /** Shadow softness (0-1) */\n shadowSoftness?: number;\n\n /** Environment map asset ID for reflections */\n envMapAssetId?: string;\n}\n\n/**\n * Anchor point for character placement in scene\n */\nexport interface AnchorPoint {\n /** Anchor point identifier */\n id: string;\n\n /** Human-readable name */\n name: string;\n\n /** Position as normalized coordinates (0-1) */\n position: { x: number; y: number };\n\n /** Suggested character scale at this point */\n suggestedScale: number;\n\n /** Ground plane Y coordinate for perspective */\n groundY: number;\n\n /** Optional viewpoint this anchor belongs to */\n viewpointId?: string;\n}\n\n/**\n * Scene source type\n */\nexport type SceneSourceType =\n | 'image'\n | 'video'\n | 'panorama_360'\n | 'panorama_180';\n\n/**\n * Scene projection type\n */\nexport type SceneProjection = 'equirectangular' | 'cubemap';\n\n/**\n * Scene status\n */\nexport type SceneStatus = 'pending' | 'processing' | 'ready' | 'failed';\n\n/**\n * Scene creation options\n */\nexport interface SceneOptions extends SmrtObjectOptions {\n /** Human-readable name */\n name?: string;\n\n /** Description */\n description?: string | null;\n\n /** Source media asset ID */\n sourceAssetId?: string | null;\n\n /** Type of source media */\n sourceType?: SceneSourceType;\n\n /** Projection type for panoramas */\n projection?: SceneProjection | null;\n\n /** Extracted camera angles from 360° panoramas */\n viewpoints?: SceneViewpoint[];\n\n /** Lighting analysis for IC-Light matching */\n lightingProfile?: LightingProfile | null;\n\n /** Location metadata */\n location?: {\n name: string;\n coordinates?: { lat: number; lng: number };\n } | null;\n\n /** Anchor points for character placement */\n anchorPoints?: AnchorPoint[];\n\n /** Scene status */\n status?: SceneStatus;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Scene for virtual production compositing\n *\n * Supports 360° panoramas, standard images, and video backgrounds\n * with viewpoint extraction, lighting analysis, and character placement.\n *\n * @example\n * ```typescript\n * import { Scene } from '@happyvertical/smrt-video';\n *\n * const scene = new Scene({\n * name: 'Town Hall Exterior',\n * sourceAssetId: 'asset-townhall-pano',\n * sourceType: 'panorama_360',\n * projection: 'equirectangular',\n * });\n * await scene.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class Scene extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Human-readable name */\n name: string = '';\n\n /** Description */\n description: string | null = null;\n\n /** Source media asset ID */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n sourceAssetId: string | null = null;\n\n /** Type of source media */\n sourceType: SceneSourceType = 'image';\n\n /** Projection type for panoramas */\n projection: SceneProjection | null = null;\n\n /** Extracted camera angles from 360° panoramas */\n viewpoints: SceneViewpoint[] = [];\n\n /** Lighting analysis for IC-Light matching */\n lightingProfile: LightingProfile | null = null;\n\n /** Location metadata */\n location: {\n name: string;\n coordinates?: { lat: number; lng: number };\n } | null = null;\n\n /** Anchor points for character placement */\n anchorPoints: AnchorPoint[] = [];\n\n /** Scene status */\n status: SceneStatus = 'pending';\n\n constructor(options: SceneOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.sourceAssetId !== undefined)\n this.sourceAssetId = options.sourceAssetId;\n if (options.sourceType !== undefined) this.sourceType = options.sourceType;\n if (options.projection !== undefined) this.projection = options.projection;\n if (options.viewpoints !== undefined) this.viewpoints = options.viewpoints;\n if (options.lightingProfile !== undefined)\n this.lightingProfile = options.lightingProfile;\n if (options.location !== undefined) this.location = options.location;\n if (options.anchorPoints !== undefined)\n this.anchorPoints = options.anchorPoints;\n if (options.status !== undefined) this.status = options.status;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n private async getSceneAssetCollection() {\n const { SceneOwnedAssetCollection } = await import('./scene-assets.js');\n return SceneOwnedAssetCollection.create({ db: this.db });\n }\n\n private getLegacyFieldAssetIds(role?: SceneAssetRole): string[] {\n if (role === 'source') {\n return this.sourceAssetId ? [this.sourceAssetId] : [];\n }\n\n if (role === 'env-map') {\n return this.lightingProfile?.envMapAssetId\n ? [this.lightingProfile.envMapAssetId]\n : [];\n }\n\n if (role === 'viewpoint-extract') {\n return this.viewpoints\n .map((viewpoint) => viewpoint.extractedAssetId || null)\n .filter((assetId): assetId is string => Boolean(assetId));\n }\n\n return [\n this.sourceAssetId,\n this.lightingProfile?.envMapAssetId || null,\n ...this.viewpoints.map((viewpoint) => viewpoint.extractedAssetId || null),\n ].filter((assetId): assetId is string => Boolean(assetId));\n }\n\n private setLegacyFieldAssetId(\n role: SceneAssetRole,\n assetId: string,\n ): boolean {\n if (role === 'source') {\n if (this.sourceAssetId === assetId) {\n return false;\n }\n\n this.sourceAssetId = assetId;\n return true;\n }\n\n if (role === 'env-map') {\n if ((this.lightingProfile?.envMapAssetId || null) === assetId) {\n return false;\n }\n\n this.lightingProfile = {\n ...(this.lightingProfile || {}),\n envMapAssetId: assetId,\n };\n return true;\n }\n\n return false;\n }\n\n private clearLegacyFieldAssetId(\n assetId: string,\n role?: SceneAssetRole,\n ): boolean {\n let changed = false;\n\n if ((!role || role === 'source') && this.sourceAssetId === assetId) {\n this.sourceAssetId = null;\n changed = true;\n }\n\n if (\n (!role || role === 'env-map') &&\n this.lightingProfile?.envMapAssetId === assetId\n ) {\n this.lightingProfile = {\n ...(this.lightingProfile || {}),\n envMapAssetId: undefined,\n };\n changed = true;\n }\n\n if (!role || role === 'viewpoint-extract') {\n let viewpointChanged = false;\n const nextViewpoints = this.viewpoints.map((viewpoint) => {\n if (viewpoint.extractedAssetId !== assetId) {\n return viewpoint;\n }\n\n viewpointChanged = true;\n return {\n ...viewpoint,\n extractedAssetId: undefined,\n };\n });\n\n if (viewpointChanged) {\n this.viewpoints = nextViewpoints;\n changed = true;\n }\n }\n\n return changed;\n }\n\n async getAssets(role?: SceneAssetRole): Promise<Asset[]> {\n const canonicalAssetIds = this.id\n ? await listCanonicalOwnedAssetIds({\n tableName: 'scene_assets',\n loadLinks: async () =>\n (await this.getSceneAssetCollection()).byLeft(\n this.id as string,\n role ? { role } : {},\n ),\n })\n : [];\n const legacyFieldAssetIds = this.getLegacyFieldAssetIds(role);\n const legacyOwnedAssetIds = this.id\n ? await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'scene_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('SceneAsset'),\n })\n : [];\n\n return resolveOwnedAssets(\n this.db,\n this.tenantId,\n mergeOwnedAssetIds(\n canonicalAssetIds,\n legacyFieldAssetIds,\n legacyOwnedAssetIds,\n ),\n );\n }\n\n async getAssetByRole(role: SceneAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n async addAsset(\n asset: Asset,\n role: SceneAssetRole = 'source',\n sortOrder = 0,\n ): Promise<void> {\n if (!this.id || !asset.id) {\n throw new Error('Cannot associate unsaved scene or asset');\n }\n\n assertValidVideoAssetRole(role);\n assertValidVideoAssetSortOrder(sortOrder);\n\n const sceneAssets = await this.getSceneAssetCollection();\n await sceneAssets.attach(this.id, asset.id, {\n role,\n sortOrder,\n tenantId: this.tenantId,\n });\n\n if (this.setLegacyFieldAssetId(role, asset.id)) {\n await this.save();\n }\n }\n\n async removeAsset(assetId: string, role?: SceneAssetRole): Promise<void> {\n if (!this.id) {\n return;\n }\n\n const sceneAssets = await this.getSceneAssetCollection();\n await sceneAssets.detach(this.id, assetId, role ? { role } : {});\n\n if (this.clearLegacyFieldAssetId(assetId, role)) {\n await this.save();\n }\n }\n\n /** Check if this is a 360° panorama */\n get isPanorama(): boolean {\n return (\n this.sourceType === 'panorama_360' || this.sourceType === 'panorama_180'\n );\n }\n\n /** Check if the scene has viewpoints extracted */\n get hasViewpoints(): boolean {\n return this.viewpoints.length > 0;\n }\n\n /** Check if the scene is ready for compositing */\n get isReady(): boolean {\n return this.status === 'ready' && this.sourceAssetId !== null;\n }\n}\n","/**\n * Character Model\n *\n * Manages virtual characters for AI-powered video production.\n * Each character combines a visual identity with a voice profile.\n *\n * Renamed from PersonalityProfile. A Character is the role being played\n * (outfit, voice, branding). A Performer is the physical likeness/face DNA.\n * \"A Performer plays Characters.\"\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport type { CharacterAssetRole } from './character-asset.js';\nimport {\n assertValidVideoAssetRole,\n assertValidVideoAssetSortOrder,\n legacyVideoAssetMetaTypes,\n listCanonicalOwnedAssetIds,\n listLegacyOwnedAssetIds,\n mergeOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport { Performer } from './performer.js';\nimport { Scene } from './scene.js';\n\n/**\n * Character status\n */\nexport type CharacterStatus = 'pending' | 'ready';\n\n/**\n * Scene-specific configuration for a character\n */\nexport interface CharacterSceneConfig {\n /** Scene ID */\n sceneId: string;\n\n /** Preferred viewpoint ID (for 360° scenes) */\n viewpointId?: string;\n\n /** Anchor point ID for placement */\n anchorPointId?: string;\n\n /** Character scale in this scene */\n scale: number;\n\n /** Character position in this scene (normalized 0-1) */\n position: { x: number; y: number };\n}\n\n/**\n * Branding configuration for video overlays\n */\nexport interface BrandingConfig {\n /** Asset ID for logo overlay */\n logoAssetId?: string | null;\n\n /** Primary brand color (hex) */\n primaryColor?: string | null;\n\n /** Background color (hex) */\n backgroundColor?: string | null;\n\n /** Lower-third template name */\n lowerThirdTemplate?: string | null;\n\n /** Font family for text overlays */\n fontFamily?: string | null;\n\n /** Whether to show news ticker */\n tickerEnabled?: boolean;\n}\n\n/**\n * Character creation options\n */\nexport interface CharacterOptions extends SmrtObjectOptions {\n /** Human-readable name for the character */\n name?: string;\n\n /** Description of the character persona */\n description?: string | null;\n\n /** Asset ID of the seed image for image-to-video generation */\n imageAssetId?: string | null;\n\n /** Asset ID of pre-baked base motion video */\n baseMotionAssetId?: string | null;\n\n /** Voice profile ID for speech synthesis */\n voiceProfileId?: string | null;\n\n /** Branding configuration for video overlays */\n brandingKit?: BrandingConfig;\n\n /** Character status */\n status?: CharacterStatus;\n\n /** Linked performer for IP-Adapter face consistency */\n performerId?: string | null;\n\n /** Default scene for this character */\n defaultSceneId?: string | null;\n\n /** Scene-specific configurations */\n sceneConfigs?: CharacterSceneConfig[];\n\n /** 1-1 profile record for this character */\n profileId?: string | null;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Virtual character for AI-powered video production\n *\n * Character represents a virtual persona combining:\n * - Visual identity: Seed image for I2V (image-to-video) generation\n * - Voice identity: Link to a VoiceProfile for TTS\n * - Branding: Logo overlays, lower-thirds, colors\n *\n * @example\n * ```typescript\n * import { Character } from '@happyvertical/smrt-video';\n *\n * const character = new Character({\n * name: 'Bentley News Anchor',\n * description: 'Professional news anchor for local broadcasts',\n * imageAssetId: 'asset-123',\n * voiceProfileId: 'voice-456',\n * brandingKit: {\n * logoAssetId: 'asset-789',\n * primaryColor: '#1a73e8',\n * lowerThirdTemplate: 'news-standard',\n * tickerEnabled: true,\n * },\n * });\n * await character.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class Character extends SmrtObject {\n /** Tenant ID for multi-tenant isolation */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Human-readable name for the character */\n name: string = '';\n\n /** Description of the character persona */\n description: string | null = null;\n\n /** Asset ID of the seed image for I2V generation */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n imageAssetId: string | null = null;\n\n /** Asset ID of pre-baked base motion video */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n baseMotionAssetId: string | null = null;\n\n /** Voice profile ID for speech synthesis */\n @crossPackageRef('@happyvertical/smrt-voice:VoiceProfile')\n voiceProfileId: string | null = null;\n\n /** Branding configuration for video overlays */\n brandingKit: BrandingConfig = {};\n\n /** Character status */\n status: CharacterStatus = 'pending';\n\n /** Linked performer for IP-Adapter face consistency */\n @foreignKey(() => Performer)\n performerId: string | null = null;\n\n /** Default scene for this character */\n @foreignKey(() => Scene)\n defaultSceneId: string | null = null;\n\n /** Scene-specific configurations */\n sceneConfigs: CharacterSceneConfig[] = [];\n\n /** 1-1 profile record for this character */\n @crossPackageRef('@happyvertical/smrt-profiles:Profile')\n profileId: string | null = null;\n\n constructor(options: CharacterOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.imageAssetId !== undefined)\n this.imageAssetId = options.imageAssetId;\n if (options.baseMotionAssetId !== undefined)\n this.baseMotionAssetId = options.baseMotionAssetId;\n if (options.voiceProfileId !== undefined)\n this.voiceProfileId = options.voiceProfileId;\n if (options.brandingKit !== undefined)\n this.brandingKit = options.brandingKit;\n if (options.status !== undefined) this.status = options.status;\n if (options.performerId !== undefined)\n this.performerId = options.performerId;\n if (options.defaultSceneId !== undefined)\n this.defaultSceneId = options.defaultSceneId;\n if (options.sceneConfigs !== undefined)\n this.sceneConfigs = options.sceneConfigs;\n if (options.profileId !== undefined) this.profileId = options.profileId;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n private async getCharacterAssetCollection() {\n const { CharacterOwnedAssetCollection } = await import(\n './character-assets.js'\n );\n return CharacterOwnedAssetCollection.create({ db: this.db });\n }\n\n private getLegacyFieldAssetIds(role?: CharacterAssetRole): string[] {\n if (role === 'seed-image') {\n return this.imageAssetId ? [this.imageAssetId] : [];\n }\n\n if (role === 'base-motion') {\n return this.baseMotionAssetId ? [this.baseMotionAssetId] : [];\n }\n\n if (role === 'logo') {\n return this.brandingKit.logoAssetId ? [this.brandingKit.logoAssetId] : [];\n }\n\n return [\n this.imageAssetId,\n this.baseMotionAssetId,\n this.brandingKit.logoAssetId || null,\n ].filter((assetId): assetId is string => Boolean(assetId));\n }\n\n private setLegacyFieldAssetId(\n role: CharacterAssetRole,\n assetId: string | null,\n ): boolean {\n if (role === 'seed-image') {\n if (this.imageAssetId === assetId) {\n return false;\n }\n\n this.imageAssetId = assetId;\n return true;\n }\n\n if (role === 'base-motion') {\n if (this.baseMotionAssetId === assetId) {\n return false;\n }\n\n this.baseMotionAssetId = assetId;\n return true;\n }\n\n if ((this.brandingKit.logoAssetId || null) === assetId) {\n return false;\n }\n\n this.brandingKit = {\n ...this.brandingKit,\n logoAssetId: assetId,\n };\n return true;\n }\n\n private clearLegacyFieldAssetId(\n assetId: string,\n role?: CharacterAssetRole,\n ): boolean {\n let changed = false;\n\n if ((!role || role === 'seed-image') && this.imageAssetId === assetId) {\n this.imageAssetId = null;\n changed = true;\n }\n\n if (\n (!role || role === 'base-motion') &&\n this.baseMotionAssetId === assetId\n ) {\n this.baseMotionAssetId = null;\n changed = true;\n }\n\n if (\n (!role || role === 'logo') &&\n this.brandingKit.logoAssetId === assetId\n ) {\n this.brandingKit = {\n ...this.brandingKit,\n logoAssetId: null,\n };\n changed = true;\n }\n\n return changed;\n }\n\n async getAssets(role?: CharacterAssetRole): Promise<Asset[]> {\n const canonicalAssetIds = this.id\n ? await listCanonicalOwnedAssetIds({\n tableName: 'character_assets',\n loadLinks: async () =>\n (await this.getCharacterAssetCollection()).byLeft(\n this.id as string,\n role ? { role } : {},\n ),\n })\n : [];\n const legacyFieldAssetIds = this.getLegacyFieldAssetIds(role);\n const legacyOwnedAssetIds = this.id\n ? await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'character_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('CharacterAsset'),\n })\n : [];\n\n return resolveOwnedAssets(\n this.db,\n this.tenantId,\n mergeOwnedAssetIds(\n canonicalAssetIds,\n legacyFieldAssetIds,\n legacyOwnedAssetIds,\n ),\n );\n }\n\n async getAssetByRole(role: CharacterAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n async addAsset(\n asset: Asset,\n role: CharacterAssetRole = 'seed-image',\n sortOrder = 0,\n ): Promise<void> {\n if (!this.id || !asset.id) {\n throw new Error('Cannot associate unsaved character or asset');\n }\n\n assertValidVideoAssetRole(role);\n assertValidVideoAssetSortOrder(sortOrder);\n\n const characterAssets = await this.getCharacterAssetCollection();\n await characterAssets.attach(this.id, asset.id, {\n role,\n sortOrder,\n tenantId: this.tenantId,\n });\n\n if (this.setLegacyFieldAssetId(role, asset.id)) {\n await this.save();\n }\n }\n\n async removeAsset(assetId: string, role?: CharacterAssetRole): Promise<void> {\n if (!this.id) {\n return;\n }\n\n const characterAssets = await this.getCharacterAssetCollection();\n await characterAssets.detach(this.id, assetId, role ? { role } : {});\n\n if (this.clearLegacyFieldAssetId(assetId, role)) {\n await this.save();\n }\n }\n\n /**\n * Check if the character has a pre-baked base motion video\n * @deprecated Use getAssetByRole('base-motion') instead\n */\n get hasBaseMotion(): boolean {\n return this.baseMotionAssetId !== null;\n }\n\n /** Check if the character is complete and ready for video generation */\n get isComplete(): boolean {\n return (\n this.imageAssetId !== null &&\n this.voiceProfileId !== null &&\n this.status === 'ready'\n );\n }\n}\n","/**\n * CharacterCollection - Collection manager for Character instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal } from '@happyvertical/smrt-tenancy';\nimport { Character } from './character.js';\n\nexport class CharacterCollection extends SmrtCollection<Character> {\n static readonly _itemClass = Character;\n\n /** Find all characters belonging to a specific tenant */\n async findByTenant(tenantId: string): Promise<Character[]> {\n return (await this.list({ where: { tenantId } })) as Character[];\n }\n\n /**\n * Find all global characters (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n */\n async findGlobal(): Promise<Character[]> {\n return queryGlobal<Character>(this);\n }\n\n /** Find characters by performer */\n async findByPerformer(performerId: string): Promise<Character[]> {\n return (await this.list({ where: { performerId } })) as Character[];\n }\n\n /** Find characters that are ready for video generation */\n async findReady(): Promise<Character[]> {\n return (await this.list({ where: { status: 'ready' } })) as Character[];\n }\n}\n","/**\n * CompositeJob Model\n *\n * Tracks the progress of compositing a character video onto a scene background.\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Scene } from './scene.js';\n\n/**\n * Composite job status\n */\nexport type CompositeJobStatus =\n | 'pending'\n | 'removing_bg'\n | 'analyzing_light'\n | 'compositing'\n | 'complete'\n | 'failed';\n\n/**\n * Composite job creation options\n */\nexport interface CompositeJobOptions extends SmrtObjectOptions {\n /** Character video asset ID (after lip-sync) */\n characterVideoAssetId?: string | null;\n\n /** Scene ID to composite onto */\n sceneId?: string | null;\n\n /** Viewpoint ID (for 360° scenes) */\n viewpointId?: string | null;\n\n /** Anchor point ID for placement */\n anchorPointId?: string | null;\n\n /** Character scale */\n scale?: number;\n\n /** Character position (normalized 0-1) */\n position?: { x: number; y: number };\n\n /** Job status */\n status?: CompositeJobStatus;\n\n /** Progress percentage (0-100) */\n progress?: number;\n\n /** Output video asset ID */\n outputAssetId?: string | null;\n\n /** Error message if failed */\n errorMessage?: string | null;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Composite job for tracking virtual production compositing\n *\n * @example\n * ```typescript\n * import { CompositeJob } from '@happyvertical/smrt-video';\n *\n * const job = new CompositeJob({\n * characterVideoAssetId: 'asset-video-123',\n * sceneId: 'scene-townhall',\n * scale: 0.8,\n * position: { x: 0.5, y: 0.7 },\n * });\n * await job.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class CompositeJob extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Character video asset ID (after lip-sync) */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n characterVideoAssetId: string | null = null;\n\n /** Scene ID to composite onto */\n @foreignKey(() => Scene)\n sceneId: string | null = null;\n\n /** Viewpoint ID (for 360° scenes) */\n viewpointId: string | null = null;\n\n /** Anchor point ID for placement */\n anchorPointId: string | null = null;\n\n /** Character scale */\n scale: number = 1.0;\n\n /** Character position (normalized 0-1) */\n position: { x: number; y: number } = { x: 0.5, y: 0.5 };\n\n /** Job status */\n status: CompositeJobStatus = 'pending';\n\n /** Progress percentage (0-100) */\n progress: number = 0;\n\n /** Output video asset ID */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n outputAssetId: string | null = null;\n\n /** Error message if failed */\n errorMessage: string | null = null;\n\n constructor(options: CompositeJobOptions = {}) {\n super(options);\n\n if (options.characterVideoAssetId !== undefined)\n this.characterVideoAssetId = options.characterVideoAssetId;\n if (options.sceneId !== undefined) this.sceneId = options.sceneId;\n if (options.viewpointId !== undefined)\n this.viewpointId = options.viewpointId;\n if (options.anchorPointId !== undefined)\n this.anchorPointId = options.anchorPointId;\n if (options.scale !== undefined) this.scale = options.scale;\n if (options.position !== undefined) this.position = options.position;\n if (options.status !== undefined) this.status = options.status;\n if (options.progress !== undefined) this.progress = options.progress;\n if (options.outputAssetId !== undefined)\n this.outputAssetId = options.outputAssetId;\n if (options.errorMessage !== undefined)\n this.errorMessage = options.errorMessage;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n /** Check if the job is complete */\n get isComplete(): boolean {\n return this.status === 'complete' && this.outputAssetId !== null;\n }\n\n /** Check if the job is in progress */\n get isProcessing(): boolean {\n return (\n this.status !== 'pending' &&\n this.status !== 'complete' &&\n this.status !== 'failed'\n );\n }\n}\n","/**\n * VideoComposition Model\n *\n * The publishable output. Defines render spec (fps, width, height).\n * Contains ordered sequences with optional transitions between them.\n * Maps to Remotion <Composition /> + <TransitionSeries>.\n *\n * Design principle: store frames, compute seconds. seconds = frames / fps.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport { Content, type ContentOptions } from '@happyvertical/smrt-content';\nimport { smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped } from '@happyvertical/smrt-tenancy';\nimport {\n legacyVideoAssetMetaTypes,\n listLegacyOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { VideoCompositionAssetRole } from './video-composition-asset.js';\n\n/**\n * Render status for the composition\n */\nexport type RenderStatus = 'draft' | 'rendering' | 'ready' | 'failed';\n\n/**\n * VideoComposition creation options\n */\nexport interface VideoCompositionOptions extends ContentOptions {\n /** Frames per second (e.g., 30) — everything downstream is in frames */\n fps?: number;\n\n /** Render width in pixels */\n width?: number;\n\n /** Render height in pixels */\n height?: number;\n\n /** Computed total: sum of sequences minus transition overlaps */\n durationInFrames?: number;\n\n /** Render status */\n renderStatus?: RenderStatus;\n\n /** Render progress (0-100) */\n renderProgress?: number;\n}\n\n/**\n * Publishable video composition\n *\n * VideoComposition is the top-level container for a rendered video.\n * It defines the render spec and contains ordered VideoSequences.\n *\n * @example\n * ```typescript\n * import { VideoComposition } from '@happyvertical/smrt-video';\n *\n * const composition = new VideoComposition({\n * title: 'Evening News - January 25, 2026',\n * fps: 30,\n * width: 1920,\n * height: 1080,\n * });\n * await composition.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoComposition extends Content {\n /** Frames per second — everything downstream is in frames */\n fps: number = 30;\n\n /** Render width in pixels */\n width: number = 1920;\n\n /** Render height in pixels */\n height: number = 1080;\n\n /** Computed total: sum of sequences minus transition overlaps */\n durationInFrames: number = 0;\n\n /** Render status */\n renderStatus: RenderStatus = 'draft';\n\n /** Render progress (0-100) */\n renderProgress: number = 0;\n\n constructor(options: VideoCompositionOptions = {}) {\n super({\n ...options,\n type: 'video-composition',\n });\n\n if (options.fps !== undefined) this.fps = options.fps;\n if (options.width !== undefined) this.width = options.width;\n if (options.height !== undefined) this.height = options.height;\n if (options.durationInFrames !== undefined)\n this.durationInFrames = options.durationInFrames;\n if (options.renderStatus !== undefined)\n this.renderStatus = options.renderStatus;\n if (options.renderProgress !== undefined)\n this.renderProgress = options.renderProgress;\n }\n\n /** Duration in seconds */\n get durationInSeconds(): number {\n if (this.fps === 0) return 0;\n return this.durationInFrames / this.fps;\n }\n\n /** Check if the composition is ready for publishing */\n get isReady(): boolean {\n return this.renderStatus === 'ready';\n }\n\n /** Check if the composition is currently rendering */\n get isRendering(): boolean {\n return this.renderStatus === 'rendering';\n }\n\n async getAssets(relationship?: string): Promise<Asset[]>;\n async getAssets(role?: VideoCompositionAssetRole): Promise<Asset[]>;\n async getAssets(relationship?: string): Promise<Asset[]> {\n const canonicalAssets = await super.getAssets(relationship);\n if (!this.id) {\n return canonicalAssets;\n }\n\n const role = relationship as VideoCompositionAssetRole | undefined;\n const legacyAssets = await resolveOwnedAssets(\n this.db,\n this.tenantId,\n await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'video_composition_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('VideoCompositionAsset'),\n }),\n );\n\n return [\n ...canonicalAssets,\n ...legacyAssets.filter(\n (asset) =>\n asset.id &&\n !canonicalAssets.some(\n (canonicalAsset) => canonicalAsset.id === asset.id,\n ),\n ),\n ];\n }\n\n async getAssetByRole(role: VideoCompositionAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n}\n","/**\n * VideoCompositionCollection - Collection manager for VideoComposition instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { type RenderStatus, VideoComposition } from './video-composition.js';\n\nexport class VideoCompositionCollection extends SmrtCollection<VideoComposition> {\n static readonly _itemClass = VideoComposition;\n\n /** Find compositions by render status */\n async findByRenderStatus(\n renderStatus: RenderStatus,\n ): Promise<VideoComposition[]> {\n return (await this.list({\n where: { renderStatus },\n })) as VideoComposition[];\n }\n\n /** Find compositions that are ready for publishing */\n async findReady(): Promise<VideoComposition[]> {\n return (await this.list({\n where: { renderStatus: 'ready' },\n })) as VideoComposition[];\n }\n}\n","/**\n * VideoSequence Model\n *\n * A thematic section of a video: \"top story\", \"weather\", \"interview\".\n * Groups VideoShots. Maps to Remotion <TransitionSeries.Sequence>.\n *\n * Design principle: store frames, compute seconds. seconds = frames / fps.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport { Content, type ContentOptions } from '@happyvertical/smrt-content';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped } from '@happyvertical/smrt-tenancy';\nimport {\n legacyVideoAssetMetaTypes,\n listLegacyOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport type { VideoSequenceAssetRole } from './video-sequence-asset.js';\n\n/**\n * Transition type to the next sequence\n */\nexport type TransitionType = 'none' | 'fade' | 'slide' | 'wipe';\n\n/**\n * VideoSequence creation options\n */\nexport interface VideoSequenceOptions extends ContentOptions {\n /** Composition this sequence belongs to (nullable — can exist standalone) */\n compositionId?: string | null;\n\n /** Order within composition */\n position?: number;\n\n /** Computed duration: sum of shot frames */\n durationInFrames?: number;\n\n /** Transition type to the next sequence */\n transitionType?: TransitionType;\n\n /** Overlap frames with next sequence for transition */\n transitionDurationFrames?: number;\n}\n\n/**\n * Thematic section of a video composition\n *\n * VideoSequence groups VideoShots into a logical section. It can belong\n * to a VideoComposition or exist standalone (e.g., during long-video generation).\n *\n * @example\n * ```typescript\n * import { VideoSequence } from '@happyvertical/smrt-video';\n *\n * const sequence = new VideoSequence({\n * title: 'Top Story',\n * position: 0,\n * transitionType: 'fade',\n * transitionDurationFrames: 15,\n * });\n * await sequence.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoSequence extends Content {\n /** Composition this sequence belongs to */\n @foreignKey('VideoComposition')\n compositionId: string | null = null;\n\n /** Order within composition */\n position: number = 0;\n\n /** Computed duration: sum of shot frames */\n durationInFrames: number = 0;\n\n /** Transition type to the next sequence */\n transitionType: TransitionType = 'none';\n\n /** Overlap frames with next sequence for transition */\n transitionDurationFrames: number = 0;\n\n constructor(options: VideoSequenceOptions = {}) {\n super({\n ...options,\n type: 'video-sequence',\n });\n\n if (options.compositionId !== undefined)\n this.compositionId = options.compositionId;\n if (options.position !== undefined) this.position = options.position;\n if (options.durationInFrames !== undefined)\n this.durationInFrames = options.durationInFrames;\n if (options.transitionType !== undefined)\n this.transitionType = options.transitionType;\n if (options.transitionDurationFrames !== undefined)\n this.transitionDurationFrames = options.transitionDurationFrames;\n }\n\n async getAssets(relationship?: string): Promise<Asset[]>;\n async getAssets(role?: VideoSequenceAssetRole): Promise<Asset[]>;\n async getAssets(relationship?: string): Promise<Asset[]> {\n const canonicalAssets = await super.getAssets(relationship);\n if (!this.id) {\n return canonicalAssets;\n }\n\n const role = relationship as VideoSequenceAssetRole | undefined;\n const legacyAssets = await resolveOwnedAssets(\n this.db,\n this.tenantId,\n await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'video_sequence_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('VideoSequenceAsset'),\n }),\n );\n\n return [\n ...canonicalAssets,\n ...legacyAssets.filter(\n (asset) =>\n asset.id &&\n !canonicalAssets.some(\n (canonicalAsset) => canonicalAsset.id === asset.id,\n ),\n ),\n ];\n }\n\n async getAssetByRole(role: VideoSequenceAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n}\n","/**\n * VideoSequenceCollection - Collection manager for VideoSequence instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { VideoSequence } from './video-sequence.js';\n\nexport class VideoSequenceCollection extends SmrtCollection<VideoSequence> {\n static readonly _itemClass = VideoSequence;\n\n /** Find sequences belonging to a composition, ordered by position */\n async findByComposition(compositionId: string): Promise<VideoSequence[]> {\n return (await this.list({\n where: { compositionId },\n orderBy: 'position ASC',\n })) as VideoSequence[];\n }\n\n /** Find standalone sequences (not in any composition) */\n async findStandalone(): Promise<VideoSequence[]> {\n return (await this.list({\n where: { compositionId: null },\n })) as VideoSequence[];\n }\n}\n","/**\n * VideoShot Model\n *\n * The atomic video generation unit. One or more characters + one scene + one pipeline run.\n * This is what ComfyUI produces. Maps to Remotion <Sequence><Video /></Sequence>.\n *\n * Design principle: store frames, compute seconds. seconds = frames / fps.\n */\n\nimport type { Asset } from '@happyvertical/smrt-assets';\nimport { Content, type ContentOptions } from '@happyvertical/smrt-content';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped } from '@happyvertical/smrt-tenancy';\nimport type { WordTiming } from '@happyvertical/smrt-voice';\nimport {\n legacyVideoAssetMetaTypes,\n listLegacyOwnedAssetIds,\n resolveOwnedAssets,\n} from './owned-asset-utils.js';\nimport { Scene } from './scene.js';\nimport { VideoSequence } from './video-sequence.js';\nimport type { VideoShotAssetRole } from './video-shot-asset.js';\n\n/**\n * Video shot status\n */\nexport type VideoShotStatus =\n | 'draft'\n | 'queued'\n | 'processing'\n | 'ready'\n | 'failed'\n | 'published';\n\n/**\n * Video metadata\n */\nexport interface VideoMetadata {\n /** Actual duration in seconds */\n duration?: number;\n\n /** Video resolution (e.g., \"1920x1080\") */\n resolution?: string;\n\n /** Aspect ratio (e.g., \"16:9\", \"9:16\") */\n aspectRatio?: string;\n\n /** Video codec (e.g., \"h264\", \"h265\") */\n codec?: string;\n\n /** Frames per second */\n fps?: number;\n\n /** File size in bytes */\n fileSize?: number;\n\n /** Word timing data from TTS for lip-sync */\n wordTimings?: WordTiming[];\n\n /** ComfyUI prompt ID for tracking */\n comfyPromptId?: string;\n}\n\n/**\n * Video shot creation options\n */\nexport interface VideoShotOptions extends ContentOptions {\n /** Sequence this shot belongs to (nullable — shots can exist standalone) */\n sequenceId?: string | null;\n\n /** Scene for this shot (nullable) */\n sceneId?: string | null;\n\n /** Order within sequence */\n position?: number;\n\n /** Actual frame count of generated clip */\n durationInFrames?: number;\n\n /** Frames to skip at start (overlap handling) */\n trimBeforeFrames?: number;\n\n /** Frames to skip at end */\n trimAfterFrames?: number;\n\n /** Script text to be spoken */\n scriptText?: string;\n\n /** Word count in the script */\n scriptWordCount?: number;\n\n /** Target duration in seconds */\n targetDuration?: number;\n\n /** Video generation status */\n shotStatus?: VideoShotStatus;\n\n /** Generation progress (0-100) */\n progress?: number;\n\n /** Error message if status is 'failed' */\n errorMessage?: string | null;\n\n /** Detailed status message for progress tracking */\n statusMessage?: string | null;\n\n /** Video metadata */\n videoMetadata?: VideoMetadata;\n}\n\n/**\n * Atomic video generation unit\n *\n * VideoShot represents a single pipeline run producing one video clip.\n * It can belong to a VideoSequence (for multi-segment long videos) or\n * exist standalone. Characters are linked via the VideoShotCharacter join model.\n *\n * @example\n * ```typescript\n * import { VideoShot } from '@happyvertical/smrt-video';\n *\n * const shot = new VideoShot({\n * scriptText: 'Welcome to the evening news.',\n * targetDuration: 30,\n * title: 'Evening News - Opening',\n * });\n * await shot.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoShot extends Content {\n /** Sequence this shot belongs to */\n @foreignKey(() => VideoSequence)\n sequenceId: string | null = null;\n\n /** Scene for this shot */\n @foreignKey(() => Scene)\n sceneId: string | null = null;\n\n /** Order within sequence */\n position: number = 0;\n\n /** Actual frame count of generated clip */\n durationInFrames: number = 0;\n\n /** Frames to skip at start (overlap handling) */\n trimBeforeFrames: number = 0;\n\n /** Frames to skip at end */\n trimAfterFrames: number = 0;\n\n /** Script text to be spoken */\n scriptText: string = '';\n\n /** Word count in the script */\n scriptWordCount: number = 0;\n\n /** Target duration in seconds */\n targetDuration: number = 30;\n\n /** Video generation status */\n shotStatus: VideoShotStatus = 'draft';\n\n /** Generation progress (0-100) */\n progress: number = 0;\n\n /** Error message if status is 'failed' */\n errorMessage: string | null = null;\n\n /** Detailed status message for progress tracking */\n statusMessage: string | null = null;\n\n /** Video metadata (duration, resolution, etc.) */\n videoMetadata: VideoMetadata = {};\n\n constructor(options: VideoShotOptions = {}) {\n super({\n ...options,\n type: 'video-shot',\n });\n\n if (options.sequenceId !== undefined) this.sequenceId = options.sequenceId;\n if (options.sceneId !== undefined) this.sceneId = options.sceneId;\n if (options.position !== undefined) this.position = options.position;\n if (options.durationInFrames !== undefined)\n this.durationInFrames = options.durationInFrames;\n if (options.trimBeforeFrames !== undefined)\n this.trimBeforeFrames = options.trimBeforeFrames;\n if (options.trimAfterFrames !== undefined)\n this.trimAfterFrames = options.trimAfterFrames;\n if (options.scriptText !== undefined) {\n this.scriptText = options.scriptText;\n this.scriptWordCount = this.scriptText\n .split(/\\s+/)\n .filter(Boolean).length;\n }\n if (options.scriptWordCount !== undefined)\n this.scriptWordCount = options.scriptWordCount;\n if (options.targetDuration !== undefined)\n this.targetDuration = options.targetDuration;\n if (options.shotStatus !== undefined) this.shotStatus = options.shotStatus;\n if (options.progress !== undefined) this.progress = options.progress;\n if (options.errorMessage !== undefined)\n this.errorMessage = options.errorMessage;\n if (options.statusMessage !== undefined)\n this.statusMessage = options.statusMessage;\n if (options.videoMetadata !== undefined)\n this.videoMetadata = options.videoMetadata;\n }\n\n /** Estimate speech duration based on word count (2.7 words/sec) */\n get estimatedDuration(): number {\n return this.scriptWordCount / 2.7;\n }\n\n /** Check if the script length matches target duration (+/- 15%) */\n get isScriptLengthValid(): boolean {\n const estimated = this.estimatedDuration;\n const tolerance = this.targetDuration * 0.15;\n return (\n estimated >= this.targetDuration - tolerance &&\n estimated <= this.targetDuration + tolerance\n );\n }\n\n /** Get the recommended word count for target duration */\n get recommendedWordCount(): { min: number; max: number; target: number } {\n const wordsPerSecond = 2.7;\n const target = Math.round(this.targetDuration * wordsPerSecond);\n const tolerance = Math.round(target * 0.15);\n return {\n min: target - tolerance,\n max: target + tolerance,\n target,\n };\n }\n\n /** Effective frame count after trimming */\n get effectiveFrames(): number {\n return Math.max(\n 0,\n this.durationInFrames - this.trimBeforeFrames - this.trimAfterFrames,\n );\n }\n\n /** Check if video generation is in progress */\n get isGenerating(): boolean {\n return this.shotStatus === 'queued' || this.shotStatus === 'processing';\n }\n\n /** Check if video is ready for publishing */\n get isReady(): boolean {\n return this.shotStatus === 'ready';\n }\n\n async getAssets(relationship?: string): Promise<Asset[]>;\n async getAssets(role?: VideoShotAssetRole): Promise<Asset[]>;\n async getAssets(relationship?: string): Promise<Asset[]> {\n const canonicalAssets = await super.getAssets(relationship);\n if (!this.id) {\n return canonicalAssets;\n }\n\n const role = relationship as VideoShotAssetRole | undefined;\n const legacyAssets = await resolveOwnedAssets(\n this.db,\n this.tenantId,\n await listLegacyOwnedAssetIds({\n db: this.db,\n ownerColumn: 'video_shot_id',\n ownerId: this.id,\n role,\n metaTypes: legacyVideoAssetMetaTypes('VideoShotAsset'),\n }),\n );\n\n return [\n ...canonicalAssets,\n ...legacyAssets.filter(\n (asset) =>\n asset.id &&\n !canonicalAssets.some(\n (canonicalAsset) => canonicalAsset.id === asset.id,\n ),\n ),\n ];\n }\n\n async getAssetByRole(role: VideoShotAssetRole): Promise<Asset | null> {\n const assets = await this.getAssets(role);\n return assets[0] || null;\n }\n\n /** Update script text and recalculate word count */\n setScript(text: string): void {\n this.scriptText = text;\n this.scriptWordCount = text.split(/\\s+/).filter(Boolean).length;\n }\n}\n","/**\n * VideoShotCharacter - Join model linking VideoShots to Characters\n *\n * Replaces the old single personalityProfileId FK on VideoContent.\n * Supports multiple characters per shot with role and ordering.\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { foreignKey, SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Character } from './character.js';\nimport { VideoShot } from './video-shot.js';\n\n/**\n * Character role within a shot\n */\nexport type VideoShotCharacterRole = 'primary' | 'secondary' | 'background';\n\n/**\n * VideoShotCharacter creation options\n */\nexport interface VideoShotCharacterOptions extends SmrtObjectOptions {\n /** Video shot ID */\n videoShotId: string;\n\n /** Character ID */\n characterId: string;\n\n /** Role of the character in this shot */\n role?: VideoShotCharacterRole;\n\n /** Order/layer position within the shot */\n position?: number;\n\n /** Tenant ID for multi-tenant isolation */\n tenantId?: string | null;\n}\n\n/**\n * Join model linking a VideoShot to a Character\n *\n * @example\n * ```typescript\n * import { VideoShotCharacter } from '@happyvertical/smrt-video';\n *\n * const link = new VideoShotCharacter({\n * videoShotId: 'shot-123',\n * characterId: 'char-456',\n * role: 'primary',\n * position: 0,\n * });\n * await link.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'delete'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoShotCharacter extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /** Video shot ID */\n @foreignKey(() => VideoShot, { required: true })\n videoShotId: string = '';\n\n /** Character ID */\n @foreignKey(() => Character, { required: true })\n characterId: string = '';\n\n /** Role of the character in this shot */\n role: VideoShotCharacterRole = 'primary';\n\n /** Order/layer position within the shot */\n position: number = 0;\n\n constructor(options: VideoShotCharacterOptions) {\n super(options);\n\n this.videoShotId = options.videoShotId;\n this.characterId = options.characterId;\n if (options.role !== undefined) this.role = options.role;\n if (options.position !== undefined) this.position = options.position;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","/**\n * VideoShotCharacterCollection - Collection manager for VideoShotCharacter instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { VideoShotCharacter } from './video-shot-character.js';\n\nexport class VideoShotCharacterCollection extends SmrtCollection<VideoShotCharacter> {\n static readonly _itemClass = VideoShotCharacter;\n\n /** Find all character links for a shot, ordered by position */\n async findByShot(videoShotId: string): Promise<VideoShotCharacter[]> {\n return (await this.list({\n where: { videoShotId },\n orderBy: 'position ASC',\n })) as VideoShotCharacter[];\n }\n\n /** Find all shot links for a character */\n async findByCharacter(characterId: string): Promise<VideoShotCharacter[]> {\n return (await this.list({\n where: { characterId },\n })) as VideoShotCharacter[];\n }\n}\n","/**\n * VideoShotCollection - Collection manager for VideoShot instances\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { VideoShot, type VideoShotStatus } from './video-shot.js';\n\nexport class VideoShotCollection extends SmrtCollection<VideoShot> {\n static readonly _itemClass = VideoShot;\n\n /** Find shots belonging to a specific sequence, ordered by position */\n async findBySequence(sequenceId: string): Promise<VideoShot[]> {\n return (await this.list({\n where: { sequenceId },\n orderBy: 'position ASC',\n })) as VideoShot[];\n }\n\n /** Find shots by status */\n async findByStatus(shotStatus: VideoShotStatus): Promise<VideoShot[]> {\n return (await this.list({ where: { shotStatus } })) as VideoShot[];\n }\n\n /** Find standalone shots (not in any sequence) */\n async findStandalone(): Promise<VideoShot[]> {\n return (await this.list({ where: { sequenceId: null } })) as VideoShot[];\n }\n}\n","/**\n * Video Workflow Model\n *\n * Manages ComfyUI workflow templates for video generation.\n */\n\nimport { createLogger } from '@happyvertical/logger';\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { SmrtObject, smrt } from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\n\nconst logger = createLogger({ level: 'info' });\n\n/**\n * Node mapping for dynamic parameter injection\n */\nexport interface NodeMapping {\n /**\n * Node ID for anchor seed image input\n */\n seedImage?: string;\n\n /**\n * Node ID for TTS audio input\n */\n audioFile?: string;\n\n /**\n * Node ID for base motion video input\n */\n baseVideo?: string;\n\n /**\n * Node ID for final video output\n */\n outputVideo?: string;\n\n /**\n * Node ID for text prompt input\n */\n prompt?: string;\n\n /**\n * Node ID for negative prompt input\n */\n negativePrompt?: string;\n\n /**\n * Node ID for sampler/scheduler settings\n */\n sampler?: string;\n\n /**\n * Node ID for video duration control\n */\n duration?: string;\n\n /**\n * Additional custom node mappings\n */\n [key: string]: string | undefined;\n}\n\n/**\n * Workflow type classification\n */\nexport type WorkflowType =\n | 'prebake'\n | 'broadcast'\n | 'lipsync'\n | 'postprod'\n | 'custom';\n\n/**\n * Video workflow creation options\n */\nexport interface VideoWorkflowOptions extends SmrtObjectOptions {\n /**\n * Human-readable name for the workflow\n */\n name?: string;\n\n /**\n * Description of what this workflow does\n */\n description?: string | null;\n\n /**\n * Workflow type classification\n * @default 'custom'\n */\n workflowType?: WorkflowType;\n\n /**\n * ComfyUI API format JSON\n */\n workflowJson?: object | null;\n\n /**\n * Node ID mappings for dynamic parameter injection\n */\n nodeMapping?: NodeMapping;\n\n /**\n * Estimated processing time in seconds\n */\n estimatedTime?: number;\n\n /**\n * Whether this workflow is active/usable\n * @default true\n */\n isActive?: boolean;\n\n /**\n * ComfyUI models required by this workflow\n */\n requiredModels?: string[];\n\n /**\n * Tenant ID for multi-tenant isolation\n */\n tenantId?: string | null;\n}\n\n/**\n * ComfyUI workflow template for video generation\n *\n * VideoWorkflow stores ComfyUI workflow definitions with node mappings\n * for dynamic parameter injection. This allows the Histrio agent to\n * inject anchor images, audio, and other inputs at runtime.\n *\n * @example\n * ```typescript\n * import { VideoWorkflow } from '@happyvertical/smrt-video';\n *\n * const workflow = new VideoWorkflow({\n * name: 'Wan 2.6 + EchoMimic',\n * description: 'Full broadcast generation with lip-sync',\n * workflowType: 'broadcast',\n * workflowJson: comfyuiWorkflowJson,\n * nodeMapping: {\n * seedImage: '1',\n * audioFile: '5',\n * outputVideo: '12',\n * },\n * estimatedTime: 600, // 10 minutes\n * requiredModels: ['wan_2.6_t2v_14b_fp8', 'echomimic_v2'],\n * });\n * await workflow.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: {\n include: ['list', 'get', 'create', 'update'],\n },\n mcp: {\n include: ['list', 'get'],\n },\n cli: true,\n})\nexport class VideoWorkflow extends SmrtObject {\n /**\n * Tenant ID for multi-tenant isolation\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Human-readable name for the workflow\n */\n name: string = '';\n\n /**\n * Description of what this workflow does\n */\n description: string | null = null;\n\n /**\n * Workflow type classification\n * - prebake: Pre-generate base motion from seed image\n * - broadcast: Full video generation pipeline\n * - lipsync: Lip-sync only (requires base video + audio)\n * - postprod: Post-production overlays and effects\n * - custom: User-defined workflow\n */\n workflowType: WorkflowType = 'custom';\n\n /**\n * ComfyUI API format JSON\n * This is the workflow definition that will be sent to ComfyUI\n */\n workflowJson: object | null = null;\n\n /**\n * Node ID mappings for dynamic parameter injection\n * Maps semantic names to ComfyUI node IDs\n */\n nodeMapping: NodeMapping = {};\n\n /**\n * Estimated processing time in seconds\n * Used for progress estimation\n */\n estimatedTime: number = 300;\n\n /**\n * Whether this workflow is active/usable\n */\n isActive: boolean = true;\n\n /**\n * ComfyUI models required by this workflow\n * Used for validation before queuing\n */\n requiredModels: string[] = [];\n\n constructor(options: VideoWorkflowOptions = {}) {\n super(options);\n\n if (options.name !== undefined) this.name = options.name;\n if (options.description !== undefined)\n this.description = options.description;\n if (options.workflowType !== undefined)\n this.workflowType = options.workflowType;\n if (options.workflowJson !== undefined)\n this.workflowJson = options.workflowJson;\n if (options.nodeMapping !== undefined)\n this.nodeMapping = options.nodeMapping;\n if (options.estimatedTime !== undefined)\n this.estimatedTime = options.estimatedTime;\n if (options.isActive !== undefined) this.isActive = options.isActive;\n if (options.requiredModels !== undefined)\n this.requiredModels = options.requiredModels;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n\n /**\n * Check if the workflow has all required node mappings\n */\n get hasRequiredMappings(): boolean {\n const required = ['outputVideo'];\n return required.every((key) => this.nodeMapping[key] !== undefined);\n }\n\n /**\n * Get a copy of the workflow JSON with injected parameters\n *\n * Parameter injection follows ComfyUI node structure conventions:\n * - seedImage, audioFile, baseVideo → node.inputs.image (file path)\n * - prompt → node.inputs.text (string)\n * - Other parameters → node.inputs[paramKey]\n *\n * @param params - Key-value pairs of parameters to inject\n * @returns Modified workflow JSON or null if no workflowJson set\n */\n injectParameters(params: Record<string, unknown>): object | null {\n if (!this.workflowJson) return null;\n\n const workflow = JSON.parse(JSON.stringify(this.workflowJson));\n const warnings: string[] = [];\n\n for (const [paramKey, nodeId] of Object.entries(this.nodeMapping)) {\n if (nodeId && params[paramKey] !== undefined) {\n // Validate nodeId exists in workflow\n if (!workflow[nodeId]) {\n warnings.push(\n `Node mapping '${paramKey}' references node '${nodeId}' which does not exist in workflow`,\n );\n continue;\n }\n\n // Inject parameter into the node\n workflow[nodeId].inputs = workflow[nodeId].inputs || {};\n\n // Map parameters to ComfyUI node input field names\n if (\n paramKey === 'seedImage' ||\n paramKey === 'audioFile' ||\n paramKey === 'baseVideo'\n ) {\n workflow[nodeId].inputs.image = params[paramKey];\n } else if (paramKey === 'prompt') {\n workflow[nodeId].inputs.text = params[paramKey];\n } else {\n workflow[nodeId].inputs[paramKey] = params[paramKey];\n }\n }\n }\n\n // Log warnings if any (in development)\n if (warnings.length > 0 && process.env.NODE_ENV !== 'production') {\n logger.warn(\n `[VideoWorkflow] Parameter injection warnings:\\n${warnings.join('\\n')}`,\n );\n }\n\n return workflow;\n }\n}\n","/**\n * CharacterAsset - legacy STI asset subclass for Character-owned assets\n *\n * @deprecated Character owned assets are now modeled canonically through\n * `CharacterOwnedAsset` join rows in `character_assets`. This legacy subtype\n * remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { Character } from './character.js';\n\n/** Roles a character asset can play */\nexport type CharacterAssetRole = 'seed-image' | 'base-motion' | 'logo';\n\nexport interface CharacterAssetOptions extends AssetOptions {\n /** Character this asset belongs to */\n characterId?: string | null;\n /** Role of this asset for the character */\n role?: CharacterAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class CharacterAsset extends Asset {\n @foreignKey(() => Character)\n characterId: string | null = null;\n\n role: CharacterAssetRole = 'seed-image';\n\n constructor(options: CharacterAssetOptions = {}) {\n super(options);\n if (options.characterId !== undefined)\n this.characterId = options.characterId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Character } from './character.js';\nimport type { CharacterAssetRole } from './character-asset.js';\n\nexport interface CharacterOwnedAssetOptions extends SmrtObjectOptions {\n characterId?: string;\n assetId?: string;\n role?: CharacterAssetRole;\n sortOrder?: number;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n name: 'CharacterOwnedAsset',\n tableName: 'character_assets',\n conflictColumns: ['character_id', 'asset_id', 'role'],\n api: false,\n mcp: false,\n cli: false,\n})\nexport class CharacterOwnedAsset extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n @foreignKey(() => Character, { required: true })\n characterId = '';\n\n @crossPackageRef('@happyvertical/smrt-assets:Asset', { required: true })\n assetId = '';\n\n @field({ required: true })\n role: CharacterAssetRole = 'seed-image';\n\n @field()\n sortOrder = 0;\n\n constructor(options: CharacterOwnedAssetOptions = {}) {\n super(options);\n if (options.characterId) this.characterId = options.characterId;\n if (options.assetId) this.assetId = options.assetId;\n if (options.role !== undefined) this.role = options.role;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","import type { SmrtCollectionOptions } from '@happyvertical/smrt-core';\nimport { SmrtJunction, smrt } from '@happyvertical/smrt-core';\nimport { CharacterOwnedAsset } from './character-owned-asset.js';\n\nexport interface CharacterOwnedAssetCollectionOptions\n extends SmrtCollectionOptions {}\n\n@smrt({\n api: false,\n mcp: false,\n cli: false,\n})\nexport class CharacterOwnedAssetCollection extends SmrtJunction<CharacterOwnedAsset> {\n static readonly _itemClass = CharacterOwnedAsset;\n protected leftField = 'characterId';\n protected rightField = 'assetId';\n}\n","/**\n * PerformerAsset - legacy STI asset subclass for Performer-owned assets\n *\n * @deprecated Performer owned assets are now modeled canonically through\n * `PerformerOwnedAsset` join rows in `performer_assets`. This legacy subtype\n * remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { Performer } from './performer.js';\n\n/** Roles a performer asset can play */\nexport type PerformerAssetRole = 'reference' | 'seed';\n\nexport interface PerformerAssetOptions extends AssetOptions {\n /** Performer this asset belongs to */\n performerId?: string | null;\n /** Role of this asset for the performer */\n role?: PerformerAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class PerformerAsset extends Asset {\n @foreignKey(() => Performer)\n performerId: string | null = null;\n\n role: PerformerAssetRole = 'reference';\n\n constructor(options: PerformerAssetOptions = {}) {\n super(options);\n if (options.performerId !== undefined)\n this.performerId = options.performerId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Performer } from './performer.js';\nimport type { PerformerAssetRole } from './performer-asset.js';\n\nexport interface PerformerOwnedAssetOptions extends SmrtObjectOptions {\n performerId?: string;\n assetId?: string;\n role?: PerformerAssetRole;\n sortOrder?: number;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n name: 'PerformerOwnedAsset',\n tableName: 'performer_assets',\n conflictColumns: ['performer_id', 'asset_id', 'role'],\n api: false,\n mcp: false,\n cli: false,\n})\nexport class PerformerOwnedAsset extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n @foreignKey(() => Performer, { required: true })\n performerId = '';\n\n @crossPackageRef('@happyvertical/smrt-assets:Asset', { required: true })\n assetId = '';\n\n @field({ required: true })\n role: PerformerAssetRole = 'reference';\n\n @field()\n sortOrder = 0;\n\n constructor(options: PerformerOwnedAssetOptions = {}) {\n super(options);\n if (options.performerId) this.performerId = options.performerId;\n if (options.assetId) this.assetId = options.assetId;\n if (options.role !== undefined) this.role = options.role;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","import type { SmrtCollectionOptions } from '@happyvertical/smrt-core';\nimport { SmrtJunction, smrt } from '@happyvertical/smrt-core';\nimport { PerformerOwnedAsset } from './performer-owned-asset.js';\n\nexport interface PerformerOwnedAssetCollectionOptions\n extends SmrtCollectionOptions {}\n\n@smrt({\n api: false,\n mcp: false,\n cli: false,\n})\nexport class PerformerOwnedAssetCollection extends SmrtJunction<PerformerOwnedAsset> {\n static readonly _itemClass = PerformerOwnedAsset;\n protected leftField = 'performerId';\n protected rightField = 'assetId';\n}\n","/**\n * SceneAsset - legacy STI asset subclass for Scene-owned assets\n *\n * @deprecated Scene owned assets are now modeled canonically through\n * `SceneOwnedAsset` join rows in `scene_assets`. This legacy subtype remains\n * readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { Scene } from './scene.js';\n\n/** Roles a scene asset can play */\nexport type SceneAssetRole = 'source' | 'viewpoint-extract' | 'env-map';\n\nexport interface SceneAssetOptions extends AssetOptions {\n /** Scene this asset belongs to */\n sceneId?: string | null;\n /** Role of this asset for the scene */\n role?: SceneAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class SceneAsset extends Asset {\n @foreignKey(() => Scene)\n sceneId: string | null = null;\n\n role: SceneAssetRole = 'source';\n\n constructor(options: SceneAssetOptions = {}) {\n super(options);\n if (options.sceneId !== undefined) this.sceneId = options.sceneId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","import type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { Scene } from './scene.js';\nimport type { SceneAssetRole } from './scene-asset.js';\n\nexport interface SceneOwnedAssetOptions extends SmrtObjectOptions {\n sceneId?: string;\n assetId?: string;\n role?: SceneAssetRole;\n sortOrder?: number;\n tenantId?: string | null;\n}\n\n@TenantScoped({ mode: 'optional' })\n@smrt({\n name: 'SceneOwnedAsset',\n tableName: 'scene_assets',\n conflictColumns: ['scene_id', 'asset_id', 'role'],\n api: false,\n mcp: false,\n cli: false,\n})\nexport class SceneOwnedAsset extends SmrtObject {\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n @foreignKey(() => Scene, { required: true })\n sceneId = '';\n\n @crossPackageRef('@happyvertical/smrt-assets:Asset', { required: true })\n assetId = '';\n\n @field({ required: true })\n role: SceneAssetRole = 'source';\n\n @field()\n sortOrder = 0;\n\n constructor(options: SceneOwnedAssetOptions = {}) {\n super(options);\n if (options.sceneId) this.sceneId = options.sceneId;\n if (options.assetId) this.assetId = options.assetId;\n if (options.role !== undefined) this.role = options.role;\n if (options.sortOrder !== undefined) this.sortOrder = options.sortOrder;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n }\n}\n","import type { SmrtCollectionOptions } from '@happyvertical/smrt-core';\nimport { SmrtJunction, smrt } from '@happyvertical/smrt-core';\nimport { SceneOwnedAsset } from './scene-owned-asset.js';\n\nexport interface SceneOwnedAssetCollectionOptions\n extends SmrtCollectionOptions {}\n\n@smrt({\n api: false,\n mcp: false,\n cli: false,\n})\nexport class SceneOwnedAssetCollection extends SmrtJunction<SceneOwnedAsset> {\n static readonly _itemClass = SceneOwnedAsset;\n protected leftField = 'sceneId';\n protected rightField = 'assetId';\n}\n","/**\n * VideoCompositionAsset - legacy STI asset subclass for VideoComposition-owned assets\n *\n * @deprecated VideoComposition now uses inherited Content asset helpers backed\n * by `content_assets`. This legacy subtype remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { VideoComposition } from './video-composition.js';\n\n/** Roles a video composition asset can play */\nexport type VideoCompositionAssetRole = 'video' | 'audio' | 'thumbnail';\n\nexport interface VideoCompositionAssetOptions extends AssetOptions {\n /** VideoComposition this asset belongs to */\n videoCompositionId?: string | null;\n /** Role of this asset for the composition */\n role?: VideoCompositionAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class VideoCompositionAsset extends Asset {\n @foreignKey(() => VideoComposition)\n videoCompositionId: string | null = null;\n\n role: VideoCompositionAssetRole = 'video';\n\n constructor(options: VideoCompositionAssetOptions = {}) {\n super(options);\n if (options.videoCompositionId !== undefined)\n this.videoCompositionId = options.videoCompositionId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","/**\n * VideoSequenceAsset - legacy STI asset subclass for VideoSequence-owned assets\n *\n * @deprecated VideoSequence now uses inherited Content asset helpers backed by\n * `content_assets`. This legacy subtype remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { VideoSequence } from './video-sequence.js';\n\n/** Roles a video sequence asset can play */\nexport type VideoSequenceAssetRole = 'video' | 'audio' | 'thumbnail';\n\nexport interface VideoSequenceAssetOptions extends AssetOptions {\n /** VideoSequence this asset belongs to */\n videoSequenceId?: string | null;\n /** Role of this asset for the sequence */\n role?: VideoSequenceAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class VideoSequenceAsset extends Asset {\n @foreignKey(() => VideoSequence)\n videoSequenceId: string | null = null;\n\n role: VideoSequenceAssetRole = 'video';\n\n constructor(options: VideoSequenceAssetOptions = {}) {\n super(options);\n if (options.videoSequenceId !== undefined)\n this.videoSequenceId = options.videoSequenceId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n","/**\n * VideoShotAsset - legacy STI asset subclass for VideoShot-owned assets\n *\n * @deprecated VideoShot now uses inherited Content asset helpers backed by\n * `content_assets`. This legacy subtype remains readable during migration.\n */\n\nimport { Asset, type AssetOptions } from '@happyvertical/smrt-assets';\nimport { foreignKey, smrt } from '@happyvertical/smrt-core';\nimport { VideoShot } from './video-shot.js';\n\n/** Roles a video shot asset can play */\nexport type VideoShotAssetRole = 'video' | 'audio' | 'thumbnail';\n\nexport interface VideoShotAssetOptions extends AssetOptions {\n /** VideoShot this asset belongs to */\n videoShotId?: string | null;\n /** Role of this asset for the shot */\n role?: VideoShotAssetRole;\n}\n\n@smrt({\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class VideoShotAsset extends Asset {\n @foreignKey(() => VideoShot)\n videoShotId: string | null = null;\n\n role: VideoShotAssetRole = 'video';\n\n constructor(options: VideoShotAssetOptions = {}) {\n super(options);\n if (options.videoShotId !== undefined)\n this.videoShotId = options.videoShotId;\n if (options.role !== undefined) this.role = options.role;\n }\n}\n"],"names":["tenantId","PerformerOwnedAssetCollection","performerAssets","__decorateClass","SceneOwnedAssetCollection","sceneAssets","CharacterOwnedAssetCollection","characterAssets","__publicField"],"mappings":";;;;;;AAsBA,eAAe;AAAA,EACb,IAAA,IAAA,mBAAA,YAAA,GAAA;AACF;AClBA,MAAM,2BAA2B;AACjC,MAAM,4BAA4B;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,SAAS,aAAa,QAA4C;AAChE,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MACE,OAAO,WAAW,YAClB,WAAW,QACX,UAAU,UACV,MAAM,QAAS,OAA6B,IAAI,GAChD;AACA,WAAQ,OAA+C;AAAA,EACzD;AAEA,SAAO,CAAA;AACT;AAEA,SAAS,qBAAqB,OAAgB,QAA0B;AACtE,QAAM,UACJ,iBAAiB,QACb,MAAM,QAAQ,gBACd,OAAO,KAAK,EAAE,YAAA;AAEpB,QAAM,YACJ,QAAQ,SAAS,eAAe,KAChC,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,gBAAgB;AAEnC,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,UAAU,QAAQ,SAAS,OAAO,aAAa;AACzD;AAEA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,MAAM,KAAK,EAAE,QAAQ,MAAA,GAAS,MAAM,GAAG,EAAE,KAAK,IAAI;AAC3D;AAEA,SAAS,eACP,UACU;AACV,QAAM,2BAAW,IAAA;AACjB,QAAM,SAAmB,CAAA;AAEzB,aAAW,WAAW,UAAU;AAC9B,QAAI,CAAC,WAAW,KAAK,IAAI,OAAO,GAAG;AACjC;AAAA,IACF;AAEA,SAAK,IAAI,OAAO;AAChB,WAAO,KAAK,OAAO;AAAA,EACrB;AAEA,SAAO;AACT;AAEO,SAAS,sBACX,QACO;AACV,QAAM,2BAAW,IAAA;AACjB,QAAM,SAAmB,CAAA;AAEzB,aAAW,SAAS,QAAQ;AAC1B,eAAW,WAAW,OAAO;AAC3B,UAAI,CAAC,WAAW,KAAK,IAAI,OAAO,GAAG;AACjC;AAAA,MACF;AAEA,WAAK,IAAI,OAAO;AAChB,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,0BAA0B,MAAoB;AAC5D,MAAI,CAAC,yBAAyB,KAAK,IAAI,GAAG;AACxC,UAAM,IAAI;AAAA,MACR,uBAAuB,IAAI;AAAA,IAAA;AAAA,EAE/B;AACF;AAEO,SAAS,+BAA+B,WAAyB;AACtE,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,KAAK,YAAY,YAAY;AAC3E,UAAM,IAAI;AAAA,MACR,sBAAsB,SAAS;AAAA,IAAA;AAAA,EAEnC;AACF;AAEA,eAAsB,mBACpB,IACAA,WACA,UACkB;AAClB,QAAM,aAAa,eAAe,QAAQ;AAC1C,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,CAAA;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,gBAAgB,OAAO,EAAE,IAAI;AAClD,MAAI;AACJ,MAAI;AACF,eAAWA,YACP,MAAM,kBAAkB,YAAY,OAAO,UAAU,UAAU,CAAC,IAChE,MAAM,OAAO,UAAU,UAAU;AAAA,EACvC,SAAS,OAAO;AACd,QAAI,qBAAqB,OAAO,QAAQ,GAAG;AACzC,aAAO,CAAA;AAAA,IACT;AAEA,UAAM;AAAA,EACR;AAEA,QAAM,gBAAgBA,YAClB,SAAS;AAAA,IACP,CAAC,UAAU,MAAM,aAAaA,aAAY,MAAM,aAAa;AAAA,EAAA,IAE/D;AACJ,QAAM,aAAa,IAAI;AAAA,IACrB,cACG,OAAO,CAAC,UAAU,MAAM,EAAE,EAC1B,IAAI,CAAC,UAAU,CAAC,MAAM,IAAc,KAAK,CAAC;AAAA,EAAA;AAG/C,SAAO,WACJ,IAAI,CAAC,YAAY,WAAW,IAAI,OAAO,CAAC,EACxC,OAAO,OAAO;AACnB;AAEA,eAAsB,2BAEpB,SAGoB;AACpB,MAAI;AACF,WAAO;AAAA,OACJ,MAAM,QAAQ,UAAA,GAAa,IAAI,CAAC,SAAS,KAAK,OAAO;AAAA,IAAA;AAAA,EAE1D,SAAS,OAAO;AACd,QAAI,qBAAqB,OAAO,QAAQ,SAAS,GAAG;AAClD,aAAO,CAAA;AAAA,IACT;AAEA,UAAM;AAAA,EACR;AACF;AAEA,eAAsB,wBAAwB,SAMxB;AACpB,QAAM,EAAE,IAAI,aAAa,SAAS,MAAM,cAAc;AACtD,MAAI,CAAC,WAAW,UAAU,WAAW,GAAG;AACtC,WAAO,CAAA;AAAA,EACT;AAEA,MAAI,CAAC,0BAA0B,SAAS,WAAW,GAAG;AACpD,UAAM,IAAI,MAAM,yCAAyC,WAAW,GAAG;AAAA,EACzE;AAEA,QAAM,SAAoB,CAAC,SAAS,GAAG,SAAS;AAChD,QAAM,UAAU;AAAA,IACd,GAAG,WAAW;AAAA,IACd,kBAAkB,kBAAkB,UAAU,MAAM,CAAC;AAAA,EAAA;AAGvD,MAAI,MAAM;AACR,YAAQ,KAAK,UAAU;AACvB,WAAO,KAAK,IAAI;AAAA,EAClB;AAEA,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AAAA,MACtB;AAAA;AAAA,gBAEU,QAAQ,KAAK,OAAO,CAAC;AAAA;AAAA,MAE/B,GAAG;AAAA,IAAA;AAGL,WAAO;AAAA,MACL,aAAa,MAAM,EAAE,IAAI,CAAC,QAAQ,OAAO,KAAK,MAAM,EAAE,CAAC;AAAA,IAAA;AAAA,EAE3D,SAAS,OAAO;AACd,QAAI,qBAAqB,KAAK,GAAG;AAC/B,aAAO,CAAA;AAAA,IACT;AAEA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,0BAA0B,WAA6B;AACrE,SAAO,CAAC,WAAW,6BAA6B,SAAS,EAAE;AAC7D;;;;;;;;;;;AC9FO,IAAM,YAAN,cAAwB,WAAW;AAAA,EAExC,WAA0B;AAAA;AAAA,EAG1B,OAAe;AAAA;AAAA,EAGf,cAA6B;AAAA;AAAA,EAG7B,MAAoB;AAAA,IAClB,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,iBAAiB;AAAA,EAAA;AAAA;AAAA,EAInB,oBAA8B,CAAA;AAAA,EAI9B,mBAAkC;AAAA,EAIlC,iBAAgC;AAAA;AAAA,EAGhC,SAA0B;AAAA,EAI1B,YAA2B;AAAA,EAE3B,YAAY,UAA4B,IAAI;AAC1C,UAAM,OAAO;AAEb,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,QAAQ,OAAW,MAAK,MAAM,QAAQ;AAClD,QAAI,QAAQ,sBAAsB;AAChC,WAAK,oBAAoB,QAAQ;AACnC,QAAI,QAAQ,qBAAqB;AAC/B,WAAK,mBAAmB,QAAQ;AAClC,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,iBAAiB,QAAQ;AAChC,QAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,QAAI,QAAQ,cAAc,OAAW,MAAK,YAAY,QAAQ;AAC9D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AAAA,EAEA,MAAc,8BAA8B;AAC1C,UAAM,EAAE,+BAAAC,+BAAA,IAAkC,MAAM,QAAA,QAAA,EAAA,KAAA,MAAA,eAAA;AAGhD,WAAOA,+BAA8B,OAAO,EAAE,IAAI,KAAK,IAAI;AAAA,EAC7D;AAAA,EAEQ,uBAAuB,MAAqC;AAClE,QAAI,SAAS,aAAa;AACxB,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,mBAAmB,CAAC,KAAK,gBAAgB,IAAI,CAAA;AAAA,IAC3D;AAEA,WAAO,CAAC,GAAG,KAAK,mBAAmB,KAAK,gBAAgB,EAAE;AAAA,MACxD,CAAC,YAA+B,QAAQ,OAAO;AAAA,IAAA;AAAA,EAEnD;AAAA,EAEQ,sBACN,MACA,SACS;AACT,QAAI,SAAS,QAAQ;AACnB,UAAI,KAAK,qBAAqB,SAAS;AACrC,eAAO;AAAA,MACT;AAEA,WAAK,mBAAmB;AACxB,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,kBAAkB,SAAS,OAAO,GAAG;AAC5C,aAAO;AAAA,IACT;AAEA,SAAK,oBAAoB,CAAC,GAAG,KAAK,mBAAmB,OAAO;AAC5D,WAAO;AAAA,EACT;AAAA,EAEQ,wBACN,SACA,MACS;AACT,QAAI,UAAU;AAEd,SAAK,CAAC,QAAQ,SAAS,WAAW,KAAK,qBAAqB,SAAS;AACnE,WAAK,mBAAmB;AACxB,gBAAU;AAAA,IACZ;AAEA,QAAI,CAAC,QAAQ,SAAS,aAAa;AACjC,YAAM,YAAY,KAAK,kBAAkB;AAAA,QACvC,CAAC,qBAAqB,qBAAqB;AAAA,MAAA;AAG7C,UAAI,UAAU,WAAW,KAAK,kBAAkB,QAAQ;AACtD,aAAK,oBAAoB;AACzB,kBAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,MAA6C;AAC3D,UAAM,oBAAoB,KAAK,KAC3B,MAAM,2BAA2B;AAAA,MAC/B,WAAW;AAAA,MACX,WAAW,aACR,MAAM,KAAK,+BAA+B;AAAA,QACzC,KAAK;AAAA,QACL,OAAO,EAAE,SAAS,CAAA;AAAA,MAAC;AAAA,IACrB,CACH,IACD,CAAA;AACJ,UAAM,sBAAsB,KAAK,uBAAuB,IAAI;AAC5D,UAAM,sBAAsB,KAAK,KAC7B,MAAM,wBAAwB;AAAA,MAC5B,IAAI,KAAK;AAAA,MACT,aAAa;AAAA,MACb,SAAS,KAAK;AAAA,MACd;AAAA,MACA,WAAW,0BAA0B,gBAAgB;AAAA,IAAA,CACtD,IACD,CAAA;AAEJ,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AAAA,EAEA,MAAM,eAAe,MAAiD;AACpE,UAAM,SAAS,MAAM,KAAK,UAAU,IAAI;AACxC,WAAO,OAAO,CAAC,KAAK;AAAA,EACtB;AAAA,EAEA,MAAM,SACJ,OACA,OAA2B,aAC3B,YAAY,GACG;AACf,QAAI,CAAC,KAAK,MAAM,CAAC,MAAM,IAAI;AACzB,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAEA,8BAA0B,IAAI;AAC9B,mCAA+B,SAAS;AAExC,UAAMC,mBAAkB,MAAM,KAAK,4BAAA;AACnC,UAAMA,iBAAgB,OAAO,KAAK,IAAI,MAAM,IAAI;AAAA,MAC9C;AAAA,MACA;AAAA,MACA,UAAU,KAAK;AAAA,IAAA,CAChB;AAED,QAAI,KAAK,sBAAsB,MAAM,MAAM,EAAE,GAAG;AAC9C,YAAM,KAAK,KAAA;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,SAAiB,MAA0C;AAC3E,QAAI,CAAC,KAAK,IAAI;AACZ;AAAA,IACF;AAEA,UAAMA,mBAAkB,MAAM,KAAK,4BAAA;AACnC,UAAMA,iBAAgB,OAAO,KAAK,IAAI,SAAS,OAAO,EAAE,KAAA,IAAS,EAAE;AAEnE,QAAI,KAAK,wBAAwB,SAAS,IAAI,GAAG;AAC/C,YAAM,KAAK,KAAA;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,gBAAyB;AAC3B,WAAO,KAAK,kBAAkB,SAAS;AAAA,EACzC;AAAA;AAAA,EAGA,IAAI,mBAA4B;AAC9B,WACE,MAAM,QAAQ,KAAK,IAAI,aAAa,KAAK,KAAK,IAAI,cAAc,SAAS;AAAA,EAE7E;AAAA;AAAA,EAGA,IAAI,UAAmB;AACrB,WAAO,KAAK,WAAW,WAAW,KAAK;AAAA,EACzC;AACF;AAjNEC,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GADjB,UAEX,WAAA,YAAA,CAAA;AAoBAA,kBAAA;AAAA,EADC,gBAAgB,kCAAkC;AAAA,GArBxC,UAsBX,WAAA,oBAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,gBAAgB,wCAAwC;AAAA,GAzB9C,UA0BX,WAAA,kBAAA,CAAA;AAOAA,kBAAA;AAAA,EADC,gBAAgB,sCAAsC;AAAA,GAhC5C,UAiCX,WAAA,aAAA,CAAA;AAjCW,YAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ;AAAA,IAAA;AAAA,IAEvD,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,SAAA;;;;;;;;;;;ACyDN,IAAM,QAAN,cAAoB,WAAW;AAAA,EAEpC,WAA0B;AAAA;AAAA,EAG1B,OAAe;AAAA;AAAA,EAGf,cAA6B;AAAA,EAI7B,gBAA+B;AAAA;AAAA,EAG/B,aAA8B;AAAA;AAAA,EAG9B,aAAqC;AAAA;AAAA,EAGrC,aAA+B,CAAA;AAAA;AAAA,EAG/B,kBAA0C;AAAA;AAAA,EAG1C,WAGW;AAAA;AAAA,EAGX,eAA8B,CAAA;AAAA;AAAA,EAG9B,SAAsB;AAAA,EAEtB,YAAY,UAAwB,IAAI;AACtC,UAAM,OAAO;AAEb,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,gBAAgB,QAAQ;AAC/B,QAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,QAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,QAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,QAAI,QAAQ,oBAAoB;AAC9B,WAAK,kBAAkB,QAAQ;AACjC,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AAAA,EAEA,MAAc,0BAA0B;AACtC,UAAM,EAAE,2BAAAC,2BAAA,IAA8B,MAAM,QAAA,QAAA,EAAA,KAAA,MAAA,WAAA;AAC5C,WAAOA,2BAA0B,OAAO,EAAE,IAAI,KAAK,IAAI;AAAA,EACzD;AAAA,EAEQ,uBAAuB,MAAiC;AAC9D,QAAI,SAAS,UAAU;AACrB,aAAO,KAAK,gBAAgB,CAAC,KAAK,aAAa,IAAI,CAAA;AAAA,IACrD;AAEA,QAAI,SAAS,WAAW;AACtB,aAAO,KAAK,iBAAiB,gBACzB,CAAC,KAAK,gBAAgB,aAAa,IACnC,CAAA;AAAA,IACN;AAEA,QAAI,SAAS,qBAAqB;AAChC,aAAO,KAAK,WACT,IAAI,CAAC,cAAc,UAAU,oBAAoB,IAAI,EACrD,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAAA,IAC5D;AAEA,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK,iBAAiB,iBAAiB;AAAA,MACvC,GAAG,KAAK,WAAW,IAAI,CAAC,cAAc,UAAU,oBAAoB,IAAI;AAAA,IAAA,EACxE,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAAA,EAC3D;AAAA,EAEQ,sBACN,MACA,SACS;AACT,QAAI,SAAS,UAAU;AACrB,UAAI,KAAK,kBAAkB,SAAS;AAClC,eAAO;AAAA,MACT;AAEA,WAAK,gBAAgB;AACrB,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,WAAW;AACtB,WAAK,KAAK,iBAAiB,iBAAiB,UAAU,SAAS;AAC7D,eAAO;AAAA,MACT;AAEA,WAAK,kBAAkB;AAAA,QACrB,GAAI,KAAK,mBAAmB,CAAA;AAAA,QAC5B,eAAe;AAAA,MAAA;AAEjB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,wBACN,SACA,MACS;AACT,QAAI,UAAU;AAEd,SAAK,CAAC,QAAQ,SAAS,aAAa,KAAK,kBAAkB,SAAS;AAClE,WAAK,gBAAgB;AACrB,gBAAU;AAAA,IACZ;AAEA,SACG,CAAC,QAAQ,SAAS,cACnB,KAAK,iBAAiB,kBAAkB,SACxC;AACA,WAAK,kBAAkB;AAAA,QACrB,GAAI,KAAK,mBAAmB,CAAA;AAAA,QAC5B,eAAe;AAAA,MAAA;AAEjB,gBAAU;AAAA,IACZ;AAEA,QAAI,CAAC,QAAQ,SAAS,qBAAqB;AACzC,UAAI,mBAAmB;AACvB,YAAM,iBAAiB,KAAK,WAAW,IAAI,CAAC,cAAc;AACxD,YAAI,UAAU,qBAAqB,SAAS;AAC1C,iBAAO;AAAA,QACT;AAEA,2BAAmB;AACnB,eAAO;AAAA,UACL,GAAG;AAAA,UACH,kBAAkB;AAAA,QAAA;AAAA,MAEtB,CAAC;AAED,UAAI,kBAAkB;AACpB,aAAK,aAAa;AAClB,kBAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,MAAyC;AACvD,UAAM,oBAAoB,KAAK,KAC3B,MAAM,2BAA2B;AAAA,MAC/B,WAAW;AAAA,MACX,WAAW,aACR,MAAM,KAAK,2BAA2B;AAAA,QACrC,KAAK;AAAA,QACL,OAAO,EAAE,SAAS,CAAA;AAAA,MAAC;AAAA,IACrB,CACH,IACD,CAAA;AACJ,UAAM,sBAAsB,KAAK,uBAAuB,IAAI;AAC5D,UAAM,sBAAsB,KAAK,KAC7B,MAAM,wBAAwB;AAAA,MAC5B,IAAI,KAAK;AAAA,MACT,aAAa;AAAA,MACb,SAAS,KAAK;AAAA,MACd;AAAA,MACA,WAAW,0BAA0B,YAAY;AAAA,IAAA,CAClD,IACD,CAAA;AAEJ,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AAAA,EAEA,MAAM,eAAe,MAA6C;AAChE,UAAM,SAAS,MAAM,KAAK,UAAU,IAAI;AACxC,WAAO,OAAO,CAAC,KAAK;AAAA,EACtB;AAAA,EAEA,MAAM,SACJ,OACA,OAAuB,UACvB,YAAY,GACG;AACf,QAAI,CAAC,KAAK,MAAM,CAAC,MAAM,IAAI;AACzB,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,8BAA0B,IAAI;AAC9B,mCAA+B,SAAS;AAExC,UAAMC,eAAc,MAAM,KAAK,wBAAA;AAC/B,UAAMA,aAAY,OAAO,KAAK,IAAI,MAAM,IAAI;AAAA,MAC1C;AAAA,MACA;AAAA,MACA,UAAU,KAAK;AAAA,IAAA,CAChB;AAED,QAAI,KAAK,sBAAsB,MAAM,MAAM,EAAE,GAAG;AAC9C,YAAM,KAAK,KAAA;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,SAAiB,MAAsC;AACvE,QAAI,CAAC,KAAK,IAAI;AACZ;AAAA,IACF;AAEA,UAAMA,eAAc,MAAM,KAAK,wBAAA;AAC/B,UAAMA,aAAY,OAAO,KAAK,IAAI,SAAS,OAAO,EAAE,KAAA,IAAS,EAAE;AAE/D,QAAI,KAAK,wBAAwB,SAAS,IAAI,GAAG;AAC/C,YAAM,KAAK,KAAA;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,aAAsB;AACxB,WACE,KAAK,eAAe,kBAAkB,KAAK,eAAe;AAAA,EAE9D;AAAA;AAAA,EAGA,IAAI,gBAAyB;AAC3B,WAAO,KAAK,WAAW,SAAS;AAAA,EAClC;AAAA;AAAA,EAGA,IAAI,UAAmB;AACrB,WAAO,KAAK,WAAW,WAAW,KAAK,kBAAkB;AAAA,EAC3D;AACF;AAzPEF,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GADjB,MAEX,WAAA,YAAA,CAAA;AAUAA,kBAAA;AAAA,EADC,gBAAgB,kCAAkC;AAAA,GAXxC,MAYX,WAAA,iBAAA,CAAA;AAZW,QAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ;AAAA,IAAA;AAAA,IAEvD,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,KAAA;;;;;;;;;;;ACxBN,IAAM,YAAN,cAAwB,WAAW;AAAA,EAGxC,WAA0B;AAAA;AAAA,EAG1B,OAAe;AAAA;AAAA,EAGf,cAA6B;AAAA,EAI7B,eAA8B;AAAA,EAI9B,oBAAmC;AAAA,EAInC,iBAAgC;AAAA;AAAA,EAGhC,cAA8B,CAAA;AAAA;AAAA,EAG9B,SAA0B;AAAA,EAI1B,cAA6B;AAAA,EAI7B,iBAAgC;AAAA;AAAA,EAGhC,eAAuC,CAAA;AAAA,EAIvC,YAA2B;AAAA,EAE3B,YAAY,UAA4B,IAAI;AAC1C,UAAM,OAAO;AAEb,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,sBAAsB;AAChC,WAAK,oBAAoB,QAAQ;AACnC,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,iBAAiB,QAAQ;AAChC,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,iBAAiB,QAAQ;AAChC,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,cAAc,OAAW,MAAK,YAAY,QAAQ;AAC9D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AAAA,EAEA,MAAc,8BAA8B;AAC1C,UAAM,EAAE,+BAAAG,+BAAA,IAAkC,MAAM,QAAA,QAAA,EAAA,KAAA,MAAA,eAAA;AAGhD,WAAOA,+BAA8B,OAAO,EAAE,IAAI,KAAK,IAAI;AAAA,EAC7D;AAAA,EAEQ,uBAAuB,MAAqC;AAClE,QAAI,SAAS,cAAc;AACzB,aAAO,KAAK,eAAe,CAAC,KAAK,YAAY,IAAI,CAAA;AAAA,IACnD;AAEA,QAAI,SAAS,eAAe;AAC1B,aAAO,KAAK,oBAAoB,CAAC,KAAK,iBAAiB,IAAI,CAAA;AAAA,IAC7D;AAEA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,YAAY,cAAc,CAAC,KAAK,YAAY,WAAW,IAAI,CAAA;AAAA,IACzE;AAEA,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,YAAY,eAAe;AAAA,IAAA,EAChC,OAAO,CAAC,YAA+B,QAAQ,OAAO,CAAC;AAAA,EAC3D;AAAA,EAEQ,sBACN,MACA,SACS;AACT,QAAI,SAAS,cAAc;AACzB,UAAI,KAAK,iBAAiB,SAAS;AACjC,eAAO;AAAA,MACT;AAEA,WAAK,eAAe;AACpB,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,eAAe;AAC1B,UAAI,KAAK,sBAAsB,SAAS;AACtC,eAAO;AAAA,MACT;AAEA,WAAK,oBAAoB;AACzB,aAAO;AAAA,IACT;AAEA,SAAK,KAAK,YAAY,eAAe,UAAU,SAAS;AACtD,aAAO;AAAA,IACT;AAEA,SAAK,cAAc;AAAA,MACjB,GAAG,KAAK;AAAA,MACR,aAAa;AAAA,IAAA;AAEf,WAAO;AAAA,EACT;AAAA,EAEQ,wBACN,SACA,MACS;AACT,QAAI,UAAU;AAEd,SAAK,CAAC,QAAQ,SAAS,iBAAiB,KAAK,iBAAiB,SAAS;AACrE,WAAK,eAAe;AACpB,gBAAU;AAAA,IACZ;AAEA,SACG,CAAC,QAAQ,SAAS,kBACnB,KAAK,sBAAsB,SAC3B;AACA,WAAK,oBAAoB;AACzB,gBAAU;AAAA,IACZ;AAEA,SACG,CAAC,QAAQ,SAAS,WACnB,KAAK,YAAY,gBAAgB,SACjC;AACA,WAAK,cAAc;AAAA,QACjB,GAAG,KAAK;AAAA,QACR,aAAa;AAAA,MAAA;AAEf,gBAAU;AAAA,IACZ;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,MAA6C;AAC3D,UAAM,oBAAoB,KAAK,KAC3B,MAAM,2BAA2B;AAAA,MAC/B,WAAW;AAAA,MACX,WAAW,aACR,MAAM,KAAK,+BAA+B;AAAA,QACzC,KAAK;AAAA,QACL,OAAO,EAAE,SAAS,CAAA;AAAA,MAAC;AAAA,IACrB,CACH,IACD,CAAA;AACJ,UAAM,sBAAsB,KAAK,uBAAuB,IAAI;AAC5D,UAAM,sBAAsB,KAAK,KAC7B,MAAM,wBAAwB;AAAA,MAC5B,IAAI,KAAK;AAAA,MACT,aAAa;AAAA,MACb,SAAS,KAAK;AAAA,MACd;AAAA,MACA,WAAW,0BAA0B,gBAAgB;AAAA,IAAA,CACtD,IACD,CAAA;AAEJ,WAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AAAA,EAEA,MAAM,eAAe,MAAiD;AACpE,UAAM,SAAS,MAAM,KAAK,UAAU,IAAI;AACxC,WAAO,OAAO,CAAC,KAAK;AAAA,EACtB;AAAA,EAEA,MAAM,SACJ,OACA,OAA2B,cAC3B,YAAY,GACG;AACf,QAAI,CAAC,KAAK,MAAM,CAAC,MAAM,IAAI;AACzB,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAEA,8BAA0B,IAAI;AAC9B,mCAA+B,SAAS;AAExC,UAAMC,mBAAkB,MAAM,KAAK,4BAAA;AACnC,UAAMA,iBAAgB,OAAO,KAAK,IAAI,MAAM,IAAI;AAAA,MAC9C;AAAA,MACA;AAAA,MACA,UAAU,KAAK;AAAA,IAAA,CAChB;AAED,QAAI,KAAK,sBAAsB,MAAM,MAAM,EAAE,GAAG;AAC9C,YAAM,KAAK,KAAA;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,SAAiB,MAA0C;AAC3E,QAAI,CAAC,KAAK,IAAI;AACZ;AAAA,IACF;AAEA,UAAMA,mBAAkB,MAAM,KAAK,4BAAA;AACnC,UAAMA,iBAAgB,OAAO,KAAK,IAAI,SAAS,OAAO,EAAE,KAAA,IAAS,EAAE;AAEnE,QAAI,KAAK,wBAAwB,SAAS,IAAI,GAAG;AAC/C,YAAM,KAAK,KAAA;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,gBAAyB;AAC3B,WAAO,KAAK,sBAAsB;AAAA,EACpC;AAAA;AAAA,EAGA,IAAI,aAAsB;AACxB,WACE,KAAK,iBAAiB,QACtB,KAAK,mBAAmB,QACxB,KAAK,WAAW;AAAA,EAEpB;AACF;AA1PEJ,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GAFjB,UAGX,WAAA,YAAA,CAAA;AAUAA,kBAAA;AAAA,EADC,gBAAgB,kCAAkC;AAAA,GAZxC,UAaX,WAAA,gBAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,gBAAgB,kCAAkC;AAAA,GAhBxC,UAiBX,WAAA,qBAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,gBAAgB,wCAAwC;AAAA,GApB9C,UAqBX,WAAA,kBAAA,CAAA;AAUAA,kBAAA;AAAA,EADC,WAAW,MAAM,SAAS;AAAA,GA9BhB,UA+BX,WAAA,eAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,WAAW,MAAM,KAAK;AAAA,GAlCZ,UAmCX,WAAA,kBAAA,CAAA;AAOAA,kBAAA;AAAA,EADC,gBAAgB,sCAAsC;AAAA,GAzC5C,UA0CX,WAAA,aAAA,CAAA;AA1CW,YAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ;AAAA,IAAA;AAAA,IAEvD,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,SAAA;ACxJN,MAAM,4BAA4B,eAA0B;AAAA,EACjE,OAAgB,aAAa;AAAA;AAAA,EAG7B,MAAM,aAAaH,WAAwC;AACzD,WAAQ,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,UAAAA,UAAA,GAAY;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAAmC;AACvC,WAAO,YAAuB,IAAI;AAAA,EACpC;AAAA;AAAA,EAGA,MAAM,gBAAgB,aAA2C;AAC/D,WAAQ,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,YAAA,GAAe;AAAA,EACpD;AAAA;AAAA,EAGA,MAAM,YAAkC;AACtC,WAAQ,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,QAAQ,QAAA,GAAW;AAAA,EACxD;AACF;;;;;;;;;;;ACwDO,IAAM,eAAN,cAA2B,WAAW;AAAA,EAE3C,WAA0B;AAAA,EAI1B,wBAAuC;AAAA,EAIvC,UAAyB;AAAA;AAAA,EAGzB,cAA6B;AAAA;AAAA,EAG7B,gBAA+B;AAAA;AAAA,EAG/B,QAAgB;AAAA;AAAA,EAGhB,WAAqC,EAAE,GAAG,KAAK,GAAG,IAAA;AAAA;AAAA,EAGlD,SAA6B;AAAA;AAAA,EAG7B,WAAmB;AAAA,EAInB,gBAA+B;AAAA;AAAA,EAG/B,eAA8B;AAAA,EAE9B,YAAY,UAA+B,IAAI;AAC7C,UAAM,OAAO;AAEb,QAAI,QAAQ,0BAA0B;AACpC,WAAK,wBAAwB,QAAQ;AACvC,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAC1D,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,gBAAgB,QAAQ;AAC/B,QAAI,QAAQ,UAAU,OAAW,MAAK,QAAQ,QAAQ;AACtD,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,gBAAgB,QAAQ;AAC/B,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AAAA;AAAA,EAGA,IAAI,aAAsB;AACxB,WAAO,KAAK,WAAW,cAAc,KAAK,kBAAkB;AAAA,EAC9D;AAAA;AAAA,EAGA,IAAI,eAAwB;AAC1B,WACE,KAAK,WAAW,aAChB,KAAK,WAAW,cAChB,KAAK,WAAW;AAAA,EAEpB;AACF;AArEEG,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GADjB,aAEX,WAAA,YAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,gBAAgB,kCAAkC;AAAA,GALxC,aAMX,WAAA,yBAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,WAAW,MAAM,KAAK;AAAA,GATZ,aAUX,WAAA,WAAA,CAAA;AAsBAA,kBAAA;AAAA,EADC,gBAAgB,kCAAkC;AAAA,GA/BxC,aAgCX,WAAA,iBAAA,CAAA;AAhCW,eAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,QAAQ;AAAA,IAAA;AAAA,IAE7C,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,YAAA;;;;;;;;;ACbN,IAAM,mBAAN,cAA+B,QAAQ;AAAA;AAAA,EAE5C,MAAc;AAAA;AAAA,EAGd,QAAgB;AAAA;AAAA,EAGhB,SAAiB;AAAA;AAAA,EAGjB,mBAA2B;AAAA;AAAA,EAG3B,eAA6B;AAAA;AAAA,EAG7B,iBAAyB;AAAA,EAEzB,YAAY,UAAmC,IAAI;AACjD,UAAM;AAAA,MACJ,GAAG;AAAA,MACH,MAAM;AAAA,IAAA,CACP;AAED,QAAI,QAAQ,QAAQ,OAAW,MAAK,MAAM,QAAQ;AAClD,QAAI,QAAQ,UAAU,OAAW,MAAK,QAAQ,QAAQ;AACtD,QAAI,QAAQ,WAAW,OAAW,MAAK,SAAS,QAAQ;AACxD,QAAI,QAAQ,qBAAqB;AAC/B,WAAK,mBAAmB,QAAQ;AAClC,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,iBAAiB,QAAQ;AAAA,EAClC;AAAA;AAAA,EAGA,IAAI,oBAA4B;AAC9B,QAAI,KAAK,QAAQ,EAAG,QAAO;AAC3B,WAAO,KAAK,mBAAmB,KAAK;AAAA,EACtC;AAAA;AAAA,EAGA,IAAI,UAAmB;AACrB,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA;AAAA,EAGA,IAAI,cAAuB;AACzB,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAIA,MAAM,UAAU,cAAyC;AACvD,UAAM,kBAAkB,MAAM,MAAM,UAAU,YAAY;AAC1D,QAAI,CAAC,KAAK,IAAI;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,OAAO;AACb,UAAM,eAAe,MAAM;AAAA,MACzB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM,wBAAwB;AAAA,QAC5B,IAAI,KAAK;AAAA,QACT,aAAa;AAAA,QACb,SAAS,KAAK;AAAA,QACd;AAAA,QACA,WAAW,0BAA0B,uBAAuB;AAAA,MAAA,CAC7D;AAAA,IAAA;AAGH,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,aAAa;AAAA,QACd,CAAC,UACC,MAAM,MACN,CAAC,gBAAgB;AAAA,UACf,CAAC,mBAAmB,eAAe,OAAO,MAAM;AAAA,QAAA;AAAA,MAClD;AAAA,IACJ;AAAA,EAEJ;AAAA,EAEA,MAAM,eAAe,MAAwD;AAC3E,UAAM,SAAS,MAAM,KAAK,UAAU,IAAI;AACxC,WAAO,OAAO,CAAC,KAAK;AAAA,EACtB;AACF;AAzFa,mBAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ;AAAA,IAAA;AAAA,IAEvD,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,gBAAA;ACxEN,MAAM,mCAAmC,eAAiC;AAAA,EAC/E,OAAgB,aAAa;AAAA;AAAA,EAG7B,MAAM,mBACJ,cAC6B;AAC7B,WAAQ,MAAM,KAAK,KAAK;AAAA,MACtB,OAAO,EAAE,aAAA;AAAA,IAAa,CACvB;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,YAAyC;AAC7C,WAAQ,MAAM,KAAK,KAAK;AAAA,MACtB,OAAO,EAAE,cAAc,QAAA;AAAA,IAAQ,CAChC;AAAA,EACH;AACF;;;;;;;;;;;ACkDO,IAAM,gBAAN,cAA4B,QAAQ;AAAA,EAGzC,gBAA+B;AAAA;AAAA,EAG/B,WAAmB;AAAA;AAAA,EAGnB,mBAA2B;AAAA;AAAA,EAG3B,iBAAiC;AAAA;AAAA,EAGjC,2BAAmC;AAAA,EAEnC,YAAY,UAAgC,IAAI;AAC9C,UAAM;AAAA,MACJ,GAAG;AAAA,MACH,MAAM;AAAA,IAAA,CACP;AAED,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,gBAAgB,QAAQ;AAC/B,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,qBAAqB;AAC/B,WAAK,mBAAmB,QAAQ;AAClC,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,iBAAiB,QAAQ;AAChC,QAAI,QAAQ,6BAA6B;AACvC,WAAK,2BAA2B,QAAQ;AAAA,EAC5C;AAAA,EAIA,MAAM,UAAU,cAAyC;AACvD,UAAM,kBAAkB,MAAM,MAAM,UAAU,YAAY;AAC1D,QAAI,CAAC,KAAK,IAAI;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,OAAO;AACb,UAAM,eAAe,MAAM;AAAA,MACzB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM,wBAAwB;AAAA,QAC5B,IAAI,KAAK;AAAA,QACT,aAAa;AAAA,QACb,SAAS,KAAK;AAAA,QACd;AAAA,QACA,WAAW,0BAA0B,oBAAoB;AAAA,MAAA,CAC1D;AAAA,IAAA;AAGH,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,aAAa;AAAA,QACd,CAAC,UACC,MAAM,MACN,CAAC,gBAAgB;AAAA,UACf,CAAC,mBAAmB,eAAe,OAAO,MAAM;AAAA,QAAA;AAAA,MAClD;AAAA,IACJ;AAAA,EAEJ;AAAA,EAEA,MAAM,eAAe,MAAqD;AACxE,UAAM,SAAS,MAAM,KAAK,UAAU,IAAI;AACxC,WAAO,OAAO,CAAC,KAAK;AAAA,EACtB;AACF;AApEEA,kBAAA;AAAA,EADC,WAAW,kBAAkB;AAAA,GAFnB,cAGX,WAAA,iBAAA,CAAA;AAHW,gBAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ;AAAA,IAAA;AAAA,IAEvD,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,aAAA;ACpEN,MAAM,gCAAgC,eAA8B;AAAA,EACzE,OAAgB,aAAa;AAAA;AAAA,EAG7B,MAAM,kBAAkB,eAAiD;AACvE,WAAQ,MAAM,KAAK,KAAK;AAAA,MACtB,OAAO,EAAE,cAAA;AAAA,MACT,SAAS;AAAA,IAAA,CACV;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,iBAA2C;AAC/C,WAAQ,MAAM,KAAK,KAAK;AAAA,MACtB,OAAO,EAAE,eAAe,KAAA;AAAA,IAAK,CAC9B;AAAA,EACH;AACF;;;;;;;;;;;ACoHO,IAAM,YAAN,cAAwB,QAAQ;AAAA,EAGrC,aAA4B;AAAA,EAI5B,UAAyB;AAAA;AAAA,EAGzB,WAAmB;AAAA;AAAA,EAGnB,mBAA2B;AAAA;AAAA,EAG3B,mBAA2B;AAAA;AAAA,EAG3B,kBAA0B;AAAA;AAAA,EAG1B,aAAqB;AAAA;AAAA,EAGrB,kBAA0B;AAAA;AAAA,EAG1B,iBAAyB;AAAA;AAAA,EAGzB,aAA8B;AAAA;AAAA,EAG9B,WAAmB;AAAA;AAAA,EAGnB,eAA8B;AAAA;AAAA,EAG9B,gBAA+B;AAAA;AAAA,EAG/B,gBAA+B,CAAA;AAAA,EAE/B,YAAY,UAA4B,IAAI;AAC1C,UAAM;AAAA,MACJ,GAAG;AAAA,MACH,MAAM;AAAA,IAAA,CACP;AAED,QAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAC1D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,qBAAqB;AAC/B,WAAK,mBAAmB,QAAQ;AAClC,QAAI,QAAQ,qBAAqB;AAC/B,WAAK,mBAAmB,QAAQ;AAClC,QAAI,QAAQ,oBAAoB;AAC9B,WAAK,kBAAkB,QAAQ;AACjC,QAAI,QAAQ,eAAe,QAAW;AACpC,WAAK,aAAa,QAAQ;AAC1B,WAAK,kBAAkB,KAAK,WACzB,MAAM,KAAK,EACX,OAAO,OAAO,EAAE;AAAA,IACrB;AACA,QAAI,QAAQ,oBAAoB;AAC9B,WAAK,kBAAkB,QAAQ;AACjC,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,iBAAiB,QAAQ;AAChC,QAAI,QAAQ,eAAe,OAAW,MAAK,aAAa,QAAQ;AAChE,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,gBAAgB,QAAQ;AAC/B,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,gBAAgB,QAAQ;AAAA,EACjC;AAAA;AAAA,EAGA,IAAI,oBAA4B;AAC9B,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAAA;AAAA,EAGA,IAAI,sBAA+B;AACjC,UAAM,YAAY,KAAK;AACvB,UAAM,YAAY,KAAK,iBAAiB;AACxC,WACE,aAAa,KAAK,iBAAiB,aACnC,aAAa,KAAK,iBAAiB;AAAA,EAEvC;AAAA;AAAA,EAGA,IAAI,uBAAqE;AACvE,UAAM,iBAAiB;AACvB,UAAM,SAAS,KAAK,MAAM,KAAK,iBAAiB,cAAc;AAC9D,UAAM,YAAY,KAAK,MAAM,SAAS,IAAI;AAC1C,WAAO;AAAA,MACL,KAAK,SAAS;AAAA,MACd,KAAK,SAAS;AAAA,MACd;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGA,IAAI,kBAA0B;AAC5B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,mBAAmB,KAAK,mBAAmB,KAAK;AAAA,IAAA;AAAA,EAEzD;AAAA;AAAA,EAGA,IAAI,eAAwB;AAC1B,WAAO,KAAK,eAAe,YAAY,KAAK,eAAe;AAAA,EAC7D;AAAA;AAAA,EAGA,IAAI,UAAmB;AACrB,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAIA,MAAM,UAAU,cAAyC;AACvD,UAAM,kBAAkB,MAAM,MAAM,UAAU,YAAY;AAC1D,QAAI,CAAC,KAAK,IAAI;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,OAAO;AACb,UAAM,eAAe,MAAM;AAAA,MACzB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM,wBAAwB;AAAA,QAC5B,IAAI,KAAK;AAAA,QACT,aAAa;AAAA,QACb,SAAS,KAAK;AAAA,QACd;AAAA,QACA,WAAW,0BAA0B,gBAAgB;AAAA,MAAA,CACtD;AAAA,IAAA;AAGH,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,aAAa;AAAA,QACd,CAAC,UACC,MAAM,MACN,CAAC,gBAAgB;AAAA,UACf,CAAC,mBAAmB,eAAe,OAAO,MAAM;AAAA,QAAA;AAAA,MAClD;AAAA,IACJ;AAAA,EAEJ;AAAA,EAEA,MAAM,eAAe,MAAiD;AACpE,UAAM,SAAS,MAAM,KAAK,UAAU,IAAI;AACxC,WAAO,OAAO,CAAC,KAAK;AAAA,EACtB;AAAA;AAAA,EAGA,UAAU,MAAoB;AAC5B,SAAK,aAAa;AAClB,SAAK,kBAAkB,KAAK,MAAM,KAAK,EAAE,OAAO,OAAO,EAAE;AAAA,EAC3D;AACF;AArKEA,kBAAA;AAAA,EADC,WAAW,MAAM,aAAa;AAAA,GAFpB,UAGX,WAAA,cAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,WAAW,MAAM,KAAK;AAAA,GANZ,UAOX,WAAA,WAAA,CAAA;AAPW,YAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ;AAAA,IAAA;AAAA,IAEvD,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,SAAA;;;;;;;;;;;AC3EN,IAAM,qBAAN,cAAiC,WAAW;AAAA,EAEjD,WAA0B;AAAA,EAI1B,cAAsB;AAAA,EAItB,cAAsB;AAAA;AAAA,EAGtB,OAA+B;AAAA;AAAA,EAG/B,WAAmB;AAAA,EAEnB,YAAY,SAAoC;AAC9C,UAAM,OAAO;AAEb,SAAK,cAAc,QAAQ;AAC3B,SAAK,cAAc,QAAQ;AAC3B,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AACF;AAzBEA,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GADjB,mBAEX,WAAA,YAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,WAAW,MAAM,WAAW,EAAE,UAAU,MAAM;AAAA,GALpC,mBAMX,WAAA,eAAA,CAAA;AAIAA,kBAAA;AAAA,EADC,WAAW,MAAM,WAAW,EAAE,UAAU,MAAM;AAAA,GATpC,mBAUX,WAAA,eAAA,CAAA;AAVW,qBAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,QAAQ;AAAA,IAAA;AAAA,IAE7C,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,kBAAA;AC1DN,MAAM,qCAAqC,eAAmC;AAAA,EACnF,OAAgB,aAAa;AAAA;AAAA,EAG7B,MAAM,WAAW,aAAoD;AACnE,WAAQ,MAAM,KAAK,KAAK;AAAA,MACtB,OAAO,EAAE,YAAA;AAAA,MACT,SAAS;AAAA,IAAA,CACV;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,gBAAgB,aAAoD;AACxE,WAAQ,MAAM,KAAK,KAAK;AAAA,MACtB,OAAO,EAAE,YAAA;AAAA,IAAY,CACtB;AAAA,EACH;AACF;ACjBO,MAAM,4BAA4B,eAA0B;AAAA,EACjE,OAAgB,aAAa;AAAA;AAAA,EAG7B,MAAM,eAAe,YAA0C;AAC7D,WAAQ,MAAM,KAAK,KAAK;AAAA,MACtB,OAAO,EAAE,WAAA;AAAA,MACT,SAAS;AAAA,IAAA,CACV;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,YAAmD;AACpE,WAAQ,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,WAAA,GAAc;AAAA,EACnD;AAAA;AAAA,EAGA,MAAM,iBAAuC;AAC3C,WAAQ,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,YAAY,KAAA,GAAQ;AAAA,EACzD;AACF;;;;;;;;;;;AChBA,MAAM,SAAS,aAAa,EAAE,OAAO,QAAQ;AAwJtC,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAK5C,WAA0B;AAAA;AAAA;AAAA;AAAA,EAK1B,OAAe;AAAA;AAAA;AAAA;AAAA,EAKf,cAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7B,eAA6B;AAAA;AAAA;AAAA;AAAA;AAAA,EAM7B,eAA8B;AAAA;AAAA;AAAA;AAAA;AAAA,EAM9B,cAA2B,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3B,gBAAwB;AAAA;AAAA;AAAA;AAAA,EAKxB,WAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpB,iBAA2B,CAAA;AAAA,EAE3B,YAAY,UAAgC,IAAI;AAC9C,UAAM,OAAO;AAEb,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,eAAe,QAAQ;AAC9B,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,kBAAkB;AAC5B,WAAK,gBAAgB,QAAQ;AAC/B,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAC5D,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,iBAAiB,QAAQ;AAChC,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,sBAA+B;AACjC,UAAM,WAAW,CAAC,aAAa;AAC/B,WAAO,SAAS,MAAM,CAAC,QAAQ,KAAK,YAAY,GAAG,MAAM,MAAS;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,iBAAiB,QAAgD;AAC/D,QAAI,CAAC,KAAK,aAAc,QAAO;AAE/B,UAAM,WAAW,KAAK,MAAM,KAAK,UAAU,KAAK,YAAY,CAAC;AAC7D,UAAM,WAAqB,CAAA;AAE3B,eAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AACjE,UAAI,UAAU,OAAO,QAAQ,MAAM,QAAW;AAE5C,YAAI,CAAC,SAAS,MAAM,GAAG;AACrB,mBAAS;AAAA,YACP,iBAAiB,QAAQ,sBAAsB,MAAM;AAAA,UAAA;AAEvD;AAAA,QACF;AAGA,iBAAS,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,UAAU,CAAA;AAGrD,YACE,aAAa,eACb,aAAa,eACb,aAAa,aACb;AACA,mBAAS,MAAM,EAAE,OAAO,QAAQ,OAAO,QAAQ;AAAA,QACjD,WAAW,aAAa,UAAU;AAChC,mBAAS,MAAM,EAAE,OAAO,OAAO,OAAO,QAAQ;AAAA,QAChD,OAAO;AACL,mBAAS,MAAM,EAAE,OAAO,QAAQ,IAAI,OAAO,QAAQ;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAGA,QAAI,SAAS,SAAS,KAAK,QAAQ,IAAI,aAAa,cAAc;AAChE,aAAO;AAAA,QACL;AAAA,EAAkD,SAAS,KAAK,IAAI,CAAC;AAAA,MAAA;AAAA,IAEzE;AAEA,WAAO;AAAA,EACT;AACF;AArIEA,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GAJjB,cAKX,WAAA,YAAA,CAAA;AALW,gBAANA,kBAAA;AAAA,EAXN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,eAAe;AAAA,IACf,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,OAAO,UAAU,QAAQ;AAAA,IAAA;AAAA,IAE7C,KAAK;AAAA,MACH,SAAS,CAAC,QAAQ,KAAK;AAAA,IAAA;AAAA,IAEzB,KAAK;AAAA,EAAA,CACN;AAAA,GACY,aAAA;;;;;;;;;;;ACxIN,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAExC,cAA6B;AAAA,EAE7B,OAA2B;AAAA,EAE3B,YAAY,UAAiC,IAAI;AAC/C,UAAM,OAAO;AACb,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AAAA,EACtD;AACF;AAVEA,kBAAA;AAAA,EADC,WAAW,MAAM,SAAS;AAAA,GADhB,eAEX,WAAA,eAAA,CAAA;AAFW,iBAANA,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK,EAAE,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ,EAAA;AAAA,IAC5D,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAA;AAAA,IAC9B,KAAK;AAAA,EAAA,CACN;AAAA,GACY,cAAA;;;;;;;;;;;ACEN,IAAM,sBAAN,cAAkC,WAAW;AAAA,EAElD,WAA0B;AAAA,EAG1B,cAAc;AAAA,EAGd,UAAU;AAAA,EAGV,OAA2B;AAAA,EAG3B,YAAY;AAAA,EAEZ,YAAY,UAAsC,IAAI;AACpD,UAAM,OAAO;AACb,QAAI,QAAQ,YAAa,MAAK,cAAc,QAAQ;AACpD,QAAI,QAAQ,QAAS,MAAK,UAAU,QAAQ;AAC5C,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,cAAc,OAAW,MAAK,YAAY,QAAQ;AAC9D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AACF;AAtBEA,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GADjB,oBAEX,WAAA,YAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,WAAW,MAAM,WAAW,EAAE,UAAU,MAAM;AAAA,GAJpC,oBAKX,WAAA,eAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,gBAAgB,oCAAoC,EAAE,UAAU,MAAM;AAAA,GAP5D,oBAQX,WAAA,WAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,MAAM,EAAE,UAAU,KAAA,CAAM;AAAA,GAVd,oBAWX,WAAA,QAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,MAAA;AAAM,GAbI,oBAcX,WAAA,aAAA,CAAA;AAdW,sBAANA,kBAAA;AAAA,EATN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,iBAAiB,CAAC,gBAAgB,YAAY,MAAM;AAAA,IACpD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA,CACN;AAAA,GACY,mBAAA;;;;;;;;;;;;ACjBN,IAAM,gCAAN,cAA4C,aAAkC;AAAA,EAEzE,YAAY;AAAA,EACZ,aAAa;AACzB;AAHEK,gBADW,+BACK,cAAa,mBAAA;AADlB,gCAANL,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA,CACN;AAAA,GACY,6BAAA;;;;;;;;;;;;;;;;;ACeN,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAExC,cAA6B;AAAA,EAE7B,OAA2B;AAAA,EAE3B,YAAY,UAAiC,IAAI;AAC/C,UAAM,OAAO;AACb,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AAAA,EACtD;AACF;AAVEA,kBAAA;AAAA,EADC,WAAW,MAAM,SAAS;AAAA,GADhB,eAEX,WAAA,eAAA,CAAA;AAFW,iBAANA,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK,EAAE,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ,EAAA;AAAA,IAC5D,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAA;AAAA,IAC9B,KAAK;AAAA,EAAA,CACN;AAAA,GACY,cAAA;;;;;;;;;;;ACEN,IAAM,sBAAN,cAAkC,WAAW;AAAA,EAElD,WAA0B;AAAA,EAG1B,cAAc;AAAA,EAGd,UAAU;AAAA,EAGV,OAA2B;AAAA,EAG3B,YAAY;AAAA,EAEZ,YAAY,UAAsC,IAAI;AACpD,UAAM,OAAO;AACb,QAAI,QAAQ,YAAa,MAAK,cAAc,QAAQ;AACpD,QAAI,QAAQ,QAAS,MAAK,UAAU,QAAQ;AAC5C,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,cAAc,OAAW,MAAK,YAAY,QAAQ;AAC9D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AACF;AAtBEA,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GADjB,oBAEX,WAAA,YAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,WAAW,MAAM,WAAW,EAAE,UAAU,MAAM;AAAA,GAJpC,oBAKX,WAAA,eAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,gBAAgB,oCAAoC,EAAE,UAAU,MAAM;AAAA,GAP5D,oBAQX,WAAA,WAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,MAAM,EAAE,UAAU,KAAA,CAAM;AAAA,GAVd,oBAWX,WAAA,QAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,MAAA;AAAM,GAbI,oBAcX,WAAA,aAAA,CAAA;AAdW,sBAANA,kBAAA;AAAA,EATN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,iBAAiB,CAAC,gBAAgB,YAAY,MAAM;AAAA,IACpD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA,CACN;AAAA,GACY,mBAAA;;;;;;;;;;;;ACjBN,IAAM,gCAAN,cAA4C,aAAkC;AAAA,EAEzE,YAAY;AAAA,EACZ,aAAa;AACzB;AAHEK,gBADW,+BACK,cAAa,mBAAA;AADlB,gCAANL,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA,CACN;AAAA,GACY,6BAAA;;;;;;;;;;;;;;;;;ACeN,IAAM,aAAN,cAAyB,MAAM;AAAA,EAEpC,UAAyB;AAAA,EAEzB,OAAuB;AAAA,EAEvB,YAAY,UAA6B,IAAI;AAC3C,UAAM,OAAO;AACb,QAAI,QAAQ,YAAY,OAAW,MAAK,UAAU,QAAQ;AAC1D,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AAAA,EACtD;AACF;AATEA,kBAAA;AAAA,EADC,WAAW,MAAM,KAAK;AAAA,GADZ,WAEX,WAAA,WAAA,CAAA;AAFW,aAANA,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK,EAAE,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ,EAAA;AAAA,IAC5D,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAA;AAAA,IAC9B,KAAK;AAAA,EAAA,CACN;AAAA,GACY,UAAA;;;;;;;;;;;ACEN,IAAM,kBAAN,cAA8B,WAAW;AAAA,EAE9C,WAA0B;AAAA,EAG1B,UAAU;AAAA,EAGV,UAAU;AAAA,EAGV,OAAuB;AAAA,EAGvB,YAAY;AAAA,EAEZ,YAAY,UAAkC,IAAI;AAChD,UAAM,OAAO;AACb,QAAI,QAAQ,QAAS,MAAK,UAAU,QAAQ;AAC5C,QAAI,QAAQ,QAAS,MAAK,UAAU,QAAQ;AAC5C,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AACpD,QAAI,QAAQ,cAAc,OAAW,MAAK,YAAY,QAAQ;AAC9D,QAAI,QAAQ,aAAa,OAAW,MAAK,WAAW,QAAQ;AAAA,EAC9D;AACF;AAtBEA,kBAAA;AAAA,EADC,SAAS,EAAE,UAAU,KAAA,CAAM;AAAA,GADjB,gBAEX,WAAA,YAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,WAAW,MAAM,OAAO,EAAE,UAAU,MAAM;AAAA,GAJhC,gBAKX,WAAA,WAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,gBAAgB,oCAAoC,EAAE,UAAU,MAAM;AAAA,GAP5D,gBAQX,WAAA,WAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,MAAM,EAAE,UAAU,KAAA,CAAM;AAAA,GAVd,gBAWX,WAAA,QAAA,CAAA;AAGAA,kBAAA;AAAA,EADC,MAAA;AAAM,GAbI,gBAcX,WAAA,aAAA,CAAA;AAdW,kBAANA,kBAAA;AAAA,EATN,aAAa,EAAE,MAAM,YAAY;AAAA,EACjC,KAAK;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,iBAAiB,CAAC,YAAY,YAAY,MAAM;AAAA,IAChD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA,CACN;AAAA,GACY,eAAA;;;;;;;;;;;;ACjBN,IAAM,4BAAN,cAAwC,aAA8B;AAAA,EAEjE,YAAY;AAAA,EACZ,aAAa;AACzB;AAHE,cADW,2BACK,cAAa,eAAA;AADlB,4BAANA,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA,CACN;AAAA,GACY,yBAAA;;;;;;;;;;;;;;;;;ACcN,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAE/C,qBAAoC;AAAA,EAEpC,OAAkC;AAAA,EAElC,YAAY,UAAwC,IAAI;AACtD,UAAM,OAAO;AACb,QAAI,QAAQ,uBAAuB;AACjC,WAAK,qBAAqB,QAAQ;AACpC,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AAAA,EACtD;AACF;AAVEA,kBAAA;AAAA,EADC,WAAW,MAAM,gBAAgB;AAAA,GADvB,sBAEX,WAAA,sBAAA,CAAA;AAFW,wBAANA,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK,EAAE,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ,EAAA;AAAA,IAC5D,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAA;AAAA,IAC9B,KAAK;AAAA,EAAA,CACN;AAAA,GACY,qBAAA;;;;;;;;;;;ACAN,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAE5C,kBAAiC;AAAA,EAEjC,OAA+B;AAAA,EAE/B,YAAY,UAAqC,IAAI;AACnD,UAAM,OAAO;AACb,QAAI,QAAQ,oBAAoB;AAC9B,WAAK,kBAAkB,QAAQ;AACjC,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AAAA,EACtD;AACF;AAVEA,kBAAA;AAAA,EADC,WAAW,MAAM,aAAa;AAAA,GADpB,mBAEX,WAAA,mBAAA,CAAA;AAFW,qBAANA,kBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK,EAAE,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ,EAAA;AAAA,IAC5D,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAA;AAAA,IAC9B,KAAK;AAAA,EAAA,CACN;AAAA,GACY,kBAAA;;;;;;;;;;;ACAN,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAExC,cAA6B;AAAA,EAE7B,OAA2B;AAAA,EAE3B,YAAY,UAAiC,IAAI;AAC/C,UAAM,OAAO;AACb,QAAI,QAAQ,gBAAgB;AAC1B,WAAK,cAAc,QAAQ;AAC7B,QAAI,QAAQ,SAAS,OAAW,MAAK,OAAO,QAAQ;AAAA,EACtD;AACF;AAVE,gBAAA;AAAA,EADC,WAAW,MAAM,SAAS;AAAA,GADhB,eAEX,WAAA,eAAA,CAAA;AAFW,iBAAN,gBAAA;AAAA,EALN,KAAK;AAAA,IACJ,KAAK,EAAE,SAAS,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ,EAAA;AAAA,IAC5D,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAA;AAAA,IAC9B,KAAK;AAAA,EAAA,CACN;AAAA,GACY,cAAA;"}
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "timestamp": 1782330672622,
3
+ "timestamp": 1782340101051,
4
4
  "packageName": "@happyvertical/smrt-video",
5
- "packageVersion": "0.35.0",
5
+ "packageVersion": "0.35.2",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-video:CharacterAsset": {
8
8
  "name": "characterasset",
@@ -16321,7 +16321,7 @@
16321
16321
  "parameters": [
16322
16322
  {
16323
16323
  "name": "params",
16324
- "type": "Record<string, any>",
16324
+ "type": "Record<string>",
16325
16325
  "optional": false
16326
16326
  }
16327
16327
  ],
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-06-24T19:51:14.190Z",
3
+ "generatedAt": "2026-06-24T22:28:22.772Z",
4
4
  "packageName": "@happyvertical/smrt-video",
5
- "packageVersion": "0.35.0",
5
+ "packageVersion": "0.35.2",
6
6
  "sourceManifestPath": "dist/manifest.json",
7
7
  "agentDocPath": "AGENTS.md",
8
8
  "sourceHashes": {
9
- "manifest": "f5507e794a481d6968766d330bb50fd9423aa389a5a3b0faff873e8cc7381eac",
10
- "packageJson": "adc09c3ffec7fa0bc4dc4f1b2167f30c40e665582871248c9a9cba0f72ff679c",
9
+ "manifest": "638bad1e4be50f45f0fc2a3cdb2e34083e74599681aeca30cbf7a021ef34833d",
10
+ "packageJson": "4197d2606864fd9f7eb535861d4e1ca2c17a28afe734762dc091d9b6d04b7b22",
11
11
  "agents": "01c6489f21d949868550deecb68d3a1e264b9dee396ef437330aa3eb81c6a0c9"
12
12
  },
13
13
  "exports": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-video",
3
- "version": "0.35.0",
3
+ "version": "0.35.2",
4
4
  "type": "module",
5
5
  "description": "Video content management for AI-powered video production in the SMRT ecosystem",
6
6
  "author": "HappyVertical",
@@ -31,13 +31,13 @@
31
31
  "dependencies": {
32
32
  "@happyvertical/logger": "^0.74.7",
33
33
  "@happyvertical/utils": "^0.74.7",
34
- "@happyvertical/smrt-assets": "0.35.0",
35
- "@happyvertical/smrt-config": "0.35.0",
36
- "@happyvertical/smrt-content": "0.35.0",
37
- "@happyvertical/smrt-core": "0.35.0",
38
- "@happyvertical/smrt-profiles": "0.35.0",
39
- "@happyvertical/smrt-tenancy": "0.35.0",
40
- "@happyvertical/smrt-voice": "0.35.0"
34
+ "@happyvertical/smrt-assets": "0.35.2",
35
+ "@happyvertical/smrt-config": "0.35.2",
36
+ "@happyvertical/smrt-content": "0.35.2",
37
+ "@happyvertical/smrt-core": "0.35.2",
38
+ "@happyvertical/smrt-profiles": "0.35.2",
39
+ "@happyvertical/smrt-voice": "0.35.2",
40
+ "@happyvertical/smrt-tenancy": "0.35.2"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@happyvertical/sql": "^0.74.7",
@@ -45,7 +45,7 @@
45
45
  "typescript": "^5.9.3",
46
46
  "vite": "^7.3.1",
47
47
  "vitest": "^4.0.17",
48
- "@happyvertical/smrt-vitest": "0.35.0"
48
+ "@happyvertical/smrt-vitest": "0.35.2"
49
49
  },
50
50
  "keywords": [
51
51
  "video",