@viji-dev/core 0.2.0-alpha.3 → 0.2.1
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/artist-dts.d.ts +1 -0
- package/dist/artist-dts.js +1 -0
- package/dist/artist-global.d.ts +656 -0
- package/dist/assets/viji.worker-BKsgIT1d.js.map +1 -1
- package/dist/index.d.ts +57 -7
- package/dist/index.js.map +1 -1
- package/package.json +10 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viji.worker-BKsgIT1d.js","sources":["../src/worker/ParameterSystem.ts","../src/worker/InteractionSystem.ts","../src/worker/VideoSystem.ts","../src/worker/VijiWorkerRuntime.ts","../src/worker/viji.worker.ts"],"sourcesContent":["import { \r\n ParameterGroup, \r\n ParameterDefinition, \r\n ParameterValue,\r\n SliderParameter,\r\n ColorParameter,\r\n ToggleParameter,\r\n SelectParameter,\r\n TextParameter,\r\n NumberParameter,\r\n SliderConfig,\r\n ColorConfig,\r\n ToggleConfig,\r\n SelectConfig,\r\n TextConfig,\r\n NumberConfig\r\n} from '../types/index.js';\r\n\r\nexport class ParameterSystem {\r\n // Parameter system for Phase 2 (new object-based approach)\r\n private parameterDefinitions = new Map<string, ParameterDefinition>();\r\n private parameterGroups = new Map<string, ParameterGroup>();\r\n private parameterValues = new Map<string, ParameterValue>();\r\n private parameterObjects = new Map<string, any>(); // Maps parameter names to their objects\r\n private parametersDefined = false;\r\n private initialValuesSynced = false; // Track if initial values have been synced from host\r\n \r\n // Debug logging control\r\n private debugMode = false;\r\n\r\n /**\r\n * Enable or disable debug logging\r\n */\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n\r\n /**\r\n * Debug logging helper\r\n */\r\n private debugLog(message: string, ...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log(message, ...args);\r\n }\r\n }\r\n\r\n // Message posting callback\r\n private postMessageCallback: (type: string, data?: any) => void;\r\n\r\n constructor(postMessageCallback: (type: string, data?: any) => void) {\r\n this.postMessageCallback = postMessageCallback;\r\n }\r\n\r\n // Parameter helper function implementations (return parameter objects)\r\n public createSliderParameter(defaultValue: number, config: SliderConfig): SliderParameter {\r\n const paramName = config.label;\r\n const sliderObject = {\r\n value: defaultValue,\r\n min: config.min ?? 0,\r\n max: config.max ?? 100,\r\n step: config.step ?? 1,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general',\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'slider',\r\n defaultValue,\r\n label: sliderObject.label,\r\n description: sliderObject.description,\r\n group: sliderObject.group,\r\n category: sliderObject.category,\r\n config: {\r\n min: sliderObject.min,\r\n max: sliderObject.max,\r\n step: sliderObject.step\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, sliderObject);\r\n return sliderObject;\r\n }\r\n\r\n public createColorParameter(defaultValue: string, config: ColorConfig): ColorParameter {\r\n const paramName = config.label;\r\n const colorObject = {\r\n value: defaultValue,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general',\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'color',\r\n defaultValue,\r\n label: colorObject.label,\r\n description: colorObject.description,\r\n group: colorObject.group,\r\n category: colorObject.category,\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, colorObject);\r\n return colorObject;\r\n }\r\n\r\n public createToggleParameter(defaultValue: boolean, config: ToggleConfig): ToggleParameter {\r\n const paramName = config.label;\r\n const toggleObject = {\r\n value: defaultValue,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'toggle',\r\n defaultValue,\r\n label: toggleObject.label,\r\n description: toggleObject.description,\r\n group: toggleObject.group,\r\n category: toggleObject.category\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, toggleObject);\r\n return toggleObject;\r\n }\r\n\r\n public createSelectParameter(defaultValue: string | number, config: SelectConfig): SelectParameter {\r\n const paramName = config.label;\r\n const selectObject = {\r\n value: defaultValue,\r\n options: config.options,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'select',\r\n defaultValue,\r\n label: selectObject.label,\r\n description: selectObject.description,\r\n group: selectObject.group,\r\n category: selectObject.category,\r\n config: {\r\n options: selectObject.options\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, selectObject);\r\n return selectObject;\r\n }\r\n\r\n public createTextParameter(defaultValue: string, config: TextConfig): TextParameter {\r\n const paramName = config.label;\r\n const textObject = {\r\n value: defaultValue,\r\n maxLength: config.maxLength ?? 1000,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'text',\r\n defaultValue,\r\n label: textObject.label,\r\n description: textObject.description,\r\n group: textObject.group,\r\n category: textObject.category,\r\n config: {\r\n maxLength: textObject.maxLength\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, textObject);\r\n return textObject;\r\n }\r\n\r\n public createNumberParameter(defaultValue: number, config: NumberConfig): NumberParameter {\r\n const paramName = config.label;\r\n const numberObject = {\r\n value: defaultValue,\r\n min: config.min ?? 0,\r\n max: config.max ?? 100,\r\n step: config.step ?? 1,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'number',\r\n defaultValue,\r\n label: numberObject.label,\r\n description: numberObject.description,\r\n group: numberObject.group,\r\n category: numberObject.category,\r\n config: {\r\n min: numberObject.min,\r\n max: numberObject.max,\r\n step: numberObject.step\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, numberObject);\r\n return numberObject;\r\n }\r\n\r\n private storeParameterDefinition(name: string, definition: ParameterDefinition): void {\r\n // This is called during scene initialization, not during define()\r\n // We'll collect these and send them when the scene is fully loaded\r\n this.parameterDefinitions.set(name, definition);\r\n this.parameterValues.set(name, definition.defaultValue);\r\n }\r\n\r\n public updateParameterValue(name: string, value: ParameterValue): boolean {\r\n const definition = this.parameterDefinitions.get(name);\r\n if (!definition) {\r\n console.warn(`Unknown parameter: ${name}. Available parameters:`, Array.from(this.parameterDefinitions.keys()));\r\n return false;\r\n }\r\n\r\n // Validation\r\n if (!this.validateParameterValue(name, value, definition)) {\r\n console.warn(`Validation failed for parameter ${name} = ${value}`);\r\n return false;\r\n }\r\n\r\n // Check if value actually changed (but always allow initial sync)\r\n const currentValue = this.parameterValues.get(name);\r\n const isInitialSync = !this.initialValuesSynced; // During initial parameter sync from host\r\n \r\n if (currentValue === value && !isInitialSync) {\r\n return false; // No change (but allow initial sync even if values match)\r\n }\r\n\r\n // Update value in both storage and parameter object\r\n this.parameterValues.set(name, value);\r\n \r\n // Update the parameter object's value property\r\n const parameterObject = this.parameterObjects.get(name);\r\n if (parameterObject) {\r\n parameterObject.value = value;\r\n }\r\n \r\n return true;\r\n }\r\n\r\n private validateParameterValue(name: string, value: ParameterValue, definition: ParameterDefinition): boolean {\r\n // Custom validation function\r\n if (definition.validate && !definition.validate(value)) {\r\n console.error(`Custom validation failed for parameter '${name}': ${value}`);\r\n return false;\r\n }\r\n\r\n // Type validation\r\n switch (definition.type) {\r\n case 'slider':\r\n case 'number':\r\n if (typeof value !== 'number' || isNaN(value)) {\r\n console.error(`Parameter '${name}' must be a number, got: ${value}`);\r\n return false;\r\n }\r\n if (definition.config?.min !== undefined && value < definition.config.min) {\r\n console.error(`Parameter '${name}' value ${value} is below minimum ${definition.config.min}`);\r\n return false;\r\n }\r\n if (definition.config?.max !== undefined && value > definition.config.max) {\r\n console.error(`Parameter '${name}' value ${value} is above maximum ${definition.config.max}`);\r\n return false;\r\n }\r\n break;\r\n case 'color':\r\n if (typeof value !== 'string' || !/^#[0-9A-Fa-f]{6}$/.test(value)) {\r\n console.error(`Parameter '${name}' must be a valid hex color, got: ${value}`);\r\n return false;\r\n }\r\n break;\r\n case 'toggle':\r\n if (typeof value !== 'boolean') {\r\n console.error(`Parameter '${name}' must be a boolean, got: ${value}`);\r\n return false;\r\n }\r\n break;\r\n case 'select':\r\n if (!definition.config?.options || !definition.config.options.includes(value as string & number)) {\r\n console.error(`Parameter '${name}' value ${value} is not in options: ${definition.config?.options}`);\r\n return false;\r\n }\r\n break;\r\n case 'text':\r\n if (typeof value !== 'string') {\r\n console.error(`Parameter '${name}' must be a string, got: ${value}`);\r\n return false;\r\n }\r\n if (definition.config?.maxLength && value.length > definition.config.maxLength) {\r\n console.error(`Parameter '${name}' text too long: ${value.length} > ${definition.config.maxLength}`);\r\n return false;\r\n }\r\n break;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Reset parameter state (called when loading new scene)\r\n public resetParameterState(): void {\r\n this.parametersDefined = false;\r\n this.initialValuesSynced = false;\r\n this.parameterDefinitions.clear();\r\n this.parameterGroups.clear();\r\n this.parameterValues.clear();\r\n this.parameterObjects.clear();\r\n }\r\n\r\n // Send all parameters (from helper functions) to host\r\n public sendAllParametersToHost(): void {\r\n // Don't send if already sent or if no parameters defined\r\n if (this.parametersDefined || this.parameterDefinitions.size === 0) {\r\n return;\r\n }\r\n\r\n try {\r\n // Group parameters by their group property\r\n const groups = new Map<string, ParameterGroup>();\r\n\r\n for (const [paramName, paramDef] of this.parameterDefinitions) {\r\n const groupName = paramDef.group || 'general';\r\n \r\n if (!groups.has(groupName)) {\r\n // Use the parameter's category if available, otherwise default to 'general'\r\n const category = paramDef.category || 'general';\r\n groups.set(groupName, {\r\n groupName,\r\n category,\r\n parameters: {}\r\n });\r\n }\r\n\r\n const group = groups.get(groupName)!;\r\n group.parameters[paramName] = paramDef;\r\n }\r\n\r\n this.parametersDefined = true;\r\n\r\n // Send parameter definitions to host for UI generation\r\n this.postMessageCallback('parameters-defined', {\r\n groups: Array.from(groups.values()),\r\n timestamp: performance.now()\r\n });\r\n\r\n this.debugLog(`All parameters sent to host: ${this.parameterDefinitions.size} parameters in ${groups.size} groups`);\r\n } catch (error) {\r\n this.postMessageCallback('parameter-validation-error', {\r\n message: `Failed to send parameters to host: ${(error as Error).message}`,\r\n code: 'PARAMETER_SENDING_ERROR'\r\n });\r\n }\r\n }\r\n\r\n // Mark initial values as synced\r\n public markInitialValuesSynced(): void {\r\n this.initialValuesSynced = true;\r\n }\r\n\r\n // Get parameter count for performance reporting\r\n public getParameterCount(): number {\r\n return this.parameterDefinitions.size;\r\n }\r\n} ","import { MouseAPI, KeyboardAPI, TouchAPI, TouchPoint } from '../types/index.js';\r\n\r\n/**\r\n * Manages user interaction state and APIs for the worker runtime.\r\n * Handles mouse, keyboard, and touch input processing for Phase 7.\r\n * \r\n * This system provides:\r\n * - Real-time interaction state management\r\n * - Frame-based event processing\r\n * - Clean API generation for artist code\r\n * - Message handling for interaction updates\r\n */\r\nexport class InteractionSystem {\r\n // Interaction enabled state\r\n private isEnabled: boolean = true;\r\n\r\n // Mouse interaction state\r\n private mouseState: MouseAPI = {\r\n x: 0, y: 0,\r\n isInCanvas: false,\r\n isPressed: false,\r\n leftButton: false,\r\n rightButton: false,\r\n middleButton: false,\r\n velocity: { x: 0, y: 0 },\r\n deltaX: 0,\r\n deltaY: 0,\r\n wheelDelta: 0,\r\n wheelX: 0,\r\n wheelY: 0,\r\n wasPressed: false,\r\n wasReleased: false,\r\n wasMoved: false\r\n };\r\n\r\n // Keyboard interaction state\r\n private keyboardState: KeyboardAPI = {\r\n isPressed: (key: string) => this.keyboardState.activeKeys.has(key.toLowerCase()),\r\n wasPressed: (key: string) => this.keyboardState.pressedThisFrame.has(key.toLowerCase()),\r\n wasReleased: (key: string) => this.keyboardState.releasedThisFrame.has(key.toLowerCase()),\r\n activeKeys: new Set<string>(),\r\n pressedThisFrame: new Set<string>(),\r\n releasedThisFrame: new Set<string>(),\r\n lastKeyPressed: '',\r\n lastKeyReleased: '',\r\n shift: false,\r\n ctrl: false,\r\n alt: false,\r\n meta: false\r\n };\r\n\r\n // Touch interaction state\r\n private touchState: TouchAPI = {\r\n points: [],\r\n count: 0,\r\n started: [],\r\n moved: [],\r\n ended: [],\r\n primary: null,\r\n gestures: {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n }\r\n };\r\n\r\n constructor() {\r\n // Bind methods for proper context when used as callbacks\r\n this.handleMouseUpdate = this.handleMouseUpdate.bind(this);\r\n this.handleKeyboardUpdate = this.handleKeyboardUpdate.bind(this);\r\n this.handleTouchUpdate = this.handleTouchUpdate.bind(this);\r\n this.frameStart = this.frameStart.bind(this);\r\n }\r\n\r\n /**\r\n * Get the interaction APIs for inclusion in the viji object\r\n */\r\n public getInteractionAPIs() {\r\n return {\r\n mouse: this.mouseState,\r\n keyboard: this.keyboardState,\r\n touches: this.touchState\r\n };\r\n }\r\n\r\n /**\r\n * Called at the start of each frame to reset frame-based events\r\n */\r\n public frameStart(): void {\r\n // Reset mouse frame events\r\n this.mouseState.wasPressed = false;\r\n this.mouseState.wasReleased = false;\r\n this.mouseState.wasMoved = false;\r\n this.mouseState.wheelDelta = 0;\r\n this.mouseState.wheelX = 0;\r\n this.mouseState.wheelY = 0;\r\n\r\n // Reset keyboard frame events\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n\r\n // Reset touch frame events\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.gestures.isTapping = false;\r\n this.touchState.gestures.pinchDelta = 0;\r\n this.touchState.gestures.rotationDelta = 0;\r\n }\r\n\r\n /**\r\n * Handle mouse update messages from the host\r\n */\r\n public handleMouseUpdate(data: {\r\n x: number;\r\n y: number;\r\n buttons: number;\r\n deltaX: number;\r\n deltaY: number;\r\n wheelDeltaX: number;\r\n wheelDeltaY: number;\r\n isInCanvas?: boolean;\r\n timestamp: number;\r\n wasPressed?: boolean;\r\n wasReleased?: boolean;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n // Update mouse position and button states\r\n this.mouseState.x = data.x;\r\n this.mouseState.y = data.y;\r\n this.mouseState.isInCanvas = data.isInCanvas !== undefined ? data.isInCanvas : true;\r\n this.mouseState.leftButton = (data.buttons & 1) !== 0;\r\n this.mouseState.rightButton = (data.buttons & 2) !== 0;\r\n this.mouseState.middleButton = (data.buttons & 4) !== 0;\r\n this.mouseState.isPressed = data.buttons > 0;\r\n \r\n // Update movement deltas and wheel\r\n this.mouseState.deltaX = data.deltaX || 0;\r\n this.mouseState.deltaY = data.deltaY || 0;\r\n this.mouseState.wheelDelta = data.wheelDeltaY || 0;\r\n this.mouseState.wheelX = data.wheelDeltaX || 0;\r\n this.mouseState.wheelY = data.wheelDeltaY || 0;\r\n \r\n // Update velocity (smoothed in InteractionManager)\r\n this.mouseState.velocity.x = data.deltaX || 0;\r\n this.mouseState.velocity.y = data.deltaY || 0;\r\n \r\n // Frame-based events (calculated in InteractionManager or provided by host)\r\n this.mouseState.wasPressed = data.wasPressed || false;\r\n this.mouseState.wasReleased = data.wasReleased || false;\r\n this.mouseState.wasMoved = (data.deltaX !== 0 || data.deltaY !== 0);\r\n }\r\n\r\n /**\r\n * Handle keyboard update messages from the host\r\n */\r\n public handleKeyboardUpdate(data: {\r\n type: 'keydown' | 'keyup';\r\n key: string;\r\n code: string;\r\n shiftKey: boolean;\r\n ctrlKey: boolean;\r\n altKey: boolean;\r\n metaKey: boolean;\r\n timestamp: number;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n const key = data.key.toLowerCase();\r\n \r\n if (data.type === 'keydown') {\r\n if (!this.keyboardState.activeKeys.has(key)) {\r\n this.keyboardState.activeKeys.add(key);\r\n this.keyboardState.pressedThisFrame.add(key);\r\n this.keyboardState.lastKeyPressed = data.key;\r\n }\r\n } else if (data.type === 'keyup') {\r\n this.keyboardState.activeKeys.delete(key);\r\n this.keyboardState.releasedThisFrame.add(key);\r\n this.keyboardState.lastKeyReleased = data.key;\r\n }\r\n \r\n // Update modifier keys\r\n this.keyboardState.shift = data.shiftKey;\r\n this.keyboardState.ctrl = data.ctrlKey;\r\n this.keyboardState.alt = data.altKey;\r\n this.keyboardState.meta = data.metaKey;\r\n }\r\n\r\n /**\r\n * Handle touch update messages from the host\r\n */\r\n public handleTouchUpdate(data: {\r\n type: 'touchstart' | 'touchmove' | 'touchend' | 'touchcancel';\r\n touches: Array<{\r\n identifier: number;\r\n clientX: number;\r\n clientY: number;\r\n pressure: number;\r\n radiusX: number;\r\n radiusY: number;\r\n rotationAngle: number;\r\n force: number;\r\n }>;\r\n timestamp: number;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n // Clear frame-based touch events\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n \r\n // Convert touch data to our TouchPoint format\r\n const touches: TouchPoint[] = data.touches.map((touch) => ({\r\n id: touch.identifier,\r\n x: touch.clientX,\r\n y: touch.clientY,\r\n pressure: touch.pressure || 0,\r\n radius: Math.max(touch.radiusX || 0, touch.radiusY || 0),\r\n radiusX: touch.radiusX || 0,\r\n radiusY: touch.radiusY || 0,\r\n rotationAngle: touch.rotationAngle || 0,\r\n force: touch.force || touch.pressure || 0,\r\n deltaX: 0, // Could be calculated if we track previous positions\r\n deltaY: 0,\r\n velocity: { x: 0, y: 0 }, // Could be calculated if we track movement\r\n isNew: data.type === 'touchstart',\r\n isActive: true,\r\n isEnding: data.type === 'touchend' || data.type === 'touchcancel'\r\n }));\r\n \r\n // Update touch state\r\n this.touchState.points = touches;\r\n this.touchState.count = touches.length;\r\n this.touchState.primary = touches[0] || null;\r\n \r\n // Set frame-based events based on message type\r\n if (data.type === 'touchstart') {\r\n this.touchState.started = touches;\r\n } else if (data.type === 'touchmove') {\r\n this.touchState.moved = touches;\r\n } else if (data.type === 'touchend' || data.type === 'touchcancel') {\r\n this.touchState.ended = touches;\r\n }\r\n \r\n // Note: Advanced gesture recognition is handled in the InteractionManager\r\n // on the host side. For now, we provide basic gesture state structure.\r\n // In the future, we could move gesture recognition here or receive \r\n // gesture data from the host.\r\n this.touchState.gestures = {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n };\r\n }\r\n\r\n /**\r\n * Reset all interaction state (called when loading new scene)\r\n */\r\n public resetInteractionState(): void {\r\n // Reset mouse state\r\n Object.assign(this.mouseState, {\r\n x: 0, y: 0,\r\n isInCanvas: false,\r\n isPressed: false,\r\n leftButton: false,\r\n rightButton: false,\r\n middleButton: false,\r\n velocity: { x: 0, y: 0 },\r\n deltaX: 0,\r\n deltaY: 0,\r\n wheelDelta: 0,\r\n wheelX: 0,\r\n wheelY: 0,\r\n wasPressed: false,\r\n wasReleased: false,\r\n wasMoved: false\r\n });\r\n\r\n // Reset keyboard state\r\n this.keyboardState.activeKeys.clear();\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n this.keyboardState.lastKeyPressed = '';\r\n this.keyboardState.lastKeyReleased = '';\r\n this.keyboardState.shift = false;\r\n this.keyboardState.ctrl = false;\r\n this.keyboardState.alt = false;\r\n this.keyboardState.meta = false;\r\n\r\n // Reset touch state\r\n this.touchState.points = [];\r\n this.touchState.count = 0;\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.primary = null;\r\n Object.assign(this.touchState.gestures, {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n });\r\n }\r\n\r\n /**\r\n * Enable or disable interaction processing\r\n */\r\n public setInteractionEnabled(enabled: boolean): void {\r\n this.isEnabled = enabled;\r\n \r\n // If disabled, reset all interaction states to prevent stale data\r\n if (!enabled) {\r\n this.resetInteractionStates();\r\n }\r\n }\r\n\r\n /**\r\n * Get current interaction enabled state\r\n */\r\n public getInteractionEnabled(): boolean {\r\n return this.isEnabled;\r\n }\r\n\r\n /**\r\n * Reset all interaction states to default values\r\n */\r\n private resetInteractionStates(): void {\r\n // Reset mouse state\r\n this.mouseState.x = 0;\r\n this.mouseState.y = 0;\r\n this.mouseState.isInCanvas = false;\r\n this.mouseState.isPressed = false;\r\n this.mouseState.leftButton = false;\r\n this.mouseState.rightButton = false;\r\n this.mouseState.middleButton = false;\r\n this.mouseState.velocity.x = 0;\r\n this.mouseState.velocity.y = 0;\r\n this.mouseState.deltaX = 0;\r\n this.mouseState.deltaY = 0;\r\n this.mouseState.wheelDelta = 0;\r\n this.mouseState.wheelX = 0;\r\n this.mouseState.wheelY = 0;\r\n this.mouseState.wasPressed = false;\r\n this.mouseState.wasReleased = false;\r\n this.mouseState.wasMoved = false;\r\n\r\n // Reset keyboard state\r\n this.keyboardState.activeKeys.clear();\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n this.keyboardState.lastKeyPressed = '';\r\n this.keyboardState.lastKeyReleased = '';\r\n this.keyboardState.shift = false;\r\n this.keyboardState.ctrl = false;\r\n this.keyboardState.alt = false;\r\n this.keyboardState.meta = false;\r\n\r\n // Reset touch state\r\n this.touchState.points = [];\r\n this.touchState.count = 0;\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.primary = null;\r\n this.touchState.gestures.isPinching = false;\r\n this.touchState.gestures.isRotating = false;\r\n this.touchState.gestures.isPanning = false;\r\n this.touchState.gestures.isTapping = false;\r\n this.touchState.gestures.pinchScale = 1;\r\n this.touchState.gestures.pinchDelta = 0;\r\n this.touchState.gestures.rotationAngle = 0;\r\n this.touchState.gestures.rotationDelta = 0;\r\n this.touchState.gestures.panDelta = { x: 0, y: 0 };\r\n this.touchState.gestures.tapCount = 0;\r\n this.touchState.gestures.lastTapTime = 0;\r\n this.touchState.gestures.tapPosition = null;\r\n }\r\n} ","/**\r\n * Worker-side Video System for Phase 10 - CORRECT OffscreenCanvas Implementation\r\n * \r\n * CORRECT Approach:\r\n * 1. Host creates OffscreenCanvas (no context!)\r\n * 2. Host transfers OffscreenCanvas to worker\r\n * 3. Worker receives OffscreenCanvas and gets context\r\n * 4. Host sends ImageBitmap frames to worker\r\n * 5. Worker draws ImageBitmap frames to its OffscreenCanvas\r\n * 6. Worker performs all analysis and effects on OffscreenCanvas\r\n * \r\n * This provides:\r\n * - True worker-side processing with full GPU access\r\n * - Zero-copy OffscreenCanvas ownership transfer\r\n * - Optimal performance for CV and artist effects\r\n * - Proper separation: host = coordination, worker = processing\r\n */\r\nexport class VideoSystem {\r\n // ✅ CORRECT: Worker-owned OffscreenCanvas (transferred from host)\r\n private offscreenCanvas: OffscreenCanvas | null = null;\r\n private ctx: OffscreenCanvasRenderingContext2D | null = null;\r\n private gl: WebGLRenderingContext | WebGL2RenderingContext | null = null;\r\n \r\n // Debug logging control\r\n private debugMode = false;\r\n\r\n /**\r\n * Enable or disable debug logging\r\n */\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n\r\n /**\r\n * Debug logging helper\r\n */\r\n private debugLog(message: string, ...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log(message, ...args);\r\n }\r\n }\r\n \r\n // Frame processing configuration\r\n private targetFrameRate = 30; // Default target FPS for video processing\r\n private lastFrameTime = 0;\r\n private frameInterval = 1000 / this.targetFrameRate; // ms between frames\r\n \r\n // Processing state\r\n private hasLoggedFirstFrame = false;\r\n private frameCount = 0;\r\n \r\n // Video state for artist API\r\n private videoState = {\r\n isConnected: false,\r\n currentFrame: null as OffscreenCanvas | null,\r\n frameWidth: 0,\r\n frameHeight: 0,\r\n frameRate: 0,\r\n frameData: null as ImageData | null\r\n };\r\n \r\n // Phase 11 preparation - CV processing placeholder\r\n private cvFeatures = {\r\n faceDetection: false,\r\n handTracking: false,\r\n bodySegmentation: false\r\n };\r\n \r\n private cvResults = {\r\n faces: [] as any[],\r\n hands: [] as any[],\r\n bodySegmentation: null as any\r\n };\r\n\r\n constructor() {\r\n // VideoSystem ready for OffscreenCanvas processing\r\n }\r\n\r\n /**\r\n * Get the video API for inclusion in the viji object\r\n */\r\n public getVideoAPI() {\r\n return {\r\n isConnected: this.videoState.isConnected,\r\n currentFrame: this.videoState.currentFrame,\r\n frameWidth: this.videoState.frameWidth,\r\n frameHeight: this.videoState.frameHeight,\r\n frameRate: this.videoState.frameRate,\r\n getFrameData: () => this.videoState.frameData,\r\n faces: this.cvResults.faces,\r\n hands: this.cvResults.hands\r\n };\r\n }\r\n\r\n /**\r\n * ✅ CORRECT: Receive OffscreenCanvas transfer from host\r\n */\r\n public handleCanvasSetup(data: {\r\n offscreenCanvas: OffscreenCanvas;\r\n width: number;\r\n height: number;\r\n timestamp: number;\r\n }): void {\r\n try {\r\n // Clean up existing canvas\r\n this.disconnectVideo();\r\n \r\n // ✅ CORRECT: Receive transferred OffscreenCanvas\r\n this.offscreenCanvas = data.offscreenCanvas;\r\n \r\n // ✅ CORRECT: Get context on WORKER side (not host!)\r\n this.ctx = this.offscreenCanvas.getContext('2d', {\r\n willReadFrequently: true // Optimize for frequent getImageData calls\r\n });\r\n \r\n if (!this.ctx) {\r\n throw new Error('Failed to get 2D context from transferred OffscreenCanvas');\r\n }\r\n \r\n // Optional: Get WebGL context for advanced effects\r\n // Note: We can have multiple contexts on the same canvas\r\n try {\r\n this.gl = this.offscreenCanvas.getContext('webgl2') || this.offscreenCanvas.getContext('webgl');\r\n } catch (e) {\r\n // WebGL not available, continue with 2D\r\n this.debugLog('WebGL not available, using 2D context only');\r\n }\r\n \r\n // Update state\r\n this.videoState.isConnected = true;\r\n this.videoState.currentFrame = this.offscreenCanvas;\r\n this.videoState.frameWidth = data.width;\r\n this.videoState.frameHeight = data.height;\r\n this.frameCount = 0;\r\n this.hasLoggedFirstFrame = false;\r\n \r\n this.debugLog('✅ OffscreenCanvas received and setup completed (worker-side)', {\r\n width: data.width,\r\n height: data.height,\r\n hasWebGL: !!this.gl,\r\n targetFrameRate: this.targetFrameRate\r\n });\r\n \r\n this.debugLog('🎬 CORRECT OffscreenCanvas approach - Worker has full GPU access!');\r\n \r\n } catch (error) {\r\n console.error('Failed to setup OffscreenCanvas in worker:', error);\r\n this.disconnectVideo();\r\n }\r\n }\r\n\r\n /**\r\n * ✅ CORRECT: Receive ImageBitmap frame and draw to worker's OffscreenCanvas\r\n */\r\n public handleFrameUpdate(data: {\r\n imageBitmap: ImageBitmap;\r\n timestamp: number;\r\n }): void {\r\n if (!this.offscreenCanvas || !this.ctx) {\r\n console.warn('🔴 Received frame but OffscreenCanvas not setup');\r\n return;\r\n }\r\n \r\n try {\r\n // Log occasionally to avoid spam (very rarely now that it's working)\r\n if (this.frameCount % 150 === 0) { // Log every 150th frame (~5 seconds at 30fps)\r\n this.debugLog('✅ Worker received ImageBitmap frame:', {\r\n bitmapSize: `${data.imageBitmap.width}x${data.imageBitmap.height}`,\r\n canvasSize: `${this.offscreenCanvas.width}x${this.offscreenCanvas.height}`,\r\n frameCount: this.frameCount,\r\n timestamp: data.timestamp\r\n });\r\n }\r\n \r\n // ✅ CORRECT: Worker draws ImageBitmap to its OffscreenCanvas\r\n this.ctx.drawImage(data.imageBitmap, 0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);\r\n \r\n // Update frame processing\r\n this.processCurrentFrame(data.timestamp);\r\n \r\n // Close the transferred ImageBitmap to free memory\r\n data.imageBitmap.close();\r\n \r\n this.frameCount++;\r\n \r\n } catch (error) {\r\n console.error('🔴 Error processing video frame (worker-side):', error);\r\n }\r\n }\r\n\r\n /**\r\n * Process current frame (called when new frame is drawn)\r\n */\r\n private processCurrentFrame(timestamp: number): void {\r\n if (!this.offscreenCanvas || !this.ctx) {\r\n return;\r\n }\r\n \r\n try {\r\n // Get current frame data for analysis\r\n this.videoState.frameData = this.ctx.getImageData(\r\n 0, 0, \r\n this.offscreenCanvas.width, \r\n this.offscreenCanvas.height\r\n );\r\n \r\n // Calculate frame rate based on frame arrival\r\n const deltaTime = timestamp - this.lastFrameTime;\r\n this.videoState.frameRate = deltaTime > 0 ? 1000 / deltaTime : 0;\r\n \r\n // Log first successful frame processing (once)\r\n if (!this.hasLoggedFirstFrame) {\r\n this.debugLog(`🎯 Worker-side OffscreenCanvas processing active: ${this.videoState.frameRate.toFixed(1)} FPS (${this.offscreenCanvas.width}x${this.offscreenCanvas.height})`);\r\n this.debugLog('✅ Full GPU access available for custom effects and CV analysis');\r\n this.hasLoggedFirstFrame = true;\r\n }\r\n \r\n // Phase 11 preparation - Perform CV analysis (placeholder)\r\n this.performCVAnalysis();\r\n \r\n this.lastFrameTime = timestamp;\r\n } catch (error) {\r\n console.error('Error processing video frame (worker-side):', error);\r\n }\r\n }\r\n\r\n /**\r\n * Handle video configuration updates (including disconnection and resize)\r\n */\r\n public handleVideoConfigUpdate(data: {\r\n targetFrameRate?: number;\r\n cvConfig?: any;\r\n width?: number;\r\n height?: number;\r\n disconnect?: boolean;\r\n timestamp: number;\r\n }): void {\r\n try {\r\n // Handle disconnection\r\n if (data.disconnect) {\r\n this.disconnectVideo();\r\n return;\r\n }\r\n \r\n // Handle resize\r\n if (data.width && data.height && this.offscreenCanvas) {\r\n this.resizeCanvas(data.width, data.height);\r\n }\r\n \r\n // Update processing configuration if provided\r\n if (data.targetFrameRate) {\r\n this.updateProcessingConfig(data.targetFrameRate);\r\n }\r\n \r\n // Phase 11 preparation - CV config\r\n if (data.cvConfig) {\r\n this.updateCVConfig(data.cvConfig);\r\n }\r\n } catch (error) {\r\n console.error('Error handling video config update:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Resize the OffscreenCanvas (when video dimensions change)\r\n */\r\n private resizeCanvas(width: number, height: number): void {\r\n if (!this.offscreenCanvas) return;\r\n \r\n try {\r\n // Resize the OffscreenCanvas\r\n this.offscreenCanvas.width = width;\r\n this.offscreenCanvas.height = height;\r\n \r\n // Update state\r\n this.videoState.frameWidth = width;\r\n this.videoState.frameHeight = height;\r\n \r\n // Reset WebGL viewport if available\r\n if (this.gl) {\r\n this.gl.viewport(0, 0, width, height);\r\n }\r\n \r\n this.debugLog(`📐 OffscreenCanvas resized to ${width}x${height} (worker-side)`);\r\n \r\n } catch (error) {\r\n console.error('Error resizing OffscreenCanvas:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect video and clean up resources\r\n */\r\n private disconnectVideo(): void {\r\n // ✅ Clear the OffscreenCanvas before disconnecting\r\n if (this.offscreenCanvas && this.ctx) {\r\n this.ctx.clearRect(0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);\r\n this.debugLog('🧹 Cleared OffscreenCanvas on disconnect');\r\n }\r\n \r\n // Clear canvas references\r\n this.offscreenCanvas = null;\r\n this.ctx = null;\r\n this.gl = null;\r\n \r\n // Update state\r\n this.videoState.isConnected = false;\r\n this.videoState.currentFrame = null;\r\n this.videoState.frameWidth = 0;\r\n this.videoState.frameHeight = 0;\r\n this.videoState.frameRate = 0;\r\n this.videoState.frameData = null;\r\n this.resetCVResults();\r\n this.hasLoggedFirstFrame = false;\r\n this.frameCount = 0;\r\n \r\n this.debugLog('Video disconnected (worker-side)');\r\n }\r\n\r\n /**\r\n * Update video processing configuration\r\n */\r\n private updateProcessingConfig(targetFrameRate: number): void {\r\n this.targetFrameRate = Math.max(1, Math.min(60, targetFrameRate)); // Clamp between 1-60 FPS\r\n this.frameInterval = 1000 / this.targetFrameRate;\r\n \r\n this.debugLog(`Video processing frame rate updated to ${this.targetFrameRate} FPS (worker-side)`);\r\n }\r\n\r\n /**\r\n * Phase 11 preparation - Update CV configuration\r\n */\r\n private updateCVConfig(cvConfig: any): void {\r\n // Placeholder for Phase 11 - Computer vision configuration\r\n this.cvFeatures = {\r\n faceDetection: cvConfig.faceDetection || false,\r\n handTracking: cvConfig.handTracking || false,\r\n bodySegmentation: cvConfig.bodySegmentation || false\r\n };\r\n \r\n this.debugLog('CV configuration updated (Phase 11 preparation, worker-side):', this.cvFeatures);\r\n }\r\n\r\n /**\r\n * Phase 11 preparation - Perform computer vision analysis\r\n */\r\n private performCVAnalysis(): void {\r\n // Placeholder for Phase 11 - Computer vision processing\r\n // This will include face detection, hand tracking, body segmentation\r\n \r\n if (this.cvFeatures.faceDetection) {\r\n // TODO Phase 11: Face detection using MediaPipe or TensorFlow.js\r\n // this.cvResults.faces = await detectFaces(this.videoState.frameData);\r\n }\r\n \r\n if (this.cvFeatures.handTracking) {\r\n // TODO Phase 11: Hand tracking using MediaPipe\r\n // this.cvResults.hands = await detectHands(this.videoState.frameData);\r\n }\r\n \r\n if (this.cvFeatures.bodySegmentation) {\r\n // TODO Phase 11: Body segmentation using TensorFlow.js\r\n // this.cvResults.bodySegmentation = await segmentBody(this.videoState.frameData);\r\n }\r\n }\r\n\r\n /**\r\n * Reset CV results\r\n */\r\n private resetCVResults(): void {\r\n this.cvResults = {\r\n faces: [],\r\n hands: [],\r\n bodySegmentation: null\r\n };\r\n }\r\n\r\n /**\r\n * Reset all video state (called when loading new scene)\r\n */\r\n public resetVideoState(): void {\r\n this.disconnectVideo();\r\n this.resetCVResults();\r\n }\r\n\r\n /**\r\n * Get current processing configuration\r\n */\r\n public getProcessingConfig(): { targetFrameRate: number; frameInterval: number; frameCount: number } {\r\n return {\r\n targetFrameRate: this.targetFrameRate,\r\n frameInterval: this.frameInterval,\r\n frameCount: this.frameCount\r\n };\r\n }\r\n\r\n /**\r\n * Get WebGL context for advanced effects (if available)\r\n */\r\n public getWebGLContext(): WebGLRenderingContext | WebGL2RenderingContext | null {\r\n return this.gl;\r\n }\r\n\r\n /**\r\n * ✅ WORKER API: Artists can access the OffscreenCanvas directly for custom effects\r\n */\r\n public getCanvasForArtistEffects(): OffscreenCanvas | null {\r\n return this.offscreenCanvas;\r\n }\r\n} ","import { \n WorkerMessage, \n WorkerInitMessage, \n WorkerFrameRateMessage, \n WorkerRefreshRateMessage, \n WorkerResolutionMessage, \n WorkerParameterMessage, \n WorkerParameterBatchMessage, \n WorkerStreamMessage, \n WorkerAudioAnalysisMessage,\n WorkerVideoCanvasSetupMessage,\n WorkerVideoFrameUpdateMessage,\n WorkerVideoConfigUpdateMessage,\n WorkerPerformanceMessage, \n WorkerSetSceneCodeMessage \n} from './types.js';\nimport { ParameterSystem } from './ParameterSystem.js';\nimport { InteractionSystem } from './InteractionSystem.js';\nimport { VideoSystem } from './VideoSystem.js';\n\n// Viji Worker Runtime Implementation\nexport class VijiWorkerRuntime {\n private canvas: OffscreenCanvas | null = null;\n private ctx: OffscreenCanvasRenderingContext2D | null = null;\n private gl: WebGLRenderingContext | WebGL2RenderingContext | null = null;\n private isRunning = false;\n private frameCount = 0;\n private lastTime = 0;\n private startTime = 0;\n private frameRateMode: 'full' | 'half' = 'full';\n private skipNextFrame = false;\n private screenRefreshRate = 60; // Will be detected\n \n // Debug logging control\n private debugMode = false;\n\n /**\n * Enable or disable debug logging\n */\n setDebugMode(enabled: boolean): void {\n this.debugMode = enabled;\n // Propagate to child systems\n if (this.videoSystem) this.videoSystem.setDebugMode(enabled);\n if (this.parameterSystem && 'setDebugMode' in this.parameterSystem) {\n (this.parameterSystem as any).setDebugMode(enabled);\n }\n if (this.interactionSystem && 'setDebugMode' in this.interactionSystem) {\n (this.interactionSystem as any).setDebugMode(enabled);\n }\n }\n\n /**\n * Debug logging helper\n */\n private debugLog(message: string, ...args: any[]): void {\n if (this.debugMode) {\n console.log(message, ...args);\n }\n }\n \n // Effective refresh rate tracking\n private effectiveFrameTimes: number[] = [];\n private lastEffectiveRateReport = 0;\n private effectiveRateReportInterval = 1000; // Report every 1 second\n\n // Parameter system\n private parameterSystem: ParameterSystem;\n \n // Interaction system (Phase 7)\n private interactionSystem: InteractionSystem;\n \n // Video system (Phase 10) - worker-side video processing\n private videoSystem: VideoSystem;\n \n // Audio state (Phase 5) - receives analysis results from host\n private audioState = {\n isConnected: false,\n volume: { rms: 0, peak: 0 },\n bands: {\n bass: 0, mid: 0, treble: 0, subBass: 0, \n lowMid: 0, highMid: 0, presence: 0, brilliance: 0\n },\n frequencyData: new Uint8Array(0)\n };\n\n // Video state is now managed by the worker-side VideoSystem\n \n // Artist API object\n public viji = {\n // Canvas (will be set during init)\n canvas: null as OffscreenCanvas | null,\n ctx: null as OffscreenCanvasRenderingContext2D | null,\n gl: null as WebGLRenderingContext | WebGL2RenderingContext | null,\n width: 0,\n height: 0,\n pixelRatio: 1,\n \n // Timing\n time: 0,\n deltaTime: 0,\n frameCount: 0,\n fps: 60,\n \n // Audio API (Phase 5) - will be set in constructor\n audio: {} as any,\n \n video: {\n isConnected: false,\n currentFrame: null as OffscreenCanvas | null,\n frameWidth: 0,\n frameHeight: 0,\n frameRate: 0,\n getFrameData: () => null,\n faces: [] as any[],\n hands: [] as any[]\n },\n \n // Interaction APIs will be added during construction\n mouse: {} as any,\n keyboard: {} as any,\n touches: {} as any,\n \n // Parameter helper functions (return parameter objects) - delegate to parameter system\n slider: (defaultValue: number, config: any) => {\n return this.parameterSystem.createSliderParameter(defaultValue, config);\n },\n \n color: (defaultValue: string, config: any) => {\n return this.parameterSystem.createColorParameter(defaultValue, config);\n },\n \n toggle: (defaultValue: boolean, config: any) => {\n return this.parameterSystem.createToggleParameter(defaultValue, config);\n },\n \n select: (defaultValue: string | number, config: any) => {\n return this.parameterSystem.createSelectParameter(defaultValue, config);\n },\n \n text: (defaultValue: string, config: any) => {\n return this.parameterSystem.createTextParameter(defaultValue, config);\n },\n \n number: (defaultValue: number, config: any) => {\n return this.parameterSystem.createNumberParameter(defaultValue, config);\n },\n \n // Context selection\n useContext: (type: '2d' | 'webgl') => {\n if (type === '2d') {\n if (!this.ctx && this.canvas) {\n this.ctx = this.canvas.getContext('2d');\n this.viji.ctx = this.ctx;\n }\n return this.ctx;\n } else if (type === 'webgl') {\n if (!this.gl && this.canvas) {\n this.gl = this.canvas.getContext('webgl2') || this.canvas.getContext('webgl');\n this.viji.gl = this.gl;\n \n // Set initial WebGL viewport\n if (this.gl) {\n this.gl.viewport(0, 0, this.viji.width, this.viji.height);\n }\n }\n return this.gl;\n }\n return null;\n }\n };\n \n constructor() {\n // Initialize parameter system with post message callback\n this.parameterSystem = new ParameterSystem((type: string, data?: any) => {\n this.postMessage(type, data);\n });\n \n // Initialize interaction system\n this.interactionSystem = new InteractionSystem();\n \n // Initialize video system (Phase 10)\n this.videoSystem = new VideoSystem();\n \n // Integrate APIs into viji object\n Object.assign(this.viji, this.interactionSystem.getInteractionAPIs());\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n \n // Initialize audio API with getFrequencyData function\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n \n this.setupMessageHandling();\n }\n\n // Reset parameter state (called when loading new scene)\n public resetParameterState(): void {\n this.parameterSystem.resetParameterState();\n this.interactionSystem.resetInteractionState();\n \n // Reset audio state\n this.audioState = {\n isConnected: false,\n volume: { rms: 0, peak: 0 },\n bands: {\n bass: 0, mid: 0, treble: 0, subBass: 0, \n lowMid: 0, highMid: 0, presence: 0, brilliance: 0\n },\n frequencyData: new Uint8Array(0)\n };\n // Update viji.audio reference\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n \n // Reset video system\n this.videoSystem.resetVideoState();\n // Update viji.video reference\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n // Send all parameters (from helper functions) to host\n public sendAllParametersToHost(): void {\n this.parameterSystem.sendAllParametersToHost();\n }\n \n private setupMessageHandling(): void {\n self.onmessage = (event: MessageEvent<WorkerMessage>) => {\n const message = event.data;\n \n switch (message.type) {\n case 'init':\n this.handleInit(message);\n break;\n case 'frame-rate-update':\n this.handleFrameRateUpdate(message);\n break;\n case 'refresh-rate-update':\n this.handleRefreshRateUpdate(message);\n break;\n case 'resolution-update':\n this.handleResolutionUpdate(message);\n break;\n case 'set-scene-code':\n this.handleSetSceneCode(message);\n break;\n case 'debug-mode':\n this.setDebugMode(message.data.enabled);\n break;\n case 'parameter-update':\n this.handleParameterUpdate(message);\n break;\n case 'parameter-batch-update':\n this.handleParameterBatchUpdate(message);\n break;\n case 'stream-update':\n this.handleStreamUpdate(message);\n break;\n case 'audio-analysis-update':\n this.handleAudioAnalysisUpdate(message);\n break;\n case 'video-canvas-setup':\n this.handleVideoCanvasSetup(message);\n break;\n case 'video-frame-update':\n this.handleVideoFrameUpdate(message);\n break;\n case 'video-config-update':\n this.handleVideoConfigUpdate(message);\n break;\n case 'mouse-update':\n this.handleMouseUpdate(message);\n break;\n case 'keyboard-update':\n this.handleKeyboardUpdate(message);\n break;\n case 'touch-update':\n this.handleTouchUpdate(message);\n break;\n case 'interaction-enabled':\n this.handleInteractionEnabled(message);\n break;\n case 'performance-update':\n this.handlePerformanceUpdate(message);\n break;\n case 'capture-frame':\n this.handleCaptureFrame(message as any);\n break;\n }\n };\n }\n \n private handleInit(message: WorkerInitMessage): void {\n try {\n this.canvas = message.data.canvas;\n this.viji.canvas = this.canvas;\n \n // Set initial effective resolution (same as canvas size initially)\n this.viji.width = this.canvas.width;\n this.viji.height = this.canvas.height;\n \n // Start render loop\n this.startRenderLoop();\n \n // Send ready response\n this.postMessage('ready', { \n id: message.id,\n canvasSize: { width: this.canvas.width, height: this.canvas.height }\n });\n } catch (error) {\n this.postMessage('error', {\n id: message.id,\n message: (error as Error).message,\n code: 'INIT_ERROR'\n });\n }\n }\n \n private handleFrameRateUpdate(message: WorkerFrameRateMessage): void {\n if (message.data && message.data.mode) {\n this.frameRateMode = message.data.mode;\n this.debugLog('Frame rate mode updated to:', message.data.mode);\n }\n }\n \n private handleRefreshRateUpdate(message: WorkerRefreshRateMessage): void {\n if (message.data && message.data.screenRefreshRate) {\n this.screenRefreshRate = message.data.screenRefreshRate;\n this.debugLog('Screen refresh rate updated to:', message.data.screenRefreshRate + 'Hz');\n }\n }\n \n private trackEffectiveFrameTime(currentTime: number): void {\n // Keep track of actual render frame times\n this.effectiveFrameTimes.push(currentTime);\n \n // Keep only the last 60 frames for calculation (1 second at 60fps)\n if (this.effectiveFrameTimes.length > 60) {\n this.effectiveFrameTimes.shift();\n }\n }\n \n private reportEffectiveRefreshRate(currentTime: number): void {\n // Report effective refresh rate every second\n if (currentTime - this.lastEffectiveRateReport >= this.effectiveRateReportInterval) {\n if (this.effectiveFrameTimes.length >= 2) {\n // Calculate effective refresh rate from actual frame times\n const totalTime = this.effectiveFrameTimes[this.effectiveFrameTimes.length - 1] - this.effectiveFrameTimes[0];\n const frameCount = this.effectiveFrameTimes.length - 1;\n const effectiveRefreshRate = Math.round((frameCount / totalTime) * 1000);\n \n // Send performance update to core\n this.postMessage('performance-update', {\n effectiveRefreshRate,\n frameRateMode: this.frameRateMode,\n screenRefreshRate: this.screenRefreshRate,\n parameterCount: this.parameterSystem.getParameterCount()\n });\n }\n \n this.lastEffectiveRateReport = currentTime;\n }\n }\n \n private handleResolutionUpdate(message: WorkerResolutionMessage): void {\n if (message.data) {\n // Update canvas resolution directly (effective dimensions * scale)\n if (this.canvas) {\n this.canvas.width = Math.round(message.data.effectiveWidth);\n this.canvas.height = Math.round(message.data.effectiveHeight);\n }\n \n // Update viji dimensions to match actual canvas\n this.viji.width = Math.round(message.data.effectiveWidth);\n this.viji.height = Math.round(message.data.effectiveHeight);\n \n // Update WebGL viewport if context exists\n if (this.gl) {\n this.gl.viewport(0, 0, this.viji.width, this.viji.height);\n }\n \n this.debugLog('Canvas resolution updated to:', this.viji.width + 'x' + this.viji.height);\n }\n }\n \n private handleParameterUpdate(message: WorkerParameterMessage): void {\n if (message.data && message.data.name !== undefined && message.data.value !== undefined) {\n this.parameterSystem.updateParameterValue(message.data.name, message.data.value);\n }\n }\n\n private handleParameterBatchUpdate(message: WorkerParameterBatchMessage): void {\n if (message.data && message.data.updates) {\n for (const update of message.data.updates) {\n this.parameterSystem.updateParameterValue(update.name, update.value);\n }\n \n // Mark initial values as synced after first batch update\n this.parameterSystem.markInitialValuesSynced();\n this.debugLog('Parameter system initialized successfully');\n }\n }\n \n private handleStreamUpdate(message: WorkerStreamMessage): void {\n // TODO: Handle general stream updates (non-audio)\n this.debugLog('Stream update:', message.data);\n }\n \n private handleAudioAnalysisUpdate(message: WorkerAudioAnalysisMessage): void {\n // Phase 5: Handle audio analysis results from host\n this.audioState = {\n isConnected: message.data.isConnected,\n volume: message.data.volume,\n bands: message.data.bands,\n frequencyData: message.data.frequencyData\n };\n \n // Update viji.audio API\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n }\n\n private handleVideoCanvasSetup(message: WorkerVideoCanvasSetupMessage): void {\n // Phase 10: Handle OffscreenCanvas transfer from host to worker-side VideoSystem\n this.videoSystem.handleCanvasSetup({\n offscreenCanvas: message.data.offscreenCanvas,\n width: message.data.width,\n height: message.data.height,\n timestamp: message.data.timestamp\n });\n \n // Update viji.video API with current VideoSystem state\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n private handleVideoFrameUpdate(message: WorkerVideoFrameUpdateMessage): void {\n // Phase 10: Handle ImageBitmap frame from host to worker-side VideoSystem\n this.videoSystem.handleFrameUpdate({\n imageBitmap: message.data.imageBitmap,\n timestamp: message.data.timestamp\n });\n \n // Update viji.video API with current VideoSystem state\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n private handleVideoConfigUpdate(message: WorkerVideoConfigUpdateMessage): void {\n // Phase 10: Handle video configuration updates\n this.videoSystem.handleVideoConfigUpdate({\n ...(message.data.targetFrameRate && { targetFrameRate: message.data.targetFrameRate }),\n ...(message.data.cvConfig && { cvConfig: message.data.cvConfig }),\n ...(message.data.width && { width: message.data.width }),\n ...(message.data.height && { height: message.data.height }),\n ...(message.data.disconnect && { disconnect: message.data.disconnect }),\n timestamp: message.data.timestamp\n });\n \n // ✅ FIX: Update viji.video API with current VideoSystem state after config changes\n // This ensures that disconnection events properly update the scene's video API\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n \n private handlePerformanceUpdate(message: WorkerPerformanceMessage): void {\n // TODO: Handle performance updates in Phase 3\n this.debugLog('Performance update:', message.data);\n }\n\n /**\n * Handle capture-frame request from host.\n * Produces an ArrayBuffer (image bytes) to send back as transferable.\n */\n private async handleCaptureFrame(message: {\n type: 'capture-frame';\n id: string;\n data: { type?: string; resolution?: number | { width: number; height: number } };\n }): Promise<void> {\n try {\n if (!this.canvas) {\n throw new Error('Canvas not initialized');\n }\n\n const mimeType = message.data.type || 'image/jpeg';\n\n // Determine target width/height\n const srcWidth = this.canvas.width;\n const srcHeight = this.canvas.height;\n let targetWidth = srcWidth;\n let targetHeight = srcHeight;\n\n if (typeof message.data.resolution === 'number') {\n const scale = message.data.resolution > 0 ? message.data.resolution : 1;\n targetWidth = Math.max(1, Math.floor(srcWidth * scale));\n targetHeight = Math.max(1, Math.floor(srcHeight * scale));\n } else if (message.data.resolution && typeof message.data.resolution === 'object') {\n targetWidth = Math.max(1, Math.floor(message.data.resolution.width));\n targetHeight = Math.max(1, Math.floor(message.data.resolution.height));\n }\n\n // Compute source crop to match aspect ratio if needed\n const srcAspect = srcWidth / srcHeight;\n const dstAspect = targetWidth / targetHeight;\n let sx = 0;\n let sy = 0;\n let sWidth = srcWidth;\n let sHeight = srcHeight;\n\n if (Math.abs(srcAspect - dstAspect) > 1e-6) {\n if (dstAspect > srcAspect) {\n // Need to crop vertically (top/bottom)\n sHeight = Math.floor(srcWidth / dstAspect);\n sy = Math.floor((srcHeight - sHeight) / 2);\n } else {\n // Need to crop horizontally (left/right)\n sWidth = Math.floor(srcHeight * dstAspect);\n sx = Math.floor((srcWidth - sWidth) / 2);\n }\n }\n\n // Draw to a temp OffscreenCanvas at target size\n const temp = new OffscreenCanvas(targetWidth, targetHeight);\n const tctx = temp.getContext('2d');\n if (!tctx) throw new Error('Failed to get 2D context');\n // Draw current frame from the main canvas onto temp with crop & scale\n tctx.drawImage(this.canvas as OffscreenCanvas, sx, sy, sWidth, sHeight, 0, 0, targetWidth, targetHeight);\n\n const blob = await temp.convertToBlob({ type: mimeType });\n const arrayBuffer = await blob.arrayBuffer();\n\n // Send back as transferable ArrayBuffer to avoid cloning overhead\n (self as any).postMessage({\n type: 'capture-frame-result',\n id: message.id,\n timestamp: Date.now(),\n data: {\n mimeType,\n buffer: arrayBuffer,\n width: targetWidth,\n height: targetHeight\n }\n }, [arrayBuffer]);\n } catch (error) {\n this.postMessage('error', {\n id: message.id,\n message: (error as Error).message,\n code: 'CAPTURE_FRAME_ERROR'\n });\n }\n }\n \n private handleSetSceneCode(message: WorkerSetSceneCodeMessage): void {\n if (message.data && message.data.sceneCode) {\n // Delegate to global scene code function\n (self as any).setSceneCode(message.data.sceneCode);\n }\n }\n \n private startRenderLoop(): void {\n this.isRunning = true;\n this.startTime = performance.now();\n this.lastTime = this.startTime;\n this.renderFrame();\n }\n \n public renderFrame(): void {\n if (!this.isRunning) return;\n \n const currentTime = performance.now();\n \n // Phase 7: Reset frame-based interaction events at start of frame\n this.interactionSystem.frameStart();\n \n // Update frame rate info\n this.viji.fps = this.frameRateMode === 'full' ? this.screenRefreshRate : this.screenRefreshRate / 2;\n \n // Check if we should render this frame\n let shouldRender = true;\n if (this.frameRateMode === 'half') {\n shouldRender = !this.skipNextFrame;\n this.skipNextFrame = !this.skipNextFrame;\n }\n \n if (shouldRender) {\n this.viji.deltaTime = (currentTime - this.lastTime) / 1000;\n this.viji.time = (currentTime - this.startTime) / 1000;\n this.viji.frameCount = ++this.frameCount;\n \n // Track effective frame times for performance calculation\n this.trackEffectiveFrameTime(currentTime);\n \n this.lastTime = currentTime;\n \n try {\n // Call artist render function\n const renderFunction = (self as any).renderFunction;\n if (renderFunction && typeof renderFunction === 'function') {\n renderFunction(this.viji);\n }\n } catch (error) {\n console.error('Render error:', error);\n this.postMessage('error', {\n message: (error as Error).message,\n code: 'RENDER_ERROR',\n stack: (error as Error).stack\n });\n }\n }\n \n // Report effective refresh rate periodically\n this.reportEffectiveRefreshRate(currentTime);\n \n // Schedule next frame check\n requestAnimationFrame(() => this.renderFrame());\n }\n \n private postMessage(type: string, data?: any): void {\n self.postMessage({\n type,\n id: data?.id || `${type}_${Date.now()}`,\n timestamp: Date.now(),\n data\n });\n }\n\n // Phase 7: Interaction Message Handlers (delegated to InteractionSystem)\n\n private handleMouseUpdate(message: any): void {\n this.interactionSystem.handleMouseUpdate(message.data);\n }\n\n private handleKeyboardUpdate(message: any): void {\n this.interactionSystem.handleKeyboardUpdate(message.data);\n }\n\n private handleTouchUpdate(message: any): void {\n this.interactionSystem.handleTouchUpdate(message.data);\n }\n\n private handleInteractionEnabled(message: any): void {\n this.interactionSystem.setInteractionEnabled(message.data.enabled);\n }\n} ","/**\n * Viji Worker Runtime - Secure WebWorker for artist scene execution\n * This worker provides the complete artist API and handles scene rendering\n */\n\nimport { VijiWorkerRuntime } from './VijiWorkerRuntime.js';\n\n// Initialize runtime\nconst runtime = new VijiWorkerRuntime();\n\n// Dynamic scene code execution\nlet renderFunction: ((viji: typeof runtime.viji) => void) | null = null;\n\n// Function to set the scene code dynamically\nfunction setSceneCode(sceneCode: string): void {\n try {\n // Reset parameter state for new scene\n runtime.resetParameterState();\n \n // Create a function from the scene code string\n // The scene code should define a render function\n const functionBody = sceneCode + '\\n' +\n 'if (typeof render === \"function\") {\\n' +\n ' return render;\\n' +\n '}\\n' +\n 'throw new Error(\"Scene code must define a render function\");';\n \n const sceneFunction = new Function('viji', functionBody);\n \n renderFunction = sceneFunction(runtime.viji);\n // Update global reference for the runtime to access\n (self as any).renderFunction = renderFunction;\n // Debug logging is controlled by VijiWorkerRuntime\n \n // After scene code execution, automatically send all parameters to host\n runtime.sendAllParametersToHost();\n } catch (error) {\n console.error('Failed to load scene code:', error);\n self.postMessage({\n type: 'error',\n id: `scene_error_${Date.now()}`,\n timestamp: Date.now(),\n data: {\n message: `Scene code error: ${(error as Error).message}`,\n code: 'SCENE_CODE_ERROR'\n }\n });\n }\n}\n\n// Expose functions to global scope for the runtime to access\n(self as any).setSceneCode = setSceneCode; "],"names":["renderFunction"],"mappings":";;EAkBO,MAAM,gBAAgB;AAAA;AAAA,IAEnB,2CAA2B,IAAA;AAAA,IAC3B,sCAAsB,IAAA;AAAA,IACtB,sCAAsB,IAAA;AAAA,IACtB,uCAAuB,IAAA;AAAA;AAAA,IACvB,oBAAoB;AAAA,IACpB,sBAAsB;AAAA;AAAA;AAAA,IAGtB,YAAY;AAAA;AAAA;AAAA;AAAA,IAKpB,aAAa,SAAwB;AACnC,WAAK,YAAY;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKQ,SAAS,YAAoB,MAAmB;AACtD,UAAI,KAAK,WAAW;AAClB,gBAAQ,IAAI,SAAS,GAAG,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA,IAGQ;AAAA,IAER,YAAY,qBAAyD;AACnE,WAAK,sBAAsB;AAAA,IAC7B;AAAA;AAAA,IAGO,sBAAsB,cAAsB,QAAuC;AACxF,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,KAAK,OAAO,OAAO;AAAA,QACnB,KAAK,OAAO,OAAO;AAAA,QACnB,MAAM,OAAO,QAAQ;AAAA,QACrB,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,QACvB,QAAQ;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,KAAK,aAAa;AAAA,UAClB,MAAM,aAAa;AAAA,QAAA;AAAA,MACrB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEO,qBAAqB,cAAsB,QAAqC;AACrF,YAAM,YAAY,OAAO;AACzB,YAAM,cAAc;AAAA,QAClB,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,YAAY;AAAA,QACnB,aAAa,YAAY;AAAA,QACzB,OAAO,YAAY;AAAA,QACnB,UAAU,YAAY;AAAA,MAAA;AAGxB,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,WAAW;AAChD,aAAO;AAAA,IACT;AAAA,IAEO,sBAAsB,cAAuB,QAAuC;AACzF,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,MAAA;AAGzB,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEO,sBAAsB,cAA+B,QAAuC;AACjG,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,SAAS,OAAO;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,QACvB,QAAQ;AAAA,UACN,SAAS,aAAa;AAAA,QAAA;AAAA,MACxB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEO,oBAAoB,cAAsB,QAAmC;AAClF,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa;AAAA,QACjB,OAAO;AAAA,QACP,WAAW,OAAO,aAAa;AAAA,QAC/B,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,WAAW;AAAA,QAClB,aAAa,WAAW;AAAA,QACxB,OAAO,WAAW;AAAA,QAClB,UAAU,WAAW;AAAA,QACrB,QAAQ;AAAA,UACN,WAAW,WAAW;AAAA,QAAA;AAAA,MACxB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,UAAU;AAC/C,aAAO;AAAA,IACT;AAAA,IAEO,sBAAsB,cAAsB,QAAuC;AACxF,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,KAAK,OAAO,OAAO;AAAA,QACnB,KAAK,OAAO,OAAO;AAAA,QACnB,MAAM,OAAO,QAAQ;AAAA,QACrB,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,QACvB,QAAQ;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,KAAK,aAAa;AAAA,UAClB,MAAM,aAAa;AAAA,QAAA;AAAA,MACrB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEQ,yBAAyB,MAAc,YAAuC;AAGpF,WAAK,qBAAqB,IAAI,MAAM,UAAU;AAC9C,WAAK,gBAAgB,IAAI,MAAM,WAAW,YAAY;AAAA,IACxD;AAAA,IAEO,qBAAqB,MAAc,OAAgC;AACxE,YAAM,aAAa,KAAK,qBAAqB,IAAI,IAAI;AACrD,UAAI,CAAC,YAAY;AACf,gBAAQ,KAAK,sBAAsB,IAAI,2BAA2B,MAAM,KAAK,KAAK,qBAAqB,KAAA,CAAM,CAAC;AAC9G,eAAO;AAAA,MACT;AAGA,UAAI,CAAC,KAAK,uBAAuB,MAAM,OAAO,UAAU,GAAG;AACzD,gBAAQ,KAAK,mCAAmC,IAAI,MAAM,KAAK,EAAE;AACjE,eAAO;AAAA,MACT;AAGA,YAAM,eAAe,KAAK,gBAAgB,IAAI,IAAI;AAClD,YAAM,gBAAgB,CAAC,KAAK;AAE5B,UAAI,iBAAiB,SAAS,CAAC,eAAe;AAC5C,eAAO;AAAA,MACT;AAGA,WAAK,gBAAgB,IAAI,MAAM,KAAK;AAGpC,YAAM,kBAAkB,KAAK,iBAAiB,IAAI,IAAI;AACtD,UAAI,iBAAiB;AACnB,wBAAgB,QAAQ;AAAA,MAC1B;AAEA,aAAO;AAAA,IACT;AAAA,IAEQ,uBAAuB,MAAc,OAAuB,YAA0C;AAE5G,UAAI,WAAW,YAAY,CAAC,WAAW,SAAS,KAAK,GAAG;AACtD,gBAAQ,MAAM,2CAA2C,IAAI,MAAM,KAAK,EAAE;AAC1E,eAAO;AAAA,MACT;AAGA,cAAQ,WAAW,MAAA;AAAA,QACjB,KAAK;AAAA,QACL,KAAK;AACH,cAAI,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AAC7C,oBAAQ,MAAM,cAAc,IAAI,4BAA4B,KAAK,EAAE;AACnE,mBAAO;AAAA,UACT;AACA,cAAI,WAAW,QAAQ,QAAQ,UAAa,QAAQ,WAAW,OAAO,KAAK;AACzE,oBAAQ,MAAM,cAAc,IAAI,WAAW,KAAK,qBAAqB,WAAW,OAAO,GAAG,EAAE;AAC5F,mBAAO;AAAA,UACT;AACA,cAAI,WAAW,QAAQ,QAAQ,UAAa,QAAQ,WAAW,OAAO,KAAK;AACzE,oBAAQ,MAAM,cAAc,IAAI,WAAW,KAAK,qBAAqB,WAAW,OAAO,GAAG,EAAE;AAC5F,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,UAAU,YAAY,CAAC,oBAAoB,KAAK,KAAK,GAAG;AACjE,oBAAQ,MAAM,cAAc,IAAI,qCAAqC,KAAK,EAAE;AAC5E,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,UAAU,WAAW;AAC9B,oBAAQ,MAAM,cAAc,IAAI,6BAA6B,KAAK,EAAE;AACpE,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,CAAC,WAAW,QAAQ,WAAW,CAAC,WAAW,OAAO,QAAQ,SAAS,KAAwB,GAAG;AAChG,oBAAQ,MAAM,cAAc,IAAI,WAAW,KAAK,uBAAuB,WAAW,QAAQ,OAAO,EAAE;AACnG,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,UAAU,UAAU;AAC7B,oBAAQ,MAAM,cAAc,IAAI,4BAA4B,KAAK,EAAE;AACnE,mBAAO;AAAA,UACT;AACA,cAAI,WAAW,QAAQ,aAAa,MAAM,SAAS,WAAW,OAAO,WAAW;AAC9E,oBAAQ,MAAM,cAAc,IAAI,oBAAoB,MAAM,MAAM,MAAM,WAAW,OAAO,SAAS,EAAE;AACnG,mBAAO;AAAA,UACT;AACA;AAAA,MAAA;AAGJ,aAAO;AAAA,IACT;AAAA;AAAA,IAGO,sBAA4B;AACjC,WAAK,oBAAoB;AACzB,WAAK,sBAAsB;AAC3B,WAAK,qBAAqB,MAAA;AAC1B,WAAK,gBAAgB,MAAA;AACrB,WAAK,gBAAgB,MAAA;AACrB,WAAK,iBAAiB,MAAA;AAAA,IACxB;AAAA;AAAA,IAGO,0BAAgC;AAErC,UAAI,KAAK,qBAAqB,KAAK,qBAAqB,SAAS,GAAG;AAClE;AAAA,MACF;AAEA,UAAI;AAEF,cAAM,6BAAa,IAAA;AAEnB,mBAAW,CAAC,WAAW,QAAQ,KAAK,KAAK,sBAAsB;AAC7D,gBAAM,YAAY,SAAS,SAAS;AAEpC,cAAI,CAAC,OAAO,IAAI,SAAS,GAAG;AAE1B,kBAAM,WAAW,SAAS,YAAY;AACtC,mBAAO,IAAI,WAAW;AAAA,cACpB;AAAA,cACA;AAAA,cACA,YAAY,CAAA;AAAA,YAAC,CACd;AAAA,UACH;AAEA,gBAAM,QAAQ,OAAO,IAAI,SAAS;AAClC,gBAAM,WAAW,SAAS,IAAI;AAAA,QAChC;AAEA,aAAK,oBAAoB;AAGzB,aAAK,oBAAoB,sBAAsB;AAAA,UAC7C,QAAQ,MAAM,KAAK,OAAO,QAAQ;AAAA,UAClC,WAAW,YAAY,IAAA;AAAA,QAAI,CAC5B;AAED,aAAK,SAAS,gCAAgC,KAAK,qBAAqB,IAAI,kBAAkB,OAAO,IAAI,SAAS;AAAA,MACpH,SAAS,OAAO;AACd,aAAK,oBAAoB,8BAA8B;AAAA,UACrD,SAAS,sCAAuC,MAAgB,OAAO;AAAA,UACvE,MAAM;AAAA,QAAA,CACP;AAAA,MACH;AAAA,IACF;AAAA;AAAA,IAGO,0BAAgC;AACrC,WAAK,sBAAsB;AAAA,IAC7B;AAAA;AAAA,IAGO,oBAA4B;AACjC,aAAO,KAAK,qBAAqB;AAAA,IACnC;AAAA,EACF;AAAA,ECnXO,MAAM,kBAAkB;AAAA;AAAA,IAErB,YAAqB;AAAA;AAAA,IAGrB,aAAuB;AAAA,MAC7B,GAAG;AAAA,MAAG,GAAG;AAAA,MACT,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,cAAc;AAAA,MACd,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,MACrB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,UAAU;AAAA,IAAA;AAAA;AAAA,IAIJ,gBAA6B;AAAA,MACnC,WAAW,CAAC,QAAgB,KAAK,cAAc,WAAW,IAAI,IAAI,aAAa;AAAA,MAC/E,YAAY,CAAC,QAAgB,KAAK,cAAc,iBAAiB,IAAI,IAAI,aAAa;AAAA,MACtF,aAAa,CAAC,QAAgB,KAAK,cAAc,kBAAkB,IAAI,IAAI,aAAa;AAAA,MACxF,gCAAgB,IAAA;AAAA,MAChB,sCAAsB,IAAA;AAAA,MACtB,uCAAuB,IAAA;AAAA,MACvB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,MAAM;AAAA,IAAA;AAAA;AAAA,IAIA,aAAuB;AAAA,MAC7B,QAAQ,CAAA;AAAA,MACR,OAAO;AAAA,MACP,SAAS,CAAA;AAAA,MACT,OAAO,CAAA;AAAA,MACP,OAAO,CAAA;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,QACf,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,UAAU;AAAA,QACV,aAAa;AAAA,QACb,aAAa;AAAA,MAAA;AAAA,IACf;AAAA,IAGF,cAAc;AAEZ,WAAK,oBAAoB,KAAK,kBAAkB,KAAK,IAAI;AACzD,WAAK,uBAAuB,KAAK,qBAAqB,KAAK,IAAI;AAC/D,WAAK,oBAAoB,KAAK,kBAAkB,KAAK,IAAI;AACzD,WAAK,aAAa,KAAK,WAAW,KAAK,IAAI;AAAA,IAC7C;AAAA;AAAA;AAAA;AAAA,IAKO,qBAAqB;AAC1B,aAAO;AAAA,QACL,OAAO,KAAK;AAAA,QACZ,UAAU,KAAK;AAAA,QACf,SAAS,KAAK;AAAA,MAAA;AAAA,IAElB;AAAA;AAAA;AAAA;AAAA,IAKO,aAAmB;AAExB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,WAAW;AAC3B,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,SAAS;AAGzB,WAAK,cAAc,iBAAiB,MAAA;AACpC,WAAK,cAAc,kBAAkB,MAAA;AAGrC,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,SAAS,YAAY;AACrC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,gBAAgB;AAAA,IAC3C;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAYhB;AAEP,UAAI,CAAC,KAAK,UAAW;AAErB,WAAK,WAAW,IAAI,KAAK;AACzB,WAAK,WAAW,IAAI,KAAK;AACzB,WAAK,WAAW,aAAa,KAAK,eAAe,SAAY,KAAK,aAAa;AAC/E,WAAK,WAAW,cAAc,KAAK,UAAU,OAAO;AACpD,WAAK,WAAW,eAAe,KAAK,UAAU,OAAO;AACrD,WAAK,WAAW,gBAAgB,KAAK,UAAU,OAAO;AACtD,WAAK,WAAW,YAAY,KAAK,UAAU;AAG3C,WAAK,WAAW,SAAS,KAAK,UAAU;AACxC,WAAK,WAAW,SAAS,KAAK,UAAU;AACxC,WAAK,WAAW,aAAa,KAAK,eAAe;AACjD,WAAK,WAAW,SAAS,KAAK,eAAe;AAC7C,WAAK,WAAW,SAAS,KAAK,eAAe;AAG7C,WAAK,WAAW,SAAS,IAAI,KAAK,UAAU;AAC5C,WAAK,WAAW,SAAS,IAAI,KAAK,UAAU;AAG5C,WAAK,WAAW,aAAa,KAAK,cAAc;AAChD,WAAK,WAAW,cAAc,KAAK,eAAe;AAClD,WAAK,WAAW,WAAY,KAAK,WAAW,KAAK,KAAK,WAAW;AAAA,IACnE;AAAA;AAAA;AAAA;AAAA,IAKO,qBAAqB,MASnB;AAEP,UAAI,CAAC,KAAK,UAAW;AACrB,YAAM,MAAM,KAAK,IAAI,YAAA;AAErB,UAAI,KAAK,SAAS,WAAW;AAC3B,YAAI,CAAC,KAAK,cAAc,WAAW,IAAI,GAAG,GAAG;AAC3C,eAAK,cAAc,WAAW,IAAI,GAAG;AACrC,eAAK,cAAc,iBAAiB,IAAI,GAAG;AAC3C,eAAK,cAAc,iBAAiB,KAAK;AAAA,QAC3C;AAAA,MACF,WAAW,KAAK,SAAS,SAAS;AAChC,aAAK,cAAc,WAAW,OAAO,GAAG;AACxC,aAAK,cAAc,kBAAkB,IAAI,GAAG;AAC5C,aAAK,cAAc,kBAAkB,KAAK;AAAA,MAC5C;AAGA,WAAK,cAAc,QAAQ,KAAK;AAChC,WAAK,cAAc,OAAO,KAAK;AAC/B,WAAK,cAAc,MAAM,KAAK;AAC9B,WAAK,cAAc,OAAO,KAAK;AAAA,IACjC;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAahB;AAEP,UAAI,CAAC,KAAK,UAAW;AAErB,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AAGxB,YAAM,UAAwB,KAAK,QAAQ,IAAI,CAAC,WAAW;AAAA,QACzD,IAAI,MAAM;AAAA,QACV,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,QACT,UAAU,MAAM,YAAY;AAAA,QAC5B,QAAQ,KAAK,IAAI,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC;AAAA,QACvD,SAAS,MAAM,WAAW;AAAA,QAC1B,SAAS,MAAM,WAAW;AAAA,QAC1B,eAAe,MAAM,iBAAiB;AAAA,QACtC,OAAO,MAAM,SAAS,MAAM,YAAY;AAAA,QACxC,QAAQ;AAAA;AAAA,QACR,QAAQ;AAAA,QACR,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA;AAAA,QACrB,OAAO,KAAK,SAAS;AAAA,QACrB,UAAU;AAAA,QACV,UAAU,KAAK,SAAS,cAAc,KAAK,SAAS;AAAA,MAAA,EACpD;AAGF,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,QAAQ,QAAQ;AAChC,WAAK,WAAW,UAAU,QAAQ,CAAC,KAAK;AAGxC,UAAI,KAAK,SAAS,cAAc;AAC9B,aAAK,WAAW,UAAU;AAAA,MAC5B,WAAW,KAAK,SAAS,aAAa;AACpC,aAAK,WAAW,QAAQ;AAAA,MAC1B,WAAW,KAAK,SAAS,cAAc,KAAK,SAAS,eAAe;AAClE,aAAK,WAAW,QAAQ;AAAA,MAC1B;AAMA,WAAK,WAAW,WAAW;AAAA,QACzB,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,QACf,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,UAAU;AAAA,QACV,aAAa;AAAA,QACb,aAAa;AAAA,MAAA;AAAA,IAEjB;AAAA;AAAA;AAAA;AAAA,IAKO,wBAA8B;AAEnC,aAAO,OAAO,KAAK,YAAY;AAAA,QAC7B,GAAG;AAAA,QAAG,GAAG;AAAA,QACT,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,cAAc;AAAA,QACd,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,UAAU;AAAA,MAAA,CACX;AAGD,WAAK,cAAc,WAAW,MAAA;AAC9B,WAAK,cAAc,iBAAiB,MAAA;AACpC,WAAK,cAAc,kBAAkB,MAAA;AACrC,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,kBAAkB;AACrC,WAAK,cAAc,QAAQ;AAC3B,WAAK,cAAc,OAAO;AAC1B,WAAK,cAAc,MAAM;AACzB,WAAK,cAAc,OAAO;AAG1B,WAAK,WAAW,SAAS,CAAA;AACzB,WAAK,WAAW,QAAQ;AACxB,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,UAAU;AAC1B,aAAO,OAAO,KAAK,WAAW,UAAU;AAAA,QACtC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,QACf,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,UAAU;AAAA,QACV,aAAa;AAAA,QACb,aAAa;AAAA,MAAA,CACd;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKO,sBAAsB,SAAwB;AACnD,WAAK,YAAY;AAGjB,UAAI,CAAC,SAAS;AACZ,aAAK,uBAAA;AAAA,MACP;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKO,wBAAiC;AACtC,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKQ,yBAA+B;AAErC,WAAK,WAAW,IAAI;AACpB,WAAK,WAAW,IAAI;AACpB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,YAAY;AAC5B,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,eAAe;AAC/B,WAAK,WAAW,SAAS,IAAI;AAC7B,WAAK,WAAW,SAAS,IAAI;AAC7B,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,WAAW;AAG3B,WAAK,cAAc,WAAW,MAAA;AAC9B,WAAK,cAAc,iBAAiB,MAAA;AACpC,WAAK,cAAc,kBAAkB,MAAA;AACrC,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,kBAAkB;AACrC,WAAK,cAAc,QAAQ;AAC3B,WAAK,cAAc,OAAO;AAC1B,WAAK,cAAc,MAAM;AACzB,WAAK,cAAc,OAAO;AAG1B,WAAK,WAAW,SAAS,CAAA;AACzB,WAAK,WAAW,QAAQ;AACxB,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,UAAU;AAC1B,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,YAAY;AACrC,WAAK,WAAW,SAAS,YAAY;AACrC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,gBAAgB;AACzC,WAAK,WAAW,SAAS,gBAAgB;AACzC,WAAK,WAAW,SAAS,WAAW,EAAE,GAAG,GAAG,GAAG,EAAA;AAC/C,WAAK,WAAW,SAAS,WAAW;AACpC,WAAK,WAAW,SAAS,cAAc;AACvC,WAAK,WAAW,SAAS,cAAc;AAAA,IACzC;AAAA,EACF;AAAA,ECrYO,MAAM,YAAY;AAAA;AAAA,IAEf,kBAA0C;AAAA,IAC1C,MAAgD;AAAA,IAChD,KAA4D;AAAA;AAAA,IAG5D,YAAY;AAAA;AAAA;AAAA;AAAA,IAKpB,aAAa,SAAwB;AACnC,WAAK,YAAY;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKQ,SAAS,YAAoB,MAAmB;AACtD,UAAI,KAAK,WAAW;AAClB,gBAAQ,IAAI,SAAS,GAAG,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA,IAGQ,kBAAkB;AAAA;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB,MAAO,KAAK;AAAA;AAAA;AAAA,IAG5B,sBAAsB;AAAA,IACtB,aAAa;AAAA;AAAA,IAGb,aAAa;AAAA,MACnB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,MACX,WAAW;AAAA,IAAA;AAAA;AAAA,IAIL,aAAa;AAAA,MACnB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,kBAAkB;AAAA,IAAA;AAAA,IAGZ,YAAY;AAAA,MAClB,OAAO,CAAA;AAAA,MACP,OAAO,CAAA;AAAA,MACP,kBAAkB;AAAA,IAAA;AAAA,IAGpB,cAAc;AAAA,IAEd;AAAA;AAAA;AAAA;AAAA,IAKO,cAAc;AACnB,aAAO;AAAA,QACL,aAAa,KAAK,WAAW;AAAA,QAC7B,cAAc,KAAK,WAAW;AAAA,QAC9B,YAAY,KAAK,WAAW;AAAA,QAC5B,aAAa,KAAK,WAAW;AAAA,QAC7B,WAAW,KAAK,WAAW;AAAA,QAC3B,cAAc,MAAM,KAAK,WAAW;AAAA,QACpC,OAAO,KAAK,UAAU;AAAA,QACtB,OAAO,KAAK,UAAU;AAAA,MAAA;AAAA,IAE1B;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAKhB;AACP,UAAI;AAEF,aAAK,gBAAA;AAGL,aAAK,kBAAkB,KAAK;AAG5B,aAAK,MAAM,KAAK,gBAAgB,WAAW,MAAM;AAAA,UAC/C,oBAAoB;AAAA;AAAA,QAAA,CACrB;AAED,YAAI,CAAC,KAAK,KAAK;AACb,gBAAM,IAAI,MAAM,2DAA2D;AAAA,QAC7E;AAIA,YAAI;AACF,eAAK,KAAK,KAAK,gBAAgB,WAAW,QAAQ,KAAK,KAAK,gBAAgB,WAAW,OAAO;AAAA,QAChG,SAAS,GAAG;AAEV,eAAK,SAAS,4CAA4C;AAAA,QAC5D;AAGA,aAAK,WAAW,cAAc;AAC9B,aAAK,WAAW,eAAe,KAAK;AACpC,aAAK,WAAW,aAAa,KAAK;AAClC,aAAK,WAAW,cAAc,KAAK;AACnC,aAAK,aAAa;AAClB,aAAK,sBAAsB;AAE3B,aAAK,SAAS,gEAAgE;AAAA,UAC5E,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,UAAU,CAAC,CAAC,KAAK;AAAA,UACjB,iBAAiB,KAAK;AAAA,QAAA,CACvB;AAED,aAAK,SAAS,mEAAmE;AAAA,MAEnF,SAAS,OAAO;AACd,gBAAQ,MAAM,8CAA8C,KAAK;AACjE,aAAK,gBAAA;AAAA,MACP;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAGhB;AACP,UAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,KAAK;AACtC,gBAAQ,KAAK,iDAAiD;AAC9D;AAAA,MACF;AAEA,UAAI;AAEF,YAAI,KAAK,aAAa,QAAQ,GAAG;AAC/B,eAAK,SAAS,wCAAwC;AAAA,YACpD,YAAY,GAAG,KAAK,YAAY,KAAK,IAAI,KAAK,YAAY,MAAM;AAAA,YAChE,YAAY,GAAG,KAAK,gBAAgB,KAAK,IAAI,KAAK,gBAAgB,MAAM;AAAA,YACxE,YAAY,KAAK;AAAA,YACjB,WAAW,KAAK;AAAA,UAAA,CACjB;AAAA,QACH;AAGA,aAAK,IAAI,UAAU,KAAK,aAAa,GAAG,GAAG,KAAK,gBAAgB,OAAO,KAAK,gBAAgB,MAAM;AAGlG,aAAK,oBAAoB,KAAK,SAAS;AAGvC,aAAK,YAAY,MAAA;AAEjB,aAAK;AAAA,MAEP,SAAS,OAAO;AACd,gBAAQ,MAAM,kDAAkD,KAAK;AAAA,MACvE;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,oBAAoB,WAAyB;AACnD,UAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,KAAK;AACtC;AAAA,MACF;AAEA,UAAI;AAEF,aAAK,WAAW,YAAY,KAAK,IAAI;AAAA,UACnC;AAAA,UAAG;AAAA,UACH,KAAK,gBAAgB;AAAA,UACrB,KAAK,gBAAgB;AAAA,QAAA;AAIvB,cAAM,YAAY,YAAY,KAAK;AACnC,aAAK,WAAW,YAAY,YAAY,IAAI,MAAO,YAAY;AAG/D,YAAI,CAAC,KAAK,qBAAqB;AACvB,eAAK,SAAS,qDAAqD,KAAK,WAAW,UAAU,QAAQ,CAAC,CAAC,SAAS,KAAK,gBAAgB,KAAK,IAAI,KAAK,gBAAgB,MAAM,GAAG;AACpL,eAAK,SAAS,gEAAgE;AAC5E,eAAK,sBAAsB;AAAA,QAC7B;AAGA,aAAK,kBAAA;AAEL,aAAK,gBAAgB;AAAA,MACvB,SAAS,OAAO;AACd,gBAAQ,MAAM,+CAA+C,KAAK;AAAA,MACpE;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKO,wBAAwB,MAOtB;AACP,UAAI;AAEF,YAAI,KAAK,YAAY;AACnB,eAAK,gBAAA;AACL;AAAA,QACF;AAGA,YAAI,KAAK,SAAS,KAAK,UAAU,KAAK,iBAAiB;AACrD,eAAK,aAAa,KAAK,OAAO,KAAK,MAAM;AAAA,QAC3C;AAGA,YAAI,KAAK,iBAAiB;AACxB,eAAK,uBAAuB,KAAK,eAAe;AAAA,QAClD;AAGA,YAAI,KAAK,UAAU;AACjB,eAAK,eAAe,KAAK,QAAQ;AAAA,QACnC;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,uCAAuC,KAAK;AAAA,MAC5D;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,aAAa,OAAe,QAAsB;AACxD,UAAI,CAAC,KAAK,gBAAiB;AAE3B,UAAI;AAEF,aAAK,gBAAgB,QAAQ;AAC7B,aAAK,gBAAgB,SAAS;AAG9B,aAAK,WAAW,aAAa;AAC7B,aAAK,WAAW,cAAc;AAG9B,YAAI,KAAK,IAAI;AACX,eAAK,GAAG,SAAS,GAAG,GAAG,OAAO,MAAM;AAAA,QACtC;AAEA,aAAK,SAAS,iCAAiC,KAAK,IAAI,MAAM,gBAAgB;AAAA,MAEhF,SAAS,OAAO;AACd,gBAAQ,MAAM,mCAAmC,KAAK;AAAA,MACxD;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,kBAAwB;AAE9B,UAAI,KAAK,mBAAmB,KAAK,KAAK;AACpC,aAAK,IAAI,UAAU,GAAG,GAAG,KAAK,gBAAgB,OAAO,KAAK,gBAAgB,MAAM;AAChF,aAAK,SAAS,0CAA0C;AAAA,MAC1D;AAGA,WAAK,kBAAkB;AACvB,WAAK,MAAM;AACX,WAAK,KAAK;AAGV,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,eAAe;AAC/B,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,YAAY;AAC5B,WAAK,WAAW,YAAY;AAC5B,WAAK,eAAA;AACL,WAAK,sBAAsB;AAC3B,WAAK,aAAa;AAElB,WAAK,SAAS,kCAAkC;AAAA,IAClD;AAAA;AAAA;AAAA;AAAA,IAKQ,uBAAuB,iBAA+B;AAC5D,WAAK,kBAAkB,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,eAAe,CAAC;AAChE,WAAK,gBAAgB,MAAO,KAAK;AAEjC,WAAK,SAAS,0CAA0C,KAAK,eAAe,oBAAoB;AAAA,IAClG;AAAA;AAAA;AAAA;AAAA,IAKQ,eAAe,UAAqB;AAE1C,WAAK,aAAa;AAAA,QAChB,eAAe,SAAS,iBAAiB;AAAA,QACzC,cAAc,SAAS,gBAAgB;AAAA,QACvC,kBAAkB,SAAS,oBAAoB;AAAA,MAAA;AAGjD,WAAK,SAAS,iEAAiE,KAAK,UAAU;AAAA,IAChG;AAAA;AAAA;AAAA;AAAA,IAKQ,oBAA0B;AAIhC,UAAI,KAAK,WAAW,cAAe;AAKnC,UAAI,KAAK,WAAW,aAAc;AAKlC,UAAI,KAAK,WAAW,iBAAkB;AAAA,IAIxC;AAAA;AAAA;AAAA;AAAA,IAKQ,iBAAuB;AAC7B,WAAK,YAAY;AAAA,QACf,OAAO,CAAA;AAAA,QACP,OAAO,CAAA;AAAA,QACP,kBAAkB;AAAA,MAAA;AAAA,IAEtB;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAwB;AAC7B,WAAK,gBAAA;AACL,WAAK,eAAA;AAAA,IACP;AAAA;AAAA;AAAA;AAAA,IAKO,sBAA8F;AACnG,aAAO;AAAA,QACL,iBAAiB,KAAK;AAAA,QACtB,eAAe,KAAK;AAAA,QACpB,YAAY,KAAK;AAAA,MAAA;AAAA,IAErB;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAyE;AAC9E,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKO,4BAAoD;AACzD,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA,ECpYO,MAAM,kBAAkB;AAAA,IACrB,SAAiC;AAAA,IACjC,MAAgD;AAAA,IAChD,KAA4D;AAAA,IAC5D,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,gBAAiC;AAAA,IACjC,gBAAgB;AAAA,IAChB,oBAAoB;AAAA;AAAA;AAAA,IAGpB,YAAY;AAAA;AAAA;AAAA;AAAA,IAKpB,aAAa,SAAwB;AACnC,WAAK,YAAY;AAEjB,UAAI,KAAK,YAAa,MAAK,YAAY,aAAa,OAAO;AAC3D,UAAI,KAAK,mBAAmB,kBAAkB,KAAK,iBAAiB;AACjE,aAAK,gBAAwB,aAAa,OAAO;AAAA,MACpD;AACA,UAAI,KAAK,qBAAqB,kBAAkB,KAAK,mBAAmB;AACrE,aAAK,kBAA0B,aAAa,OAAO;AAAA,MACtD;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,SAAS,YAAoB,MAAmB;AACtD,UAAI,KAAK,WAAW;AAClB,gBAAQ,IAAI,SAAS,GAAG,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA,IAGQ,sBAAgC,CAAA;AAAA,IAChC,0BAA0B;AAAA,IAC1B,8BAA8B;AAAA;AAAA;AAAA,IAG9B;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA,aAAa;AAAA,MACnB,aAAa;AAAA,MACb,QAAQ,EAAE,KAAK,GAAG,MAAM,EAAA;AAAA,MACxB,OAAO;AAAA,QACL,MAAM;AAAA,QAAG,KAAK;AAAA,QAAG,QAAQ;AAAA,QAAG,SAAS;AAAA,QACrC,QAAQ;AAAA,QAAG,SAAS;AAAA,QAAG,UAAU;AAAA,QAAG,YAAY;AAAA,MAAA;AAAA,MAElD,eAAe,IAAI,WAAW,CAAC;AAAA,IAAA;AAAA;AAAA;AAAA,IAM1B,OAAO;AAAA;AAAA,MAEZ,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA;AAAA,MAGZ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,KAAK;AAAA;AAAA,MAGL,OAAO,CAAA;AAAA,MAEP,OAAO;AAAA,QACL,aAAa;AAAA,QACb,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,WAAW;AAAA,QACX,cAAc,MAAM;AAAA,QACpB,OAAO,CAAA;AAAA,QACP,OAAO,CAAA;AAAA,MAAC;AAAA;AAAA,MAIV,OAAO,CAAA;AAAA,MACP,UAAU,CAAA;AAAA,MACV,SAAS,CAAA;AAAA;AAAA,MAGT,QAAQ,CAAC,cAAsB,WAAgB;AAC7C,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA,MAEA,OAAO,CAAC,cAAsB,WAAgB;AAC5C,eAAO,KAAK,gBAAgB,qBAAqB,cAAc,MAAM;AAAA,MACvE;AAAA,MAEA,QAAQ,CAAC,cAAuB,WAAgB;AAC9C,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA,MAEA,QAAQ,CAAC,cAA+B,WAAgB;AACtD,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA,MAEA,MAAM,CAAC,cAAsB,WAAgB;AAC3C,eAAO,KAAK,gBAAgB,oBAAoB,cAAc,MAAM;AAAA,MACtE;AAAA,MAEA,QAAQ,CAAC,cAAsB,WAAgB;AAC7C,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA;AAAA,MAGA,YAAY,CAAC,SAAyB;AACpC,YAAI,SAAS,MAAM;AACjB,cAAI,CAAC,KAAK,OAAO,KAAK,QAAQ;AAC5B,iBAAK,MAAM,KAAK,OAAO,WAAW,IAAI;AACtC,iBAAK,KAAK,MAAM,KAAK;AAAA,UACvB;AACA,iBAAO,KAAK;AAAA,QACd,WAAW,SAAS,SAAS;AAC3B,cAAI,CAAC,KAAK,MAAM,KAAK,QAAQ;AAC3B,iBAAK,KAAK,KAAK,OAAO,WAAW,QAAQ,KAAK,KAAK,OAAO,WAAW,OAAO;AAC5E,iBAAK,KAAK,KAAK,KAAK;AAGpB,gBAAI,KAAK,IAAI;AACX,mBAAK,GAAG,SAAS,GAAG,GAAG,KAAK,KAAK,OAAO,KAAK,KAAK,MAAM;AAAA,YAC1D;AAAA,UACF;AACA,iBAAO,KAAK;AAAA,QACd;AACA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,IAGF,cAAc;AAEZ,WAAK,kBAAkB,IAAI,gBAAgB,CAAC,MAAc,SAAe;AACvE,aAAK,YAAY,MAAM,IAAI;AAAA,MAC7B,CAAC;AAGD,WAAK,oBAAoB,IAAI,kBAAA;AAG7B,WAAK,cAAc,IAAI,YAAA;AAGvB,aAAO,OAAO,KAAK,MAAM,KAAK,kBAAkB,oBAAoB;AACpE,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAG7D,WAAK,KAAK,QAAQ;AAAA,QAChB,GAAG,KAAK;AAAA,QACR,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAAA;AAG1C,WAAK,qBAAA;AAAA,IACP;AAAA;AAAA,IAGO,sBAA4B;AACjC,WAAK,gBAAgB,oBAAA;AACrB,WAAK,kBAAkB,sBAAA;AAGvB,WAAK,aAAa;AAAA,QAChB,aAAa;AAAA,QACb,QAAQ,EAAE,KAAK,GAAG,MAAM,EAAA;AAAA,QACxB,OAAO;AAAA,UACL,MAAM;AAAA,UAAG,KAAK;AAAA,UAAG,QAAQ;AAAA,UAAG,SAAS;AAAA,UACrC,QAAQ;AAAA,UAAG,SAAS;AAAA,UAAG,UAAU;AAAA,UAAG,YAAY;AAAA,QAAA;AAAA,QAElD,eAAe,IAAI,WAAW,CAAC;AAAA,MAAA;AAGjC,WAAK,KAAK,QAAQ;AAAA,QAChB,GAAG,KAAK;AAAA,QACR,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAAA;AAI1C,WAAK,YAAY,gBAAA;AAEjB,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAAA,IAC/D;AAAA;AAAA,IAGO,0BAAgC;AACrC,WAAK,gBAAgB,wBAAA;AAAA,IACvB;AAAA,IAEQ,uBAA6B;AACnC,WAAK,YAAY,CAAC,UAAuC;AACvD,cAAM,UAAU,MAAM;AAEtB,gBAAQ,QAAQ,MAAA;AAAA,UACd,KAAK;AACH,iBAAK,WAAW,OAAO;AACvB;AAAA,UACF,KAAK;AACH,iBAAK,sBAAsB,OAAO;AAClC;AAAA,UACF,KAAK;AACH,iBAAK,wBAAwB,OAAO;AACpC;AAAA,UACF,KAAK;AACH,iBAAK,uBAAuB,OAAO;AACnC;AAAA,UACI,KAAK;AACX,iBAAK,mBAAmB,OAAO;AAC/B;AAAA,UACF,KAAK;AACH,iBAAK,aAAa,QAAQ,KAAK,OAAO;AACtC;AAAA,UACA,KAAK;AACH,iBAAK,sBAAsB,OAAO;AAClC;AAAA,UACF,KAAK;AACH,iBAAK,2BAA2B,OAAO;AACvC;AAAA,UACF,KAAK;AACH,iBAAK,mBAAmB,OAAO;AAC/B;AAAA,UACF,KAAK;AACH,iBAAK,0BAA0B,OAAO;AACtC;AAAA,UACF,KAAK;AACH,iBAAK,uBAAuB,OAAO;AACnC;AAAA,UACF,KAAK;AACH,iBAAK,uBAAuB,OAAO;AACnC;AAAA,UACF,KAAK;AACH,iBAAK,wBAAwB,OAAO;AACpC;AAAA,UACF,KAAK;AACH,iBAAK,kBAAkB,OAAO;AAC9B;AAAA,UACF,KAAK;AACH,iBAAK,qBAAqB,OAAO;AACjC;AAAA,UACF,KAAK;AACH,iBAAK,kBAAkB,OAAO;AAC9B;AAAA,UACF,KAAK;AACH,iBAAK,yBAAyB,OAAO;AACrC;AAAA,UACF,KAAK;AACH,iBAAK,wBAAwB,OAAO;AACpC;AAAA,UACF,KAAK;AACH,iBAAK,mBAAmB,OAAc;AACtC;AAAA,QAAA;AAAA,MAEN;AAAA,IACF;AAAA,IAEQ,WAAW,SAAkC;AACnD,UAAI;AACF,aAAK,SAAS,QAAQ,KAAK;AAC3B,aAAK,KAAK,SAAS,KAAK;AAGxB,aAAK,KAAK,QAAQ,KAAK,OAAO;AAC9B,aAAK,KAAK,SAAS,KAAK,OAAO;AAG/B,aAAK,gBAAA;AAGL,aAAK,YAAY,SAAS;AAAA,UACxB,IAAI,QAAQ;AAAA,UACZ,YAAY,EAAE,OAAO,KAAK,OAAO,OAAO,QAAQ,KAAK,OAAO,OAAA;AAAA,QAAO,CACpE;AAAA,MACH,SAAS,OAAO;AACd,aAAK,YAAY,SAAS;AAAA,UACxB,IAAI,QAAQ;AAAA,UACZ,SAAU,MAAgB;AAAA,UAC1B,MAAM;AAAA,QAAA,CACP;AAAA,MACH;AAAA,IACF;AAAA,IAEQ,sBAAsB,SAAuC;AACnE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,MAAM;AACrC,aAAK,gBAAgB,QAAQ,KAAK;AAClC,aAAK,SAAS,+BAA+B,QAAQ,KAAK,IAAI;AAAA,MAChE;AAAA,IACF;AAAA,IAEQ,wBAAwB,SAAyC;AACvE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,mBAAmB;AAClD,aAAK,oBAAoB,QAAQ,KAAK;AACtC,aAAK,SAAS,mCAAmC,QAAQ,KAAK,oBAAoB,IAAI;AAAA,MACxF;AAAA,IACF;AAAA,IAEQ,wBAAwB,aAA2B;AAEzD,WAAK,oBAAoB,KAAK,WAAW;AAGzC,UAAI,KAAK,oBAAoB,SAAS,IAAI;AACxC,aAAK,oBAAoB,MAAA;AAAA,MAC3B;AAAA,IACF;AAAA,IAEQ,2BAA2B,aAA2B;AAE5D,UAAI,cAAc,KAAK,2BAA2B,KAAK,6BAA6B;AAClF,YAAI,KAAK,oBAAoB,UAAU,GAAG;AAExC,gBAAM,YAAY,KAAK,oBAAoB,KAAK,oBAAoB,SAAS,CAAC,IAAI,KAAK,oBAAoB,CAAC;AAC5G,gBAAM,aAAa,KAAK,oBAAoB,SAAS;AACrD,gBAAM,uBAAuB,KAAK,MAAO,aAAa,YAAa,GAAI;AAGvE,eAAK,YAAY,sBAAsB;AAAA,YACrC;AAAA,YACA,eAAe,KAAK;AAAA,YACpB,mBAAmB,KAAK;AAAA,YACxB,gBAAgB,KAAK,gBAAgB,kBAAA;AAAA,UAAkB,CACxD;AAAA,QACH;AAEA,aAAK,0BAA0B;AAAA,MACjC;AAAA,IACF;AAAA,IAEQ,uBAAuB,SAAwC;AACrE,UAAI,QAAQ,MAAM;AAEhB,YAAI,KAAK,QAAQ;AACf,eAAK,OAAO,QAAQ,KAAK,MAAM,QAAQ,KAAK,cAAc;AAC1D,eAAK,OAAO,SAAS,KAAK,MAAM,QAAQ,KAAK,eAAe;AAAA,QAC9D;AAGA,aAAK,KAAK,QAAQ,KAAK,MAAM,QAAQ,KAAK,cAAc;AACxD,aAAK,KAAK,SAAS,KAAK,MAAM,QAAQ,KAAK,eAAe;AAG1D,YAAI,KAAK,IAAI;AACX,eAAK,GAAG,SAAS,GAAG,GAAG,KAAK,KAAK,OAAO,KAAK,KAAK,MAAM;AAAA,QAC1D;AAEA,aAAK,SAAS,iCAAiC,KAAK,KAAK,QAAQ,MAAM,KAAK,KAAK,MAAM;AAAA,MACzF;AAAA,IACF;AAAA,IAEQ,sBAAsB,SAAuC;AACnE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,SAAS,UAAa,QAAQ,KAAK,UAAU,QAAW;AACvF,aAAK,gBAAgB,qBAAqB,QAAQ,KAAK,MAAM,QAAQ,KAAK,KAAK;AAAA,MACjF;AAAA,IACF;AAAA,IAEQ,2BAA2B,SAA4C;AAC7E,UAAI,QAAQ,QAAQ,QAAQ,KAAK,SAAS;AACxC,mBAAW,UAAU,QAAQ,KAAK,SAAS;AACzC,eAAK,gBAAgB,qBAAqB,OAAO,MAAM,OAAO,KAAK;AAAA,QACrE;AAGA,aAAK,gBAAgB,wBAAA;AACrB,aAAK,SAAS,2CAA2C;AAAA,MAC3D;AAAA,IACF;AAAA,IAEQ,mBAAmB,SAAoC;AAE7D,WAAK,SAAS,kBAAkB,QAAQ,IAAI;AAAA,IAC9C;AAAA,IAEQ,0BAA0B,SAA2C;AAE3E,WAAK,aAAa;AAAA,QAChB,aAAa,QAAQ,KAAK;AAAA,QAC1B,QAAQ,QAAQ,KAAK;AAAA,QACrB,OAAO,QAAQ,KAAK;AAAA,QACpB,eAAe,QAAQ,KAAK;AAAA,MAAA;AAI9B,WAAK,KAAK,QAAQ;AAAA,QAChB,GAAG,KAAK;AAAA,QACR,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAAA;AAAA,IAE5C;AAAA,IAEQ,uBAAuB,SAA8C;AAE3E,WAAK,YAAY,kBAAkB;AAAA,QACjC,iBAAiB,QAAQ,KAAK;AAAA,QAC9B,OAAO,QAAQ,KAAK;AAAA,QACpB,QAAQ,QAAQ,KAAK;AAAA,QACrB,WAAW,QAAQ,KAAK;AAAA,MAAA,CACzB;AAGD,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAAA,IAC/D;AAAA,IAEQ,uBAAuB,SAA8C;AAE3E,WAAK,YAAY,kBAAkB;AAAA,QACjC,aAAa,QAAQ,KAAK;AAAA,QAC1B,WAAW,QAAQ,KAAK;AAAA,MAAA,CACzB;AAGD,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAAA,IAC/D;AAAA,IAEQ,wBAAwB,SAA+C;AAE7E,WAAK,YAAY,wBAAwB;AAAA,QACvC,GAAI,QAAQ,KAAK,mBAAmB,EAAE,iBAAiB,QAAQ,KAAK,gBAAA;AAAA,QACpE,GAAI,QAAQ,KAAK,YAAY,EAAE,UAAU,QAAQ,KAAK,SAAA;AAAA,QACtD,GAAI,QAAQ,KAAK,SAAS,EAAE,OAAO,QAAQ,KAAK,MAAA;AAAA,QAChD,GAAI,QAAQ,KAAK,UAAU,EAAE,QAAQ,QAAQ,KAAK,OAAA;AAAA,QAClD,GAAI,QAAQ,KAAK,cAAc,EAAE,YAAY,QAAQ,KAAK,WAAA;AAAA,QAC1D,WAAW,QAAQ,KAAK;AAAA,MAAA,CACzB;AAID,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAAA,IAC/D;AAAA,IAEQ,wBAAwB,SAAyC;AAEvE,WAAK,SAAS,uBAAuB,QAAQ,IAAI;AAAA,IACnD;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAc,mBAAmB,SAIf;AAChB,UAAI;AACF,YAAI,CAAC,KAAK,QAAQ;AAChB,gBAAM,IAAI,MAAM,wBAAwB;AAAA,QAC1C;AAEA,cAAM,WAAW,QAAQ,KAAK,QAAQ;AAGtC,cAAM,WAAW,KAAK,OAAO;AAC7B,cAAM,YAAY,KAAK,OAAO;AAC9B,YAAI,cAAc;AAClB,YAAI,eAAe;AAEnB,YAAI,OAAO,QAAQ,KAAK,eAAe,UAAU;AAC/C,gBAAM,QAAQ,QAAQ,KAAK,aAAa,IAAI,QAAQ,KAAK,aAAa;AACtE,wBAAc,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,KAAK,CAAC;AACtD,yBAAe,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,KAAK,CAAC;AAAA,QAC1D,WAAW,QAAQ,KAAK,cAAc,OAAO,QAAQ,KAAK,eAAe,UAAU;AACjF,wBAAc,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,WAAW,KAAK,CAAC;AACnE,yBAAe,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,WAAW,MAAM,CAAC;AAAA,QACvE;AAGA,cAAM,YAAY,WAAW;AAC7B,cAAM,YAAY,cAAc;AAChC,YAAI,KAAK;AACT,YAAI,KAAK;AACT,YAAI,SAAS;AACb,YAAI,UAAU;AAEd,YAAI,KAAK,IAAI,YAAY,SAAS,IAAI,MAAM;AAC1C,cAAI,YAAY,WAAW;AAEzB,sBAAU,KAAK,MAAM,WAAW,SAAS;AACzC,iBAAK,KAAK,OAAO,YAAY,WAAW,CAAC;AAAA,UAC3C,OAAO;AAEL,qBAAS,KAAK,MAAM,YAAY,SAAS;AACzC,iBAAK,KAAK,OAAO,WAAW,UAAU,CAAC;AAAA,UACzC;AAAA,QACF;AAGA,cAAM,OAAO,IAAI,gBAAgB,aAAa,YAAY;AAC1D,cAAM,OAAO,KAAK,WAAW,IAAI;AACjC,YAAI,CAAC,KAAM,OAAM,IAAI,MAAM,0BAA0B;AAErD,aAAK,UAAU,KAAK,QAA2B,IAAI,IAAI,QAAQ,SAAS,GAAG,GAAG,aAAa,YAAY;AAEvG,cAAM,OAAO,MAAM,KAAK,cAAc,EAAE,MAAM,UAAU;AACxD,cAAM,cAAc,MAAM,KAAK,YAAA;AAG9B,aAAa,YAAY;AAAA,UACxB,MAAM;AAAA,UACN,IAAI,QAAQ;AAAA,UACZ,WAAW,KAAK,IAAA;AAAA,UAChB,MAAM;AAAA,YACJ;AAAA,YACA,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,QAAQ;AAAA,UAAA;AAAA,QACV,GACC,CAAC,WAAW,CAAC;AAAA,MAClB,SAAS,OAAO;AACd,aAAK,YAAY,SAAS;AAAA,UACxB,IAAI,QAAQ;AAAA,UACZ,SAAU,MAAgB;AAAA,UAC1B,MAAM;AAAA,QAAA,CACP;AAAA,MACH;AAAA,IACF;AAAA,IAEQ,mBAAmB,SAA0C;AACnE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,WAAW;AAEzC,aAAa,aAAa,QAAQ,KAAK,SAAS;AAAA,MACnD;AAAA,IACF;AAAA,IAEQ,kBAAwB;AAC9B,WAAK,YAAY;AACjB,WAAK,YAAY,YAAY,IAAA;AAC7B,WAAK,WAAW,KAAK;AACrB,WAAK,YAAA;AAAA,IACP;AAAA,IAEO,cAAoB;AACzB,UAAI,CAAC,KAAK,UAAW;AAErB,YAAM,cAAc,YAAY,IAAA;AAGhC,WAAK,kBAAkB,WAAA;AAGvB,WAAK,KAAK,MAAM,KAAK,kBAAkB,SAAS,KAAK,oBAAoB,KAAK,oBAAoB;AAGlG,UAAI,eAAe;AACnB,UAAI,KAAK,kBAAkB,QAAQ;AACjC,uBAAe,CAAC,KAAK;AACrB,aAAK,gBAAgB,CAAC,KAAK;AAAA,MAC7B;AAEA,UAAI,cAAc;AAChB,aAAK,KAAK,aAAa,cAAc,KAAK,YAAY;AACtD,aAAK,KAAK,QAAQ,cAAc,KAAK,aAAa;AAClD,aAAK,KAAK,aAAa,EAAE,KAAK;AAG9B,aAAK,wBAAwB,WAAW;AAExC,aAAK,WAAW;AAEhB,YAAI;AAEF,gBAAMA,kBAAkB,KAAa;AACrC,cAAIA,mBAAkB,OAAOA,oBAAmB,YAAY;AAC1D,YAAAA,gBAAe,KAAK,IAAI;AAAA,UAC1B;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,MAAM,iBAAiB,KAAK;AACpC,eAAK,YAAY,SAAS;AAAA,YACxB,SAAU,MAAgB;AAAA,YAC1B,MAAM;AAAA,YACN,OAAQ,MAAgB;AAAA,UAAA,CACzB;AAAA,QACH;AAAA,MACF;AAGA,WAAK,2BAA2B,WAAW;AAG3C,4BAAsB,MAAM,KAAK,aAAa;AAAA,IAChD;AAAA,IAEQ,YAAY,MAAc,MAAkB;AAClD,WAAK,YAAY;AAAA,QACf;AAAA,QACA,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI,KAAK,KAAK;AAAA,QACrC,WAAW,KAAK,IAAA;AAAA,QAChB;AAAA,MAAA,CACD;AAAA,IACH;AAAA;AAAA,IAIQ,kBAAkB,SAAoB;AAC5C,WAAK,kBAAkB,kBAAkB,QAAQ,IAAI;AAAA,IACvD;AAAA,IAEQ,qBAAqB,SAAoB;AAC/C,WAAK,kBAAkB,qBAAqB,QAAQ,IAAI;AAAA,IAC1D;AAAA,IAEQ,kBAAkB,SAAoB;AAC5C,WAAK,kBAAkB,kBAAkB,QAAQ,IAAI;AAAA,IACvD;AAAA,IAEQ,yBAAyB,SAAoB;AACnD,WAAK,kBAAkB,sBAAsB,QAAQ,KAAK,OAAO;AAAA,IACnE;AAAA,EACF;AC5nBA,QAAM,UAAU,IAAI,kBAAA;AAGpB,MAAI,iBAA+D;AAGnE,WAAS,aAAa,WAAyB;AAC7C,QAAI;AAEF,cAAQ,oBAAA;AAIR,YAAM,eAAe,YAAY;AAMjC,YAAM,gBAAgB,IAAI,SAAS,QAAQ,YAAY;AAEvD,uBAAiB,cAAc,QAAQ,IAAI;AAE1C,WAAa,iBAAiB;AAI/B,cAAQ,wBAAA;AAAA,IACV,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AACjD,WAAK,YAAY;AAAA,QACf,MAAM;AAAA,QACN,IAAI,eAAe,KAAK,IAAA,CAAK;AAAA,QAC7B,WAAW,KAAK,IAAA;AAAA,QAChB,MAAM;AAAA,UACJ,SAAS,qBAAsB,MAAgB,OAAO;AAAA,UACtD,MAAM;AAAA,QAAA;AAAA,MACR,CACD;AAAA,IACH;AAAA,EACF;AAGC,OAAa,eAAe;;"}
|
|
1
|
+
{"version":3,"file":"viji.worker-BKsgIT1d.js","sources":["../src/worker/ParameterSystem.ts","../src/worker/InteractionSystem.ts","../src/worker/VideoSystem.ts","../src/worker/VijiWorkerRuntime.ts","../src/worker/viji.worker.ts"],"sourcesContent":["import { \r\n ParameterGroup, \r\n ParameterDefinition, \r\n ParameterValue,\r\n SliderParameter,\r\n ColorParameter,\r\n ToggleParameter,\r\n SelectParameter,\r\n TextParameter,\r\n NumberParameter,\r\n SliderConfig,\r\n ColorConfig,\r\n ToggleConfig,\r\n SelectConfig,\r\n TextConfig,\r\n NumberConfig\r\n} from '../types/index.js';\r\n\r\nexport class ParameterSystem {\r\n // Parameter system for Phase 2 (new object-based approach)\r\n private parameterDefinitions = new Map<string, ParameterDefinition>();\r\n private parameterGroups = new Map<string, ParameterGroup>();\r\n private parameterValues = new Map<string, ParameterValue>();\r\n private parameterObjects = new Map<string, any>(); // Maps parameter names to their objects\r\n private parametersDefined = false;\r\n private initialValuesSynced = false; // Track if initial values have been synced from host\r\n \r\n // Debug logging control\r\n private debugMode = false;\r\n\r\n /**\r\n * Enable or disable debug logging\r\n */\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n\r\n /**\r\n * Debug logging helper\r\n */\r\n private debugLog(message: string, ...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log(message, ...args);\r\n }\r\n }\r\n\r\n // Message posting callback\r\n private postMessageCallback: (type: string, data?: any) => void;\r\n\r\n constructor(postMessageCallback: (type: string, data?: any) => void) {\r\n this.postMessageCallback = postMessageCallback;\r\n }\r\n\r\n // Parameter helper function implementations (return parameter objects)\r\n public createSliderParameter(defaultValue: number, config: SliderConfig): SliderParameter {\r\n const paramName = config.label;\r\n const sliderObject = {\r\n value: defaultValue,\r\n min: config.min ?? 0,\r\n max: config.max ?? 100,\r\n step: config.step ?? 1,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general',\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'slider',\r\n defaultValue,\r\n label: sliderObject.label,\r\n description: sliderObject.description,\r\n group: sliderObject.group,\r\n category: sliderObject.category,\r\n config: {\r\n min: sliderObject.min,\r\n max: sliderObject.max,\r\n step: sliderObject.step\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, sliderObject);\r\n return sliderObject;\r\n }\r\n\r\n public createColorParameter(defaultValue: string, config: ColorConfig): ColorParameter {\r\n const paramName = config.label;\r\n const colorObject = {\r\n value: defaultValue,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general',\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'color',\r\n defaultValue,\r\n label: colorObject.label,\r\n description: colorObject.description,\r\n group: colorObject.group,\r\n category: colorObject.category,\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, colorObject);\r\n return colorObject;\r\n }\r\n\r\n public createToggleParameter(defaultValue: boolean, config: ToggleConfig): ToggleParameter {\r\n const paramName = config.label;\r\n const toggleObject = {\r\n value: defaultValue,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'toggle',\r\n defaultValue,\r\n label: toggleObject.label,\r\n description: toggleObject.description,\r\n group: toggleObject.group,\r\n category: toggleObject.category\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, toggleObject);\r\n return toggleObject;\r\n }\r\n\r\n public createSelectParameter(defaultValue: string | number, config: SelectConfig): SelectParameter {\r\n const paramName = config.label;\r\n const selectObject = {\r\n value: defaultValue,\r\n options: config.options,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'select',\r\n defaultValue,\r\n label: selectObject.label,\r\n description: selectObject.description,\r\n group: selectObject.group,\r\n category: selectObject.category,\r\n config: {\r\n options: selectObject.options\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, selectObject);\r\n return selectObject;\r\n }\r\n\r\n public createTextParameter(defaultValue: string, config: TextConfig): TextParameter {\r\n const paramName = config.label;\r\n const textObject = {\r\n value: defaultValue,\r\n maxLength: config.maxLength ?? 1000,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'text',\r\n defaultValue,\r\n label: textObject.label,\r\n description: textObject.description,\r\n group: textObject.group,\r\n category: textObject.category,\r\n config: {\r\n maxLength: textObject.maxLength\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, textObject);\r\n return textObject;\r\n }\r\n\r\n public createNumberParameter(defaultValue: number, config: NumberConfig): NumberParameter {\r\n const paramName = config.label;\r\n const numberObject = {\r\n value: defaultValue,\r\n min: config.min ?? 0,\r\n max: config.max ?? 100,\r\n step: config.step ?? 1,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'number',\r\n defaultValue,\r\n label: numberObject.label,\r\n description: numberObject.description,\r\n group: numberObject.group,\r\n category: numberObject.category,\r\n config: {\r\n min: numberObject.min,\r\n max: numberObject.max,\r\n step: numberObject.step\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, numberObject);\r\n return numberObject;\r\n }\r\n\r\n private storeParameterDefinition(name: string, definition: ParameterDefinition): void {\r\n // This is called during scene initialization, not during define()\r\n // We'll collect these and send them when the scene is fully loaded\r\n this.parameterDefinitions.set(name, definition);\r\n this.parameterValues.set(name, definition.defaultValue);\r\n }\r\n\r\n public updateParameterValue(name: string, value: ParameterValue): boolean {\r\n const definition = this.parameterDefinitions.get(name);\r\n if (!definition) {\r\n console.warn(`Unknown parameter: ${name}. Available parameters:`, Array.from(this.parameterDefinitions.keys()));\r\n return false;\r\n }\r\n\r\n // Validation\r\n if (!this.validateParameterValue(name, value, definition)) {\r\n console.warn(`Validation failed for parameter ${name} = ${value}`);\r\n return false;\r\n }\r\n\r\n // Check if value actually changed (but always allow initial sync)\r\n const currentValue = this.parameterValues.get(name);\r\n const isInitialSync = !this.initialValuesSynced; // During initial parameter sync from host\r\n \r\n if (currentValue === value && !isInitialSync) {\r\n return false; // No change (but allow initial sync even if values match)\r\n }\r\n\r\n // Update value in both storage and parameter object\r\n this.parameterValues.set(name, value);\r\n \r\n // Update the parameter object's value property\r\n const parameterObject = this.parameterObjects.get(name);\r\n if (parameterObject) {\r\n parameterObject.value = value;\r\n }\r\n \r\n return true;\r\n }\r\n\r\n private validateParameterValue(name: string, value: ParameterValue, definition: ParameterDefinition): boolean {\r\n // Custom validation function\r\n if (definition.validate && !definition.validate(value)) {\r\n console.error(`Custom validation failed for parameter '${name}': ${value}`);\r\n return false;\r\n }\r\n\r\n // Type validation\r\n switch (definition.type) {\r\n case 'slider':\r\n case 'number':\r\n if (typeof value !== 'number' || isNaN(value)) {\r\n console.error(`Parameter '${name}' must be a number, got: ${value}`);\r\n return false;\r\n }\r\n if (definition.config?.min !== undefined && value < definition.config.min) {\r\n console.error(`Parameter '${name}' value ${value} is below minimum ${definition.config.min}`);\r\n return false;\r\n }\r\n if (definition.config?.max !== undefined && value > definition.config.max) {\r\n console.error(`Parameter '${name}' value ${value} is above maximum ${definition.config.max}`);\r\n return false;\r\n }\r\n break;\r\n case 'color':\r\n if (typeof value !== 'string' || !/^#[0-9A-Fa-f]{6}$/.test(value)) {\r\n console.error(`Parameter '${name}' must be a valid hex color, got: ${value}`);\r\n return false;\r\n }\r\n break;\r\n case 'toggle':\r\n if (typeof value !== 'boolean') {\r\n console.error(`Parameter '${name}' must be a boolean, got: ${value}`);\r\n return false;\r\n }\r\n break;\r\n case 'select':\r\n if (!definition.config?.options || !definition.config.options.includes(value as string & number)) {\r\n console.error(`Parameter '${name}' value ${value} is not in options: ${definition.config?.options}`);\r\n return false;\r\n }\r\n break;\r\n case 'text':\r\n if (typeof value !== 'string') {\r\n console.error(`Parameter '${name}' must be a string, got: ${value}`);\r\n return false;\r\n }\r\n if (definition.config?.maxLength && value.length > definition.config.maxLength) {\r\n console.error(`Parameter '${name}' text too long: ${value.length} > ${definition.config.maxLength}`);\r\n return false;\r\n }\r\n break;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Reset parameter state (called when loading new scene)\r\n public resetParameterState(): void {\r\n this.parametersDefined = false;\r\n this.initialValuesSynced = false;\r\n this.parameterDefinitions.clear();\r\n this.parameterGroups.clear();\r\n this.parameterValues.clear();\r\n this.parameterObjects.clear();\r\n }\r\n\r\n // Send all parameters (from helper functions) to host\r\n public sendAllParametersToHost(): void {\r\n // Don't send if already sent or if no parameters defined\r\n if (this.parametersDefined || this.parameterDefinitions.size === 0) {\r\n return;\r\n }\r\n\r\n try {\r\n // Group parameters by their group property\r\n const groups = new Map<string, ParameterGroup>();\r\n\r\n for (const [paramName, paramDef] of this.parameterDefinitions) {\r\n const groupName = paramDef.group || 'general';\r\n \r\n if (!groups.has(groupName)) {\r\n // Use the parameter's category if available, otherwise default to 'general'\r\n const category = paramDef.category || 'general';\r\n groups.set(groupName, {\r\n groupName,\r\n category,\r\n parameters: {}\r\n });\r\n }\r\n\r\n const group = groups.get(groupName)!;\r\n group.parameters[paramName] = paramDef;\r\n }\r\n\r\n this.parametersDefined = true;\r\n\r\n // Send parameter definitions to host for UI generation\r\n this.postMessageCallback('parameters-defined', {\r\n groups: Array.from(groups.values()),\r\n timestamp: performance.now()\r\n });\r\n\r\n this.debugLog(`All parameters sent to host: ${this.parameterDefinitions.size} parameters in ${groups.size} groups`);\r\n } catch (error) {\r\n this.postMessageCallback('parameter-validation-error', {\r\n message: `Failed to send parameters to host: ${(error as Error).message}`,\r\n code: 'PARAMETER_SENDING_ERROR'\r\n });\r\n }\r\n }\r\n\r\n // Mark initial values as synced\r\n public markInitialValuesSynced(): void {\r\n this.initialValuesSynced = true;\r\n }\r\n\r\n // Get parameter count for performance reporting\r\n public getParameterCount(): number {\r\n return this.parameterDefinitions.size;\r\n }\r\n} ","import { MouseAPI, KeyboardAPI, TouchAPI, TouchPoint } from '../types/index.js';\r\n\r\n/**\r\n * Manages user interaction state and APIs for the worker runtime.\r\n * Handles mouse, keyboard, and touch input processing for Phase 7.\r\n * \r\n * This system provides:\r\n * - Real-time interaction state management\r\n * - Frame-based event processing\r\n * - Clean API generation for artist code\r\n * - Message handling for interaction updates\r\n */\r\nexport class InteractionSystem {\r\n // Interaction enabled state\r\n private isEnabled: boolean = true;\r\n\r\n // Mouse interaction state\r\n private mouseState: MouseAPI = {\r\n x: 0, y: 0,\r\n isInCanvas: false,\r\n isPressed: false,\r\n leftButton: false,\r\n rightButton: false,\r\n middleButton: false,\r\n velocity: { x: 0, y: 0 },\r\n deltaX: 0,\r\n deltaY: 0,\r\n wheelDelta: 0,\r\n wheelX: 0,\r\n wheelY: 0,\r\n wasPressed: false,\r\n wasReleased: false,\r\n wasMoved: false\r\n };\r\n\r\n // Keyboard interaction state\r\n private keyboardState: KeyboardAPI = {\r\n isPressed: (key: string) => this.keyboardState.activeKeys.has(key.toLowerCase()),\r\n wasPressed: (key: string) => this.keyboardState.pressedThisFrame.has(key.toLowerCase()),\r\n wasReleased: (key: string) => this.keyboardState.releasedThisFrame.has(key.toLowerCase()),\r\n activeKeys: new Set<string>(),\r\n pressedThisFrame: new Set<string>(),\r\n releasedThisFrame: new Set<string>(),\r\n lastKeyPressed: '',\r\n lastKeyReleased: '',\r\n shift: false,\r\n ctrl: false,\r\n alt: false,\r\n meta: false\r\n };\r\n\r\n // Touch interaction state\r\n private touchState: TouchAPI = {\r\n points: [],\r\n count: 0,\r\n started: [],\r\n moved: [],\r\n ended: [],\r\n primary: null,\r\n gestures: {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n }\r\n };\r\n\r\n constructor() {\r\n // Bind methods for proper context when used as callbacks\r\n this.handleMouseUpdate = this.handleMouseUpdate.bind(this);\r\n this.handleKeyboardUpdate = this.handleKeyboardUpdate.bind(this);\r\n this.handleTouchUpdate = this.handleTouchUpdate.bind(this);\r\n this.frameStart = this.frameStart.bind(this);\r\n }\r\n\r\n /**\r\n * Get the interaction APIs for inclusion in the viji object\r\n */\r\n public getInteractionAPIs() {\r\n return {\r\n mouse: this.mouseState,\r\n keyboard: this.keyboardState,\r\n touches: this.touchState\r\n };\r\n }\r\n\r\n /**\r\n * Called at the start of each frame to reset frame-based events\r\n */\r\n public frameStart(): void {\r\n // Reset mouse frame events\r\n this.mouseState.wasPressed = false;\r\n this.mouseState.wasReleased = false;\r\n this.mouseState.wasMoved = false;\r\n this.mouseState.wheelDelta = 0;\r\n this.mouseState.wheelX = 0;\r\n this.mouseState.wheelY = 0;\r\n\r\n // Reset keyboard frame events\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n\r\n // Reset touch frame events\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.gestures.isTapping = false;\r\n this.touchState.gestures.pinchDelta = 0;\r\n this.touchState.gestures.rotationDelta = 0;\r\n }\r\n\r\n /**\r\n * Handle mouse update messages from the host\r\n */\r\n public handleMouseUpdate(data: {\r\n x: number;\r\n y: number;\r\n buttons: number;\r\n deltaX: number;\r\n deltaY: number;\r\n wheelDeltaX: number;\r\n wheelDeltaY: number;\r\n isInCanvas?: boolean;\r\n timestamp: number;\r\n wasPressed?: boolean;\r\n wasReleased?: boolean;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n // Update mouse position and button states\r\n this.mouseState.x = data.x;\r\n this.mouseState.y = data.y;\r\n this.mouseState.isInCanvas = data.isInCanvas !== undefined ? data.isInCanvas : true;\r\n this.mouseState.leftButton = (data.buttons & 1) !== 0;\r\n this.mouseState.rightButton = (data.buttons & 2) !== 0;\r\n this.mouseState.middleButton = (data.buttons & 4) !== 0;\r\n this.mouseState.isPressed = data.buttons > 0;\r\n \r\n // Update movement deltas and wheel\r\n this.mouseState.deltaX = data.deltaX || 0;\r\n this.mouseState.deltaY = data.deltaY || 0;\r\n this.mouseState.wheelDelta = data.wheelDeltaY || 0;\r\n this.mouseState.wheelX = data.wheelDeltaX || 0;\r\n this.mouseState.wheelY = data.wheelDeltaY || 0;\r\n \r\n // Update velocity (smoothed in InteractionManager)\r\n this.mouseState.velocity.x = data.deltaX || 0;\r\n this.mouseState.velocity.y = data.deltaY || 0;\r\n \r\n // Frame-based events (calculated in InteractionManager or provided by host)\r\n this.mouseState.wasPressed = data.wasPressed || false;\r\n this.mouseState.wasReleased = data.wasReleased || false;\r\n this.mouseState.wasMoved = (data.deltaX !== 0 || data.deltaY !== 0);\r\n }\r\n\r\n /**\r\n * Handle keyboard update messages from the host\r\n */\r\n public handleKeyboardUpdate(data: {\r\n type: 'keydown' | 'keyup';\r\n key: string;\r\n code: string;\r\n shiftKey: boolean;\r\n ctrlKey: boolean;\r\n altKey: boolean;\r\n metaKey: boolean;\r\n timestamp: number;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n const key = data.key.toLowerCase();\r\n \r\n if (data.type === 'keydown') {\r\n if (!this.keyboardState.activeKeys.has(key)) {\r\n this.keyboardState.activeKeys.add(key);\r\n this.keyboardState.pressedThisFrame.add(key);\r\n this.keyboardState.lastKeyPressed = data.key;\r\n }\r\n } else if (data.type === 'keyup') {\r\n this.keyboardState.activeKeys.delete(key);\r\n this.keyboardState.releasedThisFrame.add(key);\r\n this.keyboardState.lastKeyReleased = data.key;\r\n }\r\n \r\n // Update modifier keys\r\n this.keyboardState.shift = data.shiftKey;\r\n this.keyboardState.ctrl = data.ctrlKey;\r\n this.keyboardState.alt = data.altKey;\r\n this.keyboardState.meta = data.metaKey;\r\n }\r\n\r\n /**\r\n * Handle touch update messages from the host\r\n */\r\n public handleTouchUpdate(data: {\r\n type: 'touchstart' | 'touchmove' | 'touchend' | 'touchcancel';\r\n touches: Array<{\r\n identifier: number;\r\n clientX: number;\r\n clientY: number;\r\n pressure: number;\r\n radiusX: number;\r\n radiusY: number;\r\n rotationAngle: number;\r\n force: number;\r\n }>;\r\n timestamp: number;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n // Clear frame-based touch events\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n \r\n // Convert touch data to our TouchPoint format\r\n const touches: TouchPoint[] = data.touches.map((touch) => ({\r\n id: touch.identifier,\r\n x: touch.clientX,\r\n y: touch.clientY,\r\n pressure: touch.pressure || 0,\r\n radius: Math.max(touch.radiusX || 0, touch.radiusY || 0),\r\n radiusX: touch.radiusX || 0,\r\n radiusY: touch.radiusY || 0,\r\n rotationAngle: touch.rotationAngle || 0,\r\n force: touch.force || touch.pressure || 0,\r\n deltaX: 0, // Could be calculated if we track previous positions\r\n deltaY: 0,\r\n velocity: { x: 0, y: 0 }, // Could be calculated if we track movement\r\n isNew: data.type === 'touchstart',\r\n isActive: true,\r\n isEnding: data.type === 'touchend' || data.type === 'touchcancel'\r\n }));\r\n \r\n // Update touch state\r\n this.touchState.points = touches;\r\n this.touchState.count = touches.length;\r\n this.touchState.primary = touches[0] || null;\r\n \r\n // Set frame-based events based on message type\r\n if (data.type === 'touchstart') {\r\n this.touchState.started = touches;\r\n } else if (data.type === 'touchmove') {\r\n this.touchState.moved = touches;\r\n } else if (data.type === 'touchend' || data.type === 'touchcancel') {\r\n this.touchState.ended = touches;\r\n }\r\n \r\n // Note: Advanced gesture recognition is handled in the InteractionManager\r\n // on the host side. For now, we provide basic gesture state structure.\r\n // In the future, we could move gesture recognition here or receive \r\n // gesture data from the host.\r\n this.touchState.gestures = {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n };\r\n }\r\n\r\n /**\r\n * Reset all interaction state (called when loading new scene)\r\n */\r\n public resetInteractionState(): void {\r\n // Reset mouse state\r\n Object.assign(this.mouseState, {\r\n x: 0, y: 0,\r\n isInCanvas: false,\r\n isPressed: false,\r\n leftButton: false,\r\n rightButton: false,\r\n middleButton: false,\r\n velocity: { x: 0, y: 0 },\r\n deltaX: 0,\r\n deltaY: 0,\r\n wheelDelta: 0,\r\n wheelX: 0,\r\n wheelY: 0,\r\n wasPressed: false,\r\n wasReleased: false,\r\n wasMoved: false\r\n });\r\n\r\n // Reset keyboard state\r\n this.keyboardState.activeKeys.clear();\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n this.keyboardState.lastKeyPressed = '';\r\n this.keyboardState.lastKeyReleased = '';\r\n this.keyboardState.shift = false;\r\n this.keyboardState.ctrl = false;\r\n this.keyboardState.alt = false;\r\n this.keyboardState.meta = false;\r\n\r\n // Reset touch state\r\n this.touchState.points = [];\r\n this.touchState.count = 0;\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.primary = null;\r\n Object.assign(this.touchState.gestures, {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n });\r\n }\r\n\r\n /**\r\n * Enable or disable interaction processing\r\n */\r\n public setInteractionEnabled(enabled: boolean): void {\r\n this.isEnabled = enabled;\r\n \r\n // If disabled, reset all interaction states to prevent stale data\r\n if (!enabled) {\r\n this.resetInteractionStates();\r\n }\r\n }\r\n\r\n /**\r\n * Get current interaction enabled state\r\n */\r\n public getInteractionEnabled(): boolean {\r\n return this.isEnabled;\r\n }\r\n\r\n /**\r\n * Reset all interaction states to default values\r\n */\r\n private resetInteractionStates(): void {\r\n // Reset mouse state\r\n this.mouseState.x = 0;\r\n this.mouseState.y = 0;\r\n this.mouseState.isInCanvas = false;\r\n this.mouseState.isPressed = false;\r\n this.mouseState.leftButton = false;\r\n this.mouseState.rightButton = false;\r\n this.mouseState.middleButton = false;\r\n this.mouseState.velocity.x = 0;\r\n this.mouseState.velocity.y = 0;\r\n this.mouseState.deltaX = 0;\r\n this.mouseState.deltaY = 0;\r\n this.mouseState.wheelDelta = 0;\r\n this.mouseState.wheelX = 0;\r\n this.mouseState.wheelY = 0;\r\n this.mouseState.wasPressed = false;\r\n this.mouseState.wasReleased = false;\r\n this.mouseState.wasMoved = false;\r\n\r\n // Reset keyboard state\r\n this.keyboardState.activeKeys.clear();\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n this.keyboardState.lastKeyPressed = '';\r\n this.keyboardState.lastKeyReleased = '';\r\n this.keyboardState.shift = false;\r\n this.keyboardState.ctrl = false;\r\n this.keyboardState.alt = false;\r\n this.keyboardState.meta = false;\r\n\r\n // Reset touch state\r\n this.touchState.points = [];\r\n this.touchState.count = 0;\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.primary = null;\r\n this.touchState.gestures.isPinching = false;\r\n this.touchState.gestures.isRotating = false;\r\n this.touchState.gestures.isPanning = false;\r\n this.touchState.gestures.isTapping = false;\r\n this.touchState.gestures.pinchScale = 1;\r\n this.touchState.gestures.pinchDelta = 0;\r\n this.touchState.gestures.rotationAngle = 0;\r\n this.touchState.gestures.rotationDelta = 0;\r\n this.touchState.gestures.panDelta = { x: 0, y: 0 };\r\n this.touchState.gestures.tapCount = 0;\r\n this.touchState.gestures.lastTapTime = 0;\r\n this.touchState.gestures.tapPosition = null;\r\n }\r\n} ","/**\r\n * Worker-side Video System for Phase 10 - CORRECT OffscreenCanvas Implementation\r\n * \r\n * CORRECT Approach:\r\n * 1. Host creates OffscreenCanvas (no context!)\r\n * 2. Host transfers OffscreenCanvas to worker\r\n * 3. Worker receives OffscreenCanvas and gets context\r\n * 4. Host sends ImageBitmap frames to worker\r\n * 5. Worker draws ImageBitmap frames to its OffscreenCanvas\r\n * 6. Worker performs all analysis and effects on OffscreenCanvas\r\n * \r\n * This provides:\r\n * - True worker-side processing with full GPU access\r\n * - Zero-copy OffscreenCanvas ownership transfer\r\n * - Optimal performance for CV and artist effects\r\n * - Proper separation: host = coordination, worker = processing\r\n */\r\nexport class VideoSystem {\r\n // ✅ CORRECT: Worker-owned OffscreenCanvas (transferred from host)\r\n private offscreenCanvas: OffscreenCanvas | null = null;\r\n private ctx: OffscreenCanvasRenderingContext2D | null = null;\r\n private gl: WebGLRenderingContext | WebGL2RenderingContext | null = null;\r\n \r\n // Debug logging control\r\n private debugMode = false;\r\n\r\n /**\r\n * Enable or disable debug logging\r\n */\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n\r\n /**\r\n * Debug logging helper\r\n */\r\n private debugLog(message: string, ...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log(message, ...args);\r\n }\r\n }\r\n \r\n // Frame processing configuration\r\n private targetFrameRate = 30; // Default target FPS for video processing\r\n private lastFrameTime = 0;\r\n private frameInterval = 1000 / this.targetFrameRate; // ms between frames\r\n \r\n // Processing state\r\n private hasLoggedFirstFrame = false;\r\n private frameCount = 0;\r\n \r\n // Video state for artist API\r\n private videoState = {\r\n isConnected: false,\r\n currentFrame: null as OffscreenCanvas | null,\r\n frameWidth: 0,\r\n frameHeight: 0,\r\n frameRate: 0,\r\n frameData: null as ImageData | null\r\n };\r\n \r\n // Phase 11 preparation - CV processing placeholder\r\n private cvFeatures = {\r\n faceDetection: false,\r\n handTracking: false,\r\n bodySegmentation: false\r\n };\r\n \r\n private cvResults = {\r\n faces: [] as any[],\r\n hands: [] as any[],\r\n bodySegmentation: null as any\r\n };\r\n\r\n constructor() {\r\n // VideoSystem ready for OffscreenCanvas processing\r\n }\r\n\r\n /**\r\n * Get the video API for inclusion in the viji object\r\n */\r\n public getVideoAPI() {\r\n return {\r\n isConnected: this.videoState.isConnected,\r\n currentFrame: this.videoState.currentFrame,\r\n frameWidth: this.videoState.frameWidth,\r\n frameHeight: this.videoState.frameHeight,\r\n frameRate: this.videoState.frameRate,\r\n getFrameData: () => this.videoState.frameData,\r\n faces: this.cvResults.faces,\r\n hands: this.cvResults.hands\r\n };\r\n }\r\n\r\n /**\r\n * ✅ CORRECT: Receive OffscreenCanvas transfer from host\r\n */\r\n public handleCanvasSetup(data: {\r\n offscreenCanvas: OffscreenCanvas;\r\n width: number;\r\n height: number;\r\n timestamp: number;\r\n }): void {\r\n try {\r\n // Clean up existing canvas\r\n this.disconnectVideo();\r\n \r\n // ✅ CORRECT: Receive transferred OffscreenCanvas\r\n this.offscreenCanvas = data.offscreenCanvas;\r\n \r\n // ✅ CORRECT: Get context on WORKER side (not host!)\r\n this.ctx = this.offscreenCanvas.getContext('2d', {\r\n willReadFrequently: true // Optimize for frequent getImageData calls\r\n });\r\n \r\n if (!this.ctx) {\r\n throw new Error('Failed to get 2D context from transferred OffscreenCanvas');\r\n }\r\n \r\n // Optional: Get WebGL context for advanced effects\r\n // Note: We can have multiple contexts on the same canvas\r\n try {\r\n this.gl = this.offscreenCanvas.getContext('webgl2') || this.offscreenCanvas.getContext('webgl');\r\n } catch (e) {\r\n // WebGL not available, continue with 2D\r\n this.debugLog('WebGL not available, using 2D context only');\r\n }\r\n \r\n // Update state\r\n this.videoState.isConnected = true;\r\n this.videoState.currentFrame = this.offscreenCanvas;\r\n this.videoState.frameWidth = data.width;\r\n this.videoState.frameHeight = data.height;\r\n this.frameCount = 0;\r\n this.hasLoggedFirstFrame = false;\r\n \r\n this.debugLog('✅ OffscreenCanvas received and setup completed (worker-side)', {\r\n width: data.width,\r\n height: data.height,\r\n hasWebGL: !!this.gl,\r\n targetFrameRate: this.targetFrameRate\r\n });\r\n \r\n this.debugLog('🎬 CORRECT OffscreenCanvas approach - Worker has full GPU access!');\r\n \r\n } catch (error) {\r\n console.error('Failed to setup OffscreenCanvas in worker:', error);\r\n this.disconnectVideo();\r\n }\r\n }\r\n\r\n /**\r\n * ✅ CORRECT: Receive ImageBitmap frame and draw to worker's OffscreenCanvas\r\n */\r\n public handleFrameUpdate(data: {\r\n imageBitmap: ImageBitmap;\r\n timestamp: number;\r\n }): void {\r\n if (!this.offscreenCanvas || !this.ctx) {\r\n console.warn('🔴 Received frame but OffscreenCanvas not setup');\r\n return;\r\n }\r\n \r\n try {\r\n // Log occasionally to avoid spam (very rarely now that it's working)\r\n if (this.frameCount % 150 === 0) { // Log every 150th frame (~5 seconds at 30fps)\r\n this.debugLog('✅ Worker received ImageBitmap frame:', {\r\n bitmapSize: `${data.imageBitmap.width}x${data.imageBitmap.height}`,\r\n canvasSize: `${this.offscreenCanvas.width}x${this.offscreenCanvas.height}`,\r\n frameCount: this.frameCount,\r\n timestamp: data.timestamp\r\n });\r\n }\r\n \r\n // ✅ CORRECT: Worker draws ImageBitmap to its OffscreenCanvas\r\n this.ctx.drawImage(data.imageBitmap, 0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);\r\n \r\n // Update frame processing\r\n this.processCurrentFrame(data.timestamp);\r\n \r\n // Close the transferred ImageBitmap to free memory\r\n data.imageBitmap.close();\r\n \r\n this.frameCount++;\r\n \r\n } catch (error) {\r\n console.error('🔴 Error processing video frame (worker-side):', error);\r\n }\r\n }\r\n\r\n /**\r\n * Process current frame (called when new frame is drawn)\r\n */\r\n private processCurrentFrame(timestamp: number): void {\r\n if (!this.offscreenCanvas || !this.ctx) {\r\n return;\r\n }\r\n \r\n try {\r\n // Get current frame data for analysis\r\n this.videoState.frameData = this.ctx.getImageData(\r\n 0, 0, \r\n this.offscreenCanvas.width, \r\n this.offscreenCanvas.height\r\n );\r\n \r\n // Calculate frame rate based on frame arrival\r\n const deltaTime = timestamp - this.lastFrameTime;\r\n this.videoState.frameRate = deltaTime > 0 ? 1000 / deltaTime : 0;\r\n \r\n // Log first successful frame processing (once)\r\n if (!this.hasLoggedFirstFrame) {\r\n this.debugLog(`🎯 Worker-side OffscreenCanvas processing active: ${this.videoState.frameRate.toFixed(1)} FPS (${this.offscreenCanvas.width}x${this.offscreenCanvas.height})`);\r\n this.debugLog('✅ Full GPU access available for custom effects and CV analysis');\r\n this.hasLoggedFirstFrame = true;\r\n }\r\n \r\n // Phase 11 preparation - Perform CV analysis (placeholder)\r\n this.performCVAnalysis();\r\n \r\n this.lastFrameTime = timestamp;\r\n } catch (error) {\r\n console.error('Error processing video frame (worker-side):', error);\r\n }\r\n }\r\n\r\n /**\r\n * Handle video configuration updates (including disconnection and resize)\r\n */\r\n public handleVideoConfigUpdate(data: {\r\n targetFrameRate?: number;\r\n cvConfig?: any;\r\n width?: number;\r\n height?: number;\r\n disconnect?: boolean;\r\n timestamp: number;\r\n }): void {\r\n try {\r\n // Handle disconnection\r\n if (data.disconnect) {\r\n this.disconnectVideo();\r\n return;\r\n }\r\n \r\n // Handle resize\r\n if (data.width && data.height && this.offscreenCanvas) {\r\n this.resizeCanvas(data.width, data.height);\r\n }\r\n \r\n // Update processing configuration if provided\r\n if (data.targetFrameRate) {\r\n this.updateProcessingConfig(data.targetFrameRate);\r\n }\r\n \r\n // Phase 11 preparation - CV config\r\n if (data.cvConfig) {\r\n this.updateCVConfig(data.cvConfig);\r\n }\r\n } catch (error) {\r\n console.error('Error handling video config update:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Resize the OffscreenCanvas (when video dimensions change)\r\n */\r\n private resizeCanvas(width: number, height: number): void {\r\n if (!this.offscreenCanvas) return;\r\n \r\n try {\r\n // Resize the OffscreenCanvas\r\n this.offscreenCanvas.width = width;\r\n this.offscreenCanvas.height = height;\r\n \r\n // Update state\r\n this.videoState.frameWidth = width;\r\n this.videoState.frameHeight = height;\r\n \r\n // Reset WebGL viewport if available\r\n if (this.gl) {\r\n this.gl.viewport(0, 0, width, height);\r\n }\r\n \r\n this.debugLog(`📐 OffscreenCanvas resized to ${width}x${height} (worker-side)`);\r\n \r\n } catch (error) {\r\n console.error('Error resizing OffscreenCanvas:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect video and clean up resources\r\n */\r\n private disconnectVideo(): void {\r\n // ✅ Clear the OffscreenCanvas before disconnecting\r\n if (this.offscreenCanvas && this.ctx) {\r\n this.ctx.clearRect(0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);\r\n this.debugLog('🧹 Cleared OffscreenCanvas on disconnect');\r\n }\r\n \r\n // Clear canvas references\r\n this.offscreenCanvas = null;\r\n this.ctx = null;\r\n this.gl = null;\r\n \r\n // Update state\r\n this.videoState.isConnected = false;\r\n this.videoState.currentFrame = null;\r\n this.videoState.frameWidth = 0;\r\n this.videoState.frameHeight = 0;\r\n this.videoState.frameRate = 0;\r\n this.videoState.frameData = null;\r\n this.resetCVResults();\r\n this.hasLoggedFirstFrame = false;\r\n this.frameCount = 0;\r\n \r\n this.debugLog('Video disconnected (worker-side)');\r\n }\r\n\r\n /**\r\n * Update video processing configuration\r\n */\r\n private updateProcessingConfig(targetFrameRate: number): void {\r\n this.targetFrameRate = Math.max(1, Math.min(60, targetFrameRate)); // Clamp between 1-60 FPS\r\n this.frameInterval = 1000 / this.targetFrameRate;\r\n \r\n this.debugLog(`Video processing frame rate updated to ${this.targetFrameRate} FPS (worker-side)`);\r\n }\r\n\r\n /**\r\n * Phase 11 preparation - Update CV configuration\r\n */\r\n private updateCVConfig(cvConfig: any): void {\r\n // Placeholder for Phase 11 - Computer vision configuration\r\n this.cvFeatures = {\r\n faceDetection: cvConfig.faceDetection || false,\r\n handTracking: cvConfig.handTracking || false,\r\n bodySegmentation: cvConfig.bodySegmentation || false\r\n };\r\n \r\n this.debugLog('CV configuration updated (Phase 11 preparation, worker-side):', this.cvFeatures);\r\n }\r\n\r\n /**\r\n * Phase 11 preparation - Perform computer vision analysis\r\n */\r\n private performCVAnalysis(): void {\r\n // Placeholder for Phase 11 - Computer vision processing\r\n // This will include face detection, hand tracking, body segmentation\r\n \r\n if (this.cvFeatures.faceDetection) {\r\n // TODO Phase 11: Face detection using MediaPipe or TensorFlow.js\r\n // this.cvResults.faces = await detectFaces(this.videoState.frameData);\r\n }\r\n \r\n if (this.cvFeatures.handTracking) {\r\n // TODO Phase 11: Hand tracking using MediaPipe\r\n // this.cvResults.hands = await detectHands(this.videoState.frameData);\r\n }\r\n \r\n if (this.cvFeatures.bodySegmentation) {\r\n // TODO Phase 11: Body segmentation using TensorFlow.js\r\n // this.cvResults.bodySegmentation = await segmentBody(this.videoState.frameData);\r\n }\r\n }\r\n\r\n /**\r\n * Reset CV results\r\n */\r\n private resetCVResults(): void {\r\n this.cvResults = {\r\n faces: [],\r\n hands: [],\r\n bodySegmentation: null\r\n };\r\n }\r\n\r\n /**\r\n * Reset all video state (called when loading new scene)\r\n */\r\n public resetVideoState(): void {\r\n this.disconnectVideo();\r\n this.resetCVResults();\r\n }\r\n\r\n /**\r\n * Get current processing configuration\r\n */\r\n public getProcessingConfig(): { targetFrameRate: number; frameInterval: number; frameCount: number } {\r\n return {\r\n targetFrameRate: this.targetFrameRate,\r\n frameInterval: this.frameInterval,\r\n frameCount: this.frameCount\r\n };\r\n }\r\n\r\n /**\r\n * Get WebGL context for advanced effects (if available)\r\n */\r\n public getWebGLContext(): WebGLRenderingContext | WebGL2RenderingContext | null {\r\n return this.gl;\r\n }\r\n\r\n /**\r\n * ✅ WORKER API: Artists can access the OffscreenCanvas directly for custom effects\r\n */\r\n public getCanvasForArtistEffects(): OffscreenCanvas | null {\r\n return this.offscreenCanvas;\r\n }\r\n} ","import { \n WorkerMessage, \n WorkerInitMessage, \n WorkerFrameRateMessage, \n WorkerRefreshRateMessage, \n WorkerResolutionMessage, \n WorkerParameterMessage, \n WorkerParameterBatchMessage, \n WorkerStreamMessage, \n WorkerAudioAnalysisMessage,\n WorkerVideoCanvasSetupMessage,\n WorkerVideoFrameUpdateMessage,\n WorkerVideoConfigUpdateMessage,\n WorkerPerformanceMessage, \n WorkerSetSceneCodeMessage \n} from './types.js';\nimport { \n SliderConfig, \n ColorConfig, \n ToggleConfig, \n SelectConfig, \n TextConfig, \n NumberConfig \n} from '../types/index.js';\nimport { ParameterSystem } from './ParameterSystem.js';\nimport { InteractionSystem } from './InteractionSystem.js';\nimport { VideoSystem } from './VideoSystem.js';\n\n// Viji Worker Runtime Implementation\nexport class VijiWorkerRuntime {\n private canvas: OffscreenCanvas | null = null;\n private ctx: OffscreenCanvasRenderingContext2D | null = null;\n private gl: WebGLRenderingContext | WebGL2RenderingContext | null = null;\n private isRunning = false;\n private frameCount = 0;\n private lastTime = 0;\n private startTime = 0;\n private frameRateMode: 'full' | 'half' = 'full';\n private skipNextFrame = false;\n private screenRefreshRate = 60; // Will be detected\n \n // Debug logging control\n private debugMode = false;\n\n /**\n * Enable or disable debug logging\n */\n setDebugMode(enabled: boolean): void {\n this.debugMode = enabled;\n // Propagate to child systems\n if (this.videoSystem) this.videoSystem.setDebugMode(enabled);\n if (this.parameterSystem && 'setDebugMode' in this.parameterSystem) {\n (this.parameterSystem as any).setDebugMode(enabled);\n }\n if (this.interactionSystem && 'setDebugMode' in this.interactionSystem) {\n (this.interactionSystem as any).setDebugMode(enabled);\n }\n }\n\n /**\n * Debug logging helper\n */\n private debugLog(message: string, ...args: any[]): void {\n if (this.debugMode) {\n console.log(message, ...args);\n }\n }\n \n // Effective refresh rate tracking\n private effectiveFrameTimes: number[] = [];\n private lastEffectiveRateReport = 0;\n private effectiveRateReportInterval = 1000; // Report every 1 second\n\n // Parameter system\n private parameterSystem: ParameterSystem;\n \n // Interaction system (Phase 7)\n private interactionSystem: InteractionSystem;\n \n // Video system (Phase 10) - worker-side video processing\n private videoSystem: VideoSystem;\n \n // Audio state (Phase 5) - receives analysis results from host\n private audioState = {\n isConnected: false,\n volume: { rms: 0, peak: 0 },\n bands: {\n bass: 0, mid: 0, treble: 0, subBass: 0, \n lowMid: 0, highMid: 0, presence: 0, brilliance: 0\n },\n frequencyData: new Uint8Array(0)\n };\n\n // Video state is now managed by the worker-side VideoSystem\n \n // Artist API object\n public viji = {\n // Canvas (will be set during init)\n canvas: null as OffscreenCanvas | null,\n ctx: null as OffscreenCanvasRenderingContext2D | null,\n gl: null as WebGLRenderingContext | WebGL2RenderingContext | null,\n width: 0,\n height: 0,\n pixelRatio: 1,\n \n // Timing\n time: 0,\n deltaTime: 0,\n frameCount: 0,\n fps: 60,\n \n // Audio API (Phase 5) - will be set in constructor\n audio: {} as any,\n \n video: {\n isConnected: false,\n currentFrame: null as OffscreenCanvas | null,\n frameWidth: 0,\n frameHeight: 0,\n frameRate: 0,\n getFrameData: () => null,\n faces: [] as any[],\n hands: [] as any[]\n },\n \n // Interaction APIs will be added during construction\n mouse: {} as any,\n keyboard: {} as any,\n touches: {} as any,\n \n // Parameter helper functions (return parameter objects) - delegate to parameter system\n slider: (defaultValue: number, config: SliderConfig) => {\n return this.parameterSystem.createSliderParameter(defaultValue, config);\n },\n \n color: (defaultValue: string, config: ColorConfig) => {\n return this.parameterSystem.createColorParameter(defaultValue, config);\n },\n \n toggle: (defaultValue: boolean, config: ToggleConfig) => {\n return this.parameterSystem.createToggleParameter(defaultValue, config);\n },\n \n select: (defaultValue: string | number, config: SelectConfig) => {\n return this.parameterSystem.createSelectParameter(defaultValue, config);\n },\n \n text: (defaultValue: string, config: TextConfig) => {\n return this.parameterSystem.createTextParameter(defaultValue, config);\n },\n \n number: (defaultValue: number, config: NumberConfig) => {\n return this.parameterSystem.createNumberParameter(defaultValue, config);\n },\n \n // Context selection\n useContext: (type: '2d' | 'webgl'): OffscreenCanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext | null => {\n if (type === '2d') {\n if (!this.ctx && this.canvas) {\n this.ctx = this.canvas.getContext('2d');\n this.viji.ctx = this.ctx;\n }\n return this.ctx;\n } else if (type === 'webgl') {\n if (!this.gl && this.canvas) {\n this.gl = this.canvas.getContext('webgl2') || this.canvas.getContext('webgl');\n this.viji.gl = this.gl;\n \n // Set initial WebGL viewport\n if (this.gl) {\n this.gl.viewport(0, 0, this.viji.width, this.viji.height);\n }\n }\n return this.gl;\n }\n return null;\n }\n };\n \n constructor() {\n // Initialize parameter system with post message callback\n this.parameterSystem = new ParameterSystem((type: string, data?: any) => {\n this.postMessage(type, data);\n });\n \n // Initialize interaction system\n this.interactionSystem = new InteractionSystem();\n \n // Initialize video system (Phase 10)\n this.videoSystem = new VideoSystem();\n \n // Integrate APIs into viji object\n Object.assign(this.viji, this.interactionSystem.getInteractionAPIs());\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n \n // Initialize audio API with getFrequencyData function\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n \n this.setupMessageHandling();\n }\n\n // Reset parameter state (called when loading new scene)\n public resetParameterState(): void {\n this.parameterSystem.resetParameterState();\n this.interactionSystem.resetInteractionState();\n \n // Reset audio state\n this.audioState = {\n isConnected: false,\n volume: { rms: 0, peak: 0 },\n bands: {\n bass: 0, mid: 0, treble: 0, subBass: 0, \n lowMid: 0, highMid: 0, presence: 0, brilliance: 0\n },\n frequencyData: new Uint8Array(0)\n };\n // Update viji.audio reference\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n \n // Reset video system\n this.videoSystem.resetVideoState();\n // Update viji.video reference\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n // Send all parameters (from helper functions) to host\n public sendAllParametersToHost(): void {\n this.parameterSystem.sendAllParametersToHost();\n }\n \n private setupMessageHandling(): void {\n self.onmessage = (event: MessageEvent<WorkerMessage>) => {\n const message = event.data;\n \n switch (message.type) {\n case 'init':\n this.handleInit(message);\n break;\n case 'frame-rate-update':\n this.handleFrameRateUpdate(message);\n break;\n case 'refresh-rate-update':\n this.handleRefreshRateUpdate(message);\n break;\n case 'resolution-update':\n this.handleResolutionUpdate(message);\n break;\n case 'set-scene-code':\n this.handleSetSceneCode(message);\n break;\n case 'debug-mode':\n this.setDebugMode(message.data.enabled);\n break;\n case 'parameter-update':\n this.handleParameterUpdate(message);\n break;\n case 'parameter-batch-update':\n this.handleParameterBatchUpdate(message);\n break;\n case 'stream-update':\n this.handleStreamUpdate(message);\n break;\n case 'audio-analysis-update':\n this.handleAudioAnalysisUpdate(message);\n break;\n case 'video-canvas-setup':\n this.handleVideoCanvasSetup(message);\n break;\n case 'video-frame-update':\n this.handleVideoFrameUpdate(message);\n break;\n case 'video-config-update':\n this.handleVideoConfigUpdate(message);\n break;\n case 'mouse-update':\n this.handleMouseUpdate(message);\n break;\n case 'keyboard-update':\n this.handleKeyboardUpdate(message);\n break;\n case 'touch-update':\n this.handleTouchUpdate(message);\n break;\n case 'interaction-enabled':\n this.handleInteractionEnabled(message);\n break;\n case 'performance-update':\n this.handlePerformanceUpdate(message);\n break;\n case 'capture-frame':\n this.handleCaptureFrame(message as any);\n break;\n }\n };\n }\n \n private handleInit(message: WorkerInitMessage): void {\n try {\n this.canvas = message.data.canvas;\n this.viji.canvas = this.canvas;\n \n // Set initial effective resolution (same as canvas size initially)\n this.viji.width = this.canvas.width;\n this.viji.height = this.canvas.height;\n \n // Start render loop\n this.startRenderLoop();\n \n // Send ready response\n this.postMessage('ready', { \n id: message.id,\n canvasSize: { width: this.canvas.width, height: this.canvas.height }\n });\n } catch (error) {\n this.postMessage('error', {\n id: message.id,\n message: (error as Error).message,\n code: 'INIT_ERROR'\n });\n }\n }\n \n private handleFrameRateUpdate(message: WorkerFrameRateMessage): void {\n if (message.data && message.data.mode) {\n this.frameRateMode = message.data.mode;\n this.debugLog('Frame rate mode updated to:', message.data.mode);\n }\n }\n \n private handleRefreshRateUpdate(message: WorkerRefreshRateMessage): void {\n if (message.data && message.data.screenRefreshRate) {\n this.screenRefreshRate = message.data.screenRefreshRate;\n this.debugLog('Screen refresh rate updated to:', message.data.screenRefreshRate + 'Hz');\n }\n }\n \n private trackEffectiveFrameTime(currentTime: number): void {\n // Keep track of actual render frame times\n this.effectiveFrameTimes.push(currentTime);\n \n // Keep only the last 60 frames for calculation (1 second at 60fps)\n if (this.effectiveFrameTimes.length > 60) {\n this.effectiveFrameTimes.shift();\n }\n }\n \n private reportEffectiveRefreshRate(currentTime: number): void {\n // Report effective refresh rate every second\n if (currentTime - this.lastEffectiveRateReport >= this.effectiveRateReportInterval) {\n if (this.effectiveFrameTimes.length >= 2) {\n // Calculate effective refresh rate from actual frame times\n const totalTime = this.effectiveFrameTimes[this.effectiveFrameTimes.length - 1] - this.effectiveFrameTimes[0];\n const frameCount = this.effectiveFrameTimes.length - 1;\n const effectiveRefreshRate = Math.round((frameCount / totalTime) * 1000);\n \n // Send performance update to core\n this.postMessage('performance-update', {\n effectiveRefreshRate,\n frameRateMode: this.frameRateMode,\n screenRefreshRate: this.screenRefreshRate,\n parameterCount: this.parameterSystem.getParameterCount()\n });\n }\n \n this.lastEffectiveRateReport = currentTime;\n }\n }\n \n private handleResolutionUpdate(message: WorkerResolutionMessage): void {\n if (message.data) {\n // Update canvas resolution directly (effective dimensions * scale)\n if (this.canvas) {\n this.canvas.width = Math.round(message.data.effectiveWidth);\n this.canvas.height = Math.round(message.data.effectiveHeight);\n }\n \n // Update viji dimensions to match actual canvas\n this.viji.width = Math.round(message.data.effectiveWidth);\n this.viji.height = Math.round(message.data.effectiveHeight);\n \n // Update WebGL viewport if context exists\n if (this.gl) {\n this.gl.viewport(0, 0, this.viji.width, this.viji.height);\n }\n \n this.debugLog('Canvas resolution updated to:', this.viji.width + 'x' + this.viji.height);\n }\n }\n \n private handleParameterUpdate(message: WorkerParameterMessage): void {\n if (message.data && message.data.name !== undefined && message.data.value !== undefined) {\n this.parameterSystem.updateParameterValue(message.data.name, message.data.value);\n }\n }\n\n private handleParameterBatchUpdate(message: WorkerParameterBatchMessage): void {\n if (message.data && message.data.updates) {\n for (const update of message.data.updates) {\n this.parameterSystem.updateParameterValue(update.name, update.value);\n }\n \n // Mark initial values as synced after first batch update\n this.parameterSystem.markInitialValuesSynced();\n this.debugLog('Parameter system initialized successfully');\n }\n }\n \n private handleStreamUpdate(message: WorkerStreamMessage): void {\n // TODO: Handle general stream updates (non-audio)\n this.debugLog('Stream update:', message.data);\n }\n \n private handleAudioAnalysisUpdate(message: WorkerAudioAnalysisMessage): void {\n // Phase 5: Handle audio analysis results from host\n this.audioState = {\n isConnected: message.data.isConnected,\n volume: message.data.volume,\n bands: message.data.bands,\n frequencyData: message.data.frequencyData\n };\n \n // Update viji.audio API\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n }\n\n private handleVideoCanvasSetup(message: WorkerVideoCanvasSetupMessage): void {\n // Phase 10: Handle OffscreenCanvas transfer from host to worker-side VideoSystem\n this.videoSystem.handleCanvasSetup({\n offscreenCanvas: message.data.offscreenCanvas,\n width: message.data.width,\n height: message.data.height,\n timestamp: message.data.timestamp\n });\n \n // Update viji.video API with current VideoSystem state\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n private handleVideoFrameUpdate(message: WorkerVideoFrameUpdateMessage): void {\n // Phase 10: Handle ImageBitmap frame from host to worker-side VideoSystem\n this.videoSystem.handleFrameUpdate({\n imageBitmap: message.data.imageBitmap,\n timestamp: message.data.timestamp\n });\n \n // Update viji.video API with current VideoSystem state\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n private handleVideoConfigUpdate(message: WorkerVideoConfigUpdateMessage): void {\n // Phase 10: Handle video configuration updates\n this.videoSystem.handleVideoConfigUpdate({\n ...(message.data.targetFrameRate && { targetFrameRate: message.data.targetFrameRate }),\n ...(message.data.cvConfig && { cvConfig: message.data.cvConfig }),\n ...(message.data.width && { width: message.data.width }),\n ...(message.data.height && { height: message.data.height }),\n ...(message.data.disconnect && { disconnect: message.data.disconnect }),\n timestamp: message.data.timestamp\n });\n \n // ✅ FIX: Update viji.video API with current VideoSystem state after config changes\n // This ensures that disconnection events properly update the scene's video API\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n \n private handlePerformanceUpdate(message: WorkerPerformanceMessage): void {\n // TODO: Handle performance updates in Phase 3\n this.debugLog('Performance update:', message.data);\n }\n\n /**\n * Handle capture-frame request from host.\n * Produces an ArrayBuffer (image bytes) to send back as transferable.\n */\n private async handleCaptureFrame(message: {\n type: 'capture-frame';\n id: string;\n data: { type?: string; resolution?: number | { width: number; height: number } };\n }): Promise<void> {\n try {\n if (!this.canvas) {\n throw new Error('Canvas not initialized');\n }\n\n const mimeType = message.data.type || 'image/jpeg';\n\n // Determine target width/height\n const srcWidth = this.canvas.width;\n const srcHeight = this.canvas.height;\n let targetWidth = srcWidth;\n let targetHeight = srcHeight;\n\n if (typeof message.data.resolution === 'number') {\n const scale = message.data.resolution > 0 ? message.data.resolution : 1;\n targetWidth = Math.max(1, Math.floor(srcWidth * scale));\n targetHeight = Math.max(1, Math.floor(srcHeight * scale));\n } else if (message.data.resolution && typeof message.data.resolution === 'object') {\n targetWidth = Math.max(1, Math.floor(message.data.resolution.width));\n targetHeight = Math.max(1, Math.floor(message.data.resolution.height));\n }\n\n // Compute source crop to match aspect ratio if needed\n const srcAspect = srcWidth / srcHeight;\n const dstAspect = targetWidth / targetHeight;\n let sx = 0;\n let sy = 0;\n let sWidth = srcWidth;\n let sHeight = srcHeight;\n\n if (Math.abs(srcAspect - dstAspect) > 1e-6) {\n if (dstAspect > srcAspect) {\n // Need to crop vertically (top/bottom)\n sHeight = Math.floor(srcWidth / dstAspect);\n sy = Math.floor((srcHeight - sHeight) / 2);\n } else {\n // Need to crop horizontally (left/right)\n sWidth = Math.floor(srcHeight * dstAspect);\n sx = Math.floor((srcWidth - sWidth) / 2);\n }\n }\n\n // Draw to a temp OffscreenCanvas at target size\n const temp = new OffscreenCanvas(targetWidth, targetHeight);\n const tctx = temp.getContext('2d');\n if (!tctx) throw new Error('Failed to get 2D context');\n // Draw current frame from the main canvas onto temp with crop & scale\n tctx.drawImage(this.canvas as OffscreenCanvas, sx, sy, sWidth, sHeight, 0, 0, targetWidth, targetHeight);\n\n const blob = await temp.convertToBlob({ type: mimeType });\n const arrayBuffer = await blob.arrayBuffer();\n\n // Send back as transferable ArrayBuffer to avoid cloning overhead\n (self as any).postMessage({\n type: 'capture-frame-result',\n id: message.id,\n timestamp: Date.now(),\n data: {\n mimeType,\n buffer: arrayBuffer,\n width: targetWidth,\n height: targetHeight\n }\n }, [arrayBuffer]);\n } catch (error) {\n this.postMessage('error', {\n id: message.id,\n message: (error as Error).message,\n code: 'CAPTURE_FRAME_ERROR'\n });\n }\n }\n \n private handleSetSceneCode(message: WorkerSetSceneCodeMessage): void {\n if (message.data && message.data.sceneCode) {\n // Delegate to global scene code function\n (self as any).setSceneCode(message.data.sceneCode);\n }\n }\n \n private startRenderLoop(): void {\n this.isRunning = true;\n this.startTime = performance.now();\n this.lastTime = this.startTime;\n this.renderFrame();\n }\n \n public renderFrame(): void {\n if (!this.isRunning) return;\n \n const currentTime = performance.now();\n \n // Phase 7: Reset frame-based interaction events at start of frame\n this.interactionSystem.frameStart();\n \n // Update frame rate info\n this.viji.fps = this.frameRateMode === 'full' ? this.screenRefreshRate : this.screenRefreshRate / 2;\n \n // Check if we should render this frame\n let shouldRender = true;\n if (this.frameRateMode === 'half') {\n shouldRender = !this.skipNextFrame;\n this.skipNextFrame = !this.skipNextFrame;\n }\n \n if (shouldRender) {\n this.viji.deltaTime = (currentTime - this.lastTime) / 1000;\n this.viji.time = (currentTime - this.startTime) / 1000;\n this.viji.frameCount = ++this.frameCount;\n \n // Track effective frame times for performance calculation\n this.trackEffectiveFrameTime(currentTime);\n \n this.lastTime = currentTime;\n \n try {\n // Call artist render function\n const renderFunction = (self as any).renderFunction;\n if (renderFunction && typeof renderFunction === 'function') {\n renderFunction(this.viji);\n }\n } catch (error) {\n console.error('Render error:', error);\n this.postMessage('error', {\n message: (error as Error).message,\n code: 'RENDER_ERROR',\n stack: (error as Error).stack\n });\n }\n }\n \n // Report effective refresh rate periodically\n this.reportEffectiveRefreshRate(currentTime);\n \n // Schedule next frame check\n requestAnimationFrame(() => this.renderFrame());\n }\n \n private postMessage(type: string, data?: any): void {\n self.postMessage({\n type,\n id: data?.id || `${type}_${Date.now()}`,\n timestamp: Date.now(),\n data\n });\n }\n\n // Phase 7: Interaction Message Handlers (delegated to InteractionSystem)\n\n private handleMouseUpdate(message: any): void {\n this.interactionSystem.handleMouseUpdate(message.data);\n }\n\n private handleKeyboardUpdate(message: any): void {\n this.interactionSystem.handleKeyboardUpdate(message.data);\n }\n\n private handleTouchUpdate(message: any): void {\n this.interactionSystem.handleTouchUpdate(message.data);\n }\n\n private handleInteractionEnabled(message: any): void {\n this.interactionSystem.setInteractionEnabled(message.data.enabled);\n }\n} ","/**\n * Viji Worker Runtime - Secure WebWorker for artist scene execution\n * This worker provides the complete artist API and handles scene rendering\n */\n\nimport { VijiWorkerRuntime } from './VijiWorkerRuntime.js';\n\n// Initialize runtime\nconst runtime = new VijiWorkerRuntime();\n\n// Dynamic scene code execution\nlet renderFunction: ((viji: typeof runtime.viji) => void) | null = null;\n\n// Function to set the scene code dynamically\nfunction setSceneCode(sceneCode: string): void {\n try {\n // Reset parameter state for new scene\n runtime.resetParameterState();\n \n // Create a function from the scene code string\n // The scene code should define a render function\n const functionBody = sceneCode + '\\n' +\n 'if (typeof render === \"function\") {\\n' +\n ' return render;\\n' +\n '}\\n' +\n 'throw new Error(\"Scene code must define a render function\");';\n \n const sceneFunction = new Function('viji', functionBody);\n \n renderFunction = sceneFunction(runtime.viji);\n // Update global reference for the runtime to access\n (self as any).renderFunction = renderFunction;\n // Debug logging is controlled by VijiWorkerRuntime\n \n // After scene code execution, automatically send all parameters to host\n runtime.sendAllParametersToHost();\n } catch (error) {\n console.error('Failed to load scene code:', error);\n self.postMessage({\n type: 'error',\n id: `scene_error_${Date.now()}`,\n timestamp: Date.now(),\n data: {\n message: `Scene code error: ${(error as Error).message}`,\n code: 'SCENE_CODE_ERROR'\n }\n });\n }\n}\n\n// Expose functions to global scope for the runtime to access\n(self as any).setSceneCode = setSceneCode; "],"names":["renderFunction"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,13 @@ export declare interface CaptureFrameOptions {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
declare interface ColorConfig {
|
|
39
|
+
label: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
group?: string;
|
|
42
|
+
category?: ParameterCategory;
|
|
43
|
+
}
|
|
44
|
+
|
|
38
45
|
declare interface ColorParameter {
|
|
39
46
|
value: string;
|
|
40
47
|
label: string;
|
|
@@ -132,6 +139,16 @@ export declare interface MouseAPI {
|
|
|
132
139
|
wasMoved: boolean;
|
|
133
140
|
}
|
|
134
141
|
|
|
142
|
+
declare interface NumberConfig {
|
|
143
|
+
min?: number;
|
|
144
|
+
max?: number;
|
|
145
|
+
step?: number;
|
|
146
|
+
label: string;
|
|
147
|
+
description?: string;
|
|
148
|
+
group?: string;
|
|
149
|
+
category?: ParameterCategory;
|
|
150
|
+
}
|
|
151
|
+
|
|
135
152
|
declare interface NumberParameter {
|
|
136
153
|
value: number;
|
|
137
154
|
min: number;
|
|
@@ -199,6 +216,14 @@ export declare type Resolution = {
|
|
|
199
216
|
height: number;
|
|
200
217
|
};
|
|
201
218
|
|
|
219
|
+
declare interface SelectConfig {
|
|
220
|
+
options: string[] | number[];
|
|
221
|
+
label: string;
|
|
222
|
+
description?: string;
|
|
223
|
+
group?: string;
|
|
224
|
+
category?: ParameterCategory;
|
|
225
|
+
}
|
|
226
|
+
|
|
202
227
|
declare interface SelectParameter {
|
|
203
228
|
value: string | number;
|
|
204
229
|
options: string[] | number[];
|
|
@@ -208,6 +233,16 @@ declare interface SelectParameter {
|
|
|
208
233
|
category: ParameterCategory;
|
|
209
234
|
}
|
|
210
235
|
|
|
236
|
+
declare interface SliderConfig {
|
|
237
|
+
min?: number;
|
|
238
|
+
max?: number;
|
|
239
|
+
step?: number;
|
|
240
|
+
label: string;
|
|
241
|
+
description?: string;
|
|
242
|
+
group?: string;
|
|
243
|
+
category?: ParameterCategory;
|
|
244
|
+
}
|
|
245
|
+
|
|
211
246
|
declare interface SliderParameter {
|
|
212
247
|
value: number;
|
|
213
248
|
min: number;
|
|
@@ -219,6 +254,14 @@ declare interface SliderParameter {
|
|
|
219
254
|
category: ParameterCategory;
|
|
220
255
|
}
|
|
221
256
|
|
|
257
|
+
declare interface TextConfig {
|
|
258
|
+
label: string;
|
|
259
|
+
description?: string;
|
|
260
|
+
group?: string;
|
|
261
|
+
category?: ParameterCategory;
|
|
262
|
+
maxLength?: number;
|
|
263
|
+
}
|
|
264
|
+
|
|
222
265
|
declare interface TextParameter {
|
|
223
266
|
value: string;
|
|
224
267
|
maxLength?: number;
|
|
@@ -228,6 +271,13 @@ declare interface TextParameter {
|
|
|
228
271
|
category: ParameterCategory;
|
|
229
272
|
}
|
|
230
273
|
|
|
274
|
+
declare interface ToggleConfig {
|
|
275
|
+
label: string;
|
|
276
|
+
description?: string;
|
|
277
|
+
group?: string;
|
|
278
|
+
category?: ParameterCategory;
|
|
279
|
+
}
|
|
280
|
+
|
|
231
281
|
declare interface ToggleParameter {
|
|
232
282
|
value: boolean;
|
|
233
283
|
label: string;
|
|
@@ -317,13 +367,13 @@ export declare interface VijiAPI {
|
|
|
317
367
|
mouse: MouseAPI;
|
|
318
368
|
keyboard: KeyboardAPI;
|
|
319
369
|
touches: TouchAPI[];
|
|
320
|
-
slider: (defaultValue: number, config:
|
|
321
|
-
color: (defaultValue: string, config:
|
|
322
|
-
toggle: (defaultValue: boolean, config:
|
|
323
|
-
select: (defaultValue: string | number, config:
|
|
324
|
-
text: (defaultValue: string, config:
|
|
325
|
-
number: (defaultValue: number, config:
|
|
326
|
-
useContext(type: '2d' | 'webgl'): OffscreenCanvasRenderingContext2D | WebGL2RenderingContext;
|
|
370
|
+
slider: (defaultValue: number, config: SliderConfig) => SliderParameter;
|
|
371
|
+
color: (defaultValue: string, config: ColorConfig) => ColorParameter;
|
|
372
|
+
toggle: (defaultValue: boolean, config: ToggleConfig) => ToggleParameter;
|
|
373
|
+
select: (defaultValue: string | number, config: SelectConfig) => SelectParameter;
|
|
374
|
+
text: (defaultValue: string, config: TextConfig) => TextParameter;
|
|
375
|
+
number: (defaultValue: number, config: NumberConfig) => NumberParameter;
|
|
376
|
+
useContext(type: '2d' | 'webgl'): OffscreenCanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext | null;
|
|
327
377
|
}
|
|
328
378
|
|
|
329
379
|
/**
|