@panelwave/player 1.0.0
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/LICENSE +21 -0
- package/README.md +24 -0
- package/fesm2022/panelwave-player.mjs +18982 -0
- package/fesm2022/panelwave-player.mjs.map +1 -0
- package/index.d.ts +7189 -0
- package/package.json +43 -0
- package/src/assets/fonts/balloon/Anton-Regular.woff +0 -0
- package/src/assets/fonts/balloon/Anton-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/ArchitectsDaughter-Regular.woff +0 -0
- package/src/assets/fonts/balloon/ArchitectsDaughter-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/Bangers-Regular.woff +0 -0
- package/src/assets/fonts/balloon/Bangers-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/Caveat-Bold.woff +0 -0
- package/src/assets/fonts/balloon/Caveat-Bold.woff2 +0 -0
- package/src/assets/fonts/balloon/Caveat-Medium.woff +0 -0
- package/src/assets/fonts/balloon/Caveat-Medium.woff2 +0 -0
- package/src/assets/fonts/balloon/Caveat-Regular.woff +0 -0
- package/src/assets/fonts/balloon/Caveat-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/Caveat-SemiBold.woff +0 -0
- package/src/assets/fonts/balloon/Caveat-SemiBold.woff2 +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Bold.woff +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Bold.woff2 +0 -0
- package/src/assets/fonts/balloon/ComicNeue-BoldItalic.woff +0 -0
- package/src/assets/fonts/balloon/ComicNeue-BoldItalic.woff2 +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Italic.woff +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Italic.woff2 +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Light.woff +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Light.woff2 +0 -0
- package/src/assets/fonts/balloon/ComicNeue-LightItalic.woff +0 -0
- package/src/assets/fonts/balloon/ComicNeue-LightItalic.woff2 +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Regular.woff +0 -0
- package/src/assets/fonts/balloon/ComicNeue-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/ComingSoon-Regular.woff +0 -0
- package/src/assets/fonts/balloon/ComingSoon-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/GloriaHallelujah.woff +0 -0
- package/src/assets/fonts/balloon/GloriaHallelujah.woff2 +0 -0
- package/src/assets/fonts/balloon/LICENSES.md +33 -0
- package/src/assets/fonts/balloon/LuckiestGuy-Regular.woff +0 -0
- package/src/assets/fonts/balloon/LuckiestGuy-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/Neucha.woff +0 -0
- package/src/assets/fonts/balloon/Neucha.woff2 +0 -0
- package/src/assets/fonts/balloon/PatrickHand-Regular.woff +0 -0
- package/src/assets/fonts/balloon/PatrickHand-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/PermanentMarker-Regular.woff +0 -0
- package/src/assets/fonts/balloon/PermanentMarker-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/ReenieBeanie.woff +0 -0
- package/src/assets/fonts/balloon/ReenieBeanie.woff2 +0 -0
- package/src/assets/fonts/balloon/RockSalt-Regular.woff +0 -0
- package/src/assets/fonts/balloon/RockSalt-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/Sigmar-Regular.woff +0 -0
- package/src/assets/fonts/balloon/Sigmar-Regular.woff2 +0 -0
- package/src/assets/fonts/balloon/balloon-fonts.css +227 -0
- package/src/assets/i18n/de.json +195 -0
- package/src/assets/i18n/en.json +195 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panelwave-player.mjs","sources":["../../../projects/player/src/lib/types/variable.types.ts","../../../projects/player/src/lib/types/player.types.ts","../../../projects/player/src/lib/types/entitlement.types.ts","../../../projects/player/src/lib/types/index.ts","../../../projects/player/src/lib/services/player-state.service.ts","../../../projects/player/src/lib/services/manifest.service.ts","../../../projects/player/src/lib/services/variable-store.service.ts","../../../projects/player/src/lib/utils/locale-utils.ts","../../../projects/player/src/lib/utils/video-config-utils.ts","../../../projects/player/src/lib/utils/asset-utils.ts","../../../projects/player/src/lib/utils/json-logic-utils.ts","../../../projects/player/src/lib/utils/balloon-config.ts","../../../projects/player/src/lib/utils/balloon-geometry.ts","../../../projects/player/src/lib/utils/comic-balloon.ts","../../../projects/player/src/lib/utils/animation-utils.ts","../../../projects/player/src/lib/utils/image-variant-utils.ts","../../../projects/player/src/lib/utils/variant-utils.ts","../../../projects/player/src/lib/utils/index.ts","../../../projects/player/src/lib/services/entitlement.service.ts","../../../projects/player/src/lib/services/flow-engine.service.ts","../../../projects/player/src/lib/services/image-cache.service.ts","../../../projects/player/src/lib/services/audio-engine.service.ts","../../../projects/player/src/lib/services/user-gesture.service.ts","../../../projects/player/src/lib/services/panel-audio.service.ts","../../../projects/player/src/lib/services/video-controller.service.ts","../../../projects/player/src/lib/services/visibility.service.ts","../../../projects/player/src/lib/services/video-sequencer.service.ts","../../../projects/player/src/lib/services/preload.service.ts","../../../projects/player/src/lib/services/tracking.service.ts","../../../projects/player/src/lib/entitlement/paywall-evaluator.ts","../../../projects/player/src/lib/services/paywall.service.ts","../../../projects/player/src/lib/entitlement/http-entitlement.adapter.ts","../../../projects/player/src/lib/services/plugin-host.service.ts","../../../projects/player/src/lib/services/export.service.ts","../../../projects/player/src/lib/services/translation.service.ts","../../../projects/player/src/lib/player.service.ts","../../../projects/player/src/lib/components/icon/pw-icon.data.ts","../../../projects/player/src/lib/components/icon/pw-icon.component.ts","../../../projects/player/src/lib/utils/translation-loader.ts","../../../projects/player/src/lib/utils/extras-utils.ts","../../../projects/player/src/lib/components/layers/video-layer/video-layer.component.ts","../../../projects/player/src/lib/components/layers/video-layer/video-layer.component.html","../../../projects/player/src/lib/components/layer-renderer/layer-renderer.component.ts","../../../projects/player/src/lib/components/layer-renderer/layer-renderer.component.html","../../../projects/player/src/lib/components/overlays/speech-bubbles/speech-bubbles.component.ts","../../../projects/player/src/lib/components/overlays/speech-bubbles/speech-bubbles.component.html","../../../projects/player/src/lib/components/overlays/hotspots-overlay/hotspots-overlay.component.ts","../../../projects/player/src/lib/components/overlays/hotspots-overlay/hotspots-overlay.component.html","../../../projects/player/src/lib/components/viewport/viewport.component.ts","../../../projects/player/src/lib/components/viewport/viewport.component.html","../../../projects/player/src/lib/services/canvas-camera.service.ts","../../../projects/player/src/lib/components/canvas-stage/canvas-stage.component.ts","../../../projects/player/src/lib/components/canvas-stage/canvas-stage.component.html","../../../projects/player/src/lib/components/toolbar/toolbar.component.ts","../../../projects/player/src/lib/components/toolbar/toolbar.component.html","../../../projects/player/src/lib/components/modals/language-modal/language-modal.component.ts","../../../projects/player/src/lib/components/modals/language-modal/language-modal.component.html","../../../projects/player/src/lib/components/overlays/thumbnail-strip/thumbnail-strip.component.ts","../../../projects/player/src/lib/components/overlays/thumbnail-strip/thumbnail-strip.component.html","../../../projects/player/src/lib/components/modals/toc-overlay/toc-overlay.component.ts","../../../projects/player/src/lib/components/modals/toc-overlay/toc-overlay.component.html","../../../projects/player/src/lib/components/overlays/paywall-overlay/paywall-overlay.component.ts","../../../projects/player/src/lib/components/overlays/paywall-overlay/paywall-overlay.component.html","../../../projects/player/src/lib/components/modals/settings-modal/settings-modal.component.ts","../../../projects/player/src/lib/components/modals/settings-modal/settings-modal.component.html","../../../projects/player/src/lib/components/modals/character-roster/character-roster.component.ts","../../../projects/player/src/lib/components/modals/character-roster/character-roster.component.html","../../../projects/player/src/lib/components/modals/extras-viewer/extras-viewer.component.ts","../../../projects/player/src/lib/components/modals/extras-viewer/extras-viewer.component.html","../../../projects/player/src/lib/components/modals/action-modal/action-modal.component.ts","../../../projects/player/src/lib/components/modals/action-modal/action-modal.component.html","../../../projects/player/src/lib/components/overlays/age-gate/age-gate.component.ts","../../../projects/player/src/lib/components/overlays/age-gate/age-gate.component.html","../../../projects/player/src/lib/components/modals/branch-chooser/branch-chooser.component.ts","../../../projects/player/src/lib/components/modals/branch-chooser/branch-chooser.component.html","../../../projects/player/src/lib/services/hotspot-action.service.ts","../../../projects/player/src/lib/components/modals/share-modal/share-modal.component.ts","../../../projects/player/src/lib/components/modals/share-modal/share-modal.component.html","../../../projects/player/src/lib/components/modals/comments-drawer/comments-drawer.component.ts","../../../projects/player/src/lib/components/modals/comments-drawer/comments-drawer.component.html","../../../projects/player/src/lib/components/player-shell/player-shell.component.ts","../../../projects/player/src/lib/components/player-shell/player-shell.component.html","../../../projects/player/src/lib/components/plugin-sandbox/plugin-sandbox.component.ts","../../../projects/player/src/lib/player.component.ts","../../../projects/player/src/public-api.ts","../../../projects/player/src/panelwave-player.ts"],"sourcesContent":["/**\n * Variable Type Definitions\n * Defines variable system for state management\n */\n\n/**\n * Variables configuration\n */\nexport interface Variables {\n /** Array of variable definitions */\n definitions?: VariableDefinition[];\n}\n\n/**\n * Variable definition\n */\nexport interface VariableDefinition {\n /** Unique variable identifier (dot-notation allowed, e.g., \"user.age\") */\n id: string;\n \n /** Human-readable description (optional) */\n description?: string;\n \n /** Variable data type */\n type: VariableType;\n \n /** Allowed values for enum type (required if type is enum) */\n enum?: string[];\n \n /** Default value (optional) */\n default?: JsonValue;\n \n /** Variable scope */\n scope: VariableScope;\n \n /** Visibility (optional, default: \"public\") */\n visibility?: 'public' | 'private';\n \n /** Whether variable is read-only (optional, default: false) */\n readOnly?: boolean;\n \n /** Minimum value for number/integer types (optional) */\n min?: number;\n \n /** Maximum value for number/integer types (optional) */\n max?: number;\n \n /** Pattern for string validation (optional) */\n pattern?: string;\n}\n\n/**\n * Variable data type\n */\nexport type VariableType =\n | 'boolean'\n | 'number'\n | 'integer'\n | 'string'\n | 'enum'\n | 'date'\n | 'time'\n | 'datetime';\n\n/**\n * Variable scope\n */\nexport type VariableScope =\n | 'global' // Shared across entire work\n | 'chapter' // Chapter-specific\n | 'page' // Page-specific\n | 'session' // Session-only (cleared on close)\n | 'persistent'; // Persisted across sessions\n\n/**\n * JSON value type (any valid JSON value)\n */\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | JsonValue[]\n | { [key: string]: JsonValue };\n\n/**\n * Variable store (runtime storage)\n */\nexport interface VariableStore {\n /** Global scope variables */\n global: Record<string, unknown>;\n \n /** Chapter scope variables by chapter ID */\n chapter: Record<string, Record<string, unknown>>;\n \n /** Page scope variables by page ID */\n page: Record<string, Record<string, unknown>>;\n \n /** Session scope variables (volatile) */\n session: Record<string, unknown>;\n \n /** Persistent scope variables (saved to storage) */\n persistent: Record<string, unknown>;\n}\n\n/**\n * Variable mutation operation\n */\nexport interface VariableMutation {\n /** Operation type */\n op: MutationOperation;\n \n /** Variable identifier */\n var: string;\n \n /** Value for the operation (optional, depends on op) */\n value?: unknown;\n \n /** Amount for increment/decrement (optional, default: 1) */\n amount?: number;\n}\n\n/**\n * Mutation operation type\n */\nexport type MutationOperation =\n | 'set' // Set to value\n | 'increment' // Increase by amount\n | 'decrement' // Decrease by amount\n | 'toggle' // Toggle boolean\n | 'append' // Append to array\n | 'remove' // Remove from array\n | 'clear'; // Clear/reset to default\n\n/**\n * Variable change event\n */\nexport interface VariableChangeEvent {\n /** Variable identifier */\n variableId: string;\n \n /** Scope where change occurred */\n scope: VariableScope;\n \n /** Previous value */\n oldValue: unknown;\n \n /** New value */\n newValue: unknown;\n \n /** Timestamp of change */\n timestamp: number;\n}\n\n/**\n * Variable validation result\n */\nexport interface VariableValidationResult {\n /** Whether the value is valid */\n valid: boolean;\n \n /** Error messages if invalid */\n errors?: string[];\n}\n\n/**\n * Variable context for JSON Logic evaluation\n */\nexport type VariableContext = Record<string, unknown>;\n\n/**\n * Reserved variable namespaces\n */\nexport const RESERVED_NAMESPACES = {\n /** User-related variables (age, preferences, entitlements) */\n user: 'user',\n \n /** UI preferences */\n prefs: 'prefs',\n \n /** Device information */\n device: 'device',\n \n /** Entitlement and access control */\n entitlement: 'entitlement',\n \n /** Plugin-specific state */\n plugin: 'plugin',\n \n /** System variables */\n system: 'system',\n} as const;\n\n/**\n * Predefined user variables\n */\nexport interface UserVariables {\n /** User age (for age gating) */\n 'user.age'?: number;\n \n /** User ID (hashed) */\n 'user.id'?: string;\n \n /** User locale preference */\n 'user.locale'?: string;\n}\n\n/**\n * Predefined preference variables\n */\nexport interface PreferenceVariables {\n /** Show speech bubbles */\n 'prefs.speech'?: boolean;\n \n /** Enable audio */\n 'prefs.audio'?: boolean;\n \n /** Enable SFX */\n 'prefs.sfx'?: boolean;\n \n /** Enable autoplay */\n 'prefs.autoplay'?: boolean;\n \n /** Seconds per panel in autoplay */\n 'prefs.secondsPerPanel'?: number;\n \n /** Manga mode (right-to-left) */\n 'prefs.mangaMode'?: boolean;\n \n /** Reduced motion preference */\n 'prefs.reducedMotion'?: boolean;\n \n /** High contrast mode */\n 'prefs.highContrast'?: boolean;\n}\n\n/**\n * Predefined device variables\n */\nexport interface DeviceVariables {\n /** Device type */\n 'device.type'?: 'desktop' | 'mobile' | 'tablet' | 'tv';\n \n /** Screen width */\n 'device.screenWidth'?: number;\n \n /** Screen height */\n 'device.screenHeight'?: number;\n \n /** Pixel density */\n 'device.pixelRatio'?: number;\n \n /** Touch support */\n 'device.touchEnabled'?: boolean;\n \n /** Network type */\n 'device.networkType'?: 'slow-2g' | '2g' | '3g' | '4g' | 'wifi';\n}\n\n/**\n * Predefined entitlement variables\n */\nexport interface EntitlementVariables {\n /** Premium access */\n 'entitlement.premium'?: boolean;\n \n /** Purchased content */\n 'entitlement.purchased'?: string[];\n \n /** Available tokens */\n 'entitlement.tokens'?: number;\n}\n","/**\r\n * Player Type Definitions\r\n * Player-specific types for runtime state and configuration\r\n */\r\n\r\nimport type { PanelWaveManifest, LocaleCode } from './manifest.types';\r\nimport type { VariableStore } from './variable.types';\r\n\r\n/**\r\n * Player options passed to the player component\r\n */\r\nexport interface PlayerOptions {\r\n /** Allow commenting features (optional, default: true) */\r\n allowComments?: boolean;\r\n \r\n /** Allow social features (like, share, bookmark) (optional, default: true) */\r\n allowSocial?: boolean;\r\n \r\n /** Theme preference (optional, default: \"auto\") */\r\n theme?: 'auto' | 'light' | 'dark';\r\n \r\n /** Enable debug mode (optional, default: false) */\r\n debug?: boolean;\r\n \r\n /** Custom CSS class for player container (optional) */\r\n className?: string;\r\n \r\n /** Enable keyboard shortcuts (optional, default: true) */\r\n enableKeyboard?: boolean;\r\n \r\n /** Enable touch gestures (optional, default: true) */\r\n enableTouch?: boolean;\r\n}\r\n\r\n/**\r\n * Deep link target for starting at a specific location\r\n */\r\nexport interface DeepLinkTarget {\r\n /** Chapter ID (optional) */\r\n chapterId?: string;\r\n \r\n /** Page ID (optional) */\r\n pageId?: string;\r\n \r\n /** Panel ID (optional) */\r\n panelId?: string;\r\n \r\n /** Variable snapshot hash (optional) */\r\n varSnapshotHash?: string;\r\n}\r\n\r\n/**\r\n * Player state (runtime)\r\n */\r\nexport interface PlayerState {\r\n /** Loaded manifest */\r\n manifest: PanelWaveManifest | null;\r\n \r\n /** Whether manifest is loaded */\r\n manifestLoaded: boolean;\r\n \r\n /** Manifest loading/parsing error (optional) */\r\n manifestError: string | null;\r\n \r\n /** Current work ID */\r\n currentWorkId: string | null;\r\n \r\n /** Current chapter ID */\r\n currentChapterId: string | null;\r\n \r\n /** Current page ID */\r\n currentPageId: string | null;\r\n \r\n /** Current panel ID */\r\n currentPanelId: string | null;\r\n \r\n /** Navigation history (panel IDs) */\r\n navigationHistory: string[];\r\n \r\n /** View mode */\r\n viewMode: ViewMode;\r\n \r\n /** Viewport state */\r\n viewport: ViewportState;\r\n \r\n /** Current locale */\r\n locale: LocaleCode;\r\n \r\n /** User preferences */\r\n preferences: PlayerPreferences;\r\n \r\n /** Variable store */\r\n variables: VariableStore;\r\n \r\n /** Entitlement status */\r\n entitlements: Record<string, boolean>;\r\n \r\n /** Current paywall gate (if any) */\r\n paywallGate: PaywallGate | null;\r\n \r\n /** Overlay visibility states */\r\n overlays: OverlayState;\r\n \r\n /** Tracking consent given */\r\n trackingConsent: boolean;\r\n \r\n /** Session ID */\r\n sessionId: string;\r\n \r\n /** Preload status */\r\n preloadStatus: PreloadStatus;\r\n \r\n /** Loading state */\r\n loading: boolean;\r\n \r\n /** Error state */\r\n error: PlayerError | null;\r\n}\r\n\r\n/**\r\n * View mode\r\n */\r\nexport type ViewMode = 'page' | 'panel' | 'canvas';\r\n\r\n/**\r\n * Viewport state\r\n */\r\nexport interface ViewportState {\r\n /** Pan offset X */\r\n panX: number;\r\n \r\n /** Pan offset Y */\r\n panY: number;\r\n \r\n /** Zoom level */\r\n zoom: number;\r\n \r\n /** Viewport width */\r\n width: number;\r\n \r\n /** Viewport height */\r\n height: number;\r\n \r\n /** Whether viewport has overflow left */\r\n hasOverflowLeft: boolean;\r\n \r\n /** Whether viewport has overflow right */\r\n hasOverflowRight: boolean;\r\n \r\n /** Whether viewport has overflow top */\r\n hasOverflowTop: boolean;\r\n \r\n /** Whether viewport has overflow bottom */\r\n hasOverflowBottom: boolean;\r\n}\r\n\r\n/**\r\n * Player preferences (user-configurable)\r\n */\r\nexport interface PlayerPreferences {\r\n /** Show speech bubbles */\r\n speech: boolean;\r\n \r\n /** Enable audio */\r\n audio: boolean;\r\n \r\n /** Enable sound effects */\r\n sfx: boolean;\r\n \r\n /** Enable autoplay */\r\n autoplay: boolean;\r\n \r\n /** Seconds per panel in autoplay mode */\r\n secondsPerPanel: number;\r\n \r\n /** Manga mode (right-to-left reading) */\r\n mangaMode: boolean;\r\n \r\n /** Reduced motion */\r\n reducedMotion: boolean;\r\n \r\n /** High contrast mode */\r\n highContrast: boolean;\r\n \r\n /** Master volume (0-1) */\r\n masterVolume: number;\r\n \r\n /** SFX volume (0-1) */\r\n sfxVolume: number;\r\n}\r\n\r\n/**\r\n * Paywall gate information\r\n */\r\nexport interface PaywallGate {\r\n /** Gate scope */\r\n scope: 'work' | 'chapter' | 'panel';\r\n \r\n /** Reference ID (chapter or panel ID) (optional) */\r\n refId?: string;\r\n \r\n /** Required entitlement */\r\n requireEntitlement?: string;\r\n \r\n /** Reason for gate */\r\n reason: string;\r\n}\r\n\r\n/**\r\n * Overlay visibility state\r\n */\r\nexport interface OverlayState {\r\n /** Toolbar visible */\r\n toolbar: boolean;\r\n \r\n /** Thumbnails visible */\r\n thumbnails: boolean;\r\n \r\n /** Table of contents visible */\r\n toc: boolean;\r\n \r\n /** Settings modal visible */\r\n settings: boolean;\r\n \r\n /** Characters roster visible */\r\n characters: boolean;\r\n \r\n /** Extras viewer visible */\r\n extras: boolean;\r\n \r\n /** Comments drawer visible */\r\n comments: boolean;\r\n \r\n /** Share modal visible */\r\n share: boolean;\r\n \r\n /** Content warning overlay visible */\r\n contentWarning: boolean;\r\n \r\n /** Paywall overlay visible */\r\n paywall: boolean;\r\n}\r\n\r\n/**\r\n * Preload status\r\n */\r\nexport interface PreloadStatus {\r\n /** Number of items in queue */\r\n queueSize: number;\r\n \r\n /** Number of items currently loading */\r\n inFlight: number;\r\n \r\n /** Number of items completed */\r\n completed: number;\r\n \r\n /** Total items to preload */\r\n total: number;\r\n}\r\n\r\n/**\r\n * Player error\r\n */\r\nexport interface PlayerError {\r\n /** Error code */\r\n code: PlayerErrorCode;\r\n \r\n /** Error message */\r\n message: string;\r\n \r\n /** Detailed error information (optional) */\r\n details?: unknown;\r\n \r\n /** Whether error is recoverable */\r\n recoverable: boolean;\r\n}\r\n\r\n/**\r\n * Player error codes\r\n */\r\nexport type PlayerErrorCode =\r\n | 'MANIFEST_LOAD_FAILED'\r\n | 'MANIFEST_INVALID'\r\n | 'ASSET_LOAD_FAILED'\r\n | 'PANEL_NOT_FOUND'\r\n | 'CHAPTER_NOT_FOUND'\r\n | 'NAVIGATION_FAILED'\r\n | 'ENTITLEMENT_CHECK_FAILED'\r\n | 'PLUGIN_LOAD_FAILED'\r\n | 'UNKNOWN_ERROR';\r\n\r\n/**\r\n * Player events\r\n */\r\nexport enum PlayerEvent {\r\n READY = 'ready',\r\n PANEL_CHANGE = 'panelChange',\r\n DECISION = 'decision',\r\n PAYWALL_SHOWN = 'paywallShown',\r\n ERROR = 'error',\r\n STATE_CHANGE = 'stateChange',\r\n PREFERENCE_CHANGE = 'preferenceChange',\r\n LOCALE_CHANGE = 'localeChange',\r\n\r\n /** A video layer started playing. */\r\n VIDEO_PLAY = 'videoPlay',\r\n /** A video layer paused. */\r\n VIDEO_PAUSE = 'videoPause',\r\n /**\r\n * A video finished (`once` mode ended) or was skipped by the sequencer\r\n * because it stalled (see `VideoTrackingPayload.reason`).\r\n */\r\n VIDEO_ENDED = 'videoEnded',\r\n /** A video completed one loop / pingpong / loop-from cycle. */\r\n VIDEO_LOOP = 'videoLoop',\r\n}\r\n\r\n/**\r\n * What triggered a video playback event, for analytics.\r\n */\r\nexport type VideoTrigger = 'view' | 'hover' | 'click' | 'sequencer';\r\n\r\n/**\r\n * Payload emitted with the `VIDEO_*` player/tracking events.\r\n */\r\nexport interface VideoTrackingPayload {\r\n /** Panel the video layer belongs to (when known). */\r\n panelId?: string;\r\n /** Catalog asset id of the video (when known). */\r\n assetId?: string;\r\n /** What initiated the playback that produced this event. */\r\n trigger: VideoTrigger;\r\n /**\r\n * Reason qualifier for `VIDEO_ENDED` — `'ended'` for a genuine finish,\r\n * `'stall-skip'` when the sequencer skipped a stalled entry.\r\n */\r\n reason?: 'ended' | 'stall-skip';\r\n}\r\n\r\n/**\r\n * Player event data\r\n */\r\nexport interface PlayerEventData {\r\n /** Event type */\r\n type: PlayerEvent;\r\n \r\n /** Event payload */\r\n payload?: unknown;\r\n \r\n /** Timestamp */\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Panel change event payload\r\n */\r\nexport interface PanelChangeEvent {\r\n /** Chapter ID */\r\n chapterId: string;\r\n \r\n /** Panel ID */\r\n panelId: string;\r\n \r\n /** Previous panel ID (optional) */\r\n previousPanelId?: string;\r\n \r\n /** Transition used */\r\n transition?: string;\r\n}\r\n\r\n/**\r\n * Decision event payload\r\n */\r\nexport interface DecisionEvent {\r\n /** Panel ID where decision was made */\r\n panelId: string;\r\n \r\n /** Choice/hotspot ID */\r\n choiceId: string;\r\n \r\n /** Chosen value (optional) */\r\n value?: unknown;\r\n \r\n /** Variables that were mutated */\r\n mutations?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Paywall event payload\r\n */\r\nexport interface PaywallEvent {\r\n /** Gate scope */\r\n scope: 'work' | 'chapter' | 'panel';\r\n \r\n /** Reference ID (optional) */\r\n refId?: string;\r\n \r\n /** Required entitlement */\r\n requireEntitlement?: string;\r\n}\r\n\r\n/**\r\n * Error event payload\r\n */\r\nexport interface ErrorEvent {\r\n /** Error code */\r\n code: string;\r\n \r\n /** Error message */\r\n message: string;\r\n \r\n /** Additional details (optional) */\r\n details?: unknown;\r\n}\r\n\r\n/**\r\n * Tracking configuration\r\n */\r\nexport interface TrackingConfig {\r\n /** Analytics endpoint URL (optional) */\r\n endpoint?: string;\r\n \r\n /** Event whitelist (optional) */\r\n whitelist?: string[];\r\n \r\n /** Whether tracking is enabled (optional, default: true if endpoint provided) */\r\n enabled?: boolean;\r\n}\r\n\r\n/**\r\n * Bookmark\r\n */\r\nexport interface Bookmark {\r\n /** Work ID */\r\n workId: string;\r\n \r\n /** Chapter ID */\r\n chapterId: string;\r\n \r\n /** Panel ID */\r\n panelId: string;\r\n \r\n /** Timestamp when bookmarked */\r\n timestamp: number;\r\n \r\n /** User note (optional) */\r\n note?: string;\r\n}\r\n\r\n/**\r\n * Reading progress\r\n */\r\nexport interface ReadingProgress {\r\n /** Work ID */\r\n workId: string;\r\n \r\n /** Last chapter ID visited */\r\n lastChapterId: string;\r\n \r\n /** Last panel ID visited */\r\n lastPanelId: string;\r\n \r\n /** Panels viewed */\r\n panelsViewed: string[];\r\n \r\n /** Percentage complete (0-100) */\r\n percentComplete: number;\r\n \r\n /** Last updated timestamp */\r\n lastUpdated: number;\r\n}\r\n\r\n/**\r\n * Player statistics\r\n */\r\nexport interface PlayerStatistics {\r\n /** Total time spent (milliseconds) */\r\n totalTimeMs: number;\r\n \r\n /** Number of panels viewed */\r\n panelsViewed: number;\r\n \r\n /** Number of decisions made */\r\n decisionsMade: number;\r\n \r\n /** Number of hotspots clicked */\r\n hotspotsClicked: number;\r\n \r\n /** Paths taken */\r\n pathsTaken: string[];\r\n}\r\n","/**\n * Entitlement Type Definitions\n * Defines entitlement adapter interface for paywall integration\n */\n\n/**\n * Entitlement adapter interface\n * Implement this interface to integrate with your entitlement/payment system\n */\nexport interface EntitlementAdapter {\n /**\n * Resolve entitlements for a given context\n * @param context - The entitlement context (work, chapter, panel)\n * @returns Promise resolving to entitlement status\n */\n resolveEntitlement(context: EntitlementContext): Promise<EntitlementStatus>;\n \n /**\n * Get a signed URL for a gated asset (optional)\n * @param assetId - The asset identifier\n * @param purpose - The purpose of the URL ('stream' or 'download')\n * @returns Promise resolving to the signed URL\n */\n getSignedUrl?(assetId: string, purpose: 'stream' | 'download'): Promise<string>;\n \n /**\n * Show paywall UI to the user (optional)\n * @param gate - The paywall gate information\n * @returns Promise that resolves when user completes or dismisses paywall\n */\n showPaywallUI?(gate: PaywallGate): Promise<void>;\n \n /**\n * Verify age for age-restricted content (optional)\n * @param minimumAge - The minimum required age\n * @returns Promise resolving to whether user meets age requirement\n */\n verifyAge?(minimumAge: number): Promise<boolean>;\n \n /**\n * Check if user is authenticated (optional)\n * @returns Whether user is currently authenticated\n */\n isAuthenticated?(): boolean;\n \n /**\n * Get current user information (optional)\n * @returns Current user information, or null if not authenticated\n */\n getCurrentUser?(): Promise<UserInfo | null>;\n}\n\n/**\n * Entitlement context for resolution\n */\nexport interface EntitlementContext {\n /** Work ID */\n workId: string;\n \n /** Chapter ID (optional) */\n chapterId?: string;\n \n /** Panel ID (optional) */\n panelId?: string;\n \n /** User token for authentication (optional) */\n userToken?: string;\n \n /** Additional context data (optional) */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Entitlement status result\n */\nexport interface EntitlementStatus {\n /** Whether user has access */\n ok: boolean;\n \n /** Dictionary of entitlement flags */\n entitlements: Record<string, boolean>;\n \n /** User information (optional) */\n user?: UserInfo;\n \n /** Reason for denial if not ok (optional) */\n reason?: string;\n \n /** Expiration timestamp for temporary access (optional) */\n expiresAt?: number;\n}\n\n/**\n * User information\n */\nexport interface UserInfo {\n /** User ID (hashed or pseudonymous) */\n id: string;\n \n /** Display name (optional) */\n displayName?: string;\n \n /** Email address (optional) */\n email?: string;\n \n /** Age (for age gating) (optional) */\n age?: number;\n \n /** Subscription tier (optional) */\n tier?: string;\n \n /** Purchased content IDs */\n purchased?: string[];\n \n /** Available tokens/credits */\n tokens?: number;\n \n /** Custom user properties */\n [key: string]: unknown;\n}\n\n/**\n * Paywall gate information\n */\nexport interface PaywallGate {\n /** Gate scope */\n scope: 'work' | 'chapter' | 'panel';\n \n /** Reference ID (chapter ID or panel ID) (optional) */\n refId?: string;\n \n /** Required entitlement type */\n requireEntitlement?: string;\n \n /** Reason for gate */\n reason: string;\n \n /** Preview information (optional) */\n preview?: PreviewInfo;\n}\n\n/**\n * Preview information for gated content\n */\nexport interface PreviewInfo {\n /** Number of preview panels allowed */\n previewPanels?: number;\n \n /** Preview mode */\n mode?: 'blur' | 'low-res' | 'watermark' | 'time-limited';\n \n /** Preview duration in seconds (for time-limited) (optional) */\n durationSeconds?: number;\n}\n\n/**\n * Purchase information\n */\nexport interface PurchaseInfo {\n /** Product ID */\n productId: string;\n \n /** Product name */\n name: string;\n \n /** Price with currency */\n price: {\n amount: number;\n currency: string;\n };\n \n /** Purchase type */\n type: 'one-time' | 'subscription' | 'token';\n \n /** Description (optional) */\n description?: string;\n}\n\n/**\n * Null entitlement adapter (always denies access)\n * Use this as a default when no adapter is provided\n */\nexport class NullEntitlementAdapter implements EntitlementAdapter {\n async resolveEntitlement(): Promise<EntitlementStatus> {\n return {\n ok: false,\n entitlements: {},\n reason: 'No entitlement adapter configured',\n };\n }\n \n async getSignedUrl(assetId: string): Promise<string> {\n // Return asset ID as-is (no signing)\n return assetId;\n }\n \n isAuthenticated(): boolean {\n return false;\n }\n \n async getCurrentUser(): Promise<UserInfo | null> {\n return null;\n }\n}\n\n/**\n * Mock entitlement adapter for development/testing\n * Grants all access by default\n */\nexport class MockEntitlementAdapter implements EntitlementAdapter {\n constructor(\n private mockUser: UserInfo = {\n id: 'mock-user',\n displayName: 'Test User',\n age: 18,\n tier: 'premium',\n }\n ) {}\n \n async resolveEntitlement(): Promise<EntitlementStatus> {\n return {\n ok: true,\n entitlements: {\n premium: true,\n purchased: true,\n },\n user: this.mockUser,\n };\n }\n \n async getSignedUrl(assetId: string): Promise<string> {\n return assetId;\n }\n \n async showPaywallUI(gate: PaywallGate): Promise<void> {\n console.log('[MockEntitlementAdapter] Paywall UI shown (mock)', gate);\n // Immediately resolve (no actual paywall)\n }\n \n async verifyAge(minimumAge: number): Promise<boolean> {\n return (this.mockUser.age ?? 0) >= minimumAge;\n }\n \n isAuthenticated(): boolean {\n return true;\n }\n \n async getCurrentUser(): Promise<UserInfo | null> {\n return this.mockUser;\n }\n}\n\n/**\n * Entitlement error\n */\nexport class EntitlementError extends Error {\n constructor(\n message: string,\n public code: EntitlementErrorCode,\n public context?: EntitlementContext\n ) {\n super(message);\n this.name = 'EntitlementError';\n }\n}\n\n/**\n * Entitlement error codes\n */\nexport type EntitlementErrorCode =\n | 'NOT_AUTHENTICATED'\n | 'INSUFFICIENT_PRIVILEGES'\n | 'AGE_RESTRICTED'\n | 'PAYMENT_REQUIRED'\n | 'REGION_RESTRICTED'\n | 'ACCOUNT_SUSPENDED'\n | 'SERVICE_UNAVAILABLE'\n | 'UNKNOWN_ERROR';\n","/**\r\n * PanelWave Player Type Definitions\r\n * Central export for all type definitions\r\n * @packageDocumentation\r\n */\r\n\r\n// Manifest types\r\nexport type {\r\n PanelWaveManifest,\r\n PanelwaveHeader,\r\n Meta,\r\n Creator,\r\n Character,\r\n ContentWarning,\r\n SequenceAudioTrack,\r\n Chapter,\r\n Page,\r\n PageLayout,\r\n PanelPlacement,\r\n Settings,\r\n UIDefaults,\r\n PreloadSettings,\r\n OutputPreset,\r\n Extras,\r\n ExtraItem,\r\n ExtraImage,\r\n Paywall,\r\n PaywallRule,\r\n Tracking,\r\n UISettings,\r\n LocalizedString,\r\n LocaleCode,\r\n OutputFormat,\r\n Transition,\r\n PanelRef,\r\n AssetRef,\r\n} from './manifest.types';\r\n\r\n// Panel types\r\nexport type {\r\n Panel,\r\n FormatView,\r\n Layer,\r\n ImageLayer,\r\n VideoLayer,\r\n VideoPlayMode,\r\n VideoStartMode,\r\n TextLayer,\r\n AudioLayer,\r\n PanelAudioTrack,\r\n PanelAudioRole,\r\n PluginLayer,\r\n LayerKind,\r\n TextStyle,\r\n Transform,\r\n SpeechBubble,\r\n BoundingBox,\r\n BubbleTail,\r\n BubbleStyle,\r\n BalloonType,\r\n TailCurve,\r\n TailConfig,\r\n HideBorderConfig,\r\n BalloonConfig,\r\n BalloonConfigOverride,\r\n Hotspot,\r\n HotspotShape,\r\n HotspotRect,\r\n HotspotCircle,\r\n HotspotPolygon,\r\n HotspotAction,\r\n HotspotGoToAction,\r\n HotspotSetVariablesAction,\r\n HotspotOpenExtrasAction,\r\n HotspotOpenModalAction,\r\n HotspotPluginEventAction,\r\n PanelVariant,\r\n PanelPartial,\r\n PluginInstance,\r\n NormalizedRect,\r\n NormalizedPoint,\r\n JsonLogic,\r\n JsonLogicExpression,\r\n Mutation,\r\n} from './panel.types';\r\n\r\n// Asset types\r\nexport type {\r\n Assets,\r\n AssetBase,\r\n AssetCatalogItem,\r\n AssetCommon,\r\n AssetCategory,\r\n AssetCatalogItemImage,\r\n ImageVariant,\r\n AssetCatalogItemAudio,\r\n AudioRole,\r\n AudioVariant,\r\n AssetCatalogItemVideo,\r\n VideoVariant,\r\n VideoPoster,\r\n AssetCatalogItemSubtitle,\r\n SubtitleVariant,\r\n AssetCatalogItemVector,\r\n VectorVariant,\r\n AssetCatalogItemJson,\r\n JsonVariant,\r\n AssetCatalogItemPluginPayload,\r\n AssetVariant,\r\n AssetReference,\r\n} from './asset.types';\r\n\r\n// Infinite canvas types (schema 1.4)\r\nexport type {\r\n WorldPoint,\r\n WorldRect,\r\n CameraMove,\r\n CameraMovePath,\r\n CameraZoomProfile,\r\n CanvasRevealMode,\r\n CanvasPlacement,\r\n CanvasDecoration,\r\n CanvasFitMode,\r\n CanvasFreeRoam,\r\n CanvasOverviewPolicy,\r\n CanvasCameraPolicy,\r\n CanvasBackground,\r\n CanvasLayout,\r\n} from './canvas.types';\r\n\r\n// Graph types\r\nexport type {\r\n Graph,\r\n Edge,\r\n NodeMetadata,\r\n NavigationPath,\r\n TraversalOptions,\r\n TraversalResult,\r\n} from './graph.types';\r\n\r\n// Variable types\r\nexport type {\r\n Variables,\r\n VariableDefinition,\r\n VariableType,\r\n VariableScope,\r\n JsonValue,\r\n VariableStore,\r\n VariableMutation,\r\n MutationOperation,\r\n VariableChangeEvent,\r\n VariableValidationResult,\r\n VariableContext,\r\n UserVariables,\r\n PreferenceVariables,\r\n DeviceVariables,\r\n EntitlementVariables,\r\n} from './variable.types';\r\n\r\nexport { RESERVED_NAMESPACES } from './variable.types';\r\n\r\n// Player types\r\nexport type {\r\n PlayerOptions,\r\n DeepLinkTarget,\r\n PlayerState,\r\n ViewMode,\r\n ViewportState,\r\n PlayerPreferences,\r\n PaywallGate,\r\n OverlayState,\r\n PreloadStatus,\r\n PlayerError,\r\n PlayerErrorCode,\r\n PlayerEventData,\r\n PanelChangeEvent,\r\n DecisionEvent,\r\n PaywallEvent,\r\n ErrorEvent,\r\n TrackingConfig,\r\n Bookmark,\r\n ReadingProgress,\r\n PlayerStatistics,\r\n} from './player.types';\r\n\r\nexport { PlayerEvent } from './player.types';\r\n\r\nexport type { VideoTrigger, VideoTrackingPayload } from './player.types';\r\n\r\n// Entitlement types\r\nexport type {\r\n EntitlementAdapter,\r\n EntitlementContext,\r\n EntitlementStatus,\r\n UserInfo,\r\n PreviewInfo,\r\n PurchaseInfo,\r\n EntitlementErrorCode,\r\n} from './entitlement.types';\r\n\r\nexport {\r\n NullEntitlementAdapter,\r\n MockEntitlementAdapter,\r\n EntitlementError,\r\n} from './entitlement.types';\r\n","/**\r\n * Player State Service\r\n * Manages the current state of the player\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport type { Panel, LocaleCode, PlayerPreferences } from '../types';\r\n\r\n/** localStorage key for the reader's explicitly set preferences. */\r\nexport const PREFERENCES_STORAGE_KEY = 'pw-preferences';\r\n\r\n/**\r\n * Built-in preference defaults. A work's `settings.ui.*Default` can override\r\n * the toggle-backed ones (speech/audio/sfx) until the reader sets them.\r\n */\r\nexport const DEFAULT_PLAYER_PREFERENCES: PlayerPreferences = {\r\n speech: true,\r\n audio: true,\r\n sfx: true,\r\n autoplay: false,\r\n secondsPerPanel: 5,\r\n mangaMode: false,\r\n reducedMotion: false,\r\n highContrast: false,\r\n masterVolume: 1,\r\n sfxVolume: 1,\r\n};\r\n\r\n/**\r\n * Player State Service\r\n * Central state management for player\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class PlayerStateService {\r\n /**\r\n * Current panel subject\r\n */\r\n private currentPanelSubject = new BehaviorSubject<Panel | null>(null);\r\n\r\n /**\r\n * Current locale subject\r\n */\r\n private localeSubject = new BehaviorSubject<LocaleCode>('en-US');\r\n\r\n /**\r\n * Reader preferences subject\r\n */\r\n private preferencesSubject = new BehaviorSubject<PlayerPreferences>({\r\n ...DEFAULT_PLAYER_PREFERENCES,\r\n });\r\n\r\n /**\r\n * Preference keys the reader set explicitly (this session or a persisted\r\n * earlier one). Only these are written to localStorage, so an untouched\r\n * preference keeps following the built-in / per-work default.\r\n */\r\n private explicitPreferenceKeys = new Set<keyof PlayerPreferences>();\r\n\r\n /**\r\n * Current panel observable\r\n */\r\n readonly currentPanel$: Observable<Panel | null> = this.currentPanelSubject.asObservable();\r\n\r\n /**\r\n * Current locale observable\r\n */\r\n readonly locale$: Observable<LocaleCode> = this.localeSubject.asObservable();\r\n\r\n /**\r\n * Reader preferences observable\r\n */\r\n readonly preferences$: Observable<PlayerPreferences> = this.preferencesSubject.asObservable();\r\n\r\n constructor() {\r\n this.loadPersistedPreferences();\r\n }\r\n\r\n /**\r\n * Set current panel\r\n */\r\n setCurrentPanel(panel: Panel | null): void {\r\n this.currentPanelSubject.next(panel);\r\n }\r\n\r\n /**\r\n * Get current panel\r\n */\r\n getCurrentPanel(): Panel | null {\r\n return this.currentPanelSubject.value;\r\n }\r\n\r\n /**\r\n * Set locale\r\n */\r\n setLocale(locale: LocaleCode): void {\r\n this.localeSubject.next(locale);\r\n }\r\n\r\n /**\r\n * Get current locale\r\n */\r\n getLocale(): LocaleCode {\r\n return this.localeSubject.value;\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Preferences\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Current preferences snapshot.\r\n */\r\n getPreferences(): PlayerPreferences {\r\n return this.preferencesSubject.value;\r\n }\r\n\r\n /**\r\n * Whether the reader has explicitly set this preference (as opposed to it\r\n * still being the built-in default).\r\n */\r\n hasPersistedPreference(key: keyof PlayerPreferences): boolean {\r\n return this.explicitPreferenceKeys.has(key);\r\n }\r\n\r\n /**\r\n * Set one preference and persist it.\r\n */\r\n updatePreference<K extends keyof PlayerPreferences>(key: K, value: PlayerPreferences[K]): void {\r\n this.updatePreferences({ [key]: value } as Partial<PlayerPreferences>);\r\n }\r\n\r\n /**\r\n * Set several preferences at once and persist them.\r\n */\r\n updatePreferences(preferences: Partial<PlayerPreferences>): void {\r\n const next = { ...this.preferencesSubject.value, ...preferences };\r\n (Object.keys(preferences) as (keyof PlayerPreferences)[]).forEach((key) =>\r\n this.explicitPreferenceKeys.add(key)\r\n );\r\n this.preferencesSubject.next(next);\r\n this.persistPreferences(next);\r\n }\r\n\r\n /**\r\n * Load the explicitly set preferences from localStorage.\r\n */\r\n private loadPersistedPreferences(): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n try {\r\n const stored = localStorage.getItem(PREFERENCES_STORAGE_KEY);\r\n if (!stored) {\r\n return;\r\n }\r\n const parsed = JSON.parse(stored) as Partial<PlayerPreferences> | null;\r\n if (!parsed || typeof parsed !== 'object') {\r\n return;\r\n }\r\n const known: Partial<PlayerPreferences> = {};\r\n for (const key of Object.keys(DEFAULT_PLAYER_PREFERENCES) as (keyof PlayerPreferences)[]) {\r\n if (parsed[key] !== undefined) {\r\n (known as Record<string, unknown>)[key] = parsed[key];\r\n }\r\n }\r\n const next = { ...this.preferencesSubject.value, ...known };\r\n (Object.keys(known) as (keyof PlayerPreferences)[]).forEach((key) =>\r\n this.explicitPreferenceKeys.add(key)\r\n );\r\n this.preferencesSubject.next(next);\r\n } catch (error) {\r\n console.warn('[PlayerStateService] Failed to load persisted preferences:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Persist only the explicitly set preferences.\r\n */\r\n private persistPreferences(preferences: PlayerPreferences): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n try {\r\n const explicit: Partial<PlayerPreferences> = {};\r\n for (const key of this.explicitPreferenceKeys) {\r\n (explicit as Record<string, unknown>)[key] = preferences[key];\r\n }\r\n localStorage.setItem(PREFERENCES_STORAGE_KEY, JSON.stringify(explicit));\r\n } catch (error) {\r\n console.warn('[PlayerStateService] Failed to persist preferences:', error);\r\n }\r\n }\r\n}\r\n","/**\n * Manifest Service\n * Handles loading, validation, and indexing of PanelWave manifests\n */\n\nimport { inject, Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { Observable, of, throwError } from 'rxjs';\nimport { catchError, map } from 'rxjs/operators';\nimport type {\n PanelWaveManifest,\n Panel,\n Chapter,\n AssetCatalogItem,\n} from '../types';\n\n/**\n * Manifest indexes for fast lookups\n */\ninterface ManifestIndexes {\n panels: Map<string, { panel: Panel; chapterId: string }>;\n chapters: Map<string, Chapter>;\n assets: Map<string, AssetCatalogItem>;\n}\n\n/**\n * Manifest Service\n * Provides manifest loading, validation, and indexed access\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ManifestService {\n private manifest: PanelWaveManifest | null = null;\n private indexes: ManifestIndexes | null = null;\n\n private readonly http = inject(HttpClient);\n\n /**\n * Load manifest from a URL\n * @param url - URL to the manifest JSON file\n * @returns Observable of the loaded manifest\n */\n loadManifestFromUrl(url: string): Observable<PanelWaveManifest> {\n return this.http.get<PanelWaveManifest>(url).pipe(\n map((manifest) => {\n this.validateManifest(manifest);\n this.setManifest(manifest);\n return manifest;\n }),\n catchError((error) => {\n const errorMessage = error.message || 'Failed to load manifest';\n return throwError(() => new Error(`Manifest load failed: ${errorMessage}`));\n })\n );\n }\n\n /**\n * Load manifest from an object\n * @param manifest - Manifest object\n * @returns Observable of the validated manifest\n */\n loadManifestFromObject(manifest: PanelWaveManifest): Observable<PanelWaveManifest> {\n try {\n this.validateManifest(manifest);\n this.setManifest(manifest);\n return of(manifest);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Validation failed';\n return throwError(() => new Error(`Manifest validation failed: ${errorMessage}`));\n }\n }\n\n /**\n * Set the current manifest and build indexes\n */\n private setManifest(manifest: PanelWaveManifest): void {\n this.manifest = manifest;\n this.indexes = this.buildIndexes(manifest);\n }\n\n /**\n * Get the current manifest\n */\n getManifest(): PanelWaveManifest | null {\n return this.manifest;\n }\n\n /**\n * Check if a manifest is loaded\n */\n hasManifest(): boolean {\n return this.manifest !== null;\n }\n\n /**\n * Clear the current manifest and indexes\n */\n clearManifest(): void {\n this.manifest = null;\n this.indexes = null;\n }\n\n /**\n * Validate manifest structure\n */\n private validateManifest(manifest: unknown): asserts manifest is PanelWaveManifest {\n if (!manifest || typeof manifest !== 'object') {\n throw new Error('Manifest must be an object');\n }\n\n const m = manifest as Partial<PanelWaveManifest>;\n\n // Validate panelwave header\n if (!m.panelwave || typeof m.panelwave !== 'object') {\n throw new Error('Missing or invalid \"panelwave\" header');\n }\n\n if (!m.panelwave.version) {\n throw new Error('Missing \"panelwave.version\"');\n }\n\n // Validate meta\n if (!m.meta || typeof m.meta !== 'object') {\n throw new Error('Missing or invalid \"meta\" section');\n }\n\n if (!m.meta.id) {\n throw new Error('Missing \"meta.id\"');\n }\n\n if (!m.meta.title || typeof m.meta.title !== 'object') {\n throw new Error('Missing or invalid \"meta.title\"');\n }\n\n if (!Array.isArray(m.meta.locales) || m.meta.locales.length === 0) {\n throw new Error('Missing or empty \"meta.locales\"');\n }\n\n if (!m.meta.default_locale) {\n throw new Error('Missing \"meta.default_locale\"');\n }\n\n // Validate chapters\n if (!Array.isArray(m.chapters) || m.chapters.length === 0) {\n throw new Error('Missing or empty \"chapters\" array');\n }\n\n // Validate each chapter\n m.chapters.forEach((chapter, index) => {\n if (!chapter.id) {\n throw new Error(`Chapter at index ${index} missing \"id\"`);\n }\n\n if (!chapter.panels || typeof chapter.panels !== 'object') {\n throw new Error(`Chapter \"${chapter.id}\" missing or invalid \"panels\"`);\n }\n\n if (Object.keys(chapter.panels).length === 0) {\n throw new Error(`Chapter \"${chapter.id}\" has no panels`);\n }\n\n if (!chapter.graph || typeof chapter.graph !== 'object') {\n throw new Error(`Chapter \"${chapter.id}\" missing or invalid \"graph\"`);\n }\n\n if (!chapter.graph.entry) {\n throw new Error(`Chapter \"${chapter.id}\" missing \"graph.entry\"`);\n }\n\n if (!Array.isArray(chapter.graph.edges)) {\n throw new Error(`Chapter \"${chapter.id}\" missing or invalid \"graph.edges\"`);\n }\n });\n }\n\n /**\n * Build indexes for fast lookups\n */\n private buildIndexes(manifest: PanelWaveManifest): ManifestIndexes {\n const panels = new Map<string, { panel: Panel; chapterId: string }>();\n const chapters = new Map<string, Chapter>();\n const assets = new Map<string, AssetCatalogItem>();\n\n // Index chapters and panels\n manifest.chapters.forEach((chapter) => {\n chapters.set(chapter.id, chapter);\n\n Object.entries(chapter.panels).forEach(([panelId, panel]) => {\n panels.set(panelId, { panel, chapterId: chapter.id });\n });\n });\n\n // Index assets\n if (manifest.assets?.catalog) {\n manifest.assets.catalog.forEach((asset) => {\n assets.set(asset.id, asset);\n });\n }\n\n return { panels, chapters, assets };\n }\n\n /**\n * Get a panel by ID\n * @param panelId - Panel identifier\n * @returns Panel and its chapter ID, or null if not found\n */\n getPanel(panelId: string): { panel: Panel; chapterId: string } | null {\n if (!this.indexes) {\n return null;\n }\n\n return this.indexes.panels.get(panelId) || null;\n }\n\n /**\n * Get a chapter by ID\n * @param chapterId - Chapter identifier\n * @returns Chapter, or null if not found\n */\n getChapter(chapterId: string): Chapter | null {\n if (!this.indexes) {\n return null;\n }\n\n return this.indexes.chapters.get(chapterId) || null;\n }\n\n /**\n * Get an asset by ID\n * @param assetId - Asset identifier\n * @returns Asset catalog item, or null if not found\n */\n getAsset(assetId: string): AssetCatalogItem | null {\n if (!this.indexes) {\n return null;\n }\n\n return this.indexes.assets.get(assetId) || null;\n }\n\n /**\n * Get all panels in a chapter\n * @param chapterId - Chapter identifier\n * @returns Array of panel IDs and panels, or empty array if chapter not found\n */\n getPanelsInChapter(chapterId: string): { id: string; panel: Panel }[] {\n const chapter = this.getChapter(chapterId);\n if (!chapter) {\n return [];\n }\n\n return Object.entries(chapter.panels).map(([id, panel]) => ({ id, panel }));\n }\n\n /**\n * Get all chapter IDs\n * @returns Array of chapter IDs\n */\n getChapterIds(): string[] {\n if (!this.indexes) {\n return [];\n }\n\n return Array.from(this.indexes.chapters.keys());\n }\n\n /**\n * Get all panel IDs\n * @returns Array of panel IDs\n */\n getPanelIds(): string[] {\n if (!this.indexes) {\n return [];\n }\n\n return Array.from(this.indexes.panels.keys());\n }\n\n /**\n * Get all asset IDs\n * @returns Array of asset IDs\n */\n getAssetIds(): string[] {\n if (!this.indexes) {\n return [];\n }\n\n return Array.from(this.indexes.assets.keys());\n }\n\n /**\n * Check if a panel exists\n * @param panelId - Panel identifier\n * @returns True if panel exists\n */\n hasPanel(panelId: string): boolean {\n return this.getPanel(panelId) !== null;\n }\n\n /**\n * Check if a chapter exists\n * @param chapterId - Chapter identifier\n * @returns True if chapter exists\n */\n hasChapter(chapterId: string): boolean {\n return this.getChapter(chapterId) !== null;\n }\n\n /**\n * Check if an asset exists\n * @param assetId - Asset identifier\n * @returns True if asset exists\n */\n hasAsset(assetId: string): boolean {\n return this.getAsset(assetId) !== null;\n }\n\n /**\n * Get entry panel for a chapter\n * @param chapterId - Chapter identifier\n * @returns Entry panel ID(s), or null if chapter not found\n */\n getChapterEntry(chapterId: string): string | string[] | null {\n const chapter = this.getChapter(chapterId);\n return chapter?.graph.entry || null;\n }\n\n /**\n * Get total panel count\n * @returns Number of panels across all chapters\n */\n getPanelCount(): number {\n if (!this.indexes) {\n return 0;\n }\n\n return this.indexes.panels.size;\n }\n\n /**\n * Get total chapter count\n * @returns Number of chapters\n */\n getChapterCount(): number {\n if (!this.indexes) {\n return 0;\n }\n\n return this.indexes.chapters.size;\n }\n\n /**\n * Get total asset count\n * @returns Number of assets\n */\n getAssetCount(): number {\n if (!this.indexes) {\n return 0;\n }\n\n return this.indexes.assets.size;\n }\n}\n","/**\r\n * Variable Store Service\r\n * Manages scoped variable storage with persistence and mutations\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport type {\r\n VariableStore,\r\n VariableScope,\r\n VariableMutation,\r\n VariableContext,\r\n VariableDefinition,\r\n} from '../types';\r\n\r\n/**\r\n * Variable Store Service\r\n * Provides scoped variable storage with mutations and persistence\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class VariableStoreService {\r\n private readonly store$ = new BehaviorSubject<VariableStore>(this.createInitialStore());\r\n private definitions = new Map<string, VariableDefinition>();\r\n\r\n // Observable store\r\n readonly store: Observable<VariableStore> = this.store$.asObservable();\r\n\r\n constructor() {\r\n // Load persistent variables from storage\r\n this.loadPersistentVariables();\r\n }\r\n\r\n /**\r\n * Create initial empty store\r\n */\r\n private createInitialStore(): VariableStore {\r\n return {\r\n global: {},\r\n chapter: {},\r\n page: {},\r\n session: {},\r\n persistent: {},\r\n };\r\n }\r\n\r\n /**\r\n * Get current store snapshot\r\n */\r\n getStore(): VariableStore {\r\n return this.store$.value;\r\n }\r\n\r\n /**\r\n * Set variable definitions\r\n * @param definitions - Array of variable definitions\r\n */\r\n setDefinitions(definitions: VariableDefinition[]): void {\r\n this.definitions.clear();\r\n definitions.forEach((def) => {\r\n this.definitions.set(def.id, def);\r\n });\r\n\r\n // Initialize variables with defaults\r\n this.initializeDefaults();\r\n }\r\n\r\n /**\r\n * Initialize variables with default values\r\n */\r\n private initializeDefaults(): void {\r\n this.definitions.forEach((def) => {\r\n if (def.default !== undefined) {\r\n // Use internal set to bypass read-only check for initialization\r\n this.setInternal(def.id, def.default, def.scope);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get a variable value\r\n * @param id - Variable identifier\r\n * @param scope - Variable scope\r\n * @param scopeId - Scope identifier (for chapter/page scopes)\r\n * @returns Variable value or undefined\r\n */\r\n get(id: string, scope: VariableScope, scopeId?: string): unknown {\r\n const store = this.store$.value;\r\n\r\n switch (scope) {\r\n case 'global':\r\n return store.global[id];\r\n\r\n case 'chapter':\r\n if (!scopeId) return undefined;\r\n return store.chapter[scopeId]?.[id];\r\n\r\n case 'page':\r\n if (!scopeId) return undefined;\r\n return store.page[scopeId]?.[id];\r\n\r\n case 'session':\r\n return store.session[id];\r\n\r\n case 'persistent':\r\n return store.persistent[id];\r\n\r\n default:\r\n return undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Set a variable value\r\n * @param id - Variable identifier\r\n * @param value - Variable value\r\n * @param scope - Variable scope\r\n * @param scopeId - Scope identifier (for chapter/page scopes)\r\n */\r\n set(id: string, value: unknown, scope: VariableScope, scopeId?: string): void {\r\n // Check if variable is read-only\r\n const def = this.definitions.get(id);\r\n if (def?.readOnly) {\r\n console.warn(`[VariableStore] Cannot set read-only variable: ${id}`);\r\n return;\r\n }\r\n\r\n // Validate type\r\n if (def && !this.validateType(value, def)) {\r\n console.warn(`[VariableStore] Type validation failed for ${id}`);\r\n return;\r\n }\r\n\r\n this.setInternal(id, value, scope, scopeId);\r\n }\r\n\r\n /**\r\n * Privileged initialization write for host-supplied values (the shell's\r\n * `initialVariables` input, the entitlement adapter's context). Unlike\r\n * `set()`, this MAY seed `readOnly` variables — that is exactly how an\r\n * externally-sourced value (e.g. a verified `user.age`) gets in while\r\n * staying immune to in-story mutations and settings edits. Types are\r\n * still validated against the definition; invalid values are dropped\r\n * with a warning. Each value lands in its definition's declared scope\r\n * (undeclared ids default to `global`).\r\n */\r\n seed(values: Record<string, unknown>): void {\r\n Object.entries(values).forEach(([id, value]) => {\r\n const def = this.definitions.get(id);\r\n if (def && !this.validateType(value, def)) {\r\n console.warn(`[VariableStore] Seed value for \"${id}\" failed type validation - dropped`);\r\n return;\r\n }\r\n this.setInternal(id, value, def?.scope ?? 'global');\r\n });\r\n }\r\n\r\n /**\r\n * Internal set method (bypasses read-only and validation checks)\r\n */\r\n private setInternal(id: string, value: unknown, scope: VariableScope, scopeId?: string): void {\r\n const store = this.store$.value;\r\n\r\n switch (scope) {\r\n case 'global':\r\n store.global[id] = value;\r\n break;\r\n\r\n case 'chapter':\r\n if (!scopeId) return;\r\n if (!store.chapter[scopeId]) {\r\n store.chapter[scopeId] = {};\r\n }\r\n store.chapter[scopeId][id] = value;\r\n break;\r\n\r\n case 'page':\r\n if (!scopeId) return;\r\n if (!store.page[scopeId]) {\r\n store.page[scopeId] = {};\r\n }\r\n store.page[scopeId][id] = value;\r\n break;\r\n\r\n case 'session':\r\n store.session[id] = value;\r\n break;\r\n\r\n case 'persistent':\r\n store.persistent[id] = value;\r\n this.persistVariable(id, value);\r\n break;\r\n }\r\n\r\n // Emit updated store\r\n this.store$.next({ ...store });\r\n }\r\n\r\n /**\r\n * Apply a variable mutation\r\n * @param mutation - Mutation to apply\r\n * @param scope - Variable scope\r\n * @param scopeId - Scope identifier (for chapter/page scopes)\r\n */\r\n applyMutation(mutation: VariableMutation, scope: VariableScope, scopeId?: string): void {\r\n const currentValue = this.get(mutation.var, scope, scopeId);\r\n\r\n switch (mutation.op) {\r\n case 'set':\r\n this.set(mutation.var, mutation.value, scope, scopeId);\r\n break;\r\n\r\n case 'increment':\r\n if (typeof currentValue === 'number') {\r\n const amount = mutation.amount ?? 1;\r\n this.set(mutation.var, currentValue + amount, scope, scopeId);\r\n }\r\n break;\r\n\r\n case 'decrement':\r\n if (typeof currentValue === 'number') {\r\n const amount = mutation.amount ?? 1;\r\n this.set(mutation.var, currentValue - amount, scope, scopeId);\r\n }\r\n break;\r\n\r\n case 'toggle':\r\n if (typeof currentValue === 'boolean') {\r\n this.set(mutation.var, !currentValue, scope, scopeId);\r\n }\r\n break;\r\n\r\n case 'append':\r\n if (Array.isArray(currentValue)) {\r\n this.set(mutation.var, [...currentValue, mutation.value], scope, scopeId);\r\n } else {\r\n this.set(mutation.var, [mutation.value], scope, scopeId);\r\n }\r\n break;\r\n\r\n case 'remove':\r\n if (Array.isArray(currentValue)) {\r\n const filtered = currentValue.filter((item) => item !== mutation.value);\r\n this.set(mutation.var, filtered, scope, scopeId);\r\n }\r\n break;\r\n\r\n case 'clear': {\r\n const def = this.definitions.get(mutation.var);\r\n const defaultValue = def?.default ?? null;\r\n this.set(mutation.var, defaultValue, scope, scopeId);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Apply a manifest Mutation[] (hotspot/edge actions). Scope comes from the\r\n * variable's definition; undeclared variables fall back to session scope.\r\n * The schema's `increment` carries its delta in `value`, so a numeric value\r\n * is mapped onto the store's `amount`.\r\n * @param mutations - Mutations in manifest shape ({ op, var, value? })\r\n * @param ids - Scope identifiers for chapter/page-scoped variables\r\n */\r\n applyMutations(\r\n mutations: { op: string; var: string; value?: unknown }[],\r\n ids?: { chapterId?: string; pageId?: string }\r\n ): void {\r\n for (const m of mutations ?? []) {\r\n const def = this.definitions.get(m.var);\r\n const scope: VariableScope = def?.scope ?? 'session';\r\n const scopeId =\r\n scope === 'chapter' ? ids?.chapterId : scope === 'page' ? ids?.pageId : undefined;\r\n if ((scope === 'chapter' || scope === 'page') && !scopeId) {\r\n continue;\r\n }\r\n this.applyMutation(\r\n {\r\n op: m.op,\r\n var: m.var,\r\n value: m.value,\r\n amount: typeof m.value === 'number' ? m.value : undefined,\r\n } as VariableMutation,\r\n scope,\r\n scopeId\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Reset a scope\r\n * @param scope - Scope to reset\r\n * @param scopeId - Scope identifier (for chapter/page scopes)\r\n */\r\n resetScope(scope: VariableScope, scopeId?: string): void {\r\n const store = this.store$.value;\r\n\r\n switch (scope) {\r\n case 'global':\r\n store.global = {};\r\n break;\r\n\r\n case 'chapter':\r\n if (scopeId) {\r\n delete store.chapter[scopeId];\r\n } else {\r\n store.chapter = {};\r\n }\r\n break;\r\n\r\n case 'page':\r\n if (scopeId) {\r\n delete store.page[scopeId];\r\n } else {\r\n store.page = {};\r\n }\r\n break;\r\n\r\n case 'session':\r\n store.session = {};\r\n break;\r\n\r\n case 'persistent':\r\n store.persistent = {};\r\n this.clearPersistentStorage();\r\n break;\r\n }\r\n\r\n this.store$.next({ ...store });\r\n\r\n // Re-initialize defaults for the reset scope\r\n this.initializeDefaultsForScope(scope, scopeId);\r\n }\r\n\r\n /**\r\n * Initialize defaults for a specific scope\r\n */\r\n private initializeDefaultsForScope(scope: VariableScope, scopeId?: string): void {\r\n this.definitions.forEach((def) => {\r\n if (def.scope === scope && def.default !== undefined) {\r\n this.set(def.id, def.default, scope, scopeId);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Create a flat context for JSON Logic evaluation\r\n * @param chapterId - Current chapter ID\r\n * @param pageId - Current page ID\r\n * @returns Flat variable context\r\n */\r\n createContext(chapterId?: string, pageId?: string): VariableContext {\r\n const store = this.store$.value;\r\n const context: VariableContext = {};\r\n\r\n // Add global variables\r\n Object.assign(context, store.global);\r\n\r\n // Add session variables\r\n Object.assign(context, store.session);\r\n\r\n // Add persistent variables\r\n Object.assign(context, store.persistent);\r\n\r\n // Add chapter-specific variables\r\n if (chapterId && store.chapter[chapterId]) {\r\n Object.assign(context, store.chapter[chapterId]);\r\n }\r\n\r\n // Add page-specific variables\r\n if (pageId && store.page[pageId]) {\r\n Object.assign(context, store.page[pageId]);\r\n }\r\n\r\n // json-logic-js resolves {\"var\": \"path.choice\"} by splitting on '.'\r\n // and traversing nested objects, but variables are stored under\r\n // their flat dotted key. Expand dotted keys into nested structures\r\n // so manifest conditions (edges, visibleIf, variants) can reference\r\n // dot-namespaced variable ids. The flat key is kept as well.\r\n this.expandDottedKeys(context);\r\n\r\n return context;\r\n }\r\n\r\n /**\r\n * Expand flat dotted keys ('path.choice') into nested objects\r\n * ({ path: { choice } }), merging into any existing plain object and\r\n * never clobbering non-object values on the way down.\r\n */\r\n private expandDottedKeys(context: VariableContext): void {\r\n for (const key of Object.keys(context)) {\r\n if (!key.includes('.')) {\r\n continue;\r\n }\r\n const parts = key.split('.');\r\n let node: Record<string, unknown> = context;\r\n let ok = true;\r\n for (let i = 0; i < parts.length - 1; i++) {\r\n const part = parts[i];\r\n const existing = node[part];\r\n if (existing === undefined || existing === null) {\r\n const child: Record<string, unknown> = {};\r\n node[part] = child;\r\n node = child;\r\n } else if (typeof existing === 'object' && !Array.isArray(existing)) {\r\n node = existing as Record<string, unknown>;\r\n } else {\r\n // A non-object value occupies this segment - leave it alone.\r\n ok = false;\r\n break;\r\n }\r\n }\r\n if (ok) {\r\n node[parts[parts.length - 1]] = context[key];\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get all variables in a scope\r\n * @param scope - Variable scope\r\n * @param scopeId - Scope identifier (for chapter/page scopes)\r\n * @returns Record of variables\r\n */\r\n getScopeVariables(scope: VariableScope, scopeId?: string): Record<string, unknown> {\r\n const store = this.store$.value;\r\n\r\n switch (scope) {\r\n case 'global':\r\n return { ...store.global };\r\n\r\n case 'chapter':\r\n return scopeId && store.chapter[scopeId] ? { ...store.chapter[scopeId] } : {};\r\n\r\n case 'page':\r\n return scopeId && store.page[scopeId] ? { ...store.page[scopeId] } : {};\r\n\r\n case 'session':\r\n return { ...store.session };\r\n\r\n case 'persistent':\r\n return { ...store.persistent };\r\n\r\n default:\r\n return {};\r\n }\r\n }\r\n\r\n /**\r\n * Check if a variable exists\r\n * @param id - Variable identifier\r\n * @param scope - Variable scope\r\n * @param scopeId - Scope identifier (for chapter/page scopes)\r\n * @returns True if variable exists\r\n */\r\n has(id: string, scope: VariableScope, scopeId?: string): boolean {\r\n return this.get(id, scope, scopeId) !== undefined;\r\n }\r\n\r\n /**\r\n * Validate variable type\r\n */\r\n private validateType(value: unknown, def: VariableDefinition): boolean {\r\n switch (def.type) {\r\n case 'boolean':\r\n return typeof value === 'boolean';\r\n\r\n case 'number':\r\n case 'integer':\r\n if (typeof value !== 'number') return false;\r\n if (def.type === 'integer' && !Number.isInteger(value)) return false;\r\n if (def.min !== undefined && value < def.min) return false;\r\n if (def.max !== undefined && value > def.max) return false;\r\n return true;\r\n\r\n case 'string':\r\n if (typeof value !== 'string') return false;\r\n if (def.pattern) {\r\n try {\r\n return new RegExp(def.pattern).test(value);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n return true;\r\n\r\n case 'enum':\r\n return def.enum ? def.enum.includes(value as string) : false;\r\n\r\n case 'date':\r\n case 'time':\r\n case 'datetime':\r\n return typeof value === 'string';\r\n\r\n default:\r\n return true;\r\n }\r\n }\r\n\r\n /**\r\n * Load persistent variables from localStorage\r\n */\r\n private loadPersistentVariables(): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n\r\n try {\r\n const stored = localStorage.getItem('pw-variables-persistent');\r\n if (stored) {\r\n const persistent = JSON.parse(stored);\r\n const store = this.store$.value;\r\n store.persistent = persistent;\r\n this.store$.next({ ...store });\r\n }\r\n } catch (error) {\r\n console.warn('[VariableStore] Failed to load persistent variables:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Persist a single variable to localStorage\r\n */\r\n private persistVariable(_id: string, _value: unknown): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n\r\n try {\r\n const store = this.store$.value;\r\n localStorage.setItem('pw-variables-persistent', JSON.stringify(store.persistent));\r\n } catch (error) {\r\n console.warn('[VariableStore] Failed to persist variable:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Clear persistent storage\r\n */\r\n private clearPersistentStorage(): void {\r\n if (typeof localStorage === 'undefined') {\r\n return;\r\n }\r\n\r\n try {\r\n localStorage.removeItem('pw-variables-persistent');\r\n } catch (error) {\r\n console.warn('[VariableStore] Failed to clear persistent storage:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Reset all scopes\r\n */\r\n resetAll(): void {\r\n this.store$.next(this.createInitialStore());\r\n this.clearPersistentStorage();\r\n this.initializeDefaults();\r\n }\r\n}\r\n","/**\n * Locale Utilities\n * Helper functions for handling localized strings and assets\n */\n\nimport type { LocalizedString, LocaleCode } from '../types';\n\n/**\n * Resolve a localized string to the best matching locale\n * \n * @param localizedString - Dictionary of localized strings\n * @param requestedLocale - Desired locale (e.g., \"en-US\")\n * @param fallbackLocale - Fallback locale (e.g., \"en-US\")\n * @returns The resolved string, or empty string if no match found\n * \n * @example\n * ```typescript\n * const title = {\n * 'en-US': 'Hello',\n * 'de-DE': 'Hallo',\n * 'fr-FR': 'Bonjour'\n * };\n * \n * resolveLocalizedString(title, 'en-GB', 'en-US');\n * // Returns: 'Hello' (falls back to en-US)\n * \n * resolveLocalizedString(title, 'de-DE', 'en-US');\n * // Returns: 'Hallo' (exact match)\n * ```\n */\nexport function resolveLocalizedString(\n localizedString: LocalizedString | undefined,\n requestedLocale: LocaleCode,\n fallbackLocale: LocaleCode\n): string {\n // Return empty string if no localized string provided\n if (!localizedString || Object.keys(localizedString).length === 0) {\n return '';\n }\n\n // Try exact match first\n if (localizedString[requestedLocale]) {\n return localizedString[requestedLocale];\n }\n\n // Try base language match (e.g., \"en\" from \"en-GB\")\n const baseLanguage = getBaseLanguage(requestedLocale);\n const baseMatch = Object.keys(localizedString).find(\n (locale) => getBaseLanguage(locale) === baseLanguage\n );\n if (baseMatch && localizedString[baseMatch]) {\n return localizedString[baseMatch];\n }\n\n // Try fallback locale\n if (localizedString[fallbackLocale]) {\n return localizedString[fallbackLocale];\n }\n\n // Try base language of fallback\n const fallbackBase = getBaseLanguage(fallbackLocale);\n const fallbackBaseMatch = Object.keys(localizedString).find(\n (locale) => getBaseLanguage(locale) === fallbackBase\n );\n if (fallbackBaseMatch && localizedString[fallbackBaseMatch]) {\n return localizedString[fallbackBaseMatch];\n }\n\n // Return first available string as last resort\n const firstLocale = Object.keys(localizedString)[0];\n return localizedString[firstLocale] || '';\n}\n\n/**\n * Extract base language from a locale code\n * \n * @param locale - Locale code (e.g., \"en-US\", \"zh-Hans-CN\")\n * @returns Base language code (e.g., \"en\", \"zh\")\n * \n * @example\n * ```typescript\n * getBaseLanguage('en-US'); // Returns: 'en'\n * getBaseLanguage('de-DE'); // Returns: 'de'\n * getBaseLanguage('zh-Hans-CN'); // Returns: 'zh'\n * getBaseLanguage('en'); // Returns: 'en'\n * ```\n */\nexport function getBaseLanguage(locale: LocaleCode): string {\n if (!locale) {\n return '';\n }\n \n // Split on hyphen and return first part\n const parts = locale.split('-');\n return parts[0].toLowerCase();\n}\n\n/**\n * Pick the best asset variant for the given locale\n * \n * @param variants - Array of asset variants with optional locale property\n * @param requestedLocale - Desired locale\n * @param fallbackLocale - Fallback locale\n * @returns The best matching variant, or first variant if no locale match\n * \n * @example\n * ```typescript\n * const variants = [\n * { src: 'audio-en.mp3', mime: 'audio/mpeg', locale: 'en-US' },\n * { src: 'audio-de.mp3', mime: 'audio/mpeg', locale: 'de-DE' },\n * { src: 'audio.mp3', mime: 'audio/mpeg' } // No locale (universal)\n * ];\n * \n * pickLocalizedAsset(variants, 'de-DE', 'en-US');\n * // Returns: { src: 'audio-de.mp3', mime: 'audio/mpeg', locale: 'de-DE' }\n * ```\n */\nexport function pickLocalizedAsset<T extends { locale?: LocaleCode }>(\n variants: T[],\n requestedLocale: LocaleCode,\n fallbackLocale: LocaleCode\n): T | undefined {\n if (!variants || variants.length === 0) {\n return undefined;\n }\n\n // Try exact locale match\n const exactMatch = variants.find((v) => v.locale === requestedLocale);\n if (exactMatch) {\n return exactMatch;\n }\n\n // Try base language match\n const baseLanguage = getBaseLanguage(requestedLocale);\n const baseMatch = variants.find(\n (v) => v.locale && getBaseLanguage(v.locale) === baseLanguage\n );\n if (baseMatch) {\n return baseMatch;\n }\n\n // Try fallback locale\n const fallbackMatch = variants.find((v) => v.locale === fallbackLocale);\n if (fallbackMatch) {\n return fallbackMatch;\n }\n\n // Try base language of fallback\n const fallbackBase = getBaseLanguage(fallbackLocale);\n const fallbackBaseMatch = variants.find(\n (v) => v.locale && getBaseLanguage(v.locale) === fallbackBase\n );\n if (fallbackBaseMatch) {\n return fallbackBaseMatch;\n }\n\n // Return variant without locale (universal) if exists\n const universalVariant = variants.find((v) => !v.locale);\n if (universalVariant) {\n return universalVariant;\n }\n\n // Return first variant as last resort\n return variants[0];\n}\n\n/**\n * Check if a locale is supported in the given list\n * \n * @param locale - Locale to check\n * @param supportedLocales - Array of supported locale codes\n * @returns True if locale is supported (exact or base language match)\n * \n * @example\n * ```typescript\n * const supported = ['en-US', 'de-DE', 'fr-FR'];\n * \n * isLocaleSupported('en-US', supported); // true (exact match)\n * isLocaleSupported('en-GB', supported); // true (base language match)\n * isLocaleSupported('es-ES', supported); // false (no match)\n * ```\n */\nexport function isLocaleSupported(\n locale: LocaleCode,\n supportedLocales: LocaleCode[]\n): boolean {\n if (!locale || !supportedLocales || supportedLocales.length === 0) {\n return false;\n }\n\n // Check exact match\n if (supportedLocales.includes(locale)) {\n return true;\n }\n\n // Check base language match\n const baseLanguage = getBaseLanguage(locale);\n return supportedLocales.some(\n (supported) => getBaseLanguage(supported) === baseLanguage\n );\n}\n\n/**\n * Get completion percentage for localized content\n * \n * @param localizedStrings - Array of localized string objects\n * @param targetLocale - Locale to check completion for\n * @returns Percentage (0-100) of strings available in target locale\n * \n * @example\n * ```typescript\n * const strings = [\n * { 'en-US': 'Hello', 'de-DE': 'Hallo' },\n * { 'en-US': 'World', 'de-DE': 'Welt' },\n * { 'en-US': 'Goodbye' } // Missing de-DE\n * ];\n * \n * getLocalizationCompleteness(strings, 'de-DE');\n * // Returns: 66.67 (2 out of 3 strings have de-DE)\n * ```\n */\nexport function getLocalizationCompleteness(\n localizedStrings: LocalizedString[],\n targetLocale: LocaleCode\n): number {\n if (!localizedStrings || localizedStrings.length === 0) {\n return 0;\n }\n\n const total = localizedStrings.length;\n const translated = localizedStrings.filter(\n (str) => str && str[targetLocale]\n ).length;\n\n return (translated / total) * 100;\n}\n\n/**\n * Create a fallback chain for locale resolution\n * \n * @param requestedLocale - Primary locale\n * @param fallbackLocale - Secondary fallback locale\n * @returns Array of locales to try in order\n * \n * @example\n * ```typescript\n * createLocaleFallbackChain('en-GB', 'en-US');\n * // Returns: ['en-GB', 'en', 'en-US']\n * \n * createLocaleFallbackChain('zh-Hans-CN', 'en-US');\n * // Returns: ['zh-Hans-CN', 'zh', 'en-US', 'en']\n * ```\n */\nexport function createLocaleFallbackChain(\n requestedLocale: LocaleCode,\n fallbackLocale: LocaleCode\n): LocaleCode[] {\n const chain: LocaleCode[] = [];\n const seen = new Set<string>();\n\n // Add requested locale\n if (requestedLocale && !seen.has(requestedLocale)) {\n chain.push(requestedLocale);\n seen.add(requestedLocale);\n }\n\n // Add base language of requested\n const requestedBase = getBaseLanguage(requestedLocale);\n if (requestedBase && !seen.has(requestedBase)) {\n chain.push(requestedBase);\n seen.add(requestedBase);\n }\n\n // Add fallback locale\n if (fallbackLocale && !seen.has(fallbackLocale)) {\n chain.push(fallbackLocale);\n seen.add(fallbackLocale);\n }\n\n // Add base language of fallback\n const fallbackBase = getBaseLanguage(fallbackLocale);\n if (fallbackBase && !seen.has(fallbackBase)) {\n chain.push(fallbackBase);\n seen.add(fallbackBase);\n }\n\n return chain;\n}\n\n/**\n * Normalize locale code to standard format\n * \n * @param locale - Locale code in any format\n * @returns Normalized locale code (e.g., \"en-US\")\n * \n * @example\n * ```typescript\n * normalizeLocaleCode('en_us'); // Returns: 'en-US'\n * normalizeLocaleCode('EN-us'); // Returns: 'en-US'\n * normalizeLocaleCode('en'); // Returns: 'en'\n * ```\n */\nexport function normalizeLocaleCode(locale: LocaleCode): LocaleCode {\n if (!locale) {\n return '';\n }\n\n // Replace underscore with hyphen\n const normalized = locale.replace(/_/g, '-');\n\n // Split into parts\n const parts = normalized.split('-');\n\n // Lowercase language code\n if (parts.length > 0) {\n parts[0] = parts[0].toLowerCase();\n }\n\n // Uppercase region code\n if (parts.length > 1) {\n parts[parts.length - 1] = parts[parts.length - 1].toUpperCase();\n }\n\n return parts.join('-');\n}\n","/**\r\n * Video Config Utilities\r\n * Resolves the effective VideoLayer playback config from layer fields,\r\n * legacy schema 1.0 fields, and work-level `settings.ui` defaults.\r\n */\r\n\r\nimport type {\r\n VideoLayer,\r\n VideoPlayMode,\r\n VideoStartMode,\r\n UIDefaults,\r\n} from '../types';\r\n\r\n/** Built-in defaults (schema 1.1) */\r\nexport const DEFAULT_VIDEO_PLAY_MODE: VideoPlayMode = 'once';\r\nexport const DEFAULT_VIDEO_START_MODE: VideoStartMode = 'on-view';\r\nexport const DEFAULT_VIDEO_MUTED = true;\r\n\r\n/**\r\n * Fully resolved, non-optional video playback configuration.\r\n */\r\nexport interface EffectiveVideoConfig {\r\n playMode: VideoPlayMode;\r\n startMode: VideoStartMode;\r\n muted: boolean;\r\n startAtMs: number;\r\n /** Only meaningful for playMode 'loop-from'; otherwise undefined. */\r\n loopFromMs?: number;\r\n}\r\n\r\n/**\r\n * Resolve the effective play mode.\r\n *\r\n * Precedence: explicit `playMode` (new field always wins) → legacy `loop: true`\r\n * ⇒ `loop` → work-level `videoPlayModeDefault` → built-in `once`.\r\n */\r\nexport function resolvePlayMode(\r\n layer: Partial<VideoLayer>,\r\n uiDefaults?: UIDefaults\r\n): VideoPlayMode {\r\n if (layer.playMode) {\r\n return layer.playMode;\r\n }\r\n // Legacy mapping: loop: true ⇒ playMode 'loop'\r\n if (layer.loop === true) {\r\n return 'loop';\r\n }\r\n if (uiDefaults?.videoPlayModeDefault) {\r\n return uiDefaults.videoPlayModeDefault;\r\n }\r\n return DEFAULT_VIDEO_PLAY_MODE;\r\n}\r\n\r\n/**\r\n * Resolve the effective start mode.\r\n *\r\n * Precedence: explicit `startMode` (new field always wins) → legacy `autoplay`\r\n * (`true` ⇒ `on-view`, explicit `false` ⇒ `on-click`) → work-level\r\n * `videoStartModeDefault` → built-in `on-view`.\r\n */\r\nexport function resolveStartMode(\r\n layer: Partial<VideoLayer>,\r\n uiDefaults?: UIDefaults\r\n): VideoStartMode {\r\n if (layer.startMode) {\r\n return layer.startMode;\r\n }\r\n // Legacy mapping: autoplay true ⇒ on-view, explicit false ⇒ on-click\r\n if (layer.autoplay === true) {\r\n return 'on-view';\r\n }\r\n if (layer.autoplay === false) {\r\n return 'on-click';\r\n }\r\n if (uiDefaults?.videoStartModeDefault) {\r\n return uiDefaults.videoStartModeDefault;\r\n }\r\n return DEFAULT_VIDEO_START_MODE;\r\n}\r\n\r\n/**\r\n * Resolve the effective muted state.\r\n *\r\n * Precedence: explicit layer `muted` → work-level `videoMutedDefault` → built-in\r\n * `true` (work-level default is muted).\r\n */\r\nexport function resolveMuted(\r\n layer: Partial<VideoLayer>,\r\n uiDefaults?: UIDefaults\r\n): boolean {\r\n if (layer.muted !== undefined) {\r\n return layer.muted;\r\n }\r\n if (uiDefaults?.videoMutedDefault !== undefined) {\r\n return uiDefaults.videoMutedDefault;\r\n }\r\n return DEFAULT_VIDEO_MUTED;\r\n}\r\n\r\n/**\r\n * Resolve the full effective video config (play mode, start mode, muted,\r\n * startAtMs, loopFromMs) from a layer and optional work-level UI defaults.\r\n */\r\nexport function resolveVideoConfig(\r\n layer: Partial<VideoLayer>,\r\n uiDefaults?: UIDefaults\r\n): EffectiveVideoConfig {\r\n const playMode = resolvePlayMode(layer, uiDefaults);\r\n return {\r\n playMode,\r\n startMode: resolveStartMode(layer, uiDefaults),\r\n muted: resolveMuted(layer, uiDefaults),\r\n startAtMs: typeof layer.startAtMs === 'number' ? Math.max(0, layer.startAtMs) : 0,\r\n loopFromMs: playMode === 'loop-from' ? layer.loopFromMs : undefined,\r\n };\r\n}\r\n","/**\r\n * Asset Utilities\r\n * Helper functions for asset URL resolution and variant selection\r\n */\r\n\r\nimport type {\r\n AssetBase,\r\n AssetCatalogItem,\r\n AssetCategory,\r\n ImageVariant,\r\n} from '../types';\r\n\r\n/**\r\n * Resolve an asset URL using base URLs and asset reference\r\n * \r\n * @param assetId - Asset identifier or full URL\r\n * @param assetBase - Asset base URL configuration\r\n * @param category - Asset category for selecting appropriate base URL\r\n * @returns Resolved absolute URL\r\n * \r\n * @example\r\n * ```typescript\r\n * const base = {\r\n * imageBase: 'https://cdn.example.com/images/',\r\n * audioBase: 'https://cdn.example.com/audio/'\r\n * };\r\n * \r\n * resolveAssetUrl('hero.jpg', base, 'image');\r\n * // Returns: 'https://cdn.example.com/images/hero.jpg'\r\n * \r\n * resolveAssetUrl('https://example.com/hero.jpg', base, 'image');\r\n * // Returns: 'https://example.com/hero.jpg' (already absolute)\r\n * ```\r\n */\r\nexport function resolveAssetUrl(\r\n assetId: string,\r\n assetBase?: AssetBase,\r\n category?: AssetCategory\r\n): string {\r\n if (!assetId) {\r\n return '';\r\n }\r\n\r\n // If already an absolute URL, return as-is\r\n if (isAbsoluteUrl(assetId)) {\r\n return assetId;\r\n }\r\n\r\n // If no base URLs provided, return relative path\r\n if (!assetBase) {\r\n return assetId;\r\n }\r\n\r\n // Select appropriate base URL based on category\r\n let baseUrl = assetBase.mediaBase || '';\r\n\r\n if (category && assetBase) {\r\n switch (category) {\r\n case 'image':\r\n baseUrl = assetBase.imageBase || assetBase.mediaBase || '';\r\n break;\r\n case 'audio':\r\n baseUrl = assetBase.audioBase || assetBase.mediaBase || '';\r\n break;\r\n case 'video':\r\n baseUrl = assetBase.videoBase || assetBase.mediaBase || '';\r\n break;\r\n case 'subtitle':\r\n baseUrl = assetBase.mediaBase || '';\r\n break;\r\n case 'vector':\r\n baseUrl = assetBase.imageBase || assetBase.mediaBase || '';\r\n break;\r\n case 'json':\r\n baseUrl = assetBase.mediaBase || '';\r\n break;\r\n case 'pluginPayload':\r\n baseUrl = assetBase.pluginsBase || assetBase.mediaBase || '';\r\n break;\r\n }\r\n }\r\n\r\n // Ensure base URL ends with slash\r\n if (baseUrl && !baseUrl.endsWith('/')) {\r\n baseUrl += '/';\r\n }\r\n\r\n // Remove leading slash from asset ID if present\r\n const cleanAssetId = assetId.startsWith('/') ? assetId.slice(1) : assetId;\r\n\r\n return baseUrl + cleanAssetId;\r\n}\r\n\r\n/**\r\n * Check if a URL is absolute\r\n * \r\n * @param url - URL to check\r\n * @returns True if URL is absolute (has protocol)\r\n */\r\nexport function isAbsoluteUrl(url: string): boolean {\r\n if (!url) {\r\n return false;\r\n }\r\n \r\n // Check for protocol (http://, https://, data:, blob:, etc.)\r\n return /^[a-z][a-z0-9+.-]*:/i.test(url);\r\n}\r\n\r\n/**\r\n * Select the best image variant based on target dimensions and pixel density\r\n * \r\n * @param variants - Array of image variants\r\n * @param targetWidth - Target width in pixels\r\n * @param pixelDensity - Device pixel ratio (default: 1)\r\n * @returns Best matching image variant\r\n * \r\n * @example\r\n * ```typescript\r\n * const variants = [\r\n * { src: 'hero-400.jpg', w: 400, h: 300, mime: 'image/jpeg' },\r\n * { src: 'hero-800.jpg', w: 800, h: 600, mime: 'image/jpeg' },\r\n * { src: 'hero-1600.jpg', w: 1600, h: 1200, mime: 'image/jpeg' }\r\n * ];\r\n * \r\n * // For 500px wide display with 2x density (1000px actual)\r\n * selectBestImageVariant(variants, 500, 2);\r\n * // Returns: hero-1600.jpg (closest match >= 1000px)\r\n * ```\r\n */\r\nexport function selectBestImageVariant(\r\n variants: ImageVariant[],\r\n targetWidth: number,\r\n pixelDensity = 1\r\n): ImageVariant | undefined {\r\n if (!variants || variants.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // Calculate actual required width considering pixel density\r\n const requiredWidth = targetWidth * pixelDensity;\r\n\r\n // Sort variants by width\r\n const sorted = [...variants].sort((a, b) => a.w - b.w);\r\n\r\n // Find smallest variant that meets or exceeds required width\r\n const suitable = sorted.find((v) => v.w >= requiredWidth);\r\n \r\n // If found, return it; otherwise return largest available\r\n return suitable || sorted[sorted.length - 1];\r\n}\r\n\r\n/**\r\n * Select asset variant by preferred format/codec\r\n * \r\n * @param variants - Array of asset variants\r\n * @param preferredFormats - Array of preferred MIME types in order\r\n * @returns Best matching variant, or first variant if no preference match\r\n * \r\n * @example\r\n * ```typescript\r\n * const variants = [\r\n * { src: 'image.avif', mime: 'image/avif', w: 1920, h: 1080 },\r\n * { src: 'image.webp', mime: 'image/webp', w: 1920, h: 1080 },\r\n * { src: 'image.jpg', mime: 'image/jpeg', w: 1920, h: 1080 }\r\n * ];\r\n * \r\n * selectVariantByFormat(variants, ['image/avif', 'image/webp', 'image/jpeg']);\r\n * // Returns: { src: 'image.avif', ... } (first available in preference order)\r\n * ```\r\n */\r\nexport function selectVariantByFormat<T extends { src: string; mime?: string }>(\r\n variants: T[],\r\n preferredFormats: string[]\r\n): T | undefined {\r\n if (!variants || variants.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // Try each preferred format in order. A variant without an explicit mime\r\n // (optional since schema 1.2) is matched via its src file extension.\r\n for (const format of preferredFormats) {\r\n const match = variants.find((v) => (v.mime ?? guessMimeType(v.src)) === format);\r\n if (match) {\r\n return match;\r\n }\r\n }\r\n\r\n // Return first variant if no preference match\r\n return variants[0];\r\n}\r\n\r\n/**\r\n * Get asset from catalog by ID\r\n * \r\n * @param catalog - Asset catalog array\r\n * @param assetId - Asset identifier\r\n * @returns Asset catalog item, or undefined if not found\r\n */\r\nexport function getAssetFromCatalog(\r\n catalog: AssetCatalogItem[] | undefined,\r\n assetId: string\r\n): AssetCatalogItem | undefined {\r\n if (!catalog || !assetId) {\r\n return undefined;\r\n }\r\n\r\n return catalog.find((asset) => asset.id === assetId);\r\n}\r\n\r\n/**\r\n * Extract file extension from a filename or URL\r\n * \r\n * @param filename - Filename or URL\r\n * @returns File extension (lowercase, without dot), or empty string\r\n * \r\n * @example\r\n * ```typescript\r\n * getFileExtension('image.jpg'); // Returns: 'jpg'\r\n * getFileExtension('https://example.com/audio.mp3?v=1'); // Returns: 'mp3'\r\n * getFileExtension('document'); // Returns: ''\r\n * ```\r\n */\r\nexport function getFileExtension(filename: string): string {\r\n if (!filename) {\r\n return '';\r\n }\r\n\r\n // Remove query string and hash\r\n const cleanName = filename.split('?')[0].split('#')[0];\r\n\r\n // Extract extension\r\n const lastDot = cleanName.lastIndexOf('.');\r\n const lastSlash = cleanName.lastIndexOf('/');\r\n\r\n // Extension must be after the last slash (if any)\r\n if (lastDot > lastSlash && lastDot !== -1) {\r\n return cleanName.slice(lastDot + 1).toLowerCase();\r\n }\r\n\r\n return '';\r\n}\r\n\r\n/**\r\n * Guess MIME type from file extension\r\n * \r\n * @param filename - Filename or URL\r\n * @returns Likely MIME type, or 'application/octet-stream' for unknown\r\n * \r\n * @example\r\n * ```typescript\r\n * guessMimeType('image.jpg'); // Returns: 'image/jpeg'\r\n * guessMimeType('audio.mp3'); // Returns: 'audio/mpeg'\r\n * guessMimeType('video.mp4'); // Returns: 'video/mp4'\r\n * ```\r\n */\r\nexport function guessMimeType(filename: string): string {\r\n const extension = getFileExtension(filename);\r\n\r\n const mimeTypes: Record<string, string> = {\r\n // Images\r\n jpg: 'image/jpeg',\r\n jpeg: 'image/jpeg',\r\n png: 'image/png',\r\n gif: 'image/gif',\r\n webp: 'image/webp',\r\n avif: 'image/avif',\r\n svg: 'image/svg+xml',\r\n \r\n // Audio\r\n mp3: 'audio/mpeg',\r\n ogg: 'audio/ogg',\r\n wav: 'audio/wav',\r\n m4a: 'audio/mp4',\r\n aac: 'audio/aac',\r\n flac: 'audio/flac',\r\n \r\n // Video\r\n mp4: 'video/mp4',\r\n webm: 'video/webm',\r\n ogv: 'video/ogg',\r\n mov: 'video/quicktime',\r\n m3u8: 'application/vnd.apple.mpegurl',\r\n \r\n // Subtitles\r\n vtt: 'text/vtt',\r\n srt: 'application/x-subrip',\r\n \r\n // Documents\r\n pdf: 'application/pdf',\r\n json: 'application/json',\r\n \r\n // Other\r\n txt: 'text/plain',\r\n html: 'text/html',\r\n css: 'text/css',\r\n js: 'application/javascript',\r\n };\r\n\r\n return mimeTypes[extension] || 'application/octet-stream';\r\n}\r\n\r\n/**\r\n * Calculate optimal image dimensions maintaining aspect ratio\r\n * \r\n * @param originalWidth - Original image width\r\n * @param originalHeight - Original image height\r\n * @param maxWidth - Maximum width constraint\r\n * @param maxHeight - Maximum height constraint\r\n * @returns Optimal dimensions { width, height }\r\n * \r\n * @example\r\n * ```typescript\r\n * calculateOptimalDimensions(1920, 1080, 800, 600);\r\n * // Returns: { width: 800, height: 450 } (maintains 16:9 aspect ratio)\r\n * ```\r\n */\r\nexport function calculateOptimalDimensions(\r\n originalWidth: number,\r\n originalHeight: number,\r\n maxWidth: number,\r\n maxHeight: number\r\n): { width: number; height: number } {\r\n if (originalWidth <= 0 || originalHeight <= 0) {\r\n return { width: 0, height: 0 };\r\n }\r\n\r\n const aspectRatio = originalWidth / originalHeight;\r\n\r\n let width = originalWidth;\r\n let height = originalHeight;\r\n\r\n // Scale down if exceeds max width\r\n if (width > maxWidth) {\r\n width = maxWidth;\r\n height = width / aspectRatio;\r\n }\r\n\r\n // Scale down if exceeds max height\r\n if (height > maxHeight) {\r\n height = maxHeight;\r\n width = height * aspectRatio;\r\n }\r\n\r\n // Floor rather than round: the fitted box must never grow beyond the\r\n // ratio-true size (337.5 -> 337, not 338).\r\n return {\r\n width: Math.floor(width),\r\n height: Math.floor(height),\r\n };\r\n}\r\n\r\n/**\r\n * Generate srcset string for responsive images\r\n * \r\n * @param variants - Array of image variants\r\n * @returns srcset string for use in <img> tag\r\n * \r\n * @example\r\n * ```typescript\r\n * const variants = [\r\n * { src: 'image-400.jpg', w: 400, h: 300, mime: 'image/jpeg' },\r\n * { src: 'image-800.jpg', w: 800, h: 600, mime: 'image/jpeg' }\r\n * ];\r\n * \r\n * generateSrcSet(variants);\r\n * // Returns: 'image-400.jpg 400w, image-800.jpg 800w'\r\n * ```\r\n */\r\nexport function generateSrcSet(variants: ImageVariant[]): string {\r\n if (!variants || variants.length === 0) {\r\n return '';\r\n }\r\n\r\n return variants\r\n .map((variant) => `${variant.src} ${variant.w}w`)\r\n .join(', ');\r\n}\r\n\r\n/**\r\n * Check if browser supports a MIME type\r\n * \r\n * @param mimeType - MIME type to check\r\n * @returns True if likely supported (based on known formats)\r\n * \r\n * Note: This is a heuristic check. For definitive support,\r\n * use HTMLMediaElement.canPlayType() at runtime.\r\n */\r\nexport function isMimeTypeSupported(mimeType: string): boolean {\r\n const commonlySupported = [\r\n 'image/jpeg',\r\n 'image/png',\r\n 'image/gif',\r\n 'image/webp',\r\n 'audio/mpeg',\r\n 'audio/ogg',\r\n 'audio/wav',\r\n 'video/mp4',\r\n 'video/webm',\r\n 'text/vtt',\r\n 'application/json',\r\n ];\r\n\r\n return commonlySupported.includes(mimeType);\r\n}\r\n\r\n/**\r\n * Estimate file size based on dimensions and format (rough heuristic)\r\n * \r\n * @param width - Image width\r\n * @param height - Image height\r\n * @param mime - MIME type\r\n * @returns Estimated size in bytes\r\n * \r\n * Note: This is a very rough estimate for planning purposes only\r\n */\r\nexport function estimateImageSize(\r\n width: number,\r\n height: number,\r\n mime: string\r\n): number {\r\n const pixels = width * height;\r\n \r\n // Rough compression ratios\r\n const compressionFactors: Record<string, number> = {\r\n 'image/jpeg': 0.1, // ~10% of uncompressed\r\n 'image/webp': 0.08, // ~8% of uncompressed\r\n 'image/avif': 0.05, // ~5% of uncompressed\r\n 'image/png': 0.3, // ~30% of uncompressed (varies greatly)\r\n 'image/gif': 0.15, // ~15% of uncompressed\r\n };\r\n\r\n const factor = compressionFactors[mime] || 0.2;\r\n const uncompressedSize = pixels * 3; // RGB = 3 bytes per pixel\r\n\r\n return Math.round(uncompressedSize * factor);\r\n}\r\n","/**\n * JSON Logic Utilities\n * Safe wrapper for json-logic-js with context creation\n */\n\nimport jsonLogic from 'json-logic-js';\nimport type { JsonLogic, VariableContext } from '../types';\n\n/**\n * Safely evaluate a JSON Logic expression\n * \n * @param logic - JSON Logic expression\n * @param context - Variable context for evaluation\n * @returns Evaluation result (typically boolean for conditions)\n * \n * @example\n * ```typescript\n * const logic = { '>=': [{ var: 'user.age' }, 18] };\n * const context = { user: { age: 25 } };\n * \n * evaluateJsonLogic(logic, context);\n * // Returns: true\n * \n * // With missing variable\n * evaluateJsonLogic(logic, {});\n * // Returns: false (safe fallback)\n * ```\n */\nexport function evaluateJsonLogic(\n logic: JsonLogic | undefined,\n context: VariableContext\n): boolean {\n // If no logic provided, consider it always true (no condition)\n if (logic === undefined || logic === null) {\n return true;\n }\n\n // If logic is a literal boolean, return it\n if (typeof logic === 'boolean') {\n return logic;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = jsonLogic.apply(logic as any, context);\n \n // Convert result to boolean\n return Boolean(result);\n } catch (error) {\n // Log error in development\n if (typeof console !== 'undefined' && console.warn) {\n console.warn('[JsonLogicUtils] Evaluation error:', error, {\n logic,\n context,\n });\n }\n \n // Default to false on error (fail closed)\n return false;\n }\n}\n\n/**\n * Create a flat variable context from nested variable store\n * \n * @param variables - Variable store with scoped values\n * @returns Flat context object for JSON Logic\n * \n * @example\n * ```typescript\n * const variables = {\n * global: { version: '1.0' },\n * session: { path: { choice: 'left' } },\n * persistent: { prefs: { speech: true } }\n * };\n * \n * createContext(variables);\n * // Returns: { version: '1.0', path: { choice: 'left' }, prefs: { speech: true } }\n * ```\n */\nexport function createContext(variables: Record<string, unknown>): VariableContext {\n const context: VariableContext = {};\n\n // Flatten all variable scopes into a single context\n Object.values(variables).forEach((scope) => {\n if (scope && typeof scope === 'object') {\n Object.assign(context, scope);\n }\n });\n\n return context;\n}\n\n/**\n * Validate JSON Logic expression structure\n * \n * @param logic - JSON Logic expression to validate\n * @returns Validation result with errors if invalid\n * \n * @example\n * ```typescript\n * validateJsonLogic({ '>=': [{ var: 'age' }, 18] });\n * // Returns: { valid: true }\n * \n * validateJsonLogic({ 'invalid-op': [1, 2] });\n * // Returns: { valid: false, errors: ['Unknown operator: invalid-op'] }\n * ```\n */\nexport function validateJsonLogic(\n logic: JsonLogic\n): { valid: boolean; errors?: string[] } {\n if (logic === null || logic === undefined) {\n return { valid: true };\n }\n\n // Literal values are valid\n if (\n typeof logic === 'boolean' ||\n typeof logic === 'number' ||\n typeof logic === 'string'\n ) {\n return { valid: true };\n }\n\n const errors: string[] = [];\n\n try {\n // Try to apply with empty context to check structure\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n jsonLogic.apply(logic as any, {});\n return { valid: true };\n } catch (error) {\n if (error instanceof Error) {\n errors.push(error.message);\n } else {\n errors.push('Unknown validation error');\n }\n return { valid: false, errors };\n }\n}\n\n/**\n * Extract variable names used in a JSON Logic expression\n * \n * @param logic - JSON Logic expression\n * @returns Array of variable names referenced\n * \n * @example\n * ```typescript\n * const logic = {\n * and: [\n * { '>=': [{ var: 'user.age' }, 18] },\n * { '==': [{ var: 'prefs.speech' }, true] }\n * ]\n * };\n * \n * extractVariableNames(logic);\n * // Returns: ['user.age', 'prefs.speech']\n * ```\n */\nexport function extractVariableNames(logic: JsonLogic): string[] {\n const variables = new Set<string>();\n\n function traverse(node: unknown): void {\n if (node === null || node === undefined) {\n return;\n }\n\n if (Array.isArray(node)) {\n node.forEach(traverse);\n return;\n }\n\n if (typeof node === 'object') {\n // Check for { var: 'varName' } pattern\n const obj = node as Record<string, unknown>;\n \n if ('var' in obj && typeof obj['var'] === 'string') {\n variables.add(obj['var']);\n }\n\n // Recurse into all properties\n Object.values(obj).forEach(traverse);\n }\n }\n\n traverse(logic);\n return Array.from(variables);\n}\n\n/**\n * Add custom operators to JSON Logic\n * \n * @example\n * ```typescript\n * // Add a custom 'contains' operator for arrays\n * addCustomOperator('contains', (array, value) => {\n * return Array.isArray(array) && array.includes(value);\n * });\n * \n * // Now can use in logic\n * const logic = { contains: [{ var: 'tags' }, 'featured'] };\n * evaluateJsonLogic(logic, { tags: ['new', 'featured'] });\n * // Returns: true\n * ```\n */\nexport function addCustomOperator(\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n implementation: (...args: any[]) => any\n): void {\n jsonLogic.add_operation(name, implementation);\n}\n\n/**\n * Remove a custom operator\n * \n * @param name - Operator name to remove\n */\nexport function removeCustomOperator(name: string): void {\n jsonLogic.rm_operation(name);\n}\n\n/**\n * Common custom operators for PanelWave\n * Call this to register helpful custom operators\n */\nexport function registerPanelWaveOperators(): void {\n // Check if a value is in an array\n addCustomOperator('in', (value: unknown, array: unknown[]) => {\n return Array.isArray(array) && array.includes(value);\n });\n\n // Check if array contains a value (reverse of 'in')\n addCustomOperator('contains', (array: unknown[], value: unknown) => {\n return Array.isArray(array) && array.includes(value);\n });\n\n // Check if string matches regex pattern\n addCustomOperator('matches', (str: unknown, pattern: string) => {\n if (typeof str !== 'string') {\n return false;\n }\n try {\n return new RegExp(pattern).test(str);\n } catch {\n return false;\n }\n });\n\n // Check if value is between min and max (inclusive)\n addCustomOperator('between', (value: unknown, min: number, max: number) => {\n if (typeof value !== 'number') {\n return false;\n }\n return value >= min && value <= max;\n });\n\n // Get length of string or array\n addCustomOperator('length', (value: unknown) => {\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length;\n }\n return 0;\n });\n\n // Check if value is empty (null, undefined, '', [], {})\n addCustomOperator('isEmpty', (value: unknown) => {\n if (value === null || value === undefined || value === '') {\n return true;\n }\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n if (typeof value === 'object') {\n return Object.keys(value).length === 0;\n }\n return false;\n });\n}\n\n/**\n * Evaluate multiple conditions with AND logic\n * \n * @param conditions - Array of JSON Logic expressions\n * @param context - Variable context\n * @returns True if all conditions evaluate to true\n */\nexport function evaluateAll(\n conditions: JsonLogic[],\n context: VariableContext\n): boolean {\n if (!conditions || conditions.length === 0) {\n return true;\n }\n\n return conditions.every((condition) => evaluateJsonLogic(condition, context));\n}\n\n/**\n * Evaluate multiple conditions with OR logic\n * \n * @param conditions - Array of JSON Logic expressions\n * @param context - Variable context\n * @returns True if any condition evaluates to true\n */\nexport function evaluateAny(\n conditions: JsonLogic[],\n context: VariableContext\n): boolean {\n if (!conditions || conditions.length === 0) {\n return false;\n }\n\n return conditions.some((condition) => evaluateJsonLogic(condition, context));\n}\n\n/**\n * Test JSON Logic evaluation with sample data\n * Useful for debugging and validation\n * \n * @param logic - JSON Logic expression\n * @param testCases - Array of test cases with context and expected result\n * @returns Test results\n */\nexport function testJsonLogic(\n logic: JsonLogic,\n testCases: { context: VariableContext; expected: boolean; description?: string }[]\n): { passed: boolean; description?: string; actual?: boolean; expected: boolean }[] {\n return testCases.map((testCase) => {\n const actual = evaluateJsonLogic(logic, testCase.context);\n const passed = actual === testCase.expected;\n\n return {\n passed,\n description: testCase.description,\n actual,\n expected: testCase.expected,\n };\n });\n}\n","/**\n * Balloon Configuration Utilities\n *\n * Provides default balloon config, merge logic, and conversion helpers\n * for rendering speech bubbles in the player.\n * Ported from CMS: apps/cms-frontend/src/app/core/models/balloon-config.model.ts\n */\n\nimport type { BalloonConfig, BalloonConfigOverride } from '../types';\n\n/** Default balloon configuration */\nexport const DEFAULT_BALLOON_CONFIG: BalloonConfig = {\n balloonType: 'normal',\n cornerRadius: 0.5,\n maxWidth: 120,\n maxHeight: 80,\n fontFamily: \"'Ames Italic', sans-serif\",\n fontSize: 12,\n strokeWidth: 2,\n strokeColor: '#000000',\n fillColor: '#ffffff',\n tail: {\n enabled: true,\n position: 180,\n length: 45,\n curve: 'straight',\n curveAmount: 0.4,\n },\n hideBorder: {\n enabled: false,\n angle: 0,\n arc: 60,\n },\n};\n\n/**\n * Merge a partial override onto a base config, producing a complete config.\n * Handles nested tail and hideBorder objects.\n */\nexport function mergeBalloonConfig(base: BalloonConfig, override?: BalloonConfigOverride | null): BalloonConfig {\n if (!override) return { ...base };\n\n return {\n ...base,\n ...override,\n tail: {\n ...base.tail,\n ...(override.tail || {}),\n },\n hideBorder: {\n ...base.hideBorder,\n ...(override.hideBorder || {}),\n },\n };\n}\n\n/**\n * Convert a BalloonConfig to the options object expected by the ComicBalloon renderer.\n */\nexport function balloonConfigToRenderOptions(config: BalloonConfig): Record<string, unknown> {\n const type = config.balloonType;\n return {\n maxWidth: config.maxWidth,\n maxHeight: config.maxHeight,\n cornerRadius: type === 'rectangle' || type === 'narrator' ? 0 : config.cornerRadius,\n sharpCorners: type === 'narrator',\n isThought: type === 'thought',\n isShout: type === 'shout',\n isWhisper: type === 'whisper',\n cutTop: type === 'cutTop' || type === 'cutTopRight' || type === 'cutTopLeft',\n cutRight: type === 'cutTopRight',\n cutLeft: type === 'cutTopLeft',\n openTail: type === 'connector',\n fontFamily: config.fontFamily,\n fontSize: config.fontSize,\n strokeWidth: config.strokeWidth,\n strokeColor: config.strokeColor,\n fillColor: config.fillColor,\n hideBorder: config.hideBorder.enabled\n ? { angle: config.hideBorder.angle, arc: config.hideBorder.arc }\n : null,\n };\n}\n\n/**\n * Convert a BalloonConfig's tail settings to the tail options expected by the renderer.\n */\nexport function balloonConfigToTailOptions(config: BalloonConfig): { position: number; length: number; curve: string; curveAmount: number } | null {\n if (!config.tail.enabled && config.balloonType !== 'connector') {\n return null;\n }\n return {\n position: config.tail.position,\n length: config.tail.length,\n curve: config.tail.curve,\n curveAmount: config.tail.curveAmount,\n };\n}\n","// SYNCED FROM panelwave-cms/apps/cms-frontend/src/app/core/utils/balloon-geometry.ts — DO NOT EDIT HERE.\n// Edit the CMS copy, then run in panelwave-cms: npm run sync:balloon\n\n/**\n * Pure geometry helpers shared by the canvas renderer and the speech-bubble\n * service so the draggable tail handle and the drawn ComicBalloon tail always\n * agree. Compass convention (same as ComicBalloon / TailConfig):\n * 0° = top, 90° = right, 180° = bottom, 270° = left.\n */\n\nexport interface BalloonCenterBounds {\n cx: number;\n cy: number;\n width: number;\n height: number;\n}\n\n/**\n * Point on the squircle (superellipse) edge for a compass angle.\n * Same formula as ComicBalloon.createSquirclePath / drawBubbleBalloon:\n * exponent n = 2 + (1 - cornerRadius) * 3.\n */\nexport function squircleEdgePoint(\n bounds: BalloonCenterBounds,\n positionDeg: number,\n cornerRadius: number\n): { x: number; y: number } {\n const angle = (positionDeg / 360) * Math.PI * 2 - Math.PI / 2;\n const rx = bounds.width / 2;\n const ry = bounds.height / 2;\n const n = 2 + (1 - cornerRadius) * 3;\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n const signX = cosA >= 0 ? 1 : -1;\n const signY = sinA >= 0 ? 1 : -1;\n return {\n x: bounds.cx + signX * rx * Math.pow(Math.abs(cosA), 2 / n),\n y: bounds.cy + signY * ry * Math.pow(Math.abs(sinA), 2 / n),\n };\n}\n\n/** Tail tip position for an angle-based TailConfig (position/length). */\nexport function tailConfigToTip(\n bounds: BalloonCenterBounds,\n tail: { position: number; length: number },\n cornerRadius: number\n): { x: number; y: number } {\n const edge = squircleEdgePoint(bounds, tail.position, cornerRadius);\n const dirX = edge.x - bounds.cx;\n const dirY = edge.y - bounds.cy;\n const dirLen = Math.sqrt(dirX * dirX + dirY * dirY) || 1;\n return {\n x: edge.x + (dirX / dirLen) * tail.length,\n y: edge.y + (dirY / dirLen) * tail.length,\n };\n}\n\n/**\n * Trail circles for a thought balloon: three shrinking bubbles from the cloud\n * edge toward the tail tip. Shared by ComicBalloon.addThoughtBubbles (SVG) and\n * InteractionRenderer.drawBubbleBalloon (canvas) so preview and editor agree —\n * the trail is NOT part of the cloud path, each renderer draws it separately.\n */\nexport function thoughtTrailCircles(\n bounds: BalloonCenterBounds,\n tailTip: { x: number; y: number }\n): { x: number; y: number; r: number }[] {\n const rx = bounds.width / 2;\n const ry = bounds.height / 2;\n\n const angle = Math.atan2(tailTip.y - bounds.cy, tailTip.x - bounds.cx);\n const edgeX = bounds.cx + (rx + 5) * Math.cos(angle);\n const edgeY = bounds.cy + (ry + 5) * Math.sin(angle);\n\n const dx = tailTip.x - edgeX;\n const dy = tailTip.y - edgeY;\n\n const sizes = [8, 5, 3];\n return sizes.map((r, i) => {\n const t = (i + 1) / sizes.length;\n const adjustedT = 0.2 + t * 0.8;\n return { x: edgeX + dx * adjustedT, y: edgeY + dy * adjustedT, r };\n });\n}\n\n/**\n * Inverse mapping: a dragged pixel tail tip → compass position (0-359, integer)\n * and length (px from the squircle edge, >= 0).\n */\nexport function tailTipToTailConfig(\n bounds: BalloonCenterBounds,\n tipX: number,\n tipY: number,\n cornerRadius: number\n): { position: number; length: number } {\n const dx = tipX - bounds.cx;\n const dy = tipY - bounds.cy;\n const rx = bounds.width / 2 || 1;\n const ry = bounds.height / 2 || 1;\n const n = 2 + (1 - cornerRadius) * 3;\n\n // The tip lies on the ray center → edge(param), so invert the superellipse\n // parameterization: find the param angle whose edge point has the same\n // geometric direction as the tip. (The param angle is NOT atan2(dy, dx)\n // when width ≠ height.)\n let alpha: number;\n if (Math.abs(dx) < 1e-9) {\n alpha = dy >= 0 ? Math.PI / 2 : -Math.PI / 2;\n } else {\n const alpha0 = Math.atan(Math.pow((rx / ry) * Math.abs(dy / dx), n / 2));\n if (dx >= 0) {\n alpha = dy >= 0 ? alpha0 : -alpha0;\n } else {\n alpha = dy >= 0 ? Math.PI - alpha0 : Math.PI + alpha0;\n }\n }\n\n // Param angle → compass degrees (the forward map is angle = pos/360·2π − π/2).\n let position = (alpha * 180) / Math.PI + 90;\n position = Math.round(position);\n position = ((position % 360) + 360) % 360;\n\n const edge = squircleEdgePoint(bounds, position, cornerRadius);\n const edgeDist = Math.hypot(edge.x - bounds.cx, edge.y - bounds.cy);\n const tipDist = Math.hypot(dx, dy);\n const length = Math.round(Math.max(0, tipDist - edgeDist));\n return { position, length };\n}\n","// SYNCED FROM panelwave-cms/apps/cms-frontend/src/app/core/utils/comic-balloon.ts — DO NOT EDIT HERE.\n// Edit the CMS copy, then run in panelwave-cms: npm run sync:balloon\n\n/**\n * Comic Book Balloon Renderer (TypeScript)\n * Creates dynamic speech balloons with auto-sizing and smooth tails.\n *\n * MASTER COPY of the balloon engine (the editor is where balloons are\n * designed and tested). The player library holds a synced copy so the\n * reader/preview render balloons exactly like the editor — edit here, then\n * run `npm run sync:balloon` in panelwave-cms.\n */\n\nimport { thoughtTrailCircles } from './balloon-geometry';\n\nexport interface BalloonPadding {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\nexport interface BalloonOptions {\n maxWidth: number;\n maxHeight: number;\n padding: BalloonPadding;\n strokeWidth: number;\n strokeColor: string;\n fillColor: string;\n tailWidth: number;\n cornerRadius: number;\n fontFamily: string;\n fontSize: number;\n lineHeight: number;\n textAlign: string;\n isThought: boolean;\n isShout: boolean;\n isWhisper: boolean;\n /** Truly square corners (narrator caption boxes); only meaningful with cornerRadius 0. */\n sharpCorners: boolean;\n cutTop: boolean;\n cutRight: boolean;\n cutLeft: boolean;\n openTail: boolean;\n hideBorder: { angle: number; arc: number } | null;\n}\n\nexport interface TailOptions {\n x?: number;\n y?: number;\n position?: number;\n length?: number;\n curve?: 'straight' | 'left' | 'right';\n curveAmount?: number;\n}\n\nexport interface CutOptions {\n top?: boolean;\n right?: boolean;\n left?: boolean;\n bottom?: boolean;\n}\n\ninterface PathPoint {\n x: number;\n y: number;\n origX: number;\n origY: number;\n}\n\nexport interface BalloonRenderResult {\n width: number;\n height: number;\n svg: SVGSVGElement;\n balloon: ComicBalloon;\n update: (newText?: string, newTailOptions?: TailOptions | null) => BalloonRenderResult;\n updateTail: (newTailOptions: TailOptions | null) => BalloonRenderResult;\n updateText: (newText: string) => BalloonRenderResult;\n}\n\nexport class ComicBalloon {\n container: HTMLElement;\n options: BalloonOptions;\n svg: SVGSVGElement | null = null;\n textElement: HTMLElement | null = null;\n balloonPath: SVGPathElement | null = null;\n tailPath: SVGPathElement | null = null;\n tailCurve = 'straight';\n tailCurveAmount = 0.4;\n\n constructor(container: string | HTMLElement, options: Partial<BalloonOptions> = {}) {\n this.container = typeof container === 'string'\n ? document.querySelector(container) as HTMLElement\n : container;\n\n this.options = {\n // 0 (or any non-positive value) means \"natural width\", consistent with\n // maxHeight (default 0). Only a missing/non-finite value falls back to 140.\n maxWidth: typeof options.maxWidth === 'number' && Number.isFinite(options.maxWidth) ? options.maxWidth : 140,\n maxHeight: options.maxHeight || 0,\n padding: options.padding || { top: 14, right: 18, bottom: 14, left: 18 },\n strokeWidth: options.strokeWidth || 2,\n strokeColor: options.strokeColor || '#000',\n fillColor: options.fillColor || '#fff',\n tailWidth: options.tailWidth || 18,\n cornerRadius: options.cornerRadius ?? 0.45,\n fontFamily: options.fontFamily || \"'Ames Italic', 'Comic Neue', sans-serif\",\n fontSize: options.fontSize || 12,\n lineHeight: options.lineHeight || 1.3,\n textAlign: options.textAlign || 'center',\n isThought: options.isThought || false,\n isShout: options.isShout || false,\n isWhisper: options.isWhisper || false,\n sharpCorners: options.sharpCorners || false,\n cutTop: options.cutTop || false,\n cutRight: options.cutRight || false,\n cutLeft: options.cutLeft || false,\n openTail: options.openTail || false,\n hideBorder: options.hideBorder || null,\n };\n }\n\n /**\n * Render the balloon with given text and tail options\n */\n render(text: string, tailOptions: TailOptions | null = null): BalloonRenderResult {\n // Clear container\n this.container.innerHTML = '';\n\n // Create SVG element\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg') as SVGSVGElement;\n this.svg.setAttribute('class', 'comic-balloon-svg');\n\n // Use the same padding as the canvas drawBalloonText (padding = 14 on each side)\n const textPadding = 14;\n const availableTextWidth = this.options.maxWidth > 0\n ? this.options.maxWidth - textPadding * 2\n : 140 - textPadding * 2;\n\n // Create a temporary text element to measure\n const tempDiv = document.createElement('div');\n tempDiv.style.cssText = `\n position: absolute;\n visibility: hidden;\n width: ${availableTextWidth}px;\n font-family: ${this.options.fontFamily};\n font-size: ${this.options.fontSize}px;\n line-height: ${this.options.lineHeight};\n text-align: ${this.options.textAlign};\n font-style: normal;\n text-transform: uppercase;\n white-space: pre-wrap;\n word-wrap: break-word;\n `;\n tempDiv.innerHTML = text;\n document.body.appendChild(tempDiv);\n\n // Measure text\n const textWidth = Math.min(tempDiv.scrollWidth, availableTextWidth);\n const textHeight = tempDiv.scrollHeight;\n document.body.removeChild(tempDiv);\n\n // Calculate balloon dimensions\n let extraPad = 0;\n if (this.options.isShout) extraPad = Math.round(this.options.fontSize * 0.4);\n if (this.options.isThought) extraPad = Math.round(this.options.fontSize * 0.4);\n\n const naturalWidth = textWidth + this.options.padding.left + this.options.padding.right + extraPad * 2;\n const naturalHeight = textHeight + this.options.padding.top + this.options.padding.bottom + extraPad * 2;\n\n const balloonWidth = this.options.maxWidth > 0 ? this.options.maxWidth : naturalWidth;\n const balloonHeight = this.options.maxHeight > 0 ? this.options.maxHeight : naturalHeight;\n\n const cx = balloonWidth / 2;\n const cy = balloonHeight / 2;\n const rx = balloonWidth / 2;\n const ry = balloonHeight / 2;\n\n // Process tail options\n let tailTip: { x: number; y: number } | null = null;\n let tailCurve = 'straight';\n let tailCurveAmount = 0.4;\n\n if (tailOptions) {\n if (tailOptions.x !== undefined && tailOptions.y !== undefined) {\n tailTip = { x: tailOptions.x, y: tailOptions.y };\n } else if (tailOptions.position !== undefined) {\n const position = tailOptions.position;\n const length = tailOptions.length || 50;\n const angle = (position / 360) * Math.PI * 2 - Math.PI / 2;\n const n = 2 + (1 - this.options.cornerRadius) * 3;\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n const signX = cosA >= 0 ? 1 : -1;\n const signY = sinA >= 0 ? 1 : -1;\n const edgeX = cx + signX * rx * Math.pow(Math.abs(cosA), 2 / n);\n const edgeY = cy + signY * ry * Math.pow(Math.abs(sinA), 2 / n);\n const dirX = edgeX - cx;\n const dirY = edgeY - cy;\n const dirLen = Math.sqrt(dirX * dirX + dirY * dirY);\n tailTip = {\n x: edgeX + (dirX / dirLen) * length,\n y: edgeY + (dirY / dirLen) * length,\n };\n }\n\n tailCurve = tailOptions.curve || 'straight';\n tailCurveAmount = tailOptions.curveAmount !== undefined ? tailOptions.curveAmount : 0.4;\n }\n\n this.tailCurve = tailCurve;\n this.tailCurveAmount = tailCurveAmount;\n\n // Calculate SVG viewBox\n const extraPadding = this.options.isThought ? 20 : (this.options.isShout ? 12 : 5);\n const strokePadding = this.options.strokeWidth + extraPadding;\n let viewBoxX = -strokePadding;\n let viewBoxY = -strokePadding;\n let viewBoxWidth = balloonWidth + strokePadding * 2;\n let viewBoxHeight = balloonHeight + strokePadding * 2;\n\n if (tailTip) {\n const tailPadding = 20;\n const minX = Math.min(viewBoxX, tailTip.x - tailPadding);\n const minY = Math.min(viewBoxY, tailTip.y - tailPadding);\n const maxX = Math.max(viewBoxX + viewBoxWidth, tailTip.x + tailPadding);\n const maxY = Math.max(viewBoxY + viewBoxHeight, tailTip.y + tailPadding);\n viewBoxX = minX;\n viewBoxY = minY;\n viewBoxWidth = maxX - minX;\n viewBoxHeight = maxY - minY;\n }\n\n this.svg.setAttribute('viewBox', `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`);\n this.svg.style.width = viewBoxWidth + 'px';\n this.svg.style.height = viewBoxHeight + 'px';\n this.svg.style.overflow = 'visible';\n\n // Create balloon path\n let balloonPath: string | { fill: string; stroke: string };\n if (this.options.isThought) {\n balloonPath = this.createThoughtBalloonPath(cx, cy, balloonWidth, balloonHeight);\n } else if (this.options.isShout) {\n balloonPath = this.createShoutBalloonPath(cx, cy, balloonWidth, balloonHeight, tailTip);\n } else {\n const cutOpts: CutOptions = {\n top: this.options.cutTop,\n right: this.options.cutRight,\n left: this.options.cutLeft,\n };\n balloonPath = this.createSquirclePath(cx, cy, balloonWidth, balloonHeight, this.options.cornerRadius, tailTip, cutOpts);\n }\n\n // Create the balloon path element(s)\n const isObjectPath = typeof balloonPath === 'object' && (balloonPath as { fill: string }).fill;\n const needSeparatePaths = isObjectPath || this.options.hideBorder;\n\n if (needSeparatePaths) {\n const objPath = balloonPath as { fill: string; stroke: string };\n const fillD = isObjectPath ? objPath.fill : (balloonPath as string);\n const strokeD = isObjectPath ? objPath.stroke : (balloonPath as string);\n\n // Fill element (closed path, no stroke)\n const fillEl = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n fillEl.setAttribute('d', fillD);\n fillEl.setAttribute('fill', this.options.fillColor);\n fillEl.setAttribute('stroke', 'none');\n this.svg.appendChild(fillEl);\n\n // Stroke element (no fill)\n this.balloonPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n this.balloonPath.setAttribute('d', strokeD);\n this.balloonPath.setAttribute('fill', 'none');\n this.balloonPath.setAttribute('stroke', this.options.strokeColor);\n this.balloonPath.setAttribute('stroke-width', String(this.options.strokeWidth));\n this.balloonPath.setAttribute('stroke-linejoin', 'round');\n this.balloonPath.setAttribute('stroke-linecap', 'round');\n\n if (this.options.isWhisper) {\n this.balloonPath.setAttribute('stroke-dasharray', '6 4');\n }\n\n // Apply clip-path to hide a border segment\n if (this.options.hideBorder) {\n const { angle: hideAngle, arc: hideArc } = this.options.hideBorder;\n const startVisible = hideAngle + hideArc / 2;\n const visibleArc = 360 - hideArc;\n const R = Math.max(viewBoxWidth, viewBoxHeight) * 2;\n const clipId = 'hide-clip-' + Math.random().toString(36).substr(2, 9);\n\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const clipPathEl = document.createElementNS('http://www.w3.org/2000/svg', 'clipPath');\n clipPathEl.setAttribute('id', clipId);\n\n let pts = `${cx.toFixed(2)},${cy.toFixed(2)}`;\n const steps = 36;\n for (let i = 0; i <= steps; i++) {\n const deg = startVisible + (i / steps) * visibleArc;\n const rad = (deg / 360) * Math.PI * 2 - Math.PI / 2;\n pts += ` ${(cx + R * Math.cos(rad)).toFixed(2)},${(cy + R * Math.sin(rad)).toFixed(2)}`;\n }\n\n const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');\n polygon.setAttribute('points', pts);\n clipPathEl.appendChild(polygon);\n defs.appendChild(clipPathEl);\n this.svg.appendChild(defs);\n\n this.balloonPath.setAttribute('clip-path', `url(#${clipId})`);\n }\n\n this.svg.appendChild(this.balloonPath);\n } else {\n this.balloonPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n this.balloonPath.setAttribute('d', balloonPath as string);\n this.balloonPath.setAttribute('fill', this.options.fillColor);\n this.balloonPath.setAttribute('stroke', this.options.strokeColor);\n this.balloonPath.setAttribute('stroke-width', String(this.options.strokeWidth));\n this.balloonPath.setAttribute('stroke-linejoin', 'round');\n this.balloonPath.setAttribute('stroke-linecap', 'round');\n\n if (this.options.isWhisper) {\n this.balloonPath.setAttribute('stroke-dasharray', '6 4');\n }\n\n this.svg.appendChild(this.balloonPath);\n }\n\n // Add thought bubbles if thought balloon\n if (this.options.isThought && tailTip) {\n this.addThoughtBubbles(cx, cy, balloonWidth, balloonHeight, tailTip);\n }\n\n // Create text element using foreignObject\n const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');\n\n // Center text within the balloon (matching canvas drawBalloonText behavior)\n const foX = (balloonWidth - textWidth) / 2;\n const foY = (balloonHeight - textHeight) / 2;\n foreignObject.setAttribute('x', String(foX));\n foreignObject.setAttribute('y', String(foY));\n foreignObject.setAttribute('width', String(textWidth));\n foreignObject.setAttribute('height', String(textHeight));\n\n const textDiv = document.createElement('div');\n textDiv.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');\n textDiv.style.cssText = `\n font-family: ${this.options.fontFamily};\n font-size: ${this.options.fontSize}px;\n line-height: ${this.options.lineHeight};\n text-align: ${this.options.textAlign};\n font-style: normal;\n text-transform: uppercase;\n color: #000;\n `;\n textDiv.innerHTML = text;\n\n foreignObject.appendChild(textDiv);\n this.svg.appendChild(foreignObject);\n\n this.container.appendChild(this.svg);\n\n return {\n width: balloonWidth,\n height: balloonHeight,\n svg: this.svg,\n balloon: this,\n update: (newText?: string, newTailOptions?: TailOptions | null) =>\n this.render(newText || text, newTailOptions !== undefined ? newTailOptions : tailOptions),\n updateTail: (newTailOptions: TailOptions | null) => this.render(text, newTailOptions),\n updateText: (newText: string) => this.render(newText, tailOptions),\n };\n }\n\n /**\n * Create a \"squircle\" path - hybrid between ellipse and rounded rectangle\n */\n createSquirclePath(\n cx: number, cy: number,\n width: number, height: number,\n cornerRadius = 0.4,\n tailTip: { x: number; y: number } | null = null,\n cutOptions: CutOptions = {}\n ): string | { fill: string; stroke: string } {\n const rx = width / 2;\n const ry = height / 2;\n const numPoints = 180;\n const points: PathPoint[] = [];\n\n if (cornerRadius === 0) {\n // sharpCorners (narrator boxes) => truly square corners; otherwise a\n // small 8px rounding keeps the 'rectangle' type friendly.\n const r = this.options.sharpCorners ? 0 : Math.min(8, rx, ry);\n const edgeT = Math.max(0, 2 * rx - 2 * r);\n const edgeR = Math.max(0, 2 * ry - 2 * r);\n const arc = (Math.PI / 2) * r;\n const perim = 2 * edgeT + 2 * edgeR + 4 * arc;\n\n const segments: { type: string; len: number; start?: { x: number; y: number }; end?: { x: number; y: number }; center?: { x: number; y: number }; startAngle?: number; endAngle?: number }[] = [\n { type: 'line', len: edgeR / 2, start: { x: cx - rx, y: cy }, end: { x: cx - rx, y: cy - ry + r } },\n { type: 'arc', len: arc, center: { x: cx - rx + r, y: cy - ry + r }, startAngle: Math.PI, endAngle: Math.PI * 1.5 },\n { type: 'line', len: edgeT, start: { x: cx - rx + r, y: cy - ry }, end: { x: cx + rx - r, y: cy - ry } },\n { type: 'arc', len: arc, center: { x: cx + rx - r, y: cy - ry + r }, startAngle: -Math.PI / 2, endAngle: 0 },\n { type: 'line', len: edgeR, start: { x: cx + rx, y: cy - ry + r }, end: { x: cx + rx, y: cy + ry - r } },\n { type: 'arc', len: arc, center: { x: cx + rx - r, y: cy + ry - r }, startAngle: 0, endAngle: Math.PI / 2 },\n { type: 'line', len: edgeT, start: { x: cx + rx - r, y: cy + ry }, end: { x: cx - rx + r, y: cy + ry } },\n { type: 'arc', len: arc, center: { x: cx - rx + r, y: cy + ry - r }, startAngle: Math.PI / 2, endAngle: Math.PI },\n { type: 'line', len: edgeR / 2, start: { x: cx - rx, y: cy + ry - r }, end: { x: cx - rx, y: cy } },\n ];\n\n for (let i = 0; i < numPoints; i++) {\n const d = (i / numPoints) * perim;\n let currentD = 0;\n let p: { x: number; y: number } | null = null;\n for (const seg of segments) {\n if (d <= currentD + seg.len || seg === segments[segments.length - 1]) {\n const t = seg.len > 0 ? (d - currentD) / seg.len : 0;\n if (seg.type === 'line') {\n p = {\n x: seg.start!.x + (seg.end!.x - seg.start!.x) * t,\n y: seg.start!.y + (seg.end!.y - seg.start!.y) * t,\n };\n } else {\n const angle = seg.startAngle! + (seg.endAngle! - seg.startAngle!) * t;\n p = {\n x: seg.center!.x + r * Math.cos(angle),\n y: seg.center!.y + r * Math.sin(angle),\n };\n }\n break;\n }\n currentD += seg.len;\n }\n\n let x = p!.x;\n let y = p!.y;\n if (cutOptions.top && y < cy - ry + 1) y = cy - ry;\n if (cutOptions.right && x > cx + rx - 1) x = cx + rx;\n if (cutOptions.left && x < cx - rx + 1) x = cx - rx;\n if (cutOptions.bottom && y > cy + ry - 1) y = cy + ry;\n\n points.push({ x, y, origX: p!.x, origY: p!.y });\n }\n } else {\n const n = 2 + (1 - cornerRadius) * 3;\n const stretchFactor = 1.3;\n\n for (let i = 0; i < numPoints; i++) {\n const angle = (i / numPoints) * Math.PI * 2 - Math.PI;\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n const signX = cosA >= 0 ? 1 : -1;\n const signY = sinA >= 0 ? 1 : -1;\n\n let currentRx = rx;\n let currentRy = ry;\n if (cutOptions.top && signY < 0) currentRy = ry * stretchFactor;\n if (cutOptions.bottom && signY > 0) currentRy = ry * stretchFactor;\n if (cutOptions.right && signX > 0) currentRx = rx * stretchFactor;\n if (cutOptions.left && signX < 0) currentRx = rx * stretchFactor;\n\n const origX = cx + signX * currentRx * Math.pow(Math.abs(cosA), 2 / n);\n const origY = cy + signY * currentRy * Math.pow(Math.abs(sinA), 2 / n);\n\n let x = origX;\n let y = origY;\n if (cutOptions.top && y < cy - ry + 1) y = cy - ry;\n if (cutOptions.right && x > cx + rx - 1) x = cx + rx;\n if (cutOptions.left && x < cx - rx + 1) x = cx - rx;\n if (cutOptions.bottom && y > cy + ry - 1) y = cy + ry;\n\n points.push({ x, y, origX, origY });\n }\n }\n\n // Remove duplicate points created by clamping\n const filteredPoints: PathPoint[] = [];\n for (let i = 0; i < points.length; i++) {\n const p = points[i];\n if (filteredPoints.length === 0) {\n filteredPoints.push(p);\n } else {\n const lastP = filteredPoints[filteredPoints.length - 1];\n const distSq = (p.x - lastP.x) ** 2 + (p.y - lastP.y) ** 2;\n if (distSq > 0.1 || i === points.length - 1) {\n filteredPoints.push(p);\n }\n }\n }\n\n const numFilteredPoints = filteredPoints.length;\n\n // If no tail, create simple path\n if (!tailTip) {\n let path = `M ${filteredPoints[0].x.toFixed(2)} ${filteredPoints[0].y.toFixed(2)}`;\n for (let i = 1; i < numFilteredPoints; i++) {\n path += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n path += ' Z';\n return path;\n }\n\n // Find the path point whose angle matches tail angle\n const tailAngle = Math.atan2(tailTip.y - cy, tailTip.x - cx);\n let centerIdx = 0;\n let minAngleDiff = Infinity;\n for (let i = 0; i < numFilteredPoints; i++) {\n const actualAngle = Math.atan2(filteredPoints[i].origY - cy, filteredPoints[i].origX - cx);\n const diff = Math.abs(this.normalizeAngle(actualAngle - tailAngle));\n if (diff < minAngleDiff) {\n minAngleDiff = diff;\n centerIdx = i;\n }\n }\n\n // Find base points (connector/open tails are drawn narrower than pointed tails)\n const tailHalfWidth = this.options.openTail ? 5 : (cornerRadius === 0 ? 5 : 8);\n let idx1 = (centerIdx - 1 + numFilteredPoints) % numFilteredPoints;\n let idx2 = (centerIdx + 1) % numFilteredPoints;\n const centerPt = filteredPoints[centerIdx];\n\n for (let step = 1; step < numFilteredPoints / 2; step++) {\n const testIdx = (centerIdx - step + numFilteredPoints) % numFilteredPoints;\n const dist = Math.hypot(filteredPoints[testIdx].x - centerPt.x, filteredPoints[testIdx].y - centerPt.y);\n if (dist >= tailHalfWidth) {\n idx1 = testIdx;\n break;\n }\n }\n\n for (let step = 1; step < numFilteredPoints / 2; step++) {\n const testIdx = (centerIdx + step) % numFilteredPoints;\n const dist = Math.hypot(filteredPoints[testIdx].x - centerPt.x, filteredPoints[testIdx].y - centerPt.y);\n if (dist >= tailHalfWidth) {\n idx2 = testIdx;\n break;\n }\n }\n\n if (idx1 === idx2) {\n idx2 = (idx1 + 1) % numFilteredPoints;\n }\n\n const lowerBase = Math.min(idx1, idx2);\n const higherBase = Math.max(idx1, idx2);\n const directDist = higherBase - lowerBase;\n const wrapDist = numFilteredPoints - directDist;\n const isWrap = wrapDist < directDist;\n\n // Open tail: return separate fill (closed) and stroke (open) paths\n if (this.options.openTail) {\n const tdx = tailTip.x - cx;\n const tdy = tailTip.y - cy;\n const tdLen = Math.sqrt(tdx * tdx + tdy * tdy);\n const perpX = -tdy / tdLen;\n const perpY = tdx / tdLen;\n const openHW = tailHalfWidth;\n\n let end1 = { x: tailTip.x + perpX * openHW, y: tailTip.y + perpY * openHW };\n let end2 = { x: tailTip.x - perpX * openHW, y: tailTip.y - perpY * openHW };\n\n const d1 = Math.hypot(end1.x - filteredPoints[lowerBase].x, end1.y - filteredPoints[lowerBase].y);\n const d2 = Math.hypot(end2.x - filteredPoints[lowerBase].x, end2.y - filteredPoints[lowerBase].y);\n if (d1 > d2) [end1, end2] = [end2, end1];\n\n let strokePath: string;\n\n if (isWrap) {\n strokePath = `M ${end1.x.toFixed(2)} ${end1.y.toFixed(2)}`;\n strokePath += ` L ${filteredPoints[lowerBase].x.toFixed(2)} ${filteredPoints[lowerBase].y.toFixed(2)}`;\n for (let i = lowerBase + 1; i <= higherBase; i++) {\n strokePath += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n strokePath += ` L ${end2.x.toFixed(2)} ${end2.y.toFixed(2)}`;\n } else {\n strokePath = `M ${end2.x.toFixed(2)} ${end2.y.toFixed(2)}`;\n strokePath += ` L ${filteredPoints[higherBase].x.toFixed(2)} ${filteredPoints[higherBase].y.toFixed(2)}`;\n for (let i = higherBase + 1; i < numFilteredPoints; i++) {\n strokePath += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n for (let i = 0; i <= lowerBase; i++) {\n strokePath += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n strokePath += ` L ${end1.x.toFixed(2)} ${end1.y.toFixed(2)}`;\n }\n\n return { fill: strokePath + ' Z', stroke: strokePath };\n }\n\n // Build tail path segment helper\n const curve = this.tailCurve || 'straight';\n // `??` (not `||`): an explicit curveAmount of 0 is a valid, deliberate value.\n const curveAmount = this.tailCurveAmount ?? 0.4;\n\n const buildTailSegment = (fromPt: PathPoint, toPt: PathPoint): string => {\n const midX = (fromPt.x + toPt.x) / 2;\n const midY = (fromPt.y + toPt.y) / 2;\n const dx = tailTip!.x - midX;\n const dy = tailTip!.y - midY;\n const len = Math.sqrt(dx * dx + dy * dy);\n\n if (curve === 'straight' || len < 1) {\n return ` L ${tailTip!.x.toFixed(2)} ${tailTip!.y.toFixed(2)} L ${toPt.x.toFixed(2)} ${toPt.y.toFixed(2)}`;\n }\n\n const perpXC = -dy / len;\n const perpYC = dx / len;\n const curveDir = curve === 'left' ? -1 : 1;\n const curveOffset = len * curveAmount * 0.3 * curveDir;\n const mid1X = (fromPt.x + tailTip!.x) / 2;\n const mid1Y = (fromPt.y + tailTip!.y) / 2;\n const ctrl1X = mid1X + perpXC * curveOffset;\n const ctrl1Y = mid1Y + perpYC * curveOffset;\n const mid2X = (tailTip!.x + toPt.x) / 2;\n const mid2Y = (tailTip!.y + toPt.y) / 2;\n const ctrl2X = mid2X + perpXC * curveOffset;\n const ctrl2Y = mid2Y + perpYC * curveOffset;\n return ` Q ${ctrl1X.toFixed(2)} ${ctrl1Y.toFixed(2)} ${tailTip!.x.toFixed(2)} ${tailTip!.y.toFixed(2)} Q ${ctrl2X.toFixed(2)} ${ctrl2Y.toFixed(2)} ${toPt.x.toFixed(2)} ${toPt.y.toFixed(2)}`;\n };\n\n let path: string;\n\n if (isWrap) {\n const startIdx = lowerBase + 1;\n if (startIdx >= higherBase) {\n path = `M ${filteredPoints[0].x.toFixed(2)} ${filteredPoints[0].y.toFixed(2)}`;\n for (let i = 1; i < numFilteredPoints; i++) {\n path += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n path += ' Z';\n } else {\n path = `M ${filteredPoints[startIdx].x.toFixed(2)} ${filteredPoints[startIdx].y.toFixed(2)}`;\n for (let i = startIdx + 1; i <= higherBase; i++) {\n path += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n path += buildTailSegment(filteredPoints[higherBase], filteredPoints[lowerBase]);\n path += ' Z';\n }\n } else {\n path = `M ${filteredPoints[0].x.toFixed(2)} ${filteredPoints[0].y.toFixed(2)}`;\n for (let i = 1; i <= lowerBase; i++) {\n path += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n path += buildTailSegment(filteredPoints[lowerBase], filteredPoints[higherBase]);\n for (let i = higherBase + 1; i < numFilteredPoints; i++) {\n path += ` L ${filteredPoints[i].x.toFixed(2)} ${filteredPoints[i].y.toFixed(2)}`;\n }\n path += ' Z';\n }\n\n return path;\n }\n\n /** Normalize angle to -PI to PI range */\n normalizeAngle(angle: number): number {\n while (angle > Math.PI) angle -= Math.PI * 2;\n while (angle < -Math.PI) angle += Math.PI * 2;\n return angle;\n }\n\n /** Create thought balloon (cloud shape with bumpy outline) */\n createThoughtBalloonPath(cx: number, cy: number, width: number, height: number): string {\n const rx = width / 2;\n const ry = height / 2;\n\n const perimeter = Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));\n const avgRadius = (rx + ry) / 2;\n const sizeFactor = Math.max(0.4, Math.min(1, avgRadius / 80));\n const targetBumpLength = 35 / sizeFactor;\n const bumps = Math.max(6, Math.floor(perimeter / targetBumpLength));\n\n const points: { x: number; y: number }[] = [];\n const pseudoRandom = (i: number) => {\n const x = Math.sin(i * 9999.99) * 10000;\n return x - Math.floor(x);\n };\n\n for (let i = 0; i < bumps; i++) {\n const t = i / bumps;\n const angleOffset = (pseudoRandom(i) - 0.5) * (Math.PI * 2 / bumps) * 0.4;\n const angle = t * Math.PI * 2 + angleOffset;\n const x = cx + rx * Math.cos(angle);\n const y = cy + ry * Math.sin(angle);\n points.push({ x, y });\n }\n\n let path = `M ${points[0].x.toFixed(2)} ${points[0].y.toFixed(2)}`;\n for (let i = 0; i < bumps; i++) {\n const p1 = points[i];\n const p2 = points[(i + 1) % bumps];\n const dx = p2.x - p1.x;\n const dy = p2.y - p1.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n const nx = dy / dist;\n const ny = -dx / dist;\n const bumpOut = dist * (0.3 + 0.3 * sizeFactor);\n const cp1x = p1.x + dx * 0.2 + nx * bumpOut;\n const cp1y = p1.y + dy * 0.2 + ny * bumpOut;\n const cp2x = p1.x + dx * 0.8 + nx * bumpOut;\n const cp2y = p1.y + dy * 0.8 + ny * bumpOut;\n path += ` C ${cp1x.toFixed(2)} ${cp1y.toFixed(2)} ${cp2x.toFixed(2)} ${cp2y.toFixed(2)} ${p2.x.toFixed(2)} ${p2.y.toFixed(2)}`;\n }\n path += ' Z';\n return path;\n }\n\n /** Add thought bubble tail (small ellipses leading to tail tip) */\n addThoughtBubbles(cx: number, cy: number, width: number, height: number, tailTip: { x: number; y: number }): void {\n // Geometry shared with the CMS canvas renderer (balloon-geometry.ts).\n const circles = thoughtTrailCircles({ cx, cy, width, height }, tailTip);\n\n for (const circle of circles) {\n const bubble = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n bubble.setAttribute('cx', circle.x.toFixed(2));\n bubble.setAttribute('cy', circle.y.toFixed(2));\n bubble.setAttribute('r', String(circle.r));\n bubble.setAttribute('fill', this.options.fillColor);\n bubble.setAttribute('stroke', this.options.strokeColor);\n bubble.setAttribute('stroke-width', String(this.options.strokeWidth));\n\n this.svg!.appendChild(bubble);\n }\n }\n\n /** Create shout balloon (jagged/burst edges) */\n createShoutBalloonPath(\n cx: number, cy: number,\n width: number, height: number,\n tailTip: { x: number; y: number } | null = null\n ): string {\n const rx = width / 2 + 10;\n const ry = height / 2 + 10;\n\n const perimeter = Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));\n const targetSpikeWidth = 25;\n const spikes = Math.max(10, Math.floor(perimeter / targetSpikeWidth));\n\n const points: { x: number; y: number; angle: number }[] = [];\n const numPoints = spikes * 2;\n\n const pseudoRandom = (i: number) => {\n const x = Math.sin(i * 1234.56) * 10000;\n return x - Math.floor(x);\n };\n\n for (let i = 0; i < numPoints; i++) {\n const t = i / numPoints;\n const isPeak = i % 2 === 0;\n const angleOffset = (pseudoRandom(i) - 0.5) * (Math.PI * 2 / numPoints) * 0.5;\n const angle = t * Math.PI * 2 + angleOffset - Math.PI;\n const peakOut = 15 + pseudoRandom(i + 100) * 15;\n const valleyIn = 0 + pseudoRandom(i + 200) * 10;\n const offset = isPeak ? peakOut : -valleyIn;\n const x = cx + (rx + offset) * Math.cos(angle);\n const y = cy + (ry + offset) * Math.sin(angle);\n points.push({ x, y, angle });\n }\n\n if (tailTip) {\n const tailAngle = Math.atan2(tailTip.y - cy, tailTip.x - cx);\n let closestPeakIdx = 0;\n let minAngleDiffS = Infinity;\n\n for (let i = 0; i < numPoints; i += 2) {\n const actualAngle = Math.atan2(points[i].y - cy, points[i].x - cx);\n const diff = Math.abs(this.normalizeAngle(actualAngle - tailAngle));\n if (diff < minAngleDiffS) {\n minAngleDiffS = diff;\n closestPeakIdx = i;\n }\n }\n\n points[closestPeakIdx] = {\n x: tailTip.x,\n y: tailTip.y,\n angle: points[closestPeakIdx].angle,\n };\n }\n\n let path = `M ${points[0].x.toFixed(2)} ${points[0].y.toFixed(2)}`;\n for (let i = 1; i < points.length; i++) {\n path += ` L ${points[i].x.toFixed(2)} ${points[i].y.toFixed(2)}`;\n }\n path += ' Z';\n return path;\n }\n}\n\n/** Helper function to create a balloon quickly */\nexport function createBalloon(\n containerSelector: string | HTMLElement,\n text: string,\n tailOptions: TailOptions | null,\n options: Partial<BalloonOptions> = {}\n): BalloonRenderResult {\n const balloon = new ComicBalloon(containerSelector, options);\n return balloon.render(text, tailOptions);\n}\n","/**\n * Animation Utilities\n * Easing functions, motion detection, and animation helpers\n */\n\n/**\n * Easing function type\n * Takes a progress value (0-1) and returns an eased value (0-1)\n */\nexport type EasingFunction = (t: number) => number;\n\n/**\n * Get an easing function by name\n * \n * @param easing - Easing name\n * @returns Easing function\n * \n * @example\n * ```typescript\n * const easeOut = getEasingFunction('ease-out');\n * easeOut(0.5); // Returns: ~0.77 (accelerates quickly, then decelerates)\n * ```\n */\nexport function getEasingFunction(\n easing = 'ease'\n): EasingFunction {\n const easingFunctions: Record<string, EasingFunction> = {\n linear: easings.linear,\n ease: easings.ease,\n 'ease-in': easings.easeIn,\n 'ease-out': easings.easeOut,\n 'ease-in-out': easings.easeInOut,\n 'ease-in-quad': easings.easeInQuad,\n 'ease-out-quad': easings.easeOutQuad,\n 'ease-in-out-quad': easings.easeInOutQuad,\n 'ease-in-cubic': easings.easeInCubic,\n 'ease-out-cubic': easings.easeOutCubic,\n 'ease-in-out-cubic': easings.easeInOutCubic,\n 'ease-in-quart': easings.easeInQuart,\n 'ease-out-quart': easings.easeOutQuart,\n 'ease-in-out-quart': easings.easeInOutQuart,\n 'ease-in-quint': easings.easeInQuint,\n 'ease-out-quint': easings.easeOutQuint,\n 'ease-in-out-quint': easings.easeInOutQuint,\n 'ease-in-sine': easings.easeInSine,\n 'ease-out-sine': easings.easeOutSine,\n 'ease-in-out-sine': easings.easeInOutSine,\n 'ease-in-expo': easings.easeInExpo,\n 'ease-out-expo': easings.easeOutExpo,\n 'ease-in-out-expo': easings.easeInOutExpo,\n 'ease-in-circ': easings.easeInCirc,\n 'ease-out-circ': easings.easeOutCirc,\n 'ease-in-out-circ': easings.easeInOutCirc,\n 'ease-in-back': easings.easeInBack,\n 'ease-out-back': easings.easeOutBack,\n 'ease-in-out-back': easings.easeInOutBack,\n 'ease-in-elastic': easings.easeInElastic,\n 'ease-out-elastic': easings.easeOutElastic,\n 'ease-in-out-elastic': easings.easeInOutElastic,\n 'ease-in-bounce': easings.easeInBounce,\n 'ease-out-bounce': easings.easeOutBounce,\n 'ease-in-out-bounce': easings.easeInOutBounce,\n };\n\n return easingFunctions[easing] || easings.ease;\n}\n\n/**\n * Check if user prefers reduced motion\n * \n * @returns True if user has reduced motion preference enabled\n * \n * @example\n * ```typescript\n * if (shouldReduceMotion()) {\n * // Use cut instead of slide transition\n * // Skip parallax effects\n * // Reduce animation duration\n * }\n * ```\n */\nexport function shouldReduceMotion(): boolean {\n if (typeof window === 'undefined' || !window.matchMedia) {\n return false;\n }\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n return mediaQuery.matches;\n}\n\n/**\n * Get adjusted animation duration based on reduced motion preference\n * \n * @param baseDuration - Base animation duration in milliseconds\n * @param reducedFactor - Factor to multiply by if reduced motion (default: 0.1)\n * @returns Adjusted duration\n * \n * @example\n * ```typescript\n * const duration = getAdjustedDuration(500);\n * // Returns: 500 if normal motion, 50 if reduced motion\n * ```\n */\nexport function getAdjustedDuration(\n baseDuration: number,\n reducedFactor = 0.1\n): number {\n return shouldReduceMotion() ? baseDuration * reducedFactor : baseDuration;\n}\n\n/**\n * Clamp a value between min and max\n * \n * @param value - Value to clamp\n * @param min - Minimum value\n * @param max - Maximum value\n * @returns Clamped value\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Linear interpolation between two values\n * \n * @param start - Start value\n * @param end - End value\n * @param t - Progress (0-1)\n * @returns Interpolated value\n * \n * @example\n * ```typescript\n * lerp(0, 100, 0.5); // Returns: 50\n * lerp(10, 20, 0.25); // Returns: 12.5\n * ```\n */\nexport function lerp(start: number, end: number, t: number): number {\n return start + (end - start) * t;\n}\n\n/**\n * Map a value from one range to another\n * \n * @param value - Input value\n * @param inMin - Input range minimum\n * @param inMax - Input range maximum\n * @param outMin - Output range minimum\n * @param outMax - Output range maximum\n * @returns Mapped value\n * \n * @example\n * ```typescript\n * mapRange(5, 0, 10, 0, 100); // Returns: 50\n * mapRange(25, 0, 100, 0, 1); // Returns: 0.25\n * ```\n */\nexport function mapRange(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number\n): number {\n const t = (value - inMin) / (inMax - inMin);\n return lerp(outMin, outMax, t);\n}\n\n/**\n * Request animation frame with fallback\n * \n * @param callback - Function to call on next frame\n * @returns Request ID for cancellation\n */\nexport function requestFrame(callback: FrameRequestCallback): number {\n if (typeof window !== 'undefined' && window.requestAnimationFrame) {\n return window.requestAnimationFrame(callback);\n }\n // Fallback to setTimeout\n return setTimeout(() => callback(Date.now()), 16) as unknown as number;\n}\n\n/**\n * Cancel animation frame with fallback\n * \n * @param id - Request ID from requestFrame\n */\nexport function cancelFrame(id: number): void {\n if (typeof window !== 'undefined' && window.cancelAnimationFrame) {\n window.cancelAnimationFrame(id);\n } else {\n clearTimeout(id);\n }\n}\n\n/**\n * Animate a value over time using requestAnimationFrame\n * \n * @param options - Animation options\n * @returns Promise that resolves when animation completes\n * \n * @example\n * ```typescript\n * await animate({\n * from: 0,\n * to: 100,\n * duration: 1000,\n * easing: 'ease-out',\n * onUpdate: (value) => {\n * element.style.opacity = value / 100;\n * }\n * });\n * ```\n */\nexport function animate(options: {\n from: number;\n to: number;\n duration: number;\n easing?: string;\n onUpdate: (value: number, progress: number) => void;\n onComplete?: () => void;\n}): Promise<void> {\n return new Promise((resolve) => {\n const { from, to, duration, easing = 'ease', onUpdate, onComplete } = options;\n const easingFn = getEasingFunction(easing);\n const startTime = performance.now();\n\n function step(currentTime: number): void {\n const elapsed = currentTime - startTime;\n const progress = clamp(elapsed / duration, 0, 1);\n const easedProgress = easingFn(progress);\n const value = lerp(from, to, easedProgress);\n\n onUpdate(value, progress);\n\n if (progress < 1) {\n requestFrame(step);\n } else {\n if (onComplete) {\n onComplete();\n }\n resolve();\n }\n }\n\n requestFrame(step);\n });\n}\n\n/**\n * Easing functions collection\n * Based on https://easings.net/\n */\nexport const easings = {\n // No easing\n linear: (t: number): number => t,\n\n // CSS standard easings\n ease: (t: number): number => {\n return t < 0.5\n ? 4 * t * t * t\n : 1 - Math.pow(-2 * t + 2, 3) / 2;\n },\n\n easeIn: (t: number): number => {\n return t * t * t;\n },\n\n easeOut: (t: number): number => {\n return 1 - Math.pow(1 - t, 3);\n },\n\n easeInOut: (t: number): number => {\n return t < 0.5\n ? 4 * t * t * t\n : 1 - Math.pow(-2 * t + 2, 3) / 2;\n },\n\n // Quadratic\n easeInQuad: (t: number): number => {\n return t * t;\n },\n\n easeOutQuad: (t: number): number => {\n return 1 - (1 - t) * (1 - t);\n },\n\n easeInOutQuad: (t: number): number => {\n return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;\n },\n\n // Cubic\n easeInCubic: (t: number): number => {\n return t * t * t;\n },\n\n easeOutCubic: (t: number): number => {\n return 1 - Math.pow(1 - t, 3);\n },\n\n easeInOutCubic: (t: number): number => {\n return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;\n },\n\n // Quartic\n easeInQuart: (t: number): number => {\n return t * t * t * t;\n },\n\n easeOutQuart: (t: number): number => {\n return 1 - Math.pow(1 - t, 4);\n },\n\n easeInOutQuart: (t: number): number => {\n return t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2;\n },\n\n // Quintic\n easeInQuint: (t: number): number => {\n return t * t * t * t * t;\n },\n\n easeOutQuint: (t: number): number => {\n return 1 - Math.pow(1 - t, 5);\n },\n\n easeInOutQuint: (t: number): number => {\n return t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2;\n },\n\n // Sine\n easeInSine: (t: number): number => {\n return 1 - Math.cos((t * Math.PI) / 2);\n },\n\n easeOutSine: (t: number): number => {\n return Math.sin((t * Math.PI) / 2);\n },\n\n easeInOutSine: (t: number): number => {\n return -(Math.cos(Math.PI * t) - 1) / 2;\n },\n\n // Exponential\n easeInExpo: (t: number): number => {\n return t === 0 ? 0 : Math.pow(2, 10 * t - 10);\n },\n\n easeOutExpo: (t: number): number => {\n return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);\n },\n\n easeInOutExpo: (t: number): number => {\n return t === 0\n ? 0\n : t === 1\n ? 1\n : t < 0.5\n ? Math.pow(2, 20 * t - 10) / 2\n : (2 - Math.pow(2, -20 * t + 10)) / 2;\n },\n\n // Circular\n easeInCirc: (t: number): number => {\n return 1 - Math.sqrt(1 - Math.pow(t, 2));\n },\n\n easeOutCirc: (t: number): number => {\n return Math.sqrt(1 - Math.pow(t - 1, 2));\n },\n\n easeInOutCirc: (t: number): number => {\n return t < 0.5\n ? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2\n : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2;\n },\n\n // Back\n easeInBack: (t: number): number => {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return c3 * t * t * t - c1 * t * t;\n },\n\n easeOutBack: (t: number): number => {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);\n },\n\n easeInOutBack: (t: number): number => {\n const c1 = 1.70158;\n const c2 = c1 * 1.525;\n return t < 0.5\n ? (Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2\n : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;\n },\n\n // Elastic\n easeInElastic: (t: number): number => {\n const c4 = (2 * Math.PI) / 3;\n return t === 0\n ? 0\n : t === 1\n ? 1\n : -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4);\n },\n\n easeOutElastic: (t: number): number => {\n const c4 = (2 * Math.PI) / 3;\n return t === 0\n ? 0\n : t === 1\n ? 1\n : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;\n },\n\n easeInOutElastic: (t: number): number => {\n const c5 = (2 * Math.PI) / 4.5;\n return t === 0\n ? 0\n : t === 1\n ? 1\n : t < 0.5\n ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2\n : (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5)) / 2 + 1;\n },\n\n // Bounce\n easeInBounce: (t: number): number => {\n return 1 - easings.easeOutBounce(1 - t);\n },\n\n easeOutBounce: (t: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (t < 1 / d1) {\n return n1 * t * t;\n } else if (t < 2 / d1) {\n return n1 * (t -= 1.5 / d1) * t + 0.75;\n } else if (t < 2.5 / d1) {\n return n1 * (t -= 2.25 / d1) * t + 0.9375;\n } else {\n return n1 * (t -= 2.625 / d1) * t + 0.984375;\n }\n },\n\n easeInOutBounce: (t: number): number => {\n return t < 0.5\n ? (1 - easings.easeOutBounce(1 - 2 * t)) / 2\n : (1 + easings.easeOutBounce(2 * t - 1)) / 2;\n },\n};\n","/**\r\n * Image variant selection by required display width (canvas view\r\n * variant-by-zoom, integration spec §5): pick the smallest variant that\r\n * still covers the width a panel actually renders at — overview zoom\r\n * selects thumbnails, close-ups the full-resolution encode.\r\n */\r\n\r\nimport type { ImageVariant } from '../types';\r\n\r\n/**\r\n * Select the image variant for a target display width in physical pixels\r\n * (CSS px × devicePixelRatio × zoom).\r\n *\r\n * - `targetWidthPx <= 0` keeps the legacy behavior (first variant).\r\n * - Otherwise: the smallest variant whose `w` covers the target, falling\r\n * back to the largest available when none is big enough.\r\n * - Variants without a usable `w` only win when no variant declares one.\r\n */\r\nexport function selectImageVariantForWidth(\r\n variants: ImageVariant[] | undefined,\r\n targetWidthPx: number\r\n): ImageVariant | undefined {\r\n if (!variants || variants.length === 0) {\r\n return undefined;\r\n }\r\n if (targetWidthPx <= 0) {\r\n return variants[0];\r\n }\r\n\r\n const sized = variants\r\n .filter((variant) => typeof variant.w === 'number' && variant.w > 0)\r\n .sort((a, b) => a.w - b.w);\r\n if (sized.length === 0) {\r\n return variants[0];\r\n }\r\n\r\n return sized.find((variant) => variant.w >= targetWidthPx) ?? sized[sized.length - 1];\r\n}\r\n\r\n/**\r\n * Quantize a required width so tiny zoom changes don't thrash variant\r\n * re-resolution (and never below one step).\r\n */\r\nexport function quantizeTargetWidth(widthPx: number, step = 256): number {\r\n return Math.max(step, Math.ceil(widthPx / step) * step);\r\n}\r\n","/**\r\n * Panel Variant Utilities\r\n *\r\n * Runtime resolution of panel `variants` (schema `PanelVariant`):\r\n * each variant carries a JSON Logic `when` condition evaluated against\r\n * the flat variable context, and an `overrides` object (schema\r\n * `PanelPartial`) whose fields REPLACE the corresponding base panel\r\n * fields wholesale (no deep merge).\r\n *\r\n * Selection: variants are evaluated in manifest order; the FIRST\r\n * variant whose `when` evaluates truthy wins. If none match, the base\r\n * panel applies unchanged.\r\n */\r\n\r\nimport type { JsonLogic } from '../types';\r\nimport type { Panel, PanelVariant } from '../types/panel.types';\r\nimport { evaluateJsonLogic } from './json-logic-utils';\r\n\r\n/** Flat JSON Logic evaluation context (see VariableStoreService.createContext). */\r\nexport type VariantContext = Record<string, unknown> | null | undefined;\r\n\r\n/** Result of resolving a panel against the variable context. */\r\nexport interface ResolvedPanel {\r\n /** The effective panel (=== the input panel when no variant applies). */\r\n panel: Panel;\r\n /** Id of the applied variant, if any. */\r\n variantId?: string;\r\n}\r\n\r\n/**\r\n * The panel fields a variant may override — mirrors the schema's\r\n * `PanelPartial` (additionalProperties: false). Anything else in\r\n * `overrides` is ignored so a manifest can never swap ids or nest\r\n * variants.\r\n */\r\nconst OVERRIDABLE_KEYS = [\r\n 'title',\r\n 'description',\r\n 'durationMs',\r\n 'formatViews',\r\n 'layers',\r\n 'animations',\r\n 'speechBubbles',\r\n 'hotspots',\r\n 'audio',\r\n 'video',\r\n 'plugins',\r\n 'accessibility',\r\n 'shareable',\r\n 'age_rating_override',\r\n 'preloadHints',\r\n 'memoryBudgetHint',\r\n 'contentWarnings',\r\n] as const;\r\n\r\n/**\r\n * Select the first variant whose `when` condition matches the context.\r\n * Returns undefined when the panel has no variants or none match.\r\n */\r\nexport function selectVariant(\r\n panel: Panel | undefined | null,\r\n context: VariantContext\r\n): PanelVariant | undefined {\r\n if (!panel?.variants?.length) {\r\n return undefined;\r\n }\r\n return panel.variants.find(\r\n (variant) =>\r\n !!variant &&\r\n variant.when !== undefined &&\r\n evaluateJsonLogic(variant.when as JsonLogic, context ?? {})\r\n );\r\n}\r\n\r\n/**\r\n * Apply a variant's overrides to a panel (whole-field replacement,\r\n * restricted to the schema's PanelPartial keys). Always returns a new\r\n * object; the base panel is never mutated.\r\n */\r\nexport function applyVariantOverrides(panel: Panel, variant: PanelVariant): Panel {\r\n const effective: Panel = { ...panel };\r\n const overrides = (variant.overrides ?? {}) as Record<string, unknown>;\r\n for (const key of OVERRIDABLE_KEYS) {\r\n if (Object.prototype.hasOwnProperty.call(overrides, key) && overrides[key] !== undefined) {\r\n (effective as Record<string, unknown>)[key] = overrides[key];\r\n }\r\n }\r\n return effective;\r\n}\r\n\r\n/**\r\n * Resolve a panel against the variable context.\r\n *\r\n * @param forcedVariantId - When set, skips condition evaluation and\r\n * applies this variant directly (manual variant cycling). `null`\r\n * forces the base panel. Unknown ids fall back to condition-based\r\n * selection.\r\n * @returns `panel === input` (same reference) when no variant applies,\r\n * so identity-based comparisons and OnPush bindings stay stable.\r\n */\r\nexport function resolvePanelVariant(\r\n panel: Panel,\r\n context: VariantContext,\r\n forcedVariantId?: string | null\r\n): ResolvedPanel {\r\n if (!panel.variants?.length) {\r\n return { panel };\r\n }\r\n\r\n if (forcedVariantId === null) {\r\n return { panel };\r\n }\r\n\r\n let variant: PanelVariant | undefined;\r\n if (forcedVariantId !== undefined) {\r\n variant = panel.variants.find((v) => v?.id === forcedVariantId);\r\n }\r\n if (!variant) {\r\n variant = selectVariant(panel, context);\r\n }\r\n if (!variant) {\r\n return { panel };\r\n }\r\n return { panel: applyVariantOverrides(panel, variant), variantId: variant.id };\r\n}\r\n\r\n/**\r\n * Resolve every panel of a chapter against the context. Panels without\r\n * an applying variant keep their original object identity; when NO\r\n * panel in the record changes, the input record itself is returned.\r\n */\r\nexport function resolvePanels(\r\n panels: Record<string, Panel>,\r\n context: VariantContext\r\n): Record<string, Panel> {\r\n let changed = false;\r\n const resolved: Record<string, Panel> = {};\r\n for (const [id, panel] of Object.entries(panels)) {\r\n const result = resolvePanelVariant(panel, context);\r\n resolved[id] = result.panel;\r\n if (result.panel !== panel) {\r\n changed = true;\r\n }\r\n }\r\n return changed ? resolved : panels;\r\n}\r\n","/**\r\n * Utility Functions\r\n * Central export for all utility modules\r\n * @packageDocumentation\r\n */\r\n\r\n// Locale utilities\r\nexport {\r\n resolveLocalizedString,\r\n getBaseLanguage,\r\n pickLocalizedAsset,\r\n isLocaleSupported,\r\n getLocalizationCompleteness,\r\n createLocaleFallbackChain,\r\n normalizeLocaleCode,\r\n} from './locale-utils';\r\n\r\n// Video config utilities\r\nexport {\r\n DEFAULT_VIDEO_PLAY_MODE,\r\n DEFAULT_VIDEO_START_MODE,\r\n DEFAULT_VIDEO_MUTED,\r\n resolvePlayMode,\r\n resolveStartMode,\r\n resolveMuted,\r\n resolveVideoConfig,\r\n type EffectiveVideoConfig,\r\n} from './video-config-utils';\r\n\r\n// Asset utilities\r\nexport {\r\n resolveAssetUrl,\r\n isAbsoluteUrl,\r\n selectBestImageVariant,\r\n selectVariantByFormat,\r\n getAssetFromCatalog,\r\n getFileExtension,\r\n guessMimeType,\r\n calculateOptimalDimensions,\r\n generateSrcSet,\r\n isMimeTypeSupported,\r\n estimateImageSize,\r\n} from './asset-utils';\r\n\r\n// JSON Logic utilities\r\nexport {\r\n evaluateJsonLogic,\r\n createContext,\r\n validateJsonLogic,\r\n extractVariableNames,\r\n addCustomOperator,\r\n removeCustomOperator,\r\n registerPanelWaveOperators,\r\n evaluateAll,\r\n evaluateAny,\r\n testJsonLogic,\r\n} from './json-logic-utils';\r\n\r\n// Balloon config utilities\r\nexport {\r\n DEFAULT_BALLOON_CONFIG,\r\n mergeBalloonConfig,\r\n balloonConfigToRenderOptions,\r\n balloonConfigToTailOptions,\r\n} from './balloon-config';\r\n\r\n// Comic Balloon renderer\r\nexport {\r\n ComicBalloon,\r\n createBalloon,\r\n type BalloonOptions,\r\n type BalloonPadding,\r\n type TailOptions,\r\n type CutOptions,\r\n type BalloonRenderResult,\r\n} from './comic-balloon';\r\n\r\n// Animation utilities\r\nexport {\r\n type EasingFunction,\r\n getEasingFunction,\r\n shouldReduceMotion,\r\n getAdjustedDuration,\r\n clamp,\r\n lerp,\r\n mapRange,\r\n requestFrame,\r\n cancelFrame,\r\n animate,\r\n easings,\r\n} from './animation-utils';\r\n\r\nexport {\r\n selectImageVariantForWidth,\r\n quantizeTargetWidth,\r\n} from './image-variant-utils';\r\n\r\n// Panel variant utilities (manifest PanelVariant runtime)\r\nexport {\r\n selectVariant,\r\n applyVariantOverrides,\r\n resolvePanelVariant,\r\n resolvePanels,\r\n type ResolvedPanel,\r\n type VariantContext,\r\n} from './variant-utils';\r\n","/**\n * Entitlement Service\n * Manages entitlement checking, paywall gating, and access control\n */\n\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport type {\n EntitlementAdapter,\n EntitlementContext,\n EntitlementStatus,\n PaywallGate,\n UserInfo,\n} from '../types/entitlement.types';\nimport { NullEntitlementAdapter } from '../types/entitlement.types';\n\n/**\n * Entitlement Service\n * Provides entitlement and paywall functionality\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class EntitlementService {\n /**\n * Current entitlement adapter\n */\n private adapter: EntitlementAdapter;\n\n /**\n * Current entitlement status\n */\n private entitlementStatus$ = new BehaviorSubject<EntitlementStatus | null>(null);\n\n /**\n * Current user\n */\n private currentUser$ = new BehaviorSubject<UserInfo | null>(null);\n\n /**\n * Cache of entitlement checks\n */\n private cache = new Map<string, EntitlementStatus>();\n\n /**\n * Cache TTL in milliseconds (5 minutes)\n */\n private readonly CACHE_TTL = 5 * 60 * 1000;\n\n /**\n * Initialize service with null adapter\n */\n constructor() {\n this.adapter = new NullEntitlementAdapter();\n }\n\n /**\n * Set the entitlement adapter\n */\n setAdapter(adapter: EntitlementAdapter): void {\n this.adapter = adapter;\n this.clearCache();\n \n // Update current user if adapter supports it\n if (this.adapter.getCurrentUser) {\n this.adapter.getCurrentUser().then(user => {\n this.currentUser$.next(user);\n });\n }\n }\n\n /**\n * Get the current entitlement adapter\n */\n getAdapter(): EntitlementAdapter {\n return this.adapter;\n }\n\n /**\n * Check entitlement for a given context\n */\n async checkEntitlement(context: EntitlementContext): Promise<EntitlementStatus> {\n // Create cache key\n const cacheKey = this.getCacheKey(context);\n\n // Check cache\n const cached = this.cache.get(cacheKey);\n if (cached) {\n // Check if expired\n if (cached.expiresAt && cached.expiresAt > Date.now()) {\n return cached;\n }\n }\n\n // Resolve entitlement\n const status = await this.adapter.resolveEntitlement(context);\n\n // Cache the result\n this.cache.set(cacheKey, status);\n\n // Update observable\n this.entitlementStatus$.next(status);\n\n // Update current user\n if (status.user) {\n this.currentUser$.next(status.user);\n }\n\n // Schedule cache cleanup\n if (status.expiresAt) {\n const ttl = status.expiresAt - Date.now();\n setTimeout(() => this.cache.delete(cacheKey), ttl);\n } else {\n setTimeout(() => this.cache.delete(cacheKey), this.CACHE_TTL);\n }\n\n return status;\n }\n\n /**\n * Check if user has access to a panel\n */\n async hasAccessToPanel(workId: string, chapterId: string, panelId: string): Promise<boolean> {\n const status = await this.checkEntitlement({\n workId,\n chapterId,\n panelId,\n });\n return status.ok;\n }\n\n /**\n * Check if user has access to a chapter\n */\n async hasAccessToChapter(workId: string, chapterId: string): Promise<boolean> {\n const status = await this.checkEntitlement({\n workId,\n chapterId,\n });\n return status.ok;\n }\n\n /**\n * Check if user has access to a work\n */\n async hasAccessToWork(workId: string): Promise<boolean> {\n const status = await this.checkEntitlement({\n workId,\n });\n return status.ok;\n }\n\n /**\n * Get signed URL for an asset\n */\n async getSignedUrl(assetId: string, purpose: 'stream' | 'download' = 'stream'): Promise<string> {\n if (this.adapter.getSignedUrl) {\n return await this.adapter.getSignedUrl(assetId, purpose);\n }\n // Return asset ID as-is if signing not supported\n return assetId;\n }\n\n /**\n * Show paywall UI\n */\n async showPaywall(gate: PaywallGate): Promise<void> {\n if (this.adapter.showPaywallUI) {\n await this.adapter.showPaywallUI(gate);\n // Clear cache after paywall interaction\n this.clearCache();\n } else {\n console.warn('[EntitlementService] showPaywallUI not implemented by adapter');\n }\n }\n\n /**\n * Verify age requirement\n */\n async verifyAge(minimumAge: number): Promise<boolean> {\n if (this.adapter.verifyAge) {\n return await this.adapter.verifyAge(minimumAge);\n }\n // If not implemented, check user age\n const user = this.currentUser$.value;\n if (user?.age !== undefined) {\n return user.age >= minimumAge;\n }\n // Default to false for age verification\n return false;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n if (this.adapter.isAuthenticated) {\n return this.adapter.isAuthenticated();\n }\n // Fall back to checking if we have a user\n return this.currentUser$.value !== null;\n }\n\n /**\n * Get current user\n */\n async getCurrentUser(): Promise<UserInfo | null> {\n if (this.adapter.getCurrentUser) {\n const user = await this.adapter.getCurrentUser();\n this.currentUser$.next(user);\n return user;\n }\n return this.currentUser$.value;\n }\n\n /**\n * Get current user as observable\n */\n getCurrentUser$(): Observable<UserInfo | null> {\n return this.currentUser$.asObservable();\n }\n\n /**\n * Get current entitlement status as observable\n */\n getEntitlementStatus$(): Observable<EntitlementStatus | null> {\n return this.entitlementStatus$.asObservable();\n }\n\n /**\n * Clear entitlement cache\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n /**\n * Create cache key from context\n */\n private getCacheKey(context: EntitlementContext): string {\n const parts = [context.workId];\n if (context.chapterId) parts.push(context.chapterId);\n if (context.panelId) parts.push(context.panelId);\n return parts.join(':');\n }\n}\n","/**\n * Flow Engine Service\n * Handles graph navigation, condition evaluation, and action application\n */\n\nimport { inject, Injectable } from '@angular/core';\nimport type { CameraMove, Edge, Graph, Mutation, Settings, Transition } from '../types';\nimport { evaluateJsonLogic } from '../utils';\nimport { EntitlementService } from './entitlement.service';\n\n/**\n * Navigation result\n */\nexport interface NavigationResult {\n nextPanelId: string | null;\n transition?: Transition;\n /** Camera travel for canvas view (edge cameraMove or the format default). */\n cameraMove?: CameraMove;\n /** Variable mutations the traversed edge carries (schema `Edge.action`). */\n action?: Mutation[];\n}\n\n/**\n * Flow Engine Service\n * Manages panel navigation through graph traversal\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class FlowEngineService {\n private readonly entitlementService = inject(EntitlementService);\n\n /**\n * Get next panel based on graph edges and conditions\n * @param graph - Navigation graph\n * @param currentPanelId - Current panel ID\n * @param context - Variable context for condition evaluation\n * @returns Navigation result with next panel and transition\n */\n getNextPanel(\n graph: Graph,\n currentPanelId: string,\n context: Record<string, unknown>,\n defaultTransition?: Transition,\n defaultCameraMove?: CameraMove\n ): NavigationResult {\n // Get edges from current panel\n const edges = this.getEdgesFromPanel(graph, currentPanelId);\n\n if (edges.length === 0) {\n return { nextPanelId: null };\n }\n\n // Filter edges by condition\n const validEdges = edges.filter((edge) => this.evaluateCondition(edge, context));\n\n if (validEdges.length === 0) {\n return { nextPanelId: null };\n }\n\n // Sort by priority (highest first)\n const sortedEdges = this.sortEdgesByPriority(validEdges);\n\n // Take first (highest priority) edge\n const selectedEdge = sortedEdges[0];\n\n return {\n nextPanelId: selectedEdge.to,\n // Edges without a transition inherit the output format's default\n // (settings.outputPresets[format].defaultTransition, schema 1.2).\n transition: selectedEdge.transition ?? defaultTransition,\n // Same inheritance for canvas-view camera moves (schema 1.4).\n cameraMove: selectedEdge.cameraMove ?? defaultCameraMove,\n action: selectedEdge.action,\n };\n }\n\n /**\n * Camera move to play when navigating BACK from `currentPanelId` to\n * `previousPanelId`: the move of the edge originally traversed\n * (previous -> current, falling back to the format default) with its\n * waypoints reversed — the camera retraces the authored path.\n */\n getReturnCameraMove(\n graph: Graph,\n previousPanelId: string,\n currentPanelId: string,\n defaultCameraMove?: CameraMove\n ): CameraMove | undefined {\n const edge = graph.edges.find(\n (candidate) => candidate.from === previousPanelId && candidate.to === currentPanelId\n );\n const move = edge?.cameraMove ?? defaultCameraMove;\n if (!move) {\n return undefined;\n }\n if (!move.waypoints || move.waypoints.length === 0) {\n return { ...move };\n }\n return { ...move, waypoints: [...move.waypoints].reverse() };\n }\n\n /**\n * Resolve the default camera move from settings.outputPresets — the\n * canvas-view counterpart of {@link getDefaultTransition}, with the same\n * no-format rule: without an active format, the default is only used when\n * every defined preset agrees on it.\n */\n getDefaultCameraMove(settings?: Settings, format?: string): CameraMove | undefined {\n const presets = settings?.outputPresets;\n if (!presets) {\n return undefined;\n }\n\n if (format) {\n return presets[format]?.defaultCameraMove;\n }\n\n const defaults = Object.values(presets)\n .map((preset) => preset?.defaultCameraMove)\n .filter((move): move is CameraMove => !!move);\n if (defaults.length === 0) {\n return undefined;\n }\n const first = JSON.stringify(defaults[0]);\n return defaults.every((move) => JSON.stringify(move) === first)\n ? defaults[0]\n : undefined;\n }\n\n /**\n * Transition to play when navigating BACK from `currentPanelId` to\n * `previousPanelId`: the transition of the edge originally traversed\n * (previous -> current, falling back to the format default), reversed.\n *\n * @param graph - Navigation graph\n * @param previousPanelId - Panel being returned to\n * @param currentPanelId - Panel being left\n * @param defaultTransition - Resolved outputPresets default, if any\n * @returns The reversed transition, or undefined\n */\n getReturnTransition(\n graph: Graph,\n previousPanelId: string,\n currentPanelId: string,\n defaultTransition?: Transition\n ): Transition | undefined {\n const edge = graph.edges.find(\n (candidate) => candidate.from === previousPanelId && candidate.to === currentPanelId\n );\n return this.reverseTransition(edge?.transition ?? defaultTransition);\n }\n\n /**\n * Reverse a transition's direction of motion (slide left <-> right,\n * up <-> down). Direction-less transitions (fade, zoom, cut) are\n * returned unchanged.\n */\n reverseTransition(transition?: Transition): Transition | undefined {\n if (!transition) {\n return undefined;\n }\n if (!transition.dir) {\n return { ...transition };\n }\n const opposite: Record<string, Transition['dir']> = {\n left: 'right',\n right: 'left',\n up: 'down',\n down: 'up',\n };\n return { ...transition, dir: opposite[transition.dir] ?? transition.dir };\n }\n\n /**\n * Resolve the default edge transition from settings.outputPresets.\n *\n * Per the manifest spec, an edge without a `transition` inherits the active\n * output format's `defaultTransition`. When no format is given (the player\n * does not track an active format yet), the default is only used if every\n * defined preset agrees on it; otherwise undefined (renderer falls back to\n * a plain cut).\n *\n * @param settings - Manifest settings\n * @param format - Active output format key, if known\n * @returns The default transition, or undefined\n */\n getDefaultTransition(settings?: Settings, format?: string): Transition | undefined {\n const presets = settings?.outputPresets;\n if (!presets) {\n return undefined;\n }\n\n if (format) {\n return presets[format]?.defaultTransition;\n }\n\n const defaults = Object.values(presets)\n .map((preset) => preset?.defaultTransition)\n .filter((transition): transition is Transition => !!transition);\n if (defaults.length === 0) {\n return undefined;\n }\n const first = JSON.stringify(defaults[0]);\n return defaults.every((transition) => JSON.stringify(transition) === first)\n ? defaults[0]\n : undefined;\n }\n\n /**\n * Get all edges originating from a panel\n * @param graph - Navigation graph\n * @param panelId - Panel ID\n * @returns Array of edges\n */\n private getEdgesFromPanel(graph: Graph, panelId: string): Edge[] {\n return graph.edges.filter((edge) => edge.from === panelId);\n }\n\n /**\n * Evaluate edge condition\n * @param edge - Edge to evaluate\n * @param context - Variable context\n * @returns True if condition passes\n */\n private evaluateCondition(edge: Edge, context: Record<string, unknown>): boolean {\n // No condition means always true\n if (!edge.condition) {\n return true;\n }\n\n return evaluateJsonLogic(edge.condition, context);\n }\n\n /**\n * Sort edges by priority (highest first)\n * @param edges - Edges to sort\n * @returns Sorted edges\n */\n private sortEdgesByPriority(edges: Edge[]): Edge[] {\n return [...edges].sort((a, b) => {\n const priorityA = a.priority ?? 0;\n const priorityB = b.priority ?? 0;\n return priorityB - priorityA; // Descending order\n });\n }\n\n /**\n * Get all possible next panels (ignoring conditions)\n * @param graph - Navigation graph\n * @param currentPanelId - Current panel ID\n * @returns Array of possible next panel IDs\n */\n getPossibleNextPanels(graph: Graph, currentPanelId: string): string[] {\n const edges = this.getEdgesFromPanel(graph, currentPanelId);\n return edges.map((edge) => edge.to);\n }\n\n /**\n * Get all edges pointing to a panel\n * @param graph - Navigation graph\n * @param panelId - Panel ID\n * @returns Array of edges\n */\n getEdgesToPanel(graph: Graph, panelId: string): Edge[] {\n return graph.edges.filter((edge) => edge.to === panelId);\n }\n\n /**\n * Get previous panels (panels with edges pointing to current)\n * @param graph - Navigation graph\n * @param currentPanelId - Current panel ID\n * @returns Array of previous panel IDs\n */\n getPreviousPanels(graph: Graph, currentPanelId: string): string[] {\n const edges = this.getEdgesToPanel(graph, currentPanelId);\n return edges.map((edge) => edge.from);\n }\n\n /**\n * Check if a panel has outgoing edges\n * @param graph - Navigation graph\n * @param panelId - Panel ID\n * @returns True if panel has outgoing edges\n */\n hasOutgoingEdges(graph: Graph, panelId: string): boolean {\n return this.getEdgesFromPanel(graph, panelId).length > 0;\n }\n\n /**\n * Check if a panel is an endpoint (no outgoing edges)\n * @param graph - Navigation graph\n * @param panelId - Panel ID\n * @returns True if panel is an endpoint\n */\n isEndpoint(graph: Graph, panelId: string): boolean {\n return !this.hasOutgoingEdges(graph, panelId);\n }\n\n /**\n * Check if a panel is the entry point\n * @param graph - Navigation graph\n * @param panelId - Panel ID\n * @returns True if panel is the entry\n */\n isEntry(graph: Graph, panelId: string): boolean {\n const entry = graph.entry;\n \n if (typeof entry === 'string') {\n return entry === panelId;\n }\n \n if (Array.isArray(entry)) {\n return entry.includes(panelId);\n }\n \n return false;\n }\n\n /**\n * Get entry panel(s) from graph\n * @param graph - Navigation graph\n * @returns Entry panel ID or array of IDs\n */\n getEntry(graph: Graph): string | string[] {\n return graph.entry;\n }\n\n /**\n * Find all endpoints in the graph\n * @param graph - Navigation graph\n * @returns Array of endpoint panel IDs\n */\n findEndpoints(graph: Graph): string[] {\n const allPanelIds = new Set<string>();\n \n // Collect all panel IDs from edges\n graph.edges.forEach((edge) => {\n allPanelIds.add(edge.from);\n allPanelIds.add(edge.to);\n });\n \n // Add entry panels\n if (typeof graph.entry === 'string') {\n allPanelIds.add(graph.entry);\n } else if (Array.isArray(graph.entry)) {\n graph.entry.forEach((id) => allPanelIds.add(id));\n }\n \n // Filter panels with no outgoing edges\n return Array.from(allPanelIds).filter((panelId) => this.isEndpoint(graph, panelId));\n }\n\n /**\n * Check if navigation path exists between two panels\n * @param graph - Navigation graph\n * @param fromPanelId - Start panel ID\n * @param toPanelId - Target panel ID\n * @param maxDepth - Maximum search depth (default: 100)\n * @returns True if path exists\n */\n hasPath(\n graph: Graph,\n fromPanelId: string,\n toPanelId: string,\n maxDepth = 100\n ): boolean {\n if (fromPanelId === toPanelId) {\n return true;\n }\n\n const visited = new Set<string>();\n const queue: { panelId: string; depth: number }[] = [\n { panelId: fromPanelId, depth: 0 },\n ];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (current.depth >= maxDepth) {\n continue;\n }\n\n if (visited.has(current.panelId)) {\n continue;\n }\n\n visited.add(current.panelId);\n\n const nextPanels = this.getPossibleNextPanels(graph, current.panelId);\n\n for (const nextPanel of nextPanels) {\n if (nextPanel === toPanelId) {\n return true;\n }\n\n queue.push({ panelId: nextPanel, depth: current.depth + 1 });\n }\n }\n\n return false;\n }\n\n /**\n * Find shortest path between two panels (ignoring conditions)\n * @param graph - Navigation graph\n * @param fromPanelId - Start panel ID\n * @param toPanelId - Target panel ID\n * @returns Array of panel IDs in path, or null if no path exists\n */\n findPath(graph: Graph, fromPanelId: string, toPanelId: string): string[] | null {\n if (fromPanelId === toPanelId) {\n return [fromPanelId];\n }\n\n const visited = new Set<string>();\n const queue: { panelId: string; path: string[] }[] = [\n { panelId: fromPanelId, path: [fromPanelId] },\n ];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current.panelId)) {\n continue;\n }\n\n visited.add(current.panelId);\n\n const nextPanels = this.getPossibleNextPanels(graph, current.panelId);\n\n for (const nextPanel of nextPanels) {\n if (nextPanel === toPanelId) {\n return [...current.path, nextPanel];\n }\n\n queue.push({\n panelId: nextPanel,\n path: [...current.path, nextPanel],\n });\n }\n }\n\n return null;\n }\n\n /**\n * Detect cycles in the graph\n * @param graph - Navigation graph\n * @returns True if graph contains cycles\n */\n hasCycles(graph: Graph): boolean {\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n const dfs = (panelId: string): boolean => {\n visited.add(panelId);\n recursionStack.add(panelId);\n\n const nextPanels = this.getPossibleNextPanels(graph, panelId);\n\n for (const nextPanel of nextPanels) {\n if (!visited.has(nextPanel)) {\n if (dfs(nextPanel)) {\n return true;\n }\n } else if (recursionStack.has(nextPanel)) {\n // Found a cycle\n return true;\n }\n }\n\n recursionStack.delete(panelId);\n return false;\n };\n\n // Check from entry points\n const entries = Array.isArray(graph.entry) ? graph.entry : [graph.entry];\n\n for (const entry of entries) {\n if (!visited.has(entry)) {\n if (dfs(entry)) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Get all reachable panels from entry\n * @param graph - Navigation graph\n * @returns Array of reachable panel IDs\n */\n getReachablePanels(graph: Graph): string[] {\n const reachable = new Set<string>();\n const entries = Array.isArray(graph.entry) ? graph.entry : [graph.entry];\n\n const dfs = (panelId: string): void => {\n if (reachable.has(panelId)) {\n return;\n }\n\n reachable.add(panelId);\n\n const nextPanels = this.getPossibleNextPanels(graph, panelId);\n nextPanels.forEach((next) => dfs(next));\n };\n\n entries.forEach((entry) => dfs(entry));\n\n return Array.from(reachable);\n }\n\n /**\n * Check if user has entitlement to access a panel\n * @param workId - Work ID\n * @param chapterId - Chapter ID\n * @param panelId - Panel ID\n * @returns Promise resolving to true if user has access\n */\n async checkPanelEntitlement(\n workId: string,\n chapterId: string,\n panelId: string\n ): Promise<boolean> {\n return await this.entitlementService.hasAccessToPanel(workId, chapterId, panelId);\n }\n\n /**\n * Check if user has entitlement to access a chapter\n * @param workId - Work ID\n * @param chapterId - Chapter ID\n * @returns Promise resolving to true if user has access\n */\n async checkChapterEntitlement(workId: string, chapterId: string): Promise<boolean> {\n return await this.entitlementService.hasAccessToChapter(workId, chapterId);\n }\n\n /**\n * Check if user has entitlement to access a work\n * @param workId - Work ID\n * @returns Promise resolving to true if user has access\n */\n async checkWorkEntitlement(workId: string): Promise<boolean> {\n return await this.entitlementService.hasAccessToWork(workId);\n }\n\n /**\n * Get entitlement service instance\n * @returns EntitlementService\n */\n getEntitlementService(): EntitlementService {\n return this.entitlementService;\n }\n}\n","/**\n * Image Cache Service\n * LRU cache for images with memory budget management\n */\n\nimport { Injectable } from '@angular/core';\n\n/**\n * Cache entry\n */\ninterface CacheEntry {\n url: string;\n bitmap: ImageBitmap | HTMLImageElement;\n size: number;\n timestamp: number;\n accessCount: number;\n}\n\n/**\n * Image Cache Service\n * Provides LRU caching for images with memory budget control\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ImageCacheService {\n /**\n * Cache storage (Map maintains insertion order)\n */\n private cache = new Map<string, CacheEntry>();\n\n /**\n * In-flight requests (for deduplication)\n */\n private inflightRequests = new Map<string, Promise<ImageBitmap | HTMLImageElement>>();\n\n /**\n * Memory budget in bytes (default: 100MB)\n */\n private readonly MEMORY_BUDGET = 100 * 1024 * 1024;\n\n /**\n * Current memory usage in bytes\n */\n private currentMemoryUsage = 0;\n\n /**\n * Support for createImageBitmap\n */\n private readonly supportsImageBitmap = typeof createImageBitmap === 'function';\n\n /**\n * Load an image from cache or network\n */\n async load(url: string): Promise<ImageBitmap | HTMLImageElement> {\n // Check cache first\n const cached = this.cache.get(url);\n if (cached) {\n // Update access statistics\n cached.timestamp = Date.now();\n cached.accessCount++;\n \n // Move to end (most recently used)\n this.cache.delete(url);\n this.cache.set(url, cached);\n \n return cached.bitmap;\n }\n\n // Check if request is already in flight\n const inflight = this.inflightRequests.get(url);\n if (inflight) {\n return inflight;\n }\n\n // Start new request\n const request = this.fetchImage(url);\n this.inflightRequests.set(url, request);\n\n try {\n const bitmap = await request;\n \n // Calculate size\n const size = this.estimateImageSize(bitmap);\n \n // Ensure we have space\n this.ensureSpace(size);\n \n // Add to cache\n const entry: CacheEntry = {\n url,\n bitmap,\n size,\n timestamp: Date.now(),\n accessCount: 1,\n };\n \n this.cache.set(url, entry);\n this.currentMemoryUsage += size;\n \n return bitmap;\n } finally {\n // Remove from in-flight\n this.inflightRequests.delete(url);\n }\n }\n\n /**\n * Fetch image from network\n */\n private async fetchImage(url: string): Promise<ImageBitmap | HTMLImageElement> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch image: ${response.statusText}`);\n }\n\n const blob = await response.blob();\n\n // Use createImageBitmap if supported\n if (this.supportsImageBitmap) {\n try {\n return await createImageBitmap(blob);\n } catch (error) {\n console.warn('createImageBitmap failed, falling back to Image:', error);\n }\n }\n\n // Fallback to HTMLImageElement\n return this.createImage(blob);\n }\n\n /**\n * Create HTMLImageElement from blob\n */\n private createImage(blob: Blob): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n const url = URL.createObjectURL(blob);\n\n img.onload = () => {\n URL.revokeObjectURL(url);\n resolve(img);\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error('Failed to load image'));\n };\n\n img.src = url;\n });\n }\n\n /**\n * Estimate image size in bytes\n */\n private estimateImageSize(bitmap: ImageBitmap | HTMLImageElement): number {\n const width = bitmap.width;\n const height = bitmap.height;\n \n // Estimate: width × height × 4 bytes per pixel (RGBA)\n return width * height * 4;\n }\n\n /**\n * Ensure we have enough space in cache\n */\n private ensureSpace(requiredSize: number): void {\n // If single image exceeds budget, clear entire cache\n if (requiredSize > this.MEMORY_BUDGET) {\n console.warn(`Image size (${requiredSize} bytes) exceeds memory budget (${this.MEMORY_BUDGET} bytes)`);\n this.clear();\n return;\n }\n\n // Evict entries until we have enough space\n while (this.currentMemoryUsage + requiredSize > this.MEMORY_BUDGET) {\n this.evictLRU();\n }\n }\n\n /**\n * Evict least recently used entry\n */\n private evictLRU(): void {\n // Get first entry (oldest/least recently used)\n const firstKey = this.cache.keys().next().value;\n if (!firstKey) return;\n\n const entry = this.cache.get(firstKey);\n if (!entry) return;\n\n // Close ImageBitmap if applicable\n if ('close' in entry.bitmap && typeof entry.bitmap.close === 'function') {\n entry.bitmap.close();\n }\n\n // Remove from cache\n this.cache.delete(firstKey);\n this.currentMemoryUsage -= entry.size;\n }\n\n /**\n * Preload an image\n */\n async preload(url: string): Promise<void> {\n try {\n await this.load(url);\n } catch (error) {\n console.error(`Failed to preload image: ${url}`, error);\n }\n }\n\n /**\n * Preload multiple images\n */\n async preloadBatch(urls: string[]): Promise<void> {\n await Promise.all(urls.map((url) => this.preload(url)));\n }\n\n /**\n * Check if URL is cached\n */\n has(url: string): boolean {\n return this.cache.has(url);\n }\n\n /**\n * Remove specific URL from cache\n */\n remove(url: string): void {\n const entry = this.cache.get(url);\n if (!entry) return;\n\n // Close ImageBitmap if applicable\n if ('close' in entry.bitmap && typeof entry.bitmap.close === 'function') {\n entry.bitmap.close();\n }\n\n this.cache.delete(url);\n this.currentMemoryUsage -= entry.size;\n }\n\n /**\n * Clear entire cache\n */\n clear(): void {\n // Close all ImageBitmaps\n this.cache.forEach((entry) => {\n if ('close' in entry.bitmap && typeof entry.bitmap.close === 'function') {\n entry.bitmap.close();\n }\n });\n\n this.cache.clear();\n this.currentMemoryUsage = 0;\n }\n\n /**\n * Get cache statistics\n */\n getStats() {\n return {\n entries: this.cache.size,\n memoryUsage: this.currentMemoryUsage,\n memoryBudget: this.MEMORY_BUDGET,\n utilizationPercent: (this.currentMemoryUsage / this.MEMORY_BUDGET) * 100,\n inflightRequests: this.inflightRequests.size,\n };\n }\n\n /**\n * Get all cached URLs\n */\n getCachedUrls(): string[] {\n return Array.from(this.cache.keys());\n }\n\n /**\n * Set memory budget (in bytes)\n */\n setMemoryBudget(bytes: number): void {\n const oldBudget = this.MEMORY_BUDGET;\n (this as unknown as { MEMORY_BUDGET: number }).MEMORY_BUDGET = bytes;\n\n // If new budget is smaller, evict entries\n if (bytes < oldBudget) {\n while (this.currentMemoryUsage > bytes) {\n this.evictLRU();\n }\n }\n }\n}\n","/**\r\n * Audio Engine Service\r\n * Manages audio playback with Web Audio API\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport { distinctUntilChanged } from 'rxjs/operators';\r\nimport type { SequenceAudioTrack } from '../types';\r\n\r\n/**\r\n * Audio role/bus type\r\n */\r\nexport type AudioRole = 'ambient' | 'music' | 'voiceover' | 'sfx';\r\n\r\n/**\r\n * Audio track definition\r\n */\r\nexport interface AudioTrack {\r\n id: string;\r\n url: string;\r\n role: AudioRole;\r\n loop?: boolean;\r\n /** Per-track gain (0-2; 1 = as authored). */\r\n volume?: number;\r\n fadeIn?: number; // milliseconds\r\n fadeOut?: number; // milliseconds\r\n}\r\n\r\n/**\r\n * Playback state\r\n */\r\nexport interface PlaybackState {\r\n id: string;\r\n role: AudioRole;\r\n playing: boolean;\r\n currentTime: number;\r\n duration: number;\r\n volume: number;\r\n}\r\n\r\n/**\r\n * Per-track bookkeeping: the element, its source node, its own gain node\r\n * (between source and bus, so fades and per-track gain never touch the bus)\r\n * and the bus it plays on.\r\n */\r\ninterface ActiveTrack {\r\n audio: HTMLAudioElement;\r\n source: MediaElementAudioSourceNode;\r\n gain: GainNode;\r\n role: AudioRole;\r\n volume: number;\r\n onEnded?: () => void;\r\n}\r\n\r\nconst ROLES: AudioRole[] = ['ambient', 'music', 'voiceover', 'sfx'];\r\n\r\n/**\r\n * Audio Engine Service\r\n * Provides Web Audio API-based audio playback with multiple buses.\r\n *\r\n * Signal chain: element -> track gain -> role gain -> master gain -> output.\r\n * Volumes and mutes are independent: a bus keeps its volume while muted and\r\n * comes back at that volume when unmuted (the toolbar's Audio/SFX toggles\r\n * drive the mute flags; the settings' volumes drive the gains).\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AudioEngineService {\r\n /**\r\n * Audio context\r\n */\r\n private audioContext?: AudioContext;\r\n\r\n /**\r\n * Master gain node\r\n */\r\n private masterGain?: GainNode;\r\n\r\n /**\r\n * Gain nodes for each role\r\n */\r\n private roleGains = new Map<AudioRole, GainNode>();\r\n\r\n /**\r\n * Active tracks by id\r\n */\r\n private tracks = new Map<string, ActiveTrack>();\r\n\r\n /**\r\n * Master volume (0-1)\r\n */\r\n private _masterVolume = 1.0;\r\n\r\n /**\r\n * Role volumes (0-1)\r\n */\r\n private roleVolumes = new Map<AudioRole, number>([\r\n ['ambient', 1.0],\r\n ['music', 1.0],\r\n ['voiceover', 1.0],\r\n ['sfx', 1.0],\r\n ]);\r\n\r\n /** Master mute flag (independent of the master volume). */\r\n private readonly masterMutedSubject = new BehaviorSubject<boolean>(false);\r\n\r\n /** Muted buses (independent of their volumes). */\r\n private mutedRoles = new Set<AudioRole>();\r\n\r\n /**\r\n * Master mute state. Video layers follow this too, so the toolbar's Audio\r\n * toggle silences the whole player, not only the WebAudio buses.\r\n */\r\n readonly masterMuted$: Observable<boolean> = this.masterMutedSubject\r\n .asObservable()\r\n .pipe(distinctUntilChanged());\r\n\r\n /**\r\n * Autoplay allowed flag\r\n */\r\n private autoplayAllowed = false;\r\n\r\n /**\r\n * Initialize audio context and gain nodes\r\n */\r\n async initialize(): Promise<void> {\r\n if (this.audioContext) {\r\n return; // Already initialized\r\n }\r\n\r\n try {\r\n // Create audio context\r\n const AudioContextCtor =\r\n window.AudioContext || (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\r\n this.audioContext = new AudioContextCtor!();\r\n\r\n // Create master gain\r\n this.masterGain = this.audioContext.createGain();\r\n this.masterGain.connect(this.audioContext.destination);\r\n this.masterGain.gain.value = this.effectiveMasterGain();\r\n\r\n // Create gain nodes for each role\r\n ROLES.forEach((role) => {\r\n const gain = this.audioContext!.createGain();\r\n gain.connect(this.masterGain!);\r\n gain.gain.value = this.effectiveRoleGain(role);\r\n this.roleGains.set(role, gain);\r\n });\r\n\r\n // Test autoplay policy\r\n await this.testAutoplayPolicy();\r\n } catch (error) {\r\n console.error('Failed to initialize audio context:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Test autoplay policy\r\n */\r\n private async testAutoplayPolicy(): Promise<void> {\r\n if (!this.audioContext) return;\r\n\r\n try {\r\n // Try to resume context\r\n if (this.audioContext.state === 'suspended') {\r\n await this.audioContext.resume();\r\n }\r\n this.autoplayAllowed = this.audioContext.state === 'running';\r\n } catch (error) {\r\n console.warn('Autoplay not allowed:', error);\r\n this.autoplayAllowed = false;\r\n }\r\n }\r\n\r\n /**\r\n * Resume audio context (call on user interaction)\r\n */\r\n async resumeContext(): Promise<void> {\r\n if (!this.audioContext) {\r\n await this.initialize();\r\n return;\r\n }\r\n\r\n if (this.audioContext.state === 'suspended') {\r\n try {\r\n await this.audioContext.resume();\r\n this.autoplayAllowed = true;\r\n } catch (error) {\r\n console.error('Failed to resume audio context:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Play audio track\r\n */\r\n async play(track: AudioTrack): Promise<void> {\r\n await this.startTrack(track, 0);\r\n }\r\n\r\n /**\r\n * Stop audio track\r\n */\r\n async stop(id: string, fadeOutMs?: number): Promise<void> {\r\n const active = this.tracks.get(id);\r\n if (!active) return;\r\n\r\n // Apply fade out if specified\r\n if (fadeOutMs && fadeOutMs > 0) {\r\n await this.fadeOut(id, fadeOutMs);\r\n // A newer track may have replaced this id while fading.\r\n if (this.tracks.get(id) !== active) {\r\n return;\r\n }\r\n }\r\n\r\n // Stop playback\r\n active.audio.pause();\r\n active.audio.currentTime = 0;\r\n\r\n // Cleanup\r\n this.cleanup(id);\r\n }\r\n\r\n /**\r\n * Pause audio track\r\n */\r\n pause(id: string): void {\r\n const audio = this.tracks.get(id)?.audio;\r\n if (audio && !audio.paused) {\r\n audio.pause();\r\n }\r\n }\r\n\r\n /**\r\n * Resume audio track\r\n */\r\n async resume(id: string): Promise<void> {\r\n const audio = this.tracks.get(id)?.audio;\r\n if (audio && audio.paused) {\r\n await audio.play();\r\n }\r\n }\r\n\r\n /**\r\n * Fade in audio\r\n */\r\n private fadeIn(id: string, durationMs: number, targetVolume: number): Promise<void> {\r\n return new Promise((resolve) => {\r\n const gainNode = this.getTrackGainNode(id);\r\n if (!gainNode || !this.audioContext) {\r\n resolve();\r\n return;\r\n }\r\n\r\n const currentTime = this.audioContext.currentTime;\r\n gainNode.gain.setValueAtTime(0, currentTime);\r\n gainNode.gain.linearRampToValueAtTime(targetVolume, currentTime + durationMs / 1000);\r\n\r\n setTimeout(resolve, durationMs);\r\n });\r\n }\r\n\r\n /**\r\n * Fade out audio\r\n */\r\n private fadeOut(id: string, durationMs: number): Promise<void> {\r\n return new Promise((resolve) => {\r\n const gainNode = this.getTrackGainNode(id);\r\n if (!gainNode || !this.audioContext) {\r\n resolve();\r\n return;\r\n }\r\n\r\n const currentTime = this.audioContext.currentTime;\r\n const currentGain = gainNode.gain.value;\r\n gainNode.gain.setValueAtTime(currentGain, currentTime);\r\n gainNode.gain.linearRampToValueAtTime(0, currentTime + durationMs / 1000);\r\n\r\n setTimeout(resolve, durationMs);\r\n });\r\n }\r\n\r\n /**\r\n * Get the per-track gain node (sits between the element and its bus).\r\n */\r\n private getTrackGainNode(id: string): GainNode | undefined {\r\n return this.tracks.get(id)?.gain;\r\n }\r\n\r\n /**\r\n * Set master volume\r\n */\r\n setMasterVolume(volume: number): void {\r\n this._masterVolume = Math.max(0, Math.min(1, volume));\r\n this.applyMasterGain();\r\n }\r\n\r\n /**\r\n * Get master volume\r\n */\r\n getMasterVolume(): number {\r\n return this._masterVolume;\r\n }\r\n\r\n /**\r\n * Mute/unmute everything without touching the master volume.\r\n */\r\n setMasterMuted(muted: boolean): void {\r\n if (this.masterMutedSubject.value === muted) {\r\n return;\r\n }\r\n this.masterMutedSubject.next(muted);\r\n this.applyMasterGain();\r\n }\r\n\r\n /**\r\n * Whether the master output is muted.\r\n */\r\n isMasterMuted(): boolean {\r\n return this.masterMutedSubject.value;\r\n }\r\n\r\n /**\r\n * Set role volume\r\n */\r\n setRoleVolume(role: AudioRole, volume: number): void {\r\n const normalizedVolume = Math.max(0, Math.min(1, volume));\r\n this.roleVolumes.set(role, normalizedVolume);\r\n this.applyRoleGain(role);\r\n }\r\n\r\n /**\r\n * Get role volume\r\n */\r\n getRoleVolume(role: AudioRole): number {\r\n return this.roleVolumes.get(role) ?? 1.0;\r\n }\r\n\r\n /**\r\n * Mute/unmute one bus without touching its volume.\r\n */\r\n setRoleMuted(role: AudioRole, muted: boolean): void {\r\n if (muted) {\r\n this.mutedRoles.add(role);\r\n } else {\r\n this.mutedRoles.delete(role);\r\n }\r\n this.applyRoleGain(role);\r\n }\r\n\r\n /**\r\n * Whether a bus is muted.\r\n */\r\n isRoleMuted(role: AudioRole): boolean {\r\n return this.mutedRoles.has(role);\r\n }\r\n\r\n /**\r\n * Change the per-track gain (0-2) of a playing track.\r\n */\r\n setTrackVolume(id: string, volume: number): void {\r\n const active = this.tracks.get(id);\r\n if (!active) return;\r\n active.volume = this.clampTrackVolume(volume);\r\n if (this.audioContext) {\r\n active.gain.gain.setValueAtTime(active.volume, this.audioContext.currentTime);\r\n } else {\r\n active.gain.gain.value = active.volume;\r\n }\r\n }\r\n\r\n /**\r\n * Get playback state\r\n */\r\n getPlaybackState(id: string): PlaybackState | undefined {\r\n const active = this.tracks.get(id);\r\n if (!active) return undefined;\r\n\r\n return {\r\n id,\r\n role: active.role,\r\n playing: !active.audio.paused,\r\n currentTime: active.audio.currentTime,\r\n duration: active.audio.duration,\r\n volume: active.volume,\r\n };\r\n }\r\n\r\n /**\r\n * Get all active tracks\r\n */\r\n getActiveTracks(): string[] {\r\n return Array.from(this.tracks.keys());\r\n }\r\n\r\n /**\r\n * Whether a track with this id is currently registered (playing or paused).\r\n */\r\n isActive(id: string): boolean {\r\n return this.tracks.has(id);\r\n }\r\n\r\n /**\r\n * Stop all audio\r\n */\r\n async stopAll(fadeOutMs?: number): Promise<void> {\r\n const ids = this.getActiveTracks();\r\n await Promise.all(ids.map((id) => this.stop(id, fadeOutMs)));\r\n }\r\n\r\n /**\r\n * Cleanup track resources\r\n */\r\n private cleanup(id: string): void {\r\n const active = this.tracks.get(id);\r\n if (!active) return;\r\n this.tracks.delete(id);\r\n\r\n if (active.onEnded && typeof active.audio.removeEventListener === 'function') {\r\n active.audio.removeEventListener('ended', active.onEnded);\r\n }\r\n active.source.disconnect();\r\n active.gain.disconnect();\r\n active.audio.src = '';\r\n active.audio.load();\r\n }\r\n\r\n /**\r\n * Check if autoplay is allowed\r\n */\r\n isAutoplayAllowed(): boolean {\r\n return this.autoplayAllowed;\r\n }\r\n\r\n /**\r\n * Play sequence audio tracks for a chapter based on playback time\r\n * @param tracks Array of sequence audio tracks from chapter\r\n * @param currentTimeMs Current playback time in milliseconds\r\n * @param assetBaseUrl Base URL for resolving asset URLs\r\n */\r\n async playSequenceTracks(\r\n tracks: SequenceAudioTrack[],\r\n currentTimeMs: number,\r\n assetBaseUrl = ''\r\n ): Promise<void> {\r\n // Ensure initialized\r\n if (!this.audioContext) {\r\n await this.initialize();\r\n }\r\n\r\n // Resume if needed\r\n if (this.audioContext!.state === 'suspended') {\r\n await this.resumeContext();\r\n }\r\n\r\n // Play tracks that should be playing at current time\r\n for (const track of tracks) {\r\n // Skip muted tracks\r\n if (track.muted) continue;\r\n\r\n const trackStartMs = track.startTime;\r\n const trackEndMs = trackStartMs + track.duration;\r\n\r\n // Check if track should be playing at current time\r\n if (currentTimeMs >= trackStartMs && currentTimeMs < trackEndMs) {\r\n // Calculate offset within the track\r\n const offsetMs = currentTimeMs - trackStartMs;\r\n const offsetSeconds = offsetMs / 1000;\r\n\r\n // Construct asset URL\r\n const audioUrl = assetBaseUrl + track.assetId;\r\n\r\n // Create audio track definition\r\n const audioTrack: AudioTrack = {\r\n id: track.id,\r\n url: audioUrl,\r\n role: track.role,\r\n loop: track.loop,\r\n volume: track.volume !== undefined && isFinite(track.volume)\r\n ? Math.max(0, Math.min(2, track.volume))\r\n : 1.0,\r\n fadeIn: track.fadeIn,\r\n fadeOut: track.fadeOut,\r\n };\r\n\r\n try {\r\n // Play track from offset\r\n await this.startTrack(audioTrack, offsetSeconds);\r\n } catch (error) {\r\n console.error(`Failed to play sequence track ${track.id}:`, error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Create the element + node chain for a track and start it (optionally\r\n * from an offset). Replaces any active track with the same id.\r\n */\r\n private async startTrack(track: AudioTrack, offsetSeconds: number): Promise<void> {\r\n // Ensure initialized\r\n if (!this.audioContext) {\r\n await this.initialize();\r\n }\r\n\r\n // Resume if needed\r\n if (this.audioContext!.state === 'suspended') {\r\n await this.resumeContext();\r\n }\r\n\r\n // Stop existing track with same ID\r\n if (this.tracks.has(track.id)) {\r\n await this.stop(track.id);\r\n }\r\n\r\n const bus = this.roleGains.get(track.role);\r\n if (!bus) {\r\n throw new Error(`Invalid role: ${track.role}`);\r\n }\r\n\r\n // Create audio element\r\n const audio = new Audio(track.url);\r\n audio.loop = track.loop || false;\r\n if (offsetSeconds > 0) {\r\n audio.currentTime = offsetSeconds;\r\n }\r\n\r\n // Element -> track gain -> bus\r\n const source = this.audioContext!.createMediaElementSource(audio);\r\n const gain = this.audioContext!.createGain();\r\n const volume = this.clampTrackVolume(track.volume);\r\n gain.gain.value = volume;\r\n source.connect(gain);\r\n gain.connect(bus);\r\n\r\n const active: ActiveTrack = { audio, source, gain, role: track.role, volume };\r\n this.tracks.set(track.id, active);\r\n\r\n // One-shot tracks release their resources when they finish.\r\n if (!audio.loop && typeof audio.addEventListener === 'function') {\r\n active.onEnded = () => {\r\n if (this.tracks.get(track.id) === active) {\r\n this.cleanup(track.id);\r\n }\r\n };\r\n audio.addEventListener('ended', active.onEnded);\r\n }\r\n\r\n try {\r\n // Apply fade in (shortened when starting mid-fade)\r\n if (track.fadeIn && track.fadeIn > 0 && offsetSeconds * 1000 < track.fadeIn) {\r\n await this.fadeIn(track.id, track.fadeIn - offsetSeconds * 1000, volume);\r\n }\r\n\r\n // Play audio\r\n await audio.play();\r\n } catch (error) {\r\n console.error(`Failed to play audio ${track.id}:`, error);\r\n // Cleanup on error\r\n this.cleanup(track.id);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Stop sequence audio tracks\r\n * @param trackIds Array of track IDs to stop (optional, stops all if not provided)\r\n */\r\n async stopSequenceTracks(trackIds?: string[]): Promise<void> {\r\n if (trackIds) {\r\n await Promise.all(trackIds.map((id) => this.stop(id)));\r\n } else {\r\n await this.stopAll();\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup on destroy\r\n */\r\n destroy(): void {\r\n // Stop all audio\r\n this.stopAll();\r\n\r\n // Close audio context\r\n if (this.audioContext && this.audioContext.state !== 'closed') {\r\n this.audioContext.close();\r\n }\r\n\r\n // Clear references\r\n this.roleGains.clear();\r\n this.tracks.clear();\r\n this.audioContext = undefined;\r\n this.masterGain = undefined;\r\n this.autoplayAllowed = false;\r\n }\r\n\r\n private clampTrackVolume(volume: number | undefined): number {\r\n if (volume === undefined || !isFinite(volume)) {\r\n return 1.0;\r\n }\r\n return Math.max(0, Math.min(2, volume));\r\n }\r\n\r\n private effectiveMasterGain(): number {\r\n return this.masterMutedSubject.value ? 0 : this._masterVolume;\r\n }\r\n\r\n private effectiveRoleGain(role: AudioRole): number {\r\n return this.mutedRoles.has(role) ? 0 : this.getRoleVolume(role);\r\n }\r\n\r\n private applyMasterGain(): void {\r\n if (this.masterGain && this.audioContext) {\r\n this.masterGain.gain.setValueAtTime(this.effectiveMasterGain(), this.audioContext.currentTime);\r\n }\r\n }\r\n\r\n private applyRoleGain(role: AudioRole): void {\r\n const gainNode = this.roleGains.get(role);\r\n if (gainNode && this.audioContext) {\r\n gainNode.gain.setValueAtTime(this.effectiveRoleGain(role), this.audioContext.currentTime);\r\n }\r\n }\r\n}\r\n","/**\r\n * User Gesture Service\r\n * Tracks whether the user has produced a \"gesture\" (click / tap / keydown)\r\n * during this session. Browsers block autoplay with audio before such a\r\n * gesture, so video playback started programmatically (e.g. on-view) must\r\n * begin muted until this flag is set.\r\n *\r\n * Hover does NOT count as a gesture (per autoplay policy).\r\n */\r\n\r\nimport { Injectable, OnDestroy, NgZone, inject } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\n/** Events that count as a user gesture for autoplay-with-audio purposes. */\r\nconst GESTURE_EVENTS: readonly (keyof DocumentEventMap)[] = [\r\n 'pointerdown',\r\n 'mousedown',\r\n 'touchstart',\r\n 'keydown',\r\n 'click',\r\n];\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class UserGestureService implements OnDestroy {\r\n private readonly zone = inject(NgZone);\r\n\r\n private readonly interacted$ = new BehaviorSubject<boolean>(false);\r\n\r\n /** Emits `false` initially, then `true` once (and stays true). */\r\n readonly userHasInteracted$: Observable<boolean> = this.interacted$.asObservable();\r\n\r\n private readonly boundHandler = (): void => this.markInteracted();\r\n\r\n private listenersAttached = false;\r\n\r\n constructor() {\r\n this.attachListeners();\r\n }\r\n\r\n /** Whether a user gesture has been registered this session. */\r\n hasInteracted(): boolean {\r\n return this.interacted$.value;\r\n }\r\n\r\n /**\r\n * Explicitly mark that a user gesture occurred (e.g. clicking an unmute\r\n * affordance). Idempotent; detaches the global listeners once set.\r\n */\r\n markInteracted(): void {\r\n if (this.interacted$.value) {\r\n return;\r\n }\r\n this.interacted$.next(true);\r\n this.detachListeners();\r\n }\r\n\r\n private attachListeners(): void {\r\n if (this.listenersAttached || typeof document === 'undefined') {\r\n return;\r\n }\r\n this.listenersAttached = true;\r\n // Run outside Angular to avoid change-detection churn on global input.\r\n this.zone.runOutsideAngular(() => {\r\n for (const type of GESTURE_EVENTS) {\r\n document.addEventListener(type, this.boundHandler, {\r\n capture: true,\r\n passive: true,\r\n });\r\n }\r\n });\r\n }\r\n\r\n private detachListeners(): void {\r\n if (!this.listenersAttached || typeof document === 'undefined') {\r\n return;\r\n }\r\n this.listenersAttached = false;\r\n for (const type of GESTURE_EVENTS) {\r\n document.removeEventListener(type, this.boundHandler, { capture: true });\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.detachListeners();\r\n this.interacted$.complete();\r\n }\r\n}\r\n","/**\r\n * Panel Audio Service\r\n *\r\n * Drives the AudioEngineService from the manifest: every panel's `audio[]`\r\n * tracks (schema `AudioTrack`) and `kind: \"audio\"` layers start when the\r\n * panel becomes current and stop when the reader leaves it. A looping track\r\n * that the next panel references too keeps playing (ambience continuity);\r\n * one-shot tracks restart on every panel enter.\r\n *\r\n * Browser autoplay policy: a track refused before the first user gesture is\r\n * remembered and retried (and the AudioContext resumed) on that gesture.\r\n */\r\n\r\nimport { Injectable, OnDestroy, inject } from '@angular/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { AudioEngineService } from './audio-engine.service';\r\nimport type { AudioRole } from './audio-engine.service';\r\nimport { ManifestService } from './manifest.service';\r\nimport { UserGestureService } from './user-gesture.service';\r\nimport { evaluateJsonLogic } from '../utils/json-logic-utils';\r\nimport { resolveAssetUrl, guessMimeType } from '../utils/asset-utils';\r\nimport type {\r\n AssetCatalogItemAudio,\r\n AudioVariant,\r\n Panel,\r\n PanelAudioRole,\r\n PanelAudioTrack,\r\n VariableContext,\r\n} from '../types';\r\n\r\n/**\r\n * A manifest track resolved to something the engine can play.\r\n */\r\nexport interface ResolvedPanelAudio {\r\n /** Engine track id (asset id, suffixed when a panel references it twice). */\r\n id: string;\r\n url: string;\r\n role: AudioRole;\r\n loop: boolean;\r\n /** Per-track gain 0-2. */\r\n gain: number;\r\n /** Delay after panel enter, ms. */\r\n startAtMs: number;\r\n}\r\n\r\n/** Fade applied when a looping track is stopped because the panel changed. */\r\nexport const PANEL_AUDIO_LEAVE_FADE_MS = 250;\r\n\r\n/**\r\n * Map a manifest role onto an engine bus. `ui` sounds share the SFX bus so\r\n * the SFX toggle covers them; `none` (the schema default) goes to the music\r\n * bus, which only the master Audio toggle silences.\r\n */\r\nexport function busForRole(role: PanelAudioRole | undefined): AudioRole {\r\n switch (role) {\r\n case 'ambient':\r\n case 'music':\r\n case 'voiceover':\r\n case 'sfx':\r\n return role;\r\n case 'ui':\r\n return 'sfx';\r\n default:\r\n return 'music';\r\n }\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class PanelAudioService implements OnDestroy {\r\n private readonly engine = inject(AudioEngineService);\r\n private readonly manifestService = inject(ManifestService);\r\n private readonly gesture = inject(UserGestureService);\r\n\r\n /** Tracks wanted by the current panel, by engine id. */\r\n private desired = new Map<string, ResolvedPanelAudio>();\r\n\r\n /** Pending `startAtMs` timers. */\r\n private timers = new Map<string, ReturnType<typeof setTimeout>>();\r\n\r\n /** Tracks refused by the autoplay policy, retried on the first gesture. */\r\n private blocked = new Set<string>();\r\n\r\n /** Assets already warned about (missing / not audio), to keep the console quiet. */\r\n private warned = new Set<string>();\r\n\r\n private currentPanelId?: string;\r\n\r\n private readonly gestureSub: Subscription;\r\n\r\n constructor() {\r\n this.gestureSub = this.gesture.userHasInteracted$.subscribe((interacted) => {\r\n if (interacted) {\r\n this.onUserGesture();\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.gestureSub.unsubscribe();\r\n this.stopAll();\r\n }\r\n\r\n /**\r\n * Make the engine's playing set match `panel`. Call whenever the current\r\n * panel (or the variable context its `visibleIf` conditions depend on)\r\n * changes. Idempotent for an unchanged panel.\r\n */\r\n syncPanel(\r\n panelId: string | undefined,\r\n panel: Panel | undefined,\r\n context: VariableContext | null | undefined\r\n ): void {\r\n const panelChanged = panelId !== this.currentPanelId;\r\n this.currentPanelId = panelId;\r\n\r\n const next = this.resolve(panel, context);\r\n\r\n // Tracks the new panel does not want any more.\r\n for (const [id, prev] of this.desired) {\r\n if (!next.has(id)) {\r\n this.release(id, prev.loop ? PANEL_AUDIO_LEAVE_FADE_MS : 0);\r\n }\r\n }\r\n\r\n for (const [id, track] of next) {\r\n const prev = this.desired.get(id);\r\n if (prev) {\r\n const pending = this.timers.has(id) || this.blocked.has(id);\r\n const active = this.engine.isActive(id);\r\n // Same panel re-evaluated (variables changed): never restart, only\r\n // follow a gain change. Across panels a looping track continues.\r\n if (!panelChanged || (track.loop && (active || pending))) {\r\n if (active && prev.gain !== track.gain) {\r\n this.engine.setTrackVolume(id, track.gain);\r\n }\r\n continue;\r\n }\r\n }\r\n this.schedule(track);\r\n }\r\n\r\n this.desired = next;\r\n }\r\n\r\n /**\r\n * Stop everything this service started (shell teardown).\r\n */\r\n stopAll(): void {\r\n for (const id of this.desired.keys()) {\r\n this.release(id, 0);\r\n }\r\n this.desired.clear();\r\n this.currentPanelId = undefined;\r\n }\r\n\r\n /**\r\n * Ids of the tracks the current panel wants (started, pending or blocked).\r\n */\r\n getDesiredTrackIds(): string[] {\r\n return Array.from(this.desired.keys());\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n\r\n private schedule(track: ResolvedPanelAudio): void {\r\n this.release(track.id, 0);\r\n if (track.startAtMs > 0) {\r\n const timer = setTimeout(() => {\r\n this.timers.delete(track.id);\r\n this.start(track);\r\n }, track.startAtMs);\r\n this.timers.set(track.id, timer);\r\n return;\r\n }\r\n this.start(track);\r\n }\r\n\r\n private start(track: ResolvedPanelAudio): void {\r\n this.blocked.delete(track.id);\r\n this.engine\r\n .play({\r\n id: track.id,\r\n url: track.url,\r\n role: track.role,\r\n loop: track.loop,\r\n volume: track.gain,\r\n })\r\n .catch((error: unknown) => {\r\n if (this.isAutoplayRefusal(error) && !this.gesture.hasInteracted()) {\r\n this.blocked.add(track.id);\r\n }\r\n });\r\n }\r\n\r\n private release(id: string, fadeMs: number): void {\r\n const timer = this.timers.get(id);\r\n if (timer !== undefined) {\r\n clearTimeout(timer);\r\n this.timers.delete(id);\r\n }\r\n this.blocked.delete(id);\r\n if (this.engine.isActive(id)) {\r\n void this.engine.stop(id, fadeMs);\r\n }\r\n }\r\n\r\n /**\r\n * First user gesture: resume a suspended context (tracks that started\r\n * silently become audible) and retry the refused ones.\r\n */\r\n private onUserGesture(): void {\r\n void this.engine.resumeContext().catch(() => undefined);\r\n for (const id of Array.from(this.blocked)) {\r\n const track = this.desired.get(id);\r\n this.blocked.delete(id);\r\n if (track) {\r\n this.start(track);\r\n }\r\n }\r\n }\r\n\r\n private isAutoplayRefusal(error: unknown): boolean {\r\n const name = (error as { name?: string } | null)?.name;\r\n return name === 'NotAllowedError' || name === 'AbortError';\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Manifest resolution\r\n // ---------------------------------------------------------------------------\r\n\r\n private resolve(\r\n panel: Panel | undefined,\r\n context: VariableContext | null | undefined\r\n ): Map<string, ResolvedPanelAudio> {\r\n const result = new Map<string, ResolvedPanelAudio>();\r\n if (!panel) {\r\n return result;\r\n }\r\n\r\n const entries: PanelAudioTrack[] = [...(panel.audio ?? [])];\r\n for (const layer of panel.layers ?? []) {\r\n if (layer.kind !== 'audio' || !layer.assetId) {\r\n continue;\r\n }\r\n const audioLayer = layer as unknown as {\r\n assetId: string;\r\n loop?: boolean;\r\n gain?: number;\r\n volume?: number;\r\n startAtMs?: number;\r\n visibleIf?: PanelAudioTrack['visibleIf'];\r\n };\r\n entries.push({\r\n assetId: audioLayer.assetId,\r\n loop: audioLayer.loop,\r\n gain: audioLayer.gain ?? audioLayer.volume,\r\n startAtMs: audioLayer.startAtMs,\r\n visibleIf: audioLayer.visibleIf ?? layer.visibleIf,\r\n });\r\n }\r\n\r\n for (const entry of entries) {\r\n if (!entry?.assetId) {\r\n continue;\r\n }\r\n if (\r\n entry.visibleIf !== undefined &&\r\n entry.visibleIf !== null &&\r\n !evaluateJsonLogic(entry.visibleIf, context ?? {})\r\n ) {\r\n continue;\r\n }\r\n const resolved = this.resolveTrack(entry);\r\n if (!resolved) {\r\n continue;\r\n }\r\n // A panel referencing the same asset twice gets distinct engine ids;\r\n // the first occurrence keeps the bare asset id so cross-panel\r\n // continuity matches.\r\n let id = resolved.id;\r\n let n = 2;\r\n while (result.has(id)) {\r\n id = `${resolved.id}#${n++}`;\r\n }\r\n result.set(id, { ...resolved, id });\r\n }\r\n return result;\r\n }\r\n\r\n private resolveTrack(entry: PanelAudioTrack): ResolvedPanelAudio | null {\r\n const asset = this.manifestService.getAsset(entry.assetId);\r\n if (!asset || asset.category !== 'audio') {\r\n this.warnOnce(entry.assetId, asset ? 'is not an audio asset' : 'is not in the asset catalog');\r\n return null;\r\n }\r\n const audioAsset = asset as AssetCatalogItemAudio;\r\n const variant = this.pickVariant(audioAsset.variants ?? []);\r\n if (!variant) {\r\n this.warnOnce(entry.assetId, 'has no audio variants');\r\n return null;\r\n }\r\n const base = this.manifestService.getManifest()?.assets?.base;\r\n const url = resolveAssetUrl(variant.src, base, 'audio');\r\n if (!url) {\r\n return null;\r\n }\r\n return {\r\n id: entry.assetId,\r\n url,\r\n role: busForRole(entry.role ?? audioAsset.role),\r\n loop: entry.loop ?? variant.loop ?? false,\r\n gain: this.clampGain(entry.gain),\r\n startAtMs: typeof entry.startAtMs === 'number' && entry.startAtMs > 0 ? entry.startAtMs : 0,\r\n };\r\n }\r\n\r\n /**\r\n * First variant the browser reports it can play; otherwise the first one\r\n * (the element will surface the real error).\r\n */\r\n private pickVariant(variants: AudioVariant[]): AudioVariant | undefined {\r\n if (variants.length <= 1) {\r\n return variants[0];\r\n }\r\n const probe = this.createProbe();\r\n if (!probe) {\r\n return variants[0];\r\n }\r\n const playable = variants.find((variant) => {\r\n const mime = variant.mime || guessMimeType(variant.src);\r\n return mime ? probe.canPlayType(mime) !== '' : false;\r\n });\r\n return playable ?? variants[0];\r\n }\r\n\r\n private createProbe(): HTMLAudioElement | null {\r\n if (typeof document === 'undefined') {\r\n return null;\r\n }\r\n try {\r\n const element = document.createElement('audio');\r\n return typeof element.canPlayType === 'function' ? element : null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n private clampGain(gain: number | undefined): number {\r\n if (typeof gain !== 'number' || !isFinite(gain)) {\r\n return 1;\r\n }\r\n return Math.max(0, Math.min(2, gain));\r\n }\r\n\r\n private warnOnce(assetId: string, reason: string): void {\r\n if (this.warned.has(assetId)) {\r\n return;\r\n }\r\n this.warned.add(assetId);\r\n console.warn(`[PanelAudioService] audio asset \"${assetId}\" ${reason}; track skipped.`);\r\n }\r\n}\r\n","/**\r\n * Video Controller Service\r\n * Manages video playback with single active video logic\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { Subject, Observable } from 'rxjs';\r\n\r\n/**\r\n * Video state\r\n */\r\nexport type VideoState = 'idle' | 'loading' | 'playing' | 'paused' | 'buffering' | 'error';\r\n\r\n/**\r\n * Video event\r\n */\r\nexport interface VideoEvent {\r\n type: 'play' | 'pause' | 'stop' | 'ended' | 'error' | 'buffering' | 'ready';\r\n videoId: string;\r\n timestamp: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Video status\r\n */\r\nexport interface VideoStatus {\r\n videoId: string;\r\n state: VideoState;\r\n currentTime: number;\r\n duration: number;\r\n buffered: number;\r\n volume: number;\r\n muted: boolean;\r\n}\r\n\r\n/**\r\n * Video Controller Service\r\n * Ensures only one video plays at a time and manages video lifecycle\r\n */\r\n/**\r\n * Registered concurrently-playing video.\r\n */\r\ninterface RegisteredVideo {\r\n element: HTMLVideoElement;\r\n muted: boolean;\r\n /**\r\n * Invoked when the controller preempts (pauses + unregisters) this video\r\n * on behalf of a newly-started unmuted video, so the owning component can\r\n * react (cancel internal timers, update UI state, emit its pause output)\r\n * instead of finding out only indirectly via the paused element.\r\n */\r\n onPreempted?: () => void;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class VideoControllerService {\r\n /**\r\n * Currently active video element (the most recently started one — retained\r\n * for backward-compatible status/pause/seek helpers).\r\n */\r\n private activeVideo?: HTMLVideoElement;\r\n\r\n /**\r\n * Active video ID\r\n */\r\n private activeVideoId?: string;\r\n\r\n /**\r\n * Registry of currently-playing videos keyed by videoId. Used to enforce\r\n * the \"at most one unmuted video at a time\" rule while allowing any number\r\n * of muted videos to play concurrently.\r\n */\r\n private readonly registry = new Map<string, RegisteredVideo>();\r\n\r\n /**\r\n * Current state\r\n */\r\n private currentState: VideoState = 'idle';\r\n\r\n /**\r\n * Video event subject\r\n */\r\n private eventSubject = new Subject<VideoEvent>();\r\n\r\n /**\r\n * Video events observable\r\n */\r\n readonly events$: Observable<VideoEvent> = this.eventSubject.asObservable();\r\n\r\n /**\r\n * Emits the videoId whenever a video completes one full pass (once → ended;\r\n * loop / loop-from / pingpong → one cycle). Used by the player shell to\r\n * drive precise, media-event-based auto-advance for video panels in panel\r\n * view (§4.5), independent of the concurrency registry.\r\n */\r\n private readonly passCompleteSubject = new Subject<string>();\r\n readonly passComplete$: Observable<string> =\r\n this.passCompleteSubject.asObservable();\r\n\r\n /** Signal that a video completed one full pass (called by the layer). */\r\n notifyPassComplete(videoId: string): void {\r\n this.passCompleteSubject.next(videoId);\r\n }\r\n\r\n /**\r\n * Error retry count\r\n */\r\n private retryCount = 0;\r\n\r\n /**\r\n * Max retry attempts\r\n */\r\n private readonly MAX_RETRIES = 3;\r\n\r\n /**\r\n * Retry delay (ms)\r\n */\r\n private readonly RETRY_DELAY = 1000;\r\n\r\n /**\r\n * Play video.\r\n *\r\n * Enforces \"at most one unmuted video at a time\": starting an unmuted video\r\n * pauses every other currently-playing unmuted video. Muted videos play\r\n * concurrently without restriction. The most recently started video becomes\r\n * the \"active\" one for status/pause/seek helpers.\r\n *\r\n * @param videoElement - The video element to play\r\n * @param videoId - Unique id for this video\r\n * @param muted - Whether this playback is muted (default false, i.e. unmuted)\r\n * @param onPreempted - Optional callback invoked if this video is later\r\n * paused by the controller to enforce the single-unmuted rule (i.e. some\r\n * other video started unmuted). Lets the owning component react (cancel\r\n * timers, update UI, emit pause) instead of only observing a paused\r\n * element.\r\n */\r\n async play(\r\n videoElement: HTMLVideoElement,\r\n videoId: string,\r\n muted = false,\r\n onPreempted?: () => void\r\n ): Promise<void> {\r\n // Enforce the single-unmuted rule: pause other unmuted videos.\r\n if (!muted) {\r\n this.pauseOtherUnmuted(videoId);\r\n }\r\n\r\n try {\r\n // Register / update this video and set it as the active one.\r\n this.registry.set(videoId, { element: videoElement, muted, onPreempted });\r\n this.activeVideo = videoElement;\r\n this.activeVideoId = videoId;\r\n this.setState('loading');\r\n\r\n // Attach event listeners\r\n this.attachEventListeners(videoElement, videoId);\r\n\r\n // Attempt playback\r\n await videoElement.play();\r\n\r\n this.setState('playing');\r\n this.retryCount = 0;\r\n this.emitEvent('play', videoId);\r\n } catch (error) {\r\n console.error(`Failed to play video ${videoId}:`, error);\r\n this.handleError(videoId, error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Pause all currently-playing unmuted videos except the given one.\r\n */\r\n private pauseOtherUnmuted(exceptVideoId: string): void {\r\n for (const [id, entry] of this.registry) {\r\n if (id === exceptVideoId || entry.muted) {\r\n continue;\r\n }\r\n entry.element.pause();\r\n this.registry.delete(id);\r\n if (this.activeVideoId === id) {\r\n this.activeVideo = undefined;\r\n this.activeVideoId = undefined;\r\n }\r\n this.emitEvent('pause', id);\r\n entry.onPreempted?.();\r\n }\r\n }\r\n\r\n /**\r\n * Update the muted state tracked for a registered video (used when an\r\n * unmute affordance flips a previously muted video to unmuted).\r\n */\r\n notifyMutedChanged(videoId: string, muted: boolean): void {\r\n const entry = this.registry.get(videoId);\r\n if (entry) {\r\n entry.muted = muted;\r\n }\r\n if (!muted) {\r\n this.pauseOtherUnmuted(videoId);\r\n }\r\n }\r\n\r\n /**\r\n * Remove a video from the concurrency registry (e.g. when it is paused,\r\n * ended, or its component is destroyed).\r\n */\r\n unregister(videoId: string): void {\r\n this.registry.delete(videoId);\r\n if (this.activeVideoId === videoId) {\r\n this.activeVideo = undefined;\r\n this.activeVideoId = undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Pause video\r\n */\r\n pause(): void {\r\n if (!this.activeVideo || this.currentState !== 'playing') {\r\n return;\r\n }\r\n\r\n this.activeVideo.pause();\r\n this.setState('paused');\r\n \r\n if (this.activeVideoId) {\r\n this.emitEvent('pause', this.activeVideoId);\r\n }\r\n }\r\n\r\n /**\r\n * Resume video\r\n */\r\n async resume(): Promise<void> {\r\n if (!this.activeVideo || this.currentState !== 'paused') {\r\n return;\r\n }\r\n\r\n try {\r\n await this.activeVideo.play();\r\n this.setState('playing');\r\n \r\n if (this.activeVideoId) {\r\n this.emitEvent('play', this.activeVideoId);\r\n }\r\n } catch (error) {\r\n console.error('Failed to resume video:', error);\r\n if (this.activeVideoId) {\r\n this.handleError(this.activeVideoId, error as Error);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Stop video\r\n */\r\n async stop(): Promise<void> {\r\n if (!this.activeVideo) {\r\n return;\r\n }\r\n\r\n const videoId = this.activeVideoId;\r\n\r\n // Pause playback\r\n this.activeVideo.pause();\r\n\r\n // Reset time\r\n this.activeVideo.currentTime = 0;\r\n\r\n // Remove event listeners\r\n this.detachEventListeners(this.activeVideo);\r\n\r\n // Clear references\r\n if (videoId) {\r\n this.registry.delete(videoId);\r\n }\r\n this.activeVideo = undefined;\r\n this.activeVideoId = undefined;\r\n this.setState('idle');\r\n this.retryCount = 0;\r\n\r\n if (videoId) {\r\n this.emitEvent('stop', videoId);\r\n }\r\n }\r\n\r\n /**\r\n * Get current video status\r\n */\r\n getStatus(): VideoStatus | undefined {\r\n if (!this.activeVideo || !this.activeVideoId) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n videoId: this.activeVideoId,\r\n state: this.currentState,\r\n currentTime: this.activeVideo.currentTime,\r\n duration: this.activeVideo.duration || 0,\r\n buffered: this.getBufferedAmount(),\r\n volume: this.activeVideo.volume,\r\n muted: this.activeVideo.muted,\r\n };\r\n }\r\n\r\n /**\r\n * Get active video ID\r\n */\r\n getActiveVideoId(): string | undefined {\r\n return this.activeVideoId;\r\n }\r\n\r\n /**\r\n * Get current state.\r\n *\r\n * NOTE: `currentState` is a single global machine that reflects only the\r\n * *most recently started* video. With the relaxed \"at most one unmuted\"\r\n * rule multiple muted videos can play concurrently, so after one of them\r\n * fires `ended` (and keeps looping) this can read `idle` while others still\r\n * play. The `VideoSequencerService` therefore does NOT consult `getState()`\r\n * for queue decisions — it tracks its own per-slot pass completion via\r\n * `notifyPassComplete()`. Treat this value as a best-effort hint for the\r\n * active video only.\r\n */\r\n getState(): VideoState {\r\n return this.currentState;\r\n }\r\n\r\n /**\r\n * Check if video is playing\r\n */\r\n isPlaying(): boolean {\r\n return this.currentState === 'playing';\r\n }\r\n\r\n /**\r\n * Set volume\r\n */\r\n setVolume(volume: number): void {\r\n if (!this.activeVideo) {\r\n return;\r\n }\r\n\r\n this.activeVideo.volume = Math.max(0, Math.min(1, volume));\r\n }\r\n\r\n /**\r\n * Set muted state\r\n */\r\n setMuted(muted: boolean): void {\r\n if (!this.activeVideo) {\r\n return;\r\n }\r\n\r\n this.activeVideo.muted = muted;\r\n }\r\n\r\n /**\r\n * Seek to time\r\n */\r\n seek(time: number): void {\r\n if (!this.activeVideo) {\r\n return;\r\n }\r\n\r\n this.activeVideo.currentTime = Math.max(0, Math.min(time, this.activeVideo.duration || 0));\r\n }\r\n\r\n /**\r\n * Attach event listeners to video element\r\n */\r\n private attachEventListeners(video: HTMLVideoElement, videoId: string): void {\r\n video.addEventListener('ended', () => this.onEnded(videoId));\r\n video.addEventListener('error', () => this.onError(videoId));\r\n video.addEventListener('waiting', () => this.onWaiting(videoId));\r\n video.addEventListener('canplay', () => this.onCanPlay(videoId));\r\n video.addEventListener('playing', () => this.onPlaying(videoId));\r\n }\r\n\r\n /**\r\n * Detach event listeners from video element\r\n */\r\n private detachEventListeners(video: HTMLVideoElement): void {\r\n // Clone and replace to remove all listeners\r\n const clone = video.cloneNode(true) as HTMLVideoElement;\r\n video.parentNode?.replaceChild(clone, video);\r\n }\r\n\r\n /**\r\n * Handle video ended.\r\n *\r\n * Deliberately does NOT touch the concurrency registry: a native `ended`\r\n * event also fires at the internal cycle boundary of a looping/pingpong\r\n * video (it keeps playing right after), so unregistering here would drop\r\n * the \"at most one unmuted video\" enforcement and the `onPreempted`\r\n * callback for any video that continues past its first cycle. The owning\r\n * component knows the play mode and is responsible for calling\r\n * `unregister()` when playback is genuinely finished (or on pause/stop/\r\n * destroy) — see `VideoLayerComponent.handleEnded()`.\r\n */\r\n private onEnded(videoId: string): void {\r\n this.setState('idle');\r\n this.emitEvent('ended', videoId);\r\n }\r\n\r\n /**\r\n * Handle video error\r\n */\r\n private onError(videoId: string): void {\r\n if (!this.activeVideo) {\r\n return;\r\n }\r\n\r\n const error = this.activeVideo.error;\r\n const errorMessage = error ? this.getErrorMessage(error) : 'Unknown error';\r\n \r\n this.handleError(videoId, new Error(errorMessage));\r\n }\r\n\r\n /**\r\n * Handle waiting (buffering)\r\n */\r\n private onWaiting(videoId: string): void {\r\n this.setState('buffering');\r\n this.emitEvent('buffering', videoId);\r\n }\r\n\r\n /**\r\n * Handle can play\r\n */\r\n private onCanPlay(videoId: string): void {\r\n if (this.currentState === 'buffering' || this.currentState === 'loading') {\r\n this.setState('paused');\r\n this.emitEvent('ready', videoId);\r\n }\r\n }\r\n\r\n /**\r\n * Handle playing\r\n */\r\n private onPlaying(_videoId: string): void {\r\n if (this.currentState !== 'playing') {\r\n this.setState('playing');\r\n }\r\n }\r\n\r\n /**\r\n * Handle error with retry logic\r\n */\r\n private handleError(videoId: string, error: Error): void {\r\n console.error(`Video error for ${videoId}:`, error);\r\n\r\n if (this.retryCount < this.MAX_RETRIES) {\r\n this.retryCount++;\r\n console.log(`Retrying video ${videoId} (attempt ${this.retryCount}/${this.MAX_RETRIES})`);\r\n\r\n setTimeout(() => {\r\n if (this.activeVideo && this.activeVideoId === videoId) {\r\n this.activeVideo.load();\r\n this.activeVideo.play().catch((err) => {\r\n console.error('Retry failed:', err);\r\n this.setState('error');\r\n this.emitEvent('error', videoId, error.message);\r\n });\r\n }\r\n }, this.RETRY_DELAY * this.retryCount);\r\n } else {\r\n this.setState('error');\r\n this.emitEvent('error', videoId, error.message);\r\n }\r\n }\r\n\r\n /**\r\n * Get error message from MediaError\r\n */\r\n private getErrorMessage(error: MediaError): string {\r\n switch (error.code) {\r\n case MediaError.MEDIA_ERR_ABORTED:\r\n return 'Video playback aborted';\r\n case MediaError.MEDIA_ERR_NETWORK:\r\n return 'Network error while loading video';\r\n case MediaError.MEDIA_ERR_DECODE:\r\n return 'Video decoding failed';\r\n case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:\r\n return 'Video format not supported';\r\n default:\r\n return 'Unknown video error';\r\n }\r\n }\r\n\r\n /**\r\n * Get buffered amount (percentage)\r\n */\r\n private getBufferedAmount(): number {\r\n if (!this.activeVideo || !this.activeVideo.buffered.length) {\r\n return 0;\r\n }\r\n\r\n const duration = this.activeVideo.duration;\r\n if (!duration || duration === 0) {\r\n return 0;\r\n }\r\n\r\n // Get end of last buffered range\r\n const bufferedEnd = this.activeVideo.buffered.end(this.activeVideo.buffered.length - 1);\r\n return (bufferedEnd / duration) * 100;\r\n }\r\n\r\n /**\r\n * Set current state\r\n */\r\n private setState(state: VideoState): void {\r\n this.currentState = state;\r\n }\r\n\r\n /**\r\n * Emit video event\r\n */\r\n private emitEvent(type: VideoEvent['type'], videoId: string, error?: string): void {\r\n this.eventSubject.next({\r\n type,\r\n videoId,\r\n timestamp: Date.now(),\r\n error,\r\n });\r\n }\r\n\r\n /**\r\n * Cleanup\r\n */\r\n destroy(): void {\r\n this.stop();\r\n this.registry.clear();\r\n this.eventSubject.complete();\r\n this.passCompleteSubject.complete();\r\n }\r\n}\r\n","/**\r\n * Visibility Service\r\n *\r\n * Thin IntersectionObserver wrapper used by the page-view video sequencer to\r\n * decide which panel placements are on-screen. A placement counts as\r\n * \"visible\" once at least `VISIBILITY_THRESHOLD` (50 %) of its box intersects\r\n * the viewport, per the video-panels concept (§4.2).\r\n *\r\n * SSR-safe: when `IntersectionObserver` / `window` are unavailable the service\r\n * degrades gracefully — `observe()` is a no-op and no visibility changes are\r\n * emitted (the caller keeps whatever initial state it had).\r\n *\r\n * The service is intentionally generic (keyed by a caller-supplied id) so it\r\n * can be reused for lazy-loading later.\r\n *\r\n * An id may map to MORE THAN ONE element (e.g. a panel with several video\r\n * layers all keyed by the same placement id): the id counts as visible while\r\n * *any* of its elements meets the threshold. Callers add elements with\r\n * {@link observe}, remove one with {@link unobserveElement}, or drop the whole\r\n * id with {@link unobserve}.\r\n */\r\n\r\nimport { Injectable, OnDestroy } from '@angular/core';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\n/** Minimum intersection ratio for a target to count as visible. */\r\nexport const VISIBILITY_THRESHOLD = 0.5;\r\n\r\n/** A single visibility state change. */\r\nexport interface VisibilityChange {\r\n /** Caller-supplied id for the observed target. */\r\n id: string;\r\n /** Whether the target is now considered visible (>= threshold). */\r\n visible: boolean;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class VisibilityService implements OnDestroy {\r\n private observer?: IntersectionObserver;\r\n\r\n /** element → id, so callbacks can resolve the caller's id. */\r\n private readonly idByElement = new Map<Element, string>();\r\n\r\n /** id → its observed elements (a panel may have several video hosts). */\r\n private readonly elementsById = new Map<string, Set<Element>>();\r\n\r\n /** Elements currently intersecting at/above the threshold. */\r\n private readonly visibleElements = new Set<Element>();\r\n\r\n /** Last known aggregate visibility per id (true when any element visible). */\r\n private readonly visible = new Map<string, boolean>();\r\n\r\n private readonly changes$ = new Subject<VisibilityChange>();\r\n\r\n /** Stream of visibility changes (only emits on transitions). */\r\n readonly changes: Observable<VisibilityChange> = this.changes$.asObservable();\r\n\r\n /**\r\n * Whether IntersectionObserver is available in this environment (false in\r\n * SSR / very old browsers).\r\n */\r\n isSupported(): boolean {\r\n return (\r\n typeof window !== 'undefined' &&\r\n typeof IntersectionObserver !== 'undefined'\r\n );\r\n }\r\n\r\n /**\r\n * Start observing `element` under the given `id`. Multiple elements may be\r\n * observed under one id — they accumulate, and the id is visible while any\r\n * of them meets the threshold. Re-observing the same element under a new id\r\n * moves it. No-op when unsupported.\r\n */\r\n observe(id: string, element: Element): void {\r\n if (!this.isSupported() || !element) {\r\n return;\r\n }\r\n // Element already tracked under a different id → move it (drop from the\r\n // old id's set and recompute that id's aggregate).\r\n const previousId = this.idByElement.get(element);\r\n if (previousId !== undefined && previousId !== id) {\r\n this.detachElement(element, previousId);\r\n this.recomputeAggregate(previousId);\r\n }\r\n\r\n if (!this.observer) {\r\n this.observer = new IntersectionObserver(\r\n (entries) => this.onEntries(entries),\r\n { threshold: [VISIBILITY_THRESHOLD] }\r\n );\r\n }\r\n\r\n this.idByElement.set(element, id);\r\n let set = this.elementsById.get(id);\r\n if (!set) {\r\n set = new Set<Element>();\r\n this.elementsById.set(id, set);\r\n }\r\n set.add(element);\r\n this.observer.observe(element);\r\n }\r\n\r\n /** Stop observing every element registered under `id`. */\r\n unobserve(id: string): void {\r\n const set = this.elementsById.get(id);\r\n if (set) {\r\n for (const element of set) {\r\n this.observer?.unobserve(element);\r\n this.idByElement.delete(element);\r\n this.visibleElements.delete(element);\r\n }\r\n }\r\n this.elementsById.delete(id);\r\n this.visible.delete(id);\r\n }\r\n\r\n /**\r\n * Stop observing a single `element`, leaving any siblings under the same id\r\n * in place. The id's aggregate visibility is recomputed (and may transition\r\n * to hidden if that element was the only visible one).\r\n */\r\n unobserveElement(element: Element): void {\r\n if (!element) {\r\n return;\r\n }\r\n const id = this.idByElement.get(element);\r\n if (id === undefined) {\r\n return;\r\n }\r\n this.detachElement(element, id);\r\n const set = this.elementsById.get(id);\r\n if (!set || set.size === 0) {\r\n this.elementsById.delete(id);\r\n this.visible.delete(id);\r\n } else {\r\n this.recomputeAggregate(id);\r\n }\r\n }\r\n\r\n /** Synchronous last-known visibility for an id (defaults to false). */\r\n isVisible(id: string): boolean {\r\n return this.visible.get(id) ?? false;\r\n }\r\n\r\n /** Stop observing everything (e.g. when leaving page view). */\r\n clear(): void {\r\n if (this.observer) {\r\n this.observer.disconnect();\r\n }\r\n this.idByElement.clear();\r\n this.elementsById.clear();\r\n this.visibleElements.clear();\r\n this.visible.clear();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.clear();\r\n this.changes$.complete();\r\n }\r\n\r\n /** Detach one element from bookkeeping (observer + maps), no recompute. */\r\n private detachElement(element: Element, id: string): void {\r\n this.observer?.unobserve(element);\r\n this.idByElement.delete(element);\r\n this.visibleElements.delete(element);\r\n this.elementsById.get(id)?.delete(element);\r\n }\r\n\r\n private onEntries(entries: IntersectionObserverEntry[]): void {\r\n const affectedIds = new Set<string>();\r\n for (const entry of entries) {\r\n const id = this.idByElement.get(entry.target);\r\n if (id === undefined) {\r\n continue;\r\n }\r\n const elementVisible =\r\n entry.isIntersecting &&\r\n entry.intersectionRatio >= VISIBILITY_THRESHOLD;\r\n if (elementVisible) {\r\n this.visibleElements.add(entry.target);\r\n } else {\r\n this.visibleElements.delete(entry.target);\r\n }\r\n affectedIds.add(id);\r\n }\r\n for (const id of affectedIds) {\r\n this.recomputeAggregate(id);\r\n }\r\n }\r\n\r\n /**\r\n * Recompute an id's aggregate visibility (visible when any of its elements\r\n * is), emitting only on a transition.\r\n */\r\n private recomputeAggregate(id: string): void {\r\n const set = this.elementsById.get(id);\r\n let nowVisible = false;\r\n if (set) {\r\n for (const element of set) {\r\n if (this.visibleElements.has(element)) {\r\n nowVisible = true;\r\n break;\r\n }\r\n }\r\n }\r\n const wasVisible = this.visible.get(id) ?? false;\r\n if (nowVisible !== wasVisible) {\r\n this.visible.set(id, nowVisible);\r\n this.changes$.next({ id, visible: nowVisible });\r\n }\r\n }\r\n}\r\n","/**\r\n * Video Sequencer Service\r\n *\r\n * Implements the page-view sequential-playback semantics of the video-panels\r\n * concept (§4.3): the *visible* `on-view` video panels of the current page\r\n * play one after another in reading order. Each queue slot plays until it\r\n * completes **one full pass** (`once` → ended; `loop`/`pingpong`/`loop-from`\r\n * → one cycle, then it keeps looping muted while the next slot starts).\r\n *\r\n * Ordering: `Page.readingOrder`; fallback (missing reading order) is placement\r\n * order — z-index, then y, then x (§7).\r\n *\r\n * A queue slot is a **panel**, not a single video: multiple video layers in\r\n * one panel form one slot; they all start together and the slot completes when\r\n * the *longest* pass completes, i.e. when every sequenced video in the panel\r\n * has reported `passComplete` (§7).\r\n *\r\n * The sequencer never touches the DOM directly. Video layer components\r\n * register a small {@link SequencedVideo} handle; the sequencer decides which\r\n * slot is \"active\" and calls `activate()` / `deactivate()` on its videos. Each\r\n * handle reports back via `notifyPassComplete()`.\r\n *\r\n * Concurrency: at most one *unmuted* video plays at a time — that rule lives in\r\n * `VideoControllerService` (relaxed in the playback core). If a user-initiated\r\n * unmuted video (hover/click) starts, the host pauses the sequencer via\r\n * {@link pause} and resumes via {@link resume} when it ends/pauses (§4.3.4).\r\n *\r\n * Auto-advance coupling (§4.3.6): when the last queue slot completes its pass\r\n * the sequencer emits {@link queueComplete}; the host advances the page/panel\r\n * only when autoplay is on.\r\n */\r\n\r\nimport { Injectable, OnDestroy, inject } from '@angular/core';\r\nimport { Observable, Subject, Subscription } from 'rxjs';\r\nimport { VisibilityService } from './visibility.service';\r\n\r\n/**\r\n * Ordering / visibility metadata for one video, supplied at registration.\r\n */\r\nexport interface SequencedVideoInfo {\r\n /** Stable id (video layer instance id). */\r\n id: string;\r\n /** Panel this video belongs to (one queue slot per panel). */\r\n panelId: string;\r\n /** Placement id used for visibility lookup (usually the panelId). */\r\n placementId: string;\r\n /**\r\n * Index of this panel in `Page.readingOrder`, or -1 when reading order is\r\n * absent / does not contain the panel. Falls back to placement order.\r\n */\r\n readingOrderIndex: number;\r\n /** Placement fallback ordering key: z-index (higher last). */\r\n z: number;\r\n /** Placement fallback ordering key: y (top first). */\r\n y: number;\r\n /** Placement fallback ordering key: x (left first). */\r\n x: number;\r\n /**\r\n * Whether this video participates in the sequence at all — only page-view\r\n * `on-view` videos do. hover/click videos register as non-sequenced so the\r\n * sequencer knows about them for bookkeeping but never queues them.\r\n */\r\n sequenced: boolean;\r\n}\r\n\r\n/**\r\n * Control handle the sequencer uses to drive a registered video component.\r\n */\r\nexport interface SequencedVideo extends SequencedVideoInfo {\r\n /** Host element observed for visibility (page view). */\r\n element: Element;\r\n /** Make this video part of the active slot: start / resume playback. */\r\n activate(): void;\r\n /** Deactivate (stop + reset) when removed from the queue / on pause. */\r\n deactivate(): void;\r\n /**\r\n * Pause keeping the position (§4.2 hover/click videos whose panel leaves\r\n * the viewport — they resume from the same spot on user interaction).\r\n */\r\n suspend?(): void;\r\n /** Optional hook invoked right before a stalled slot is skipped. */\r\n onStallSkip?(): void;\r\n}\r\n\r\n/** Default stall-skip timeout: 10 s (§7). */\r\nexport const DEFAULT_STALL_TIMEOUT_MS = 10_000;\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class VideoSequencerService implements OnDestroy {\r\n private readonly visibility = inject(VisibilityService);\r\n\r\n /** All registered videos keyed by id (sequenced and non-sequenced). */\r\n private readonly registry = new Map<string, SequencedVideo>();\r\n\r\n /** Ordered queue of *sequenced + visible* panel ids (slots). */\r\n private queue: string[] = [];\r\n\r\n /** Panel id of the currently active (playing) slot, if any. */\r\n private activePanelId: string | null = null;\r\n\r\n /**\r\n * For the active slot: ids of its videos that have not yet completed their\r\n * pass. The slot completes when this set is empty (longest pass wins, §7).\r\n */\r\n private pendingPass = new Set<string>();\r\n\r\n /** Whether the sequencer is paused (e.g. an unmuted user video is playing). */\r\n private paused = false;\r\n\r\n /** Whether a page-view sequence is currently running. */\r\n private running = false;\r\n\r\n /** Stall-skip timer for the active slot. */\r\n private stallTimer?: ReturnType<typeof setTimeout>;\r\n\r\n /**\r\n * Stall-skip timeout (ms). If the active slot makes no progress for this\r\n * long the sequencer skips it (§7). Injectable via {@link setStallTimeout}\r\n * rather than a magic number.\r\n */\r\n private stallTimeoutMs = DEFAULT_STALL_TIMEOUT_MS;\r\n\r\n private visibilitySub?: Subscription;\r\n\r\n private readonly queueComplete$ = new Subject<void>();\r\n\r\n /**\r\n * Emits when the queue has completed its last slot's pass (§4.3.6). The\r\n * host advances the page/panel only when autoplay is enabled.\r\n */\r\n readonly queueComplete: Observable<void> = this.queueComplete$.asObservable();\r\n\r\n /** Configure the stall-skip timeout (ms). */\r\n setStallTimeout(ms: number): void {\r\n if (Number.isFinite(ms) && ms > 0) {\r\n this.stallTimeoutMs = ms;\r\n }\r\n }\r\n\r\n /** Current stall-skip timeout (ms). */\r\n getStallTimeout(): number {\r\n return this.stallTimeoutMs;\r\n }\r\n\r\n /** The visibility service instance (exposed so hosts can observe elements). */\r\n getVisibility(): VisibilityService {\r\n return this.visibility;\r\n }\r\n\r\n /**\r\n * Begin a page-view sequence. Clears prior state and subscribes to\r\n * visibility changes so newly-visible videos append and leaving ones drop.\r\n * Already-registered sequenced videos (components reused across a page\r\n * change) are re-observed and re-queued.\r\n */\r\n start(): void {\r\n this.reset();\r\n this.running = true;\r\n this.visibilitySub = this.visibility.changes.subscribe((change) =>\r\n this.onVisibilityChange(change.id, change.visible)\r\n );\r\n // Re-enlist videos that are still registered from a previous run.\r\n for (const video of this.registry.values()) {\r\n if (video.element) {\r\n this.visibility.observe(video.placementId, video.element);\r\n }\r\n if (!video.sequenced) {\r\n continue;\r\n }\r\n if (\r\n !this.visibility.isSupported() ||\r\n this.visibility.isVisible(video.placementId)\r\n ) {\r\n this.appendSlot(video.panelId);\r\n }\r\n }\r\n }\r\n\r\n /** Stop the sequence and release all observers/timers. */\r\n reset(): void {\r\n this.running = false;\r\n this.paused = false;\r\n this.activePanelId = null;\r\n this.pendingPass.clear();\r\n this.queue = [];\r\n this.clearStallTimer();\r\n this.visibilitySub?.unsubscribe();\r\n this.visibilitySub = undefined;\r\n this.visibility.clear();\r\n // Deactivate everything currently registered.\r\n for (const video of this.registry.values()) {\r\n video.deactivate();\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.reset();\r\n this.queueComplete$.complete();\r\n }\r\n\r\n /**\r\n * Register a video with the sequencer. Sequenced videos begin observing\r\n * their placement for visibility; when already visible their panel is\r\n * appended to the queue (and playback kicks off if the queue was idle).\r\n */\r\n register(video: SequencedVideo): void {\r\n this.registry.set(video.id, video);\r\n if (!this.running) {\r\n return;\r\n }\r\n // Observe every page-view video's placement: sequenced ones drive the\r\n // queue; hover/click ones are suspended when they leave the viewport\r\n // (§4.2, position kept).\r\n if (video.element) {\r\n this.visibility.observe(video.placementId, video.element);\r\n }\r\n if (!video.sequenced) {\r\n return;\r\n }\r\n // If IntersectionObserver is unsupported (SSR/tests without DOM), treat as\r\n // visible so the sequence still runs.\r\n if (!this.visibility.isSupported() || this.visibility.isVisible(video.placementId)) {\r\n this.appendSlot(video.panelId);\r\n }\r\n // A late-arriving video for the already-active slot must start too.\r\n if (video.panelId === this.activePanelId) {\r\n this.pendingPass.add(video.id);\r\n if (!this.paused) {\r\n video.activate();\r\n }\r\n }\r\n }\r\n\r\n /** Remove a video (component destroyed / no longer sequenced). */\r\n unregister(id: string): void {\r\n const video = this.registry.get(id);\r\n this.registry.delete(id);\r\n if (!video) {\r\n return;\r\n }\r\n // Stop observing just this video's host — siblings sharing the placement\r\n // id keep driving the panel's visibility (a wholesale unobserve here would\r\n // freeze visibility for a multi-video panel when one layer leaves first).\r\n if (video.element) {\r\n this.visibility.unobserveElement(video.element);\r\n }\r\n // If it was part of the active slot, drop it from the pending set and\r\n // complete the slot early if it was the last outstanding video.\r\n if (video.panelId === this.activePanelId) {\r\n this.pendingPass.delete(id);\r\n if (this.pendingPass.size === 0) {\r\n this.completeActiveSlot();\r\n return;\r\n }\r\n }\r\n // If no more sequenced videos remain for this panel, drop the slot.\r\n if (!this.panelHasSequencedVideos(video.panelId)) {\r\n this.queue = this.queue.filter((pid) => pid !== video.panelId);\r\n }\r\n }\r\n\r\n /**\r\n * Pause the sequence (an unmuted user-initiated video started). The active\r\n * slot is deactivated; {@link resume} restarts it from the front.\r\n */\r\n pause(): void {\r\n if (this.paused) return;\r\n this.paused = true;\r\n this.clearStallTimer();\r\n if (this.activePanelId) {\r\n // Re-queue the paused slot at the front so resume replays it.\r\n const panelId = this.activePanelId;\r\n this.deactivatePanel(panelId);\r\n this.activePanelId = null;\r\n this.pendingPass.clear();\r\n if (!this.queue.includes(panelId)) {\r\n this.queue.unshift(panelId);\r\n }\r\n }\r\n }\r\n\r\n /** Resume the sequence after a pause. */\r\n resume(): void {\r\n if (!this.paused) return;\r\n this.paused = false;\r\n if (!this.activePanelId) {\r\n this.playNext();\r\n }\r\n }\r\n\r\n isPaused(): boolean {\r\n return this.paused;\r\n }\r\n\r\n isRunning(): boolean {\r\n return this.running;\r\n }\r\n\r\n /** Current queue of panel-slot ids — for tests/inspection. */\r\n getQueue(): readonly string[] {\r\n return this.queue;\r\n }\r\n\r\n /** Currently active slot (panel id) or null. */\r\n getActivePanelId(): string | null {\r\n return this.activePanelId;\r\n }\r\n\r\n /**\r\n * Called by a video when it completes one full pass. The slot advances only\r\n * once every sequenced video in the active panel has completed (§7). The\r\n * finished video keeps looping muted on its own (loop modes) or freezes\r\n * (once) — the sequencer does not touch it further.\r\n */\r\n notifyPassComplete(id: string): void {\r\n const video = this.registry.get(id);\r\n if (!video || video.panelId !== this.activePanelId) {\r\n return;\r\n }\r\n this.pendingPass.delete(id);\r\n if (this.pendingPass.size === 0) {\r\n this.completeActiveSlot();\r\n }\r\n }\r\n\r\n /**\r\n * Called by a video to report media progress — resets the stall timer for\r\n * the active slot.\r\n */\r\n notifyProgress(id: string): void {\r\n const video = this.registry.get(id);\r\n if (video && video.panelId === this.activePanelId) {\r\n this.armStallTimer();\r\n }\r\n }\r\n\r\n /**\r\n * Called by a video to signal it started buffering (arms the stall timer for\r\n * the active slot).\r\n */\r\n notifyStalling(id: string): void {\r\n const video = this.registry.get(id);\r\n if (video && video.panelId === this.activePanelId) {\r\n this.armStallTimer();\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Queue mechanics\r\n // ---------------------------------------------------------------------------\r\n\r\n private onVisibilityChange(placementId: string, visible: boolean): void {\r\n // §4.2: hover/click videos leaving the viewport pause keeping position.\r\n if (!visible) {\r\n for (const video of this.registry.values()) {\r\n if (!video.sequenced && video.placementId === placementId) {\r\n video.suspend?.();\r\n }\r\n }\r\n }\r\n // Resolve the placement id back to a panel id via any of its videos.\r\n const panelId = this.panelIdForPlacement(placementId);\r\n if (!panelId) {\r\n return;\r\n }\r\n if (visible) {\r\n this.appendSlot(panelId);\r\n } else {\r\n this.removeSlot(panelId);\r\n }\r\n }\r\n\r\n private appendSlot(panelId: string): void {\r\n if (this.queue.includes(panelId) || panelId === this.activePanelId) {\r\n return;\r\n }\r\n this.queue.push(panelId);\r\n this.sortQueue();\r\n if (!this.paused && this.activePanelId === null) {\r\n this.playNext();\r\n }\r\n }\r\n\r\n private removeSlot(panelId: string): void {\r\n const wasActive = this.activePanelId === panelId;\r\n this.queue = this.queue.filter((pid) => pid !== panelId);\r\n // Leaving the viewport: on-view videos pause + reset (§4.2).\r\n this.deactivatePanel(panelId);\r\n if (wasActive) {\r\n this.clearStallTimer();\r\n this.activePanelId = null;\r\n this.pendingPass.clear();\r\n this.advance();\r\n }\r\n }\r\n\r\n /** Order the queue by reading order, falling back to placement order. */\r\n private sortQueue(): void {\r\n this.queue.sort((a, b) => {\r\n const va = this.representativeVideo(a);\r\n const vb = this.representativeVideo(b);\r\n if (!va || !vb) return 0;\r\n return this.compare(va, vb);\r\n });\r\n }\r\n\r\n private compare(a: SequencedVideoInfo, b: SequencedVideoInfo): number {\r\n const ra = a.readingOrderIndex;\r\n const rb = b.readingOrderIndex;\r\n const aHas = ra >= 0;\r\n const bHas = rb >= 0;\r\n // Both have a reading-order index: sort by it.\r\n if (aHas && bHas && ra !== rb) {\r\n return ra - rb;\r\n }\r\n // Reading order present for one only: it wins (comes first).\r\n if (aHas !== bHas) {\r\n return aHas ? -1 : 1;\r\n }\r\n // Fallback placement order: z, then y, then x.\r\n if (a.z !== b.z) return a.z - b.z;\r\n if (a.y !== b.y) return a.y - b.y;\r\n if (a.x !== b.x) return a.x - b.x;\r\n return 0;\r\n }\r\n\r\n /** Called when the active slot's longest pass finished. */\r\n private completeActiveSlot(): void {\r\n this.clearStallTimer();\r\n this.activePanelId = null;\r\n this.pendingPass.clear();\r\n this.advance();\r\n }\r\n\r\n /**\r\n * Advance to the next queue slot, or emit `queueComplete` when the queue is\r\n * exhausted.\r\n */\r\n private advance(): void {\r\n if (this.paused || !this.running) {\r\n return;\r\n }\r\n if (this.queue.length === 0) {\r\n this.queueComplete$.next();\r\n return;\r\n }\r\n this.playNext();\r\n }\r\n\r\n /** Activate the head slot of the queue (all its sequenced videos). */\r\n private playNext(): void {\r\n if (this.paused || !this.running) {\r\n return;\r\n }\r\n const nextPanelId = this.queue[0];\r\n if (!nextPanelId) {\r\n this.queueComplete$.next();\r\n return;\r\n }\r\n // Drop the head from the queue as we begin playing it: a completed loop\r\n // video keeps looping on its own and must not be replayed by the queue.\r\n this.queue = this.queue.slice(1);\r\n const videos = this.sequencedVideosForPanel(nextPanelId);\r\n if (videos.length === 0) {\r\n // Stale slot; try the next one.\r\n this.playNext();\r\n return;\r\n }\r\n this.activePanelId = nextPanelId;\r\n this.pendingPass = new Set(videos.map((v) => v.id));\r\n this.armStallTimer();\r\n for (const video of videos) {\r\n video.activate();\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Stall-skip\r\n // ---------------------------------------------------------------------------\r\n\r\n private armStallTimer(): void {\r\n this.clearStallTimer();\r\n if (typeof setTimeout === 'undefined') {\r\n return;\r\n }\r\n this.stallTimer = setTimeout(() => {\r\n this.onStallTimeout();\r\n }, this.stallTimeoutMs);\r\n }\r\n\r\n private onStallTimeout(): void {\r\n this.stallTimer = undefined;\r\n const panelId = this.activePanelId;\r\n if (!panelId) {\r\n return;\r\n }\r\n // Skip the stalled slot: notify + deactivate its videos, then move on.\r\n for (const video of this.sequencedVideosForPanel(panelId)) {\r\n video.onStallSkip?.();\r\n video.deactivate();\r\n }\r\n this.activePanelId = null;\r\n this.pendingPass.clear();\r\n this.advance();\r\n }\r\n\r\n private clearStallTimer(): void {\r\n if (this.stallTimer !== undefined) {\r\n clearTimeout(this.stallTimer);\r\n this.stallTimer = undefined;\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Registry helpers\r\n // ---------------------------------------------------------------------------\r\n\r\n private sequencedVideosForPanel(panelId: string): SequencedVideo[] {\r\n const result: SequencedVideo[] = [];\r\n for (const video of this.registry.values()) {\r\n if (video.sequenced && video.panelId === panelId) {\r\n result.push(video);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n private panelHasSequencedVideos(panelId: string): boolean {\r\n for (const video of this.registry.values()) {\r\n if (video.sequenced && video.panelId === panelId) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n private representativeVideo(panelId: string): SequencedVideo | undefined {\r\n for (const video of this.registry.values()) {\r\n if (video.sequenced && video.panelId === panelId) {\r\n return video;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n private panelIdForPlacement(placementId: string): string | undefined {\r\n for (const video of this.registry.values()) {\r\n if (video.sequenced && video.placementId === placementId) {\r\n return video.panelId;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n private deactivatePanel(panelId: string): void {\r\n for (const video of this.sequencedVideosForPanel(panelId)) {\r\n video.deactivate();\r\n }\r\n }\r\n}\r\n","/**\r\n * Preload Service\r\n * Intelligently preloads content based on prediction and priority\r\n */\r\n\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Subject, Observable } from 'rxjs';\r\nimport { ImageCacheService } from './image-cache.service';\r\n\r\n/**\r\n * Preload priority\r\n */\r\nexport type PreloadPriority = 'high' | 'medium' | 'low';\r\n\r\n/**\r\n * Preload item\r\n */\r\nexport interface PreloadItem {\r\n id: string;\r\n type: 'image' | 'audio' | 'video';\r\n url: string;\r\n priority: PreloadPriority;\r\n panelId?: string;\r\n chapterId?: string;\r\n}\r\n\r\n/**\r\n * Preload status\r\n */\r\nexport interface PreloadStatus {\r\n itemId: string;\r\n status: 'queued' | 'loading' | 'loaded' | 'error';\r\n progress?: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Network information\r\n */\r\ninterface NetworkInfo {\r\n effectiveType: '4g' | '3g' | '2g' | 'slow-2g';\r\n downlink: number;\r\n rtt: number;\r\n saveData: boolean;\r\n}\r\n\r\n/**\r\n * Preload Service\r\n * Manages intelligent content preloading with priority queue and network awareness\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class PreloadService {\r\n /**\r\n * Preload queue (priority-based)\r\n */\r\n private queue: PreloadItem[] = [];\r\n\r\n /**\r\n * Currently loading items\r\n */\r\n private loading = new Map<string, Promise<void>>();\r\n\r\n /**\r\n * Loaded items\r\n */\r\n private loaded = new Set<string>();\r\n\r\n /**\r\n * Status subject\r\n */\r\n private statusSubject = new Subject<PreloadStatus>();\r\n\r\n /**\r\n * Status observable\r\n */\r\n readonly status$: Observable<PreloadStatus> = this.statusSubject.asObservable();\r\n\r\n /**\r\n * Max concurrent requests\r\n */\r\n private maxConcurrent = 3;\r\n\r\n /**\r\n * Current concurrent count\r\n */\r\n private currentConcurrent = 0;\r\n\r\n /**\r\n * Network-aware throttling enabled\r\n */\r\n private networkAware = true;\r\n\r\n /**\r\n * Network connection info\r\n */\r\n private networkInfo?: NetworkInfo;\r\n\r\n /**\r\n * Idle callback ID\r\n */\r\n private idleCallbackId?: number;\r\n\r\n /** Low-priority items handed to requestIdleCallback but not started yet. */\r\n private idlePending = 0;\r\n\r\n private readonly imageCache = inject(ImageCacheService);\r\n\r\n constructor() {\r\n this.detectNetwork();\r\n this.adjustConcurrencyByNetwork();\r\n }\r\n\r\n /**\r\n * Add item to preload queue\r\n */\r\n add(item: PreloadItem): void {\r\n // Check if already loaded or in queue\r\n if (this.loaded.has(item.id) || this.isInQueue(item.id)) {\r\n return;\r\n }\r\n\r\n // Add to queue\r\n this.queue.push(item);\r\n\r\n // Sort by priority\r\n this.sortQueue();\r\n\r\n // Emit queued status\r\n this.emitStatus(item.id, 'queued');\r\n\r\n // Start processing\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Add multiple items\r\n */\r\n addBatch(items: PreloadItem[]): void {\r\n items.forEach((item) => this.add(item));\r\n }\r\n\r\n /**\r\n * Preload next N panels\r\n */\r\n preloadNext(currentPanelIndex: number, panelUrls: string[], count = 3): void {\r\n const items: PreloadItem[] = [];\r\n\r\n for (let i = 1; i <= count; i++) {\r\n const index = currentPanelIndex + i;\r\n if (index < panelUrls.length) {\r\n const priority = i === 1 ? 'high' : i === 2 ? 'medium' : 'low';\r\n items.push({\r\n id: `panel-${index}`,\r\n type: 'image',\r\n url: panelUrls[index],\r\n priority,\r\n panelId: `${index}`,\r\n });\r\n }\r\n }\r\n\r\n this.addBatch(items);\r\n }\r\n\r\n /**\r\n * Predict and preload based on direction\r\n */\r\n predictAndPreload(\r\n currentIndex: number,\r\n totalPanels: number,\r\n direction: 'forward' | 'backward' | 'auto',\r\n panelUrls: string[]\r\n ): void {\r\n const predictedIndices = this.predict(currentIndex, totalPanels, direction);\r\n\r\n const items: PreloadItem[] = predictedIndices\r\n .map((index, i) => {\r\n if (index >= 0 && index < panelUrls.length) {\r\n const priority: PreloadPriority = i === 0 ? 'high' : i === 1 ? 'medium' : 'low';\r\n return {\r\n id: `panel-${index}`,\r\n type: 'image' as const,\r\n url: panelUrls[index],\r\n priority,\r\n panelId: `${index}`,\r\n } as PreloadItem;\r\n }\r\n return null;\r\n })\r\n .filter((item): item is PreloadItem => item !== null);\r\n\r\n this.addBatch(items);\r\n }\r\n\r\n /**\r\n * Predict next indices based on direction\r\n */\r\n private predict(\r\n currentIndex: number,\r\n totalPanels: number,\r\n direction: 'forward' | 'backward' | 'auto'\r\n ): number[] {\r\n const indices: number[] = [];\r\n\r\n if (direction === 'forward' || direction === 'auto') {\r\n // Predict forward: next 3 panels\r\n indices.push(currentIndex + 1, currentIndex + 2, currentIndex + 3);\r\n }\r\n\r\n if (direction === 'backward') {\r\n // Predict backward: previous 3 panels\r\n indices.push(currentIndex - 1, currentIndex - 2, currentIndex - 3);\r\n }\r\n\r\n if (direction === 'auto') {\r\n // Also predict one backward\r\n indices.push(currentIndex - 1);\r\n }\r\n\r\n // Filter valid indices\r\n return indices.filter((i) => i >= 0 && i < totalPanels);\r\n }\r\n\r\n /**\r\n * Clear queue\r\n */\r\n clearQueue(): void {\r\n this.queue = [];\r\n if (this.idleCallbackId && 'cancelIdleCallback' in window) {\r\n (window as unknown as { cancelIdleCallback(id: number): void }).cancelIdleCallback(\r\n this.idleCallbackId\r\n );\r\n this.idleCallbackId = undefined;\r\n }\r\n this.idlePending = 0;\r\n }\r\n\r\n /**\r\n * Remove item from queue\r\n */\r\n remove(itemId: string): void {\r\n this.queue = this.queue.filter((item) => item.id !== itemId);\r\n }\r\n\r\n /**\r\n * Check if item is in queue\r\n */\r\n private isInQueue(itemId: string): boolean {\r\n return this.queue.some((item) => item.id === itemId);\r\n }\r\n\r\n /**\r\n * Sort queue by priority\r\n */\r\n private sortQueue(): void {\r\n const priorityOrder: Record<PreloadPriority, number> = {\r\n high: 0,\r\n medium: 1,\r\n low: 2,\r\n };\r\n\r\n this.queue.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);\r\n }\r\n\r\n /**\r\n * Process queue\r\n */\r\n private processQueue(): void {\r\n // Check concurrency limit\r\n while (this.currentConcurrent < this.maxConcurrent && this.queue.length > 0) {\r\n const item = this.queue.shift();\r\n if (!item) break;\r\n\r\n // Use idle callback for low priority\r\n if (item.priority === 'low' && 'requestIdleCallback' in window) {\r\n this.scheduleIdleLoad(item);\r\n } else {\r\n this.loadItem(item);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Schedule load during idle time\r\n */\r\n private scheduleIdleLoad(item: PreloadItem): void {\r\n // An idle-scheduled item is out of the queue array but not yet\r\n // loading — track it so getQueueStatus() still accounts for it.\r\n this.idlePending++;\r\n const callback = () => {\r\n this.idlePending = Math.max(0, this.idlePending - 1);\r\n this.loadItem(item);\r\n };\r\n\r\n if ('requestIdleCallback' in window) {\r\n this.idleCallbackId = window.requestIdleCallback(callback, { timeout: 2000 });\r\n } else {\r\n // Fallback to setTimeout\r\n setTimeout(callback, 100);\r\n }\r\n }\r\n\r\n /**\r\n * Load individual item\r\n */\r\n private async loadItem(item: PreloadItem): Promise<void> {\r\n // Check if already loading\r\n if (this.loading.has(item.id)) {\r\n return this.loading.get(item.id);\r\n }\r\n\r\n this.currentConcurrent++;\r\n this.emitStatus(item.id, 'loading');\r\n\r\n const loadPromise = this.performLoad(item);\r\n this.loading.set(item.id, loadPromise);\r\n\r\n try {\r\n await loadPromise;\r\n this.loaded.add(item.id);\r\n this.emitStatus(item.id, 'loaded');\r\n } catch (error) {\r\n console.error(`Failed to preload ${item.id}:`, error);\r\n this.emitStatus(item.id, 'error', (error as Error).message);\r\n } finally {\r\n this.currentConcurrent--;\r\n this.loading.delete(item.id);\r\n\r\n // Process next items\r\n this.processQueue();\r\n }\r\n }\r\n\r\n /**\r\n * Perform actual load\r\n */\r\n private async performLoad(item: PreloadItem): Promise<void> {\r\n switch (item.type) {\r\n case 'image':\r\n await this.imageCache.preload(item.url);\r\n break;\r\n case 'audio':\r\n await this.preloadAudio(item.url);\r\n break;\r\n case 'video':\r\n await this.preloadVideo(item.url);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Preload audio\r\n */\r\n private async preloadAudio(url: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const audio = new Audio(url);\r\n audio.addEventListener('canplaythrough', () => resolve(), { once: true });\r\n audio.addEventListener('error', () => reject(new Error('Audio load failed')), { once: true });\r\n audio.load();\r\n });\r\n }\r\n\r\n /**\r\n * Preload video\r\n */\r\n private async preloadVideo(url: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const video = document.createElement('video');\r\n video.src = url;\r\n video.preload = 'metadata';\r\n video.addEventListener('loadedmetadata', () => resolve(), { once: true });\r\n video.addEventListener('error', () => reject(new Error('Video load failed')), { once: true });\r\n video.load();\r\n });\r\n }\r\n\r\n /**\r\n * Detect network connection\r\n */\r\n private detectNetwork(): void {\r\n const nav = navigator as Navigator & {\r\n connection?: {\r\n effectiveType?: '4g' | '3g' | '2g' | 'slow-2g';\r\n downlink?: number;\r\n rtt?: number;\r\n saveData?: boolean;\r\n addEventListener(type: 'change', listener: () => void): void;\r\n };\r\n };\r\n const conn = nav.connection;\r\n if (conn) {\r\n this.networkInfo = {\r\n effectiveType: conn.effectiveType || '4g',\r\n downlink: conn.downlink || 10,\r\n rtt: conn.rtt || 50,\r\n saveData: conn.saveData || false,\r\n };\r\n\r\n // Listen for changes\r\n conn.addEventListener('change', () => {\r\n this.detectNetwork();\r\n this.adjustConcurrencyByNetwork();\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Adjust concurrency based on network\r\n */\r\n private adjustConcurrencyByNetwork(): void {\r\n if (!this.networkAware || !this.networkInfo) {\r\n this.maxConcurrent = 3;\r\n return;\r\n }\r\n\r\n // Don't preload on save-data mode\r\n if (this.networkInfo.saveData) {\r\n this.maxConcurrent = 0;\r\n this.clearQueue();\r\n return;\r\n }\r\n\r\n // Adjust based on connection type\r\n switch (this.networkInfo.effectiveType) {\r\n case '4g':\r\n this.maxConcurrent = 5;\r\n break;\r\n case '3g':\r\n this.maxConcurrent = 2;\r\n break;\r\n case '2g':\r\n case 'slow-2g':\r\n this.maxConcurrent = 1;\r\n break;\r\n default:\r\n this.maxConcurrent = 3;\r\n }\r\n }\r\n\r\n /**\r\n * Set max concurrent requests\r\n */\r\n setMaxConcurrent(max: number): void {\r\n this.maxConcurrent = Math.max(0, max);\r\n }\r\n\r\n /**\r\n * Enable/disable network-aware throttling\r\n */\r\n setNetworkAware(enabled: boolean): void {\r\n this.networkAware = enabled;\r\n if (enabled) {\r\n this.adjustConcurrencyByNetwork();\r\n }\r\n }\r\n\r\n /**\r\n * Get queue status\r\n */\r\n getQueueStatus() {\r\n return {\r\n // Idle-scheduled low-priority items count as queued: they left the\r\n // queue array but have not started loading yet.\r\n queued: this.queue.length + this.idlePending,\r\n loading: this.currentConcurrent,\r\n loaded: this.loaded.size,\r\n maxConcurrent: this.maxConcurrent,\r\n };\r\n }\r\n\r\n /**\r\n * Emit status event\r\n */\r\n private emitStatus(itemId: string, status: PreloadStatus['status'], error?: string): void {\r\n this.statusSubject.next({\r\n itemId,\r\n status,\r\n error,\r\n });\r\n }\r\n\r\n /**\r\n * Cleanup\r\n */\r\n destroy(): void {\r\n this.clearQueue();\r\n this.loading.clear();\r\n this.loaded.clear();\r\n \r\n if (this.idleCallbackId && 'cancelIdleCallback' in window) {\r\n window.cancelIdleCallback(this.idleCallbackId);\r\n }\r\n \r\n this.statusSubject.complete();\r\n }\r\n}\r\n","/**\r\n * Tracking Service\r\n * Manages analytics event tracking with consent, batching, and debouncing\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\n\r\n/**\r\n * Tracking event\r\n */\r\nexport interface TrackingEvent {\r\n type: string;\r\n timestamp: number;\r\n data?: Record<string, unknown>;\r\n sessionId?: string;\r\n}\r\n\r\n/**\r\n * Tracking configuration\r\n */\r\nexport interface TrackingConfig {\r\n endpoint?: string;\r\n consentRequired: boolean;\r\n eventWhitelist?: string[];\r\n batchSize?: number;\r\n batchInterval?: number;\r\n debounceMs?: number;\r\n}\r\n\r\n/**\r\n * Tracking Service\r\n * Handles analytics events with privacy-conscious features\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class TrackingService {\r\n /**\r\n * Session ID (anonymized)\r\n */\r\n private sessionId: string;\r\n\r\n /**\r\n * User consent status\r\n */\r\n private hasConsent = false;\r\n\r\n /**\r\n * Configuration\r\n */\r\n private config: TrackingConfig = {\r\n consentRequired: true,\r\n batchSize: 10,\r\n batchInterval: 5000, // 5 seconds\r\n debounceMs: 300,\r\n };\r\n\r\n /**\r\n * Event queue\r\n */\r\n private eventQueue: TrackingEvent[] = [];\r\n\r\n /**\r\n * Event subject\r\n */\r\n private eventSubject = new Subject<TrackingEvent>();\r\n\r\n /**\r\n * Batch trigger subject\r\n */\r\n private batchTrigger = new Subject<void>();\r\n\r\n /**\r\n * Event whitelist (from manifest)\r\n */\r\n private eventWhitelist?: Set<string>;\r\n\r\n /**\r\n * Debounce timers\r\n */\r\n private debounceTimers = new Map<string, number>();\r\n\r\n constructor() {\r\n this.sessionId = this.generateSessionId();\r\n this.setupBatching();\r\n }\r\n\r\n /**\r\n * Configure tracking\r\n */\r\n configure(config: Partial<TrackingConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n\r\n // Update whitelist\r\n if (config.eventWhitelist) {\r\n this.eventWhitelist = new Set(config.eventWhitelist);\r\n }\r\n }\r\n\r\n /**\r\n * Set user consent\r\n */\r\n setConsent(consent: boolean): void {\r\n this.hasConsent = consent;\r\n\r\n if (!consent) {\r\n // Clear queue if consent revoked\r\n this.eventQueue = [];\r\n }\r\n }\r\n\r\n /**\r\n * Get consent status\r\n */\r\n getConsent(): boolean {\r\n return this.hasConsent;\r\n }\r\n\r\n /**\r\n * Track an event\r\n */\r\n track(type: string, data?: Record<string, unknown>): void {\r\n // Check consent\r\n if (this.config.consentRequired && !this.hasConsent) {\r\n return;\r\n }\r\n\r\n // Check whitelist\r\n if (this.eventWhitelist && !this.eventWhitelist.has(type)) {\r\n return;\r\n }\r\n\r\n // Create event\r\n const event: TrackingEvent = {\r\n type,\r\n timestamp: Date.now(),\r\n data,\r\n sessionId: this.sessionId,\r\n };\r\n\r\n // Apply debouncing for certain event types\r\n if (this.shouldDebounce(type)) {\r\n this.trackDebounced(event);\r\n } else {\r\n this.addToQueue(event);\r\n }\r\n }\r\n\r\n /**\r\n * Track event with debouncing\r\n */\r\n private trackDebounced(event: TrackingEvent): void {\r\n const { type } = event;\r\n\r\n // Clear existing timer\r\n const existingTimer = this.debounceTimers.get(type);\r\n if (existingTimer !== undefined) {\r\n window.clearTimeout(existingTimer);\r\n }\r\n\r\n // Set new timer\r\n const timer = window.setTimeout(() => {\r\n this.addToQueue(event);\r\n this.debounceTimers.delete(type);\r\n }, this.config.debounceMs || 300);\r\n\r\n this.debounceTimers.set(type, timer);\r\n }\r\n\r\n /**\r\n * Check if event type should be debounced\r\n */\r\n private shouldDebounce(type: string): boolean {\r\n // Debounce high-frequency events\r\n const debounceTypes = ['scroll', 'mousemove', 'resize', 'progress'];\r\n return debounceTypes.includes(type);\r\n }\r\n\r\n /**\r\n * Add event to queue\r\n */\r\n private addToQueue(event: TrackingEvent): void {\r\n this.eventQueue.push(event);\r\n this.eventSubject.next(event);\r\n\r\n // Check if batch is full\r\n if (this.eventQueue.length >= (this.config.batchSize || 10)) {\r\n this.sendBatch();\r\n }\r\n }\r\n\r\n /**\r\n * Setup batching logic\r\n */\r\n private setupBatching(): void {\r\n // Batch by interval\r\n setInterval(() => {\r\n if (this.eventQueue.length > 0) {\r\n this.sendBatch();\r\n }\r\n }, this.config.batchInterval || 5000);\r\n }\r\n\r\n /**\r\n * Send batch of events\r\n */\r\n private async sendBatch(): Promise<void> {\r\n if (this.eventQueue.length === 0) {\r\n return;\r\n }\r\n\r\n // Get events to send\r\n const events = [...this.eventQueue];\r\n this.eventQueue = [];\r\n\r\n // Send to endpoint if configured\r\n if (this.config.endpoint) {\r\n try {\r\n await this.sendToEndpoint(events);\r\n } catch (error) {\r\n console.error('Failed to send tracking events:', error);\r\n // Don't re-queue on failure to avoid memory buildup\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Send events to endpoint\r\n */\r\n private async sendToEndpoint(events: TrackingEvent[]): Promise<void> {\r\n if (!this.config.endpoint) {\r\n return;\r\n }\r\n\r\n const response = await fetch(this.config.endpoint, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n sessionId: this.sessionId,\r\n events,\r\n timestamp: Date.now(),\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`Tracking endpoint returned ${response.status}`);\r\n }\r\n }\r\n\r\n /**\r\n * Generate anonymized session ID\r\n */\r\n private generateSessionId(): string {\r\n // Use crypto.randomUUID if available\r\n if ('randomUUID' in crypto) {\r\n return crypto.randomUUID();\r\n }\r\n\r\n // Fallback to random generation\r\n const timestamp = Date.now().toString(36);\r\n const randomPart = Math.random().toString(36).substring(2, 15);\r\n const randomPart2 = Math.random().toString(36).substring(2, 15);\r\n return `${timestamp}-${randomPart}-${randomPart2}`;\r\n }\r\n\r\n /**\r\n * Get current session ID\r\n */\r\n getSessionId(): string {\r\n return this.sessionId;\r\n }\r\n\r\n /**\r\n * Override the session ID so tracking shares one session with the player\r\n * state (PlayerStateService also mints an ID; analytics must use a single\r\n * one or the backend sees two half-sessions). Call before events are\r\n * queued; already-queued events keep their stamped ID.\r\n */\r\n setSessionId(sessionId: string): void {\r\n if (sessionId && sessionId.trim().length > 0) {\r\n this.sessionId = sessionId;\r\n }\r\n }\r\n\r\n /**\r\n * Synchronous flush for pagehide/unload, where async fetch is unreliable.\r\n * Uses navigator.sendBeacon with a text/plain payload — a \"simple\" content\r\n * type, so the cross-origin POST needs no CORS preflight during unload\r\n * (the ingest endpoint reads the raw body regardless of content type).\r\n * Falls back to fetch({keepalive}) where sendBeacon is unavailable.\r\n */\r\n flushSync(): void {\r\n if (this.eventQueue.length === 0 || !this.config.endpoint) {\r\n this.eventQueue = [];\r\n return;\r\n }\r\n\r\n const events = [...this.eventQueue];\r\n this.eventQueue = [];\r\n\r\n const body = JSON.stringify({\r\n sessionId: this.sessionId,\r\n events,\r\n timestamp: Date.now(),\r\n });\r\n\r\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\r\n const ok = navigator.sendBeacon(\r\n this.config.endpoint,\r\n new Blob([body], { type: 'text/plain' })\r\n );\r\n if (ok) {\r\n return;\r\n }\r\n }\r\n\r\n try {\r\n void fetch(this.config.endpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body,\r\n keepalive: true,\r\n });\r\n } catch {\r\n // Unload path — nothing sensible left to do.\r\n }\r\n }\r\n\r\n /**\r\n * Get queue size\r\n */\r\n getQueueSize(): number {\r\n return this.eventQueue.length;\r\n }\r\n\r\n /**\r\n * Flush queue immediately\r\n */\r\n async flush(): Promise<void> {\r\n await this.sendBatch();\r\n }\r\n\r\n /**\r\n * Clear all pending events\r\n */\r\n clear(): void {\r\n this.eventQueue = [];\r\n \r\n // Clear debounce timers\r\n this.debounceTimers.forEach((timer) => {\r\n window.clearTimeout(timer);\r\n });\r\n this.debounceTimers.clear();\r\n }\r\n\r\n /**\r\n * Cleanup\r\n */\r\n destroy(): void {\r\n // Flush remaining events\r\n this.flush();\r\n \r\n // Clear queue\r\n this.clear();\r\n \r\n // Complete subjects\r\n this.eventSubject.complete();\r\n this.batchTrigger.complete();\r\n }\r\n}\r\n","/**\r\n * Paywall evaluator — the one place that answers\r\n * \"can this reader see this panel, given these rules?\".\r\n *\r\n * Pure and dependency-free (no Angular, no RxJS) so it can be unit-tested in\r\n * isolation and reused outside the player.\r\n *\r\n * PARITY NOTE: the CMS carries a copy at\r\n * `panelwave-cms/apps/cms-frontend/src/app/core/entitlement/paywall-evaluator.ts`,\r\n * where it drives the paywall content map and the entitlement simulator. This\r\n * module is the canonical version — the CMS copy should be replaced by an\r\n * import from `@panelwave/player` once the CMS consumes the player package\r\n * (it does not today). Until then, any semantic change must land in BOTH, or\r\n * an author will see one thing in the CMS preview and readers another.\r\n *\r\n * Semantics:\r\n * - Only ACTIVE rules participate. A manifest only ever carries active rules\r\n * (the CMS filters on `is_active` at export), so every rule read from a\r\n * manifest is active by definition.\r\n * - The first active work/global rule gates the whole work; panels whose\r\n * global reading-order index < `previewPanelCount` stay readable as the\r\n * free preview.\r\n * - Panel-scoped rules gate exactly their `targetPanelIds` — preview does NOT\r\n * override an explicit panel gate.\r\n * - A gated panel unlocks when the gating rule's requirement is satisfied by\r\n * the reader's entitlement snapshot.\r\n */\r\n\r\nimport type { PanelWaveManifest, PaywallRule as ManifestPaywallRule } from '../types/manifest.types';\r\n\r\nexport type EvaluatorEntitlementType = 'free' | 'subscription' | 'purchase' | 'age_gate';\r\nexport type EvaluatorScope = 'global' | 'work' | 'chapter' | 'panel';\r\n\r\n/** The rule shape the evaluator needs (a superset of the manifest rule). */\r\nexport interface EvaluatorRule {\r\n id: string;\r\n scope: EvaluatorScope;\r\n entitlementType: EvaluatorEntitlementType;\r\n isActive: boolean;\r\n /** Tiers that satisfy a subscription rule; empty/absent = any tier. */\r\n subscriptionTiers?: string[];\r\n /** Products that satisfy a purchase rule; empty/absent = any purchase. */\r\n requiredProductIds?: string[];\r\n /** Minimum age for an age_gate rule (default 18). */\r\n minimumAge?: number;\r\n /** Free-preview length for work/global rules (panels in reading order). */\r\n previewPanelCount?: number;\r\n /** Panels gated by a panel-scoped rule. */\r\n targetPanelIds?: string[];\r\n}\r\n\r\n/** What the reader \"has\" — the shape payments produce and the player consumes. */\r\nexport interface EntitlementSnapshot {\r\n /** Active subscription tier, or null when not subscribed. */\r\n subscriptionTier: string | null;\r\n purchasedProductIds: string[];\r\n age?: number;\r\n ageVerified: boolean;\r\n}\r\n\r\n/** A panel to evaluate: id + its global reading-order index. */\r\nexport interface PanelRef {\r\n id: string;\r\n index: number;\r\n}\r\n\r\nexport type LockReason =\r\n | 'subscription_required'\r\n | 'purchase_required'\r\n | 'age_verification_required'\r\n | null;\r\n\r\nexport interface AccessDecision {\r\n panelId: string;\r\n locked: boolean;\r\n /** Why it is locked (null when accessible). */\r\n reason: LockReason;\r\n /** The rule that decided (also set for preview/unlocked-by-entitlement). */\r\n appliedRuleId: string | null;\r\n /** True when access exists only because the panel is inside the free preview. */\r\n preview: boolean;\r\n}\r\n\r\nconst DEFAULT_MINIMUM_AGE = 18;\r\n\r\n/** Does the reader's snapshot satisfy this rule's requirement? */\r\nexport function satisfiesRule(rule: EvaluatorRule, entitlement: EntitlementSnapshot): boolean {\r\n switch (rule.entitlementType) {\r\n case 'free':\r\n return true;\r\n case 'subscription': {\r\n if (!entitlement.subscriptionTier) return false;\r\n const tiers = rule.subscriptionTiers ?? [];\r\n return tiers.length === 0 || tiers.includes(entitlement.subscriptionTier);\r\n }\r\n case 'purchase': {\r\n const required = rule.requiredProductIds ?? [];\r\n if (required.length === 0) return entitlement.purchasedProductIds.length > 0;\r\n return required.some((id) => entitlement.purchasedProductIds.includes(id));\r\n }\r\n case 'age_gate': {\r\n const min = rule.minimumAge ?? DEFAULT_MINIMUM_AGE;\r\n return entitlement.ageVerified && (entitlement.age ?? 0) >= min;\r\n }\r\n }\r\n}\r\n\r\nfunction lockReasonFor(rule: EvaluatorRule): LockReason {\r\n switch (rule.entitlementType) {\r\n case 'subscription':\r\n return 'subscription_required';\r\n case 'purchase':\r\n return 'purchase_required';\r\n case 'age_gate':\r\n return 'age_verification_required';\r\n case 'free':\r\n return null;\r\n }\r\n}\r\n\r\n/** The active work/global rule (first one wins — mirrors the CMS content map). */\r\nexport function findWorkGateRule(rules: EvaluatorRule[]): EvaluatorRule | null {\r\n return rules.find((r) => r.isActive && (r.scope === 'work' || r.scope === 'global')) ?? null;\r\n}\r\n\r\n/**\r\n * Evaluate one panel against the rules for a given reader snapshot.\r\n */\r\nexport function evaluatePanelAccess(\r\n rules: EvaluatorRule[],\r\n entitlement: EntitlementSnapshot,\r\n panel: PanelRef,\r\n): AccessDecision {\r\n const active = rules.filter((r) => r.isActive);\r\n\r\n // 1. Explicit panel gates take precedence (preview never overrides them).\r\n const panelRule = active.find(\r\n (r) => r.scope === 'panel' && (r.targetPanelIds ?? []).includes(panel.id),\r\n );\r\n if (panelRule) {\r\n const ok = satisfiesRule(panelRule, entitlement);\r\n return {\r\n panelId: panel.id,\r\n locked: !ok,\r\n reason: ok ? null : lockReasonFor(panelRule),\r\n appliedRuleId: panelRule.id,\r\n preview: false,\r\n };\r\n }\r\n\r\n // 2. Work/global gate with free preview.\r\n const workRule = findWorkGateRule(active);\r\n if (workRule) {\r\n const previewCount = workRule.previewPanelCount ?? 0;\r\n if (panel.index < previewCount) {\r\n return {\r\n panelId: panel.id,\r\n locked: false,\r\n reason: null,\r\n appliedRuleId: workRule.id,\r\n preview: true,\r\n };\r\n }\r\n const ok = satisfiesRule(workRule, entitlement);\r\n return {\r\n panelId: panel.id,\r\n locked: !ok,\r\n reason: ok ? null : lockReasonFor(workRule),\r\n appliedRuleId: workRule.id,\r\n preview: false,\r\n };\r\n }\r\n\r\n // 3. No gate at all — free content.\r\n return { panelId: panel.id, locked: false, reason: null, appliedRuleId: null, preview: false };\r\n}\r\n\r\n/** Evaluate a whole work (panels in reading order). */\r\nexport function evaluateWorkAccess(\r\n rules: EvaluatorRule[],\r\n entitlement: EntitlementSnapshot,\r\n panels: PanelRef[],\r\n): AccessDecision[] {\r\n return panels.map((panel) => evaluatePanelAccess(rules, entitlement, panel));\r\n}\r\n\r\n/** A snapshot with no entitlements — what an anonymous first-time reader has. */\r\nexport const ANONYMOUS_READER: EntitlementSnapshot = Object.freeze({\r\n subscriptionTier: null,\r\n purchasedProductIds: [],\r\n ageVerified: false,\r\n});\r\n\r\n// ── Manifest bridge ────────────────────────────────────────────────────────\r\n\r\nconst KNOWN_ENTITLEMENT_TYPES: EvaluatorEntitlementType[] = [\r\n 'free',\r\n 'subscription',\r\n 'purchase',\r\n 'age_gate',\r\n];\r\n\r\n/**\r\n * Normalise one manifest rule onto the evaluator's shape.\r\n *\r\n * The manifest carries two generations of field names side by side (the\r\n * schema allows both): `requireEntitlement` / `previewPanels` / `ageGate` from\r\n * the original format, and `entitlementType` / `previewPanelCount` /\r\n * `minimumAge` written by the CMS exporter. Prefer the CMS names and fall\r\n * back to the originals, so a manifest from either era gates identically.\r\n *\r\n * A rule with `minimumAge`/`ageGate` but no recognised entitlement type is an\r\n * age gate — that is the only sane reading of a rule that names an age.\r\n */\r\nexport function fromManifestRule(rule: ManifestPaywallRule, index: number): EvaluatorRule {\r\n const raw = rule as ManifestPaywallRule & Record<string, unknown>;\r\n\r\n const declared = (raw['entitlementType'] ?? raw['requireEntitlement']) as string | undefined;\r\n const minimumAge = (raw['minimumAge'] ?? raw['ageGate']) as number | undefined;\r\n\r\n let entitlementType: EvaluatorEntitlementType;\r\n if (declared && KNOWN_ENTITLEMENT_TYPES.includes(declared as EvaluatorEntitlementType)) {\r\n entitlementType = declared as EvaluatorEntitlementType;\r\n } else if (minimumAge !== undefined) {\r\n entitlementType = 'age_gate';\r\n } else if (declared === 'premium') {\r\n // Original format's subscription marker.\r\n entitlementType = 'subscription';\r\n } else if (declared) {\r\n // 'token', 'purchaseId', or any custom marker: treat as a purchase gate.\r\n entitlementType = 'purchase';\r\n } else {\r\n entitlementType = 'free';\r\n }\r\n\r\n const scope = (raw['scope'] as string) === 'extras' ? 'work' : (raw['scope'] as EvaluatorScope);\r\n\r\n return {\r\n id: (raw['id'] as string) ?? `rule-${index}`,\r\n scope: scope ?? 'work',\r\n entitlementType,\r\n // A manifest only carries rules the CMS already filtered to active.\r\n isActive: true,\r\n subscriptionTiers: raw['subscriptionTiers'] as string[] | undefined,\r\n requiredProductIds: raw['requiredProductIds'] as string[] | undefined,\r\n minimumAge,\r\n previewPanelCount: (raw['previewPanelCount'] ?? raw['previewPanels']) as number | undefined,\r\n targetPanelIds: (raw['targetPanelIds'] as string[] | undefined) ??\r\n // A panel-scoped rule from the original format names its single target\r\n // in refId rather than a list.\r\n ((raw['scope'] as string) === 'panel' && raw['refId']\r\n ? [raw['refId'] as string]\r\n : undefined),\r\n };\r\n}\r\n\r\n/** Normalise every rule in a manifest. Returns [] when the work has no paywall. */\r\nexport function rulesFromManifest(manifest: PanelWaveManifest | null): EvaluatorRule[] {\r\n const rules = manifest?.paywall?.rules;\r\n if (!rules?.length) return [];\r\n return rules.map(fromManifestRule);\r\n}\r\n\r\n/**\r\n * Global reading order for preview counting: chapters in array order, and\r\n * within a chapter the panel declaration order.\r\n *\r\n * That declaration order IS the reading order as the CMS exports it, and it is\r\n * the same order the author saw when they chose a preview length — which is\r\n * what makes \"the first N panels are free\" mean the same thing on both sides.\r\n */\r\nexport function readingOrderFromManifest(manifest: PanelWaveManifest | null): string[] {\r\n if (!manifest?.chapters?.length) return [];\r\n const order: string[] = [];\r\n for (const chapter of manifest.chapters) {\r\n for (const panelId of Object.keys(chapter.panels ?? {})) {\r\n order.push(panelId);\r\n }\r\n }\r\n return order;\r\n}\r\n\r\n/**\r\n * Map a decision onto the player's `EntitlementStatus` contract.\r\n */\r\nexport function toEntitlementStatus(\r\n decision: AccessDecision,\r\n entitlement: EntitlementSnapshot,\r\n): { ok: boolean; entitlements: Record<string, boolean>; reason?: string } {\r\n return {\r\n ok: !decision.locked,\r\n entitlements: {\r\n subscription: entitlement.subscriptionTier !== null,\r\n purchased: entitlement.purchasedProductIds.length > 0,\r\n ageVerified: entitlement.ageVerified,\r\n preview: decision.preview,\r\n },\r\n ...(decision.locked && decision.reason ? { reason: decision.reason } : {}),\r\n };\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nimport type { PanelWaveManifest } from '../types/manifest.types';\r\nimport type { PaywallGate } from '../types/entitlement.types';\r\nimport {\r\n ANONYMOUS_READER,\r\n evaluatePanelAccess,\r\n readingOrderFromManifest,\r\n rulesFromManifest,\r\n type AccessDecision,\r\n type EntitlementSnapshot,\r\n type EvaluatorRule,\r\n type LockReason,\r\n} from '../entitlement/paywall-evaluator';\r\n\r\n/**\r\n * Paywall service — decides whether the reader may see a panel, and describes\r\n * the gate when they may not.\r\n *\r\n * Before this existed the player had all the paywall parts and no wiring:\r\n * `PlayerStateService.showPaywallGate()` was never called, the overlay was\r\n * never rendered, and the manifest's `paywall.rules` were never read. Reaching\r\n * gated content simply threw a navigation error.\r\n *\r\n * Deliberately synchronous. Rules come from the manifest the reader already\r\n * downloaded and the snapshot is fetched once, so a panel turn never waits on\r\n * the network — which is what makes gating usable at reading speed.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class PaywallService {\r\n private rules: EvaluatorRule[] = [];\r\n private readingOrder = new Map<string, number>();\r\n private manifest: PanelWaveManifest | null = null;\r\n\r\n private snapshotSubject = new BehaviorSubject<EntitlementSnapshot>(ANONYMOUS_READER);\r\n readonly snapshot$: Observable<EntitlementSnapshot> = this.snapshotSubject.asObservable();\r\n\r\n /** Load the rules and reading order from a manifest. Safe to call repeatedly. */\r\n setManifest(manifest: PanelWaveManifest | null): void {\r\n this.manifest = manifest;\r\n this.rules = rulesFromManifest(manifest);\r\n this.readingOrder = new Map(\r\n readingOrderFromManifest(manifest).map((panelId, index) => [panelId, index]),\r\n );\r\n }\r\n\r\n /** Replace what the reader owns (after sign-in, or a completed purchase). */\r\n setSnapshot(snapshot: EntitlementSnapshot | null | undefined): void {\r\n this.snapshotSubject.next(snapshot ?? ANONYMOUS_READER);\r\n }\r\n\r\n getSnapshot(): EntitlementSnapshot {\r\n return this.snapshotSubject.value;\r\n }\r\n\r\n /** True when the work carries no paywall rules at all. */\r\n get isFreeWork(): boolean {\r\n return this.rules.length === 0;\r\n }\r\n\r\n /** Reading-order index used for preview counting, or -1 when unknown. */\r\n indexOf(panelId: string): number {\r\n return this.readingOrder.get(panelId) ?? -1;\r\n }\r\n\r\n /**\r\n * Decide access for one panel.\r\n *\r\n * An unknown panel id gets `MAX_SAFE_INTEGER` as its index so it falls\r\n * OUTSIDE any free preview: a panel the reading order does not know about\r\n * must not be handed out as a free sample.\r\n */\r\n evaluate(panelId: string): AccessDecision {\r\n if (this.rules.length === 0) {\r\n return { panelId, locked: false, reason: null, appliedRuleId: null, preview: false };\r\n }\r\n const index = this.readingOrder.get(panelId) ?? Number.MAX_SAFE_INTEGER;\r\n return evaluatePanelAccess(this.rules, this.snapshotSubject.value, { id: panelId, index });\r\n }\r\n\r\n /** Convenience: may the reader open this panel? */\r\n canAccess(panelId: string): boolean {\r\n return !this.evaluate(panelId).locked;\r\n }\r\n\r\n /**\r\n * Describe the gate blocking a panel, or null when it is not gated.\r\n * The shape is the player's existing `PaywallGate`, so the overlay needs\r\n * no changes to render it.\r\n */\r\n gateFor(panelId: string): PaywallGate | null {\r\n const decision = this.evaluate(panelId);\r\n if (!decision.locked) return null;\r\n\r\n const rule = this.rules.find((r) => r.id === decision.appliedRuleId);\r\n const scope: PaywallGate['scope'] =\r\n rule?.scope === 'panel' ? 'panel' : rule?.scope === 'chapter' ? 'chapter' : 'work';\r\n\r\n return {\r\n scope,\r\n refId: rule?.scope === 'panel' ? panelId : undefined,\r\n requireEntitlement: rule?.entitlementType,\r\n reason: PaywallService.readerMessage(decision.reason),\r\n preview: rule?.previewPanelCount\r\n ? { previewPanels: rule.previewPanelCount }\r\n : undefined,\r\n };\r\n }\r\n\r\n /** The rule that gates a panel, for callers that need its price or name. */\r\n ruleFor(panelId: string): EvaluatorRule | null {\r\n const decision = this.evaluate(panelId);\r\n if (!decision.appliedRuleId) return null;\r\n return this.rules.find((r) => r.id === decision.appliedRuleId) ?? null;\r\n }\r\n\r\n /** Reset to a manifest-less, entitlement-less state. */\r\n clear(): void {\r\n this.manifest = null;\r\n this.rules = [];\r\n this.readingOrder.clear();\r\n this.snapshotSubject.next(ANONYMOUS_READER);\r\n }\r\n\r\n /**\r\n * Reader-facing wording for a lock reason. Kept here rather than in the\r\n * overlay so the same sentence is used wherever a gate is explained.\r\n */\r\n static readerMessage(reason: LockReason): string {\r\n switch (reason) {\r\n case 'subscription_required':\r\n return 'This part of the story is included with a subscription.';\r\n case 'purchase_required':\r\n return 'This part of the story is available to buy.';\r\n case 'age_verification_required':\r\n return 'This content is age-restricted. Confirm your age to continue.';\r\n default:\r\n return 'This content requires an entitlement to access.';\r\n }\r\n }\r\n}\r\n","/**\r\n * HTTP entitlement adapter — the real one.\r\n *\r\n * Until now the player shipped only `NullEntitlementAdapter` (denies\r\n * everything) and `MockEntitlementAdapter` (grants everything), so nothing\r\n * ever gated on an actual purchase. This adapter fetches the reader's\r\n * entitlement snapshot from a backend and evaluates the manifest's paywall\r\n * rules against it locally.\r\n *\r\n * Why evaluate locally rather than asking the server per panel:\r\n * - the rules are already in the manifest the reader downloaded, so a\r\n * round-trip per panel would tell the client something it can compute;\r\n * - navigation must not stall on the network at every panel turn;\r\n * - the snapshot is the only thing that needs to be authoritative, and it\r\n * is fetched once and cached.\r\n *\r\n * This is NOT a security boundary. A determined reader can edit client state,\r\n * so anything that must not leak — full-resolution art, downloads — has to be\r\n * served through signed URLs the backend only issues to an entitled reader.\r\n * `getSignedUrl` is the hook for exactly that.\r\n */\r\n\r\nimport type {\r\n EntitlementAdapter,\r\n EntitlementContext,\r\n EntitlementStatus,\r\n UserInfo,\r\n} from '../types/entitlement.types';\r\nimport type { PanelWaveManifest } from '../types/manifest.types';\r\nimport {\r\n ANONYMOUS_READER,\r\n evaluatePanelAccess,\r\n readingOrderFromManifest,\r\n rulesFromManifest,\r\n toEntitlementStatus,\r\n type EntitlementSnapshot,\r\n type EvaluatorRule,\r\n} from './paywall-evaluator';\r\n\r\n/** Wire shape of the snapshot endpoint. */\r\nexport interface EntitlementSnapshotResponse {\r\n ok: boolean;\r\n data?: {\r\n subscriptionTier: string | null;\r\n purchasedProductIds: string[];\r\n age?: number;\r\n ageVerified: boolean;\r\n user?: UserInfo;\r\n };\r\n}\r\n\r\nexport interface HttpEntitlementAdapterConfig {\r\n /**\r\n * Endpoint returning the reader's snapshot for a work. `{workId}` is\r\n * substituted, e.g. `https://api.panelwave.org/public/works/{workId}/entitlement`.\r\n */\r\n endpoint: string;\r\n\r\n /** Bearer token for an identified reader. Omit for anonymous readers. */\r\n readerToken?: string;\r\n\r\n /** Endpoint that mints a signed URL for a gated asset (optional). */\r\n signedUrlEndpoint?: string;\r\n\r\n /** How long a fetched snapshot stays fresh. Default 5 minutes. */\r\n ttlMs?: number;\r\n\r\n /** Injected for tests; defaults to global fetch. */\r\n fetchImpl?: typeof fetch;\r\n}\r\n\r\nconst DEFAULT_TTL_MS = 5 * 60 * 1000;\r\n\r\nexport class HttpEntitlementAdapter implements EntitlementAdapter {\r\n private manifest: PanelWaveManifest | null = null;\r\n private rules: EvaluatorRule[] = [];\r\n private readingOrder = new Map<string, number>();\r\n\r\n private snapshot: EntitlementSnapshot = ANONYMOUS_READER;\r\n private user: UserInfo | null = null;\r\n private snapshotFetchedAt = 0;\r\n private inFlight: Promise<void> | null = null;\r\n\r\n constructor(private config: HttpEntitlementAdapterConfig) {}\r\n\r\n /**\r\n * Give the adapter the manifest whose rules it should evaluate. The player\r\n * shell calls this once the manifest is loaded; without it every panel\r\n * evaluates as ungated, which is the correct failure direction for a work\r\n * that has no paywall at all.\r\n */\r\n setManifest(manifest: PanelWaveManifest | null): void {\r\n this.manifest = manifest;\r\n this.rules = rulesFromManifest(manifest);\r\n this.readingOrder = new Map(\r\n readingOrderFromManifest(manifest).map((panelId, index) => [panelId, index]),\r\n );\r\n }\r\n\r\n /** Swap the reader token (sign-in / sign-out) and drop the cached snapshot. */\r\n setReaderToken(token: string | undefined): void {\r\n this.config = { ...this.config, readerToken: token };\r\n this.invalidate();\r\n }\r\n\r\n /** Force the next check to refetch — call after a completed purchase. */\r\n invalidate(): void {\r\n this.snapshotFetchedAt = 0;\r\n this.snapshot = ANONYMOUS_READER;\r\n this.user = null;\r\n }\r\n\r\n /** The snapshot currently in hand (may be stale/anonymous). */\r\n getSnapshot(): EntitlementSnapshot {\r\n return this.snapshot;\r\n }\r\n\r\n async resolveEntitlement(context: EntitlementContext): Promise<EntitlementStatus> {\r\n await this.ensureSnapshot(context.workId);\r\n\r\n // No paywall on this work: everything is readable.\r\n if (this.rules.length === 0) {\r\n return { ok: true, entitlements: {}, ...(this.user ? { user: this.user } : {}) };\r\n }\r\n\r\n // A work-level check with no panel: gate only if the reader fails the\r\n // work rule outright. Preview panels are a per-panel concern.\r\n const panelId = context.panelId ?? '';\r\n const index = this.readingOrder.get(panelId) ?? Number.MAX_SAFE_INTEGER;\r\n\r\n const decision = evaluatePanelAccess(this.rules, this.snapshot, { id: panelId, index });\r\n const status = toEntitlementStatus(decision, this.snapshot);\r\n\r\n return {\r\n ...status,\r\n ...(this.user ? { user: this.user } : {}),\r\n ...(this.config.ttlMs !== 0\r\n ? { expiresAt: this.snapshotFetchedAt + (this.config.ttlMs ?? DEFAULT_TTL_MS) }\r\n : {}),\r\n };\r\n }\r\n\r\n async getSignedUrl(assetId: string, purpose: 'stream' | 'download' = 'stream'): Promise<string> {\r\n if (!this.config.signedUrlEndpoint) return assetId;\r\n try {\r\n const res = await this.fetchImpl()(\r\n `${this.config.signedUrlEndpoint}?assetId=${encodeURIComponent(assetId)}&purpose=${purpose}`,\r\n { headers: this.headers() },\r\n );\r\n if (!res.ok) return assetId;\r\n const body = (await res.json()) as { ok?: boolean; data?: { url?: string } };\r\n return body?.data?.url ?? assetId;\r\n } catch {\r\n // Falling back to the raw id keeps ungated art rendering when the\r\n // signing service is down, rather than blanking the page.\r\n return assetId;\r\n }\r\n }\r\n\r\n isAuthenticated(): boolean {\r\n return !!this.config.readerToken;\r\n }\r\n\r\n async getCurrentUser(): Promise<UserInfo | null> {\r\n return this.user;\r\n }\r\n\r\n async verifyAge(minimumAge: number): Promise<boolean> {\r\n return this.snapshot.ageVerified && (this.snapshot.age ?? 0) >= minimumAge;\r\n }\r\n\r\n // ── internals ────────────────────────────────────────────────────────────\r\n\r\n private fetchImpl(): typeof fetch {\r\n return this.config.fetchImpl ?? fetch;\r\n }\r\n\r\n private headers(): Record<string, string> {\r\n const h: Record<string, string> = { Accept: 'application/json' };\r\n if (this.config.readerToken) h['Authorization'] = `Bearer ${this.config.readerToken}`;\r\n return h;\r\n }\r\n\r\n /** Fetch once, share the promise, and respect the TTL. */\r\n private async ensureSnapshot(workId: string): Promise<void> {\r\n const ttl = this.config.ttlMs ?? DEFAULT_TTL_MS;\r\n if (this.snapshotFetchedAt && Date.now() - this.snapshotFetchedAt < ttl) return;\r\n if (this.inFlight) return this.inFlight;\r\n\r\n this.inFlight = this.fetchSnapshot(workId).finally(() => {\r\n this.inFlight = null;\r\n });\r\n return this.inFlight;\r\n }\r\n\r\n private async fetchSnapshot(workId: string): Promise<void> {\r\n const url = this.config.endpoint.replace('{workId}', encodeURIComponent(workId));\r\n try {\r\n const res = await this.fetchImpl()(url, { headers: this.headers() });\r\n if (!res.ok) {\r\n // Treat any backend failure as \"no entitlements\" rather than as\r\n // access: failing open would give away paid content on an outage.\r\n this.snapshot = ANONYMOUS_READER;\r\n this.user = null;\r\n this.snapshotFetchedAt = Date.now();\r\n return;\r\n }\r\n const body = (await res.json()) as EntitlementSnapshotResponse;\r\n const data = body?.data;\r\n this.snapshot = data\r\n ? {\r\n subscriptionTier: data.subscriptionTier ?? null,\r\n purchasedProductIds: data.purchasedProductIds ?? [],\r\n age: data.age,\r\n ageVerified: !!data.ageVerified,\r\n }\r\n : ANONYMOUS_READER;\r\n this.user = data?.user ?? null;\r\n this.snapshotFetchedAt = Date.now();\r\n } catch {\r\n this.snapshot = ANONYMOUS_READER;\r\n this.user = null;\r\n this.snapshotFetchedAt = Date.now();\r\n }\r\n }\r\n}\r\n","/**\n * Plugin Host Service\n * Manages plugin lifecycle, communication, and sandboxing\n */\n\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport type {\n PluginManifest,\n PluginInstance,\n PluginState,\n PluginMessage,\n PluginMessageType,\n PluginConfig,\n PluginCapability,\n PluginPermissionRequest,\n PluginAPICall,\n} from '../types/plugin.types';\n\n/** Origin used by browsers for opaque (e.g. sandboxed) documents. */\nconst OPAQUE_ORIGIN = 'null';\n\n/** Messaging channel of a plugin iframe (internal). */\ninterface PluginChannel {\n /** Origin the plugin document runs in; OPAQUE_ORIGIN when opaque. */\n origin: string;\n /** Origins accepted on incoming messages from this plugin. */\n acceptedOrigins: Set<string>;\n}\n\n/**\n * Plugin Host Service\n * Central service for managing plugins\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class PluginHostService {\n /**\n * Registered plugins\n */\n private plugins = new Map<string, PluginInstance>();\n\n /**\n * Plugin configurations\n */\n private config: PluginConfig = {\n enabled: true,\n maxPlugins: 10,\n loadTimeout: 10000,\n sandboxAttributes: [\n 'allow-scripts',\n // Lets a CROSS-origin plugin keep its real origin (storage, fetch with\n // credentials). It is stripped automatically for plugins served from the\n // host's own origin, where it would cancel the sandbox (see\n // createPluginIframe). postMessage works without it.\n 'allow-same-origin',\n ],\n autoGrantCapabilities: ['read-manifest', 'read-state'],\n };\n\n /**\n * Plugins observable\n */\n private plugins$ = new BehaviorSubject<Map<string, PluginInstance>>(\n new Map()\n );\n\n /**\n * Permission requests\n */\n private permissionRequests$ = new Subject<PluginPermissionRequest>();\n\n /**\n * Pending lifecycle waits (plugin:ready / plugin:mounted), keyed per plugin\n * AND message type so concurrent mounts never clobber each other.\n */\n private lifecycleWaiters = new Map<string, () => void>();\n\n /**\n * Channel info of each plugin whose iframe exists: the origin its document\n * runs in ('null' when opaque) and the set of origins accepted for incoming\n * messages.\n */\n private pluginChannels = new Map<string, PluginChannel>();\n\n /**\n * API method handlers\n */\n private apiHandlers = new Map<string, (...args: unknown[]) => Promise<unknown>>();\n\n /**\n * Event subscriptions\n */\n private eventSubscriptions = new Map<string, Set<string>>(); // eventType -> pluginIds\n\n /**\n * Initialize service\n */\n constructor() {\n this.setupMessageListener();\n this.registerDefaultAPIHandlers();\n }\n\n /**\n * Configure plugin system\n */\n configure(config: Partial<PluginConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Get configuration\n */\n getConfig(): PluginConfig {\n return { ...this.config };\n }\n\n /**\n * Load a plugin\n */\n async loadPlugin(manifest: PluginManifest): Promise<void> {\n if (!this.config.enabled) {\n throw new Error('Plugin system is disabled');\n }\n\n const existing = manifest.id ? this.plugins.get(manifest.id) : undefined;\n if (existing) {\n if (existing.state !== 'error') {\n throw new Error(`Plugin ${manifest.id} is already loaded`);\n }\n // A previous load/mount failed: drop the stale record so it can be retried.\n this.removePluginRecord(manifest.id, existing);\n }\n\n if (\n this.config.maxPlugins &&\n this.plugins.size >= this.config.maxPlugins\n ) {\n throw new Error('Maximum number of plugins reached');\n }\n\n // Validate manifest\n this.validateManifest(manifest);\n\n // Create plugin instance\n const instance: PluginInstance = {\n manifest,\n state: 'loading',\n iframe: null,\n grantedCapabilities: [],\n deniedCapabilities: [],\n };\n\n this.plugins.set(manifest.id, instance);\n this.emitPluginsUpdate();\n\n try {\n // Request required capabilities\n await this.requestCapabilities(\n manifest.id,\n manifest.capabilities,\n true\n );\n\n // Request optional capabilities\n if (manifest.optionalCapabilities) {\n await this.requestCapabilities(\n manifest.id,\n manifest.optionalCapabilities,\n false\n );\n }\n\n // Update state\n this.updatePluginState(manifest.id, 'loaded');\n } catch (error) {\n this.handlePluginError(manifest.id, error as Error);\n throw error;\n }\n }\n\n /**\n * Mount a plugin\n */\n async mountPlugin(\n pluginId: string,\n container: HTMLElement\n ): Promise<void> {\n const instance = this.plugins.get(pluginId);\n if (!instance) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n if (instance.state !== 'loaded') {\n throw new Error(`Plugin ${pluginId} is not in loaded state`);\n }\n\n this.updatePluginState(pluginId, 'mounting');\n\n try {\n // Create iframe sandbox\n const iframe = this.createPluginIframe(instance);\n container.appendChild(iframe);\n instance.iframe = iframe;\n\n // Wait for plugin to be ready\n await this.waitForPluginReady(pluginId);\n\n // Send mount message\n await this.sendPluginMessage(pluginId, {\n type: 'plugin:mount',\n pluginId,\n payload: {\n context: this.getPluginContext(instance),\n },\n });\n\n // Wait for mounted confirmation\n await this.waitForPluginMounted(pluginId);\n\n instance.mountedAt = new Date();\n this.updatePluginState(pluginId, 'mounted');\n } catch (error) {\n this.handlePluginError(pluginId, error as Error);\n throw error;\n }\n }\n\n /**\n * Update a plugin with new data\n */\n async updatePlugin(pluginId: string, data: unknown): Promise<void> {\n const instance = this.plugins.get(pluginId);\n if (!instance || instance.state !== 'mounted') {\n return;\n }\n\n this.updatePluginState(pluginId, 'updating');\n\n try {\n await this.sendPluginMessage(pluginId, {\n type: 'plugin:update',\n pluginId,\n payload: data,\n });\n\n this.updatePluginState(pluginId, 'mounted');\n } catch (error) {\n this.handlePluginError(pluginId, error as Error);\n }\n }\n\n /**\n * Unmount a plugin\n */\n async unmountPlugin(pluginId: string): Promise<void> {\n const instance = this.plugins.get(pluginId);\n if (!instance || instance.state !== 'mounted') {\n return;\n }\n\n this.updatePluginState(pluginId, 'unmounting');\n\n try {\n // Send unmount message\n await this.sendPluginMessage(pluginId, {\n type: 'plugin:unmount',\n pluginId,\n });\n\n // Remove iframe\n if (instance.iframe) {\n instance.iframe.remove();\n instance.iframe = null;\n }\n this.pluginChannels.delete(pluginId);\n\n // Clean up event subscriptions\n this.cleanupEventSubscriptions(pluginId);\n\n this.updatePluginState(pluginId, 'loaded');\n } catch (error) {\n this.handlePluginError(pluginId, error as Error);\n }\n }\n\n /**\n * Dispose a plugin completely\n */\n async disposePlugin(pluginId: string): Promise<void> {\n const instance = this.plugins.get(pluginId);\n if (!instance) {\n return;\n }\n\n // Unmount if mounted\n if (instance.state === 'mounted') {\n await this.unmountPlugin(pluginId);\n }\n\n // Send dispose message\n try {\n await this.sendPluginMessage(pluginId, {\n type: 'plugin:dispose',\n pluginId,\n });\n } catch {\n // Ignore errors during disposal\n }\n\n // Remove iframe, subscriptions and the registry entry\n this.removePluginRecord(pluginId, instance);\n }\n\n /**\n * Remove a plugin's iframe, messaging channel, event subscriptions and\n * registry entry.\n */\n private removePluginRecord(pluginId: string, instance: PluginInstance): void {\n if (instance.iframe) {\n instance.iframe.remove();\n instance.iframe = null;\n }\n this.pluginChannels.delete(pluginId);\n this.cleanupEventSubscriptions(pluginId);\n this.plugins.delete(pluginId);\n this.emitPluginsUpdate();\n }\n\n /**\n * Get all plugins\n */\n getPlugins(): Map<string, PluginInstance> {\n return new Map(this.plugins);\n }\n\n /**\n * Get plugins observable\n */\n getPlugins$(): Observable<Map<string, PluginInstance>> {\n return this.plugins$.asObservable();\n }\n\n /**\n * Get plugin by ID\n */\n getPlugin(pluginId: string): PluginInstance | undefined {\n return this.plugins.get(pluginId);\n }\n\n /**\n * Get permission requests observable\n */\n getPermissionRequests$(): Observable<PluginPermissionRequest> {\n return this.permissionRequests$.asObservable();\n }\n\n /**\n * Grant permission\n */\n grantPermission(\n pluginId: string,\n capability: PluginCapability\n ): void {\n const instance = this.plugins.get(pluginId);\n if (!instance) {\n return;\n }\n\n if (!instance.grantedCapabilities.includes(capability)) {\n instance.grantedCapabilities.push(capability);\n }\n\n // Remove from denied if present\n const deniedIndex = instance.deniedCapabilities.indexOf(capability);\n if (deniedIndex > -1) {\n instance.deniedCapabilities.splice(deniedIndex, 1);\n }\n\n this.emitPluginsUpdate();\n }\n\n /**\n * Deny permission\n */\n denyPermission(\n pluginId: string,\n capability: PluginCapability\n ): void {\n const instance = this.plugins.get(pluginId);\n if (!instance) {\n return;\n }\n\n if (!instance.deniedCapabilities.includes(capability)) {\n instance.deniedCapabilities.push(capability);\n }\n\n // Remove from granted if present\n const grantedIndex = instance.grantedCapabilities.indexOf(capability);\n if (grantedIndex > -1) {\n instance.grantedCapabilities.splice(grantedIndex, 1);\n }\n\n this.emitPluginsUpdate();\n }\n\n /**\n * Register API handler\n */\n registerAPIHandler(\n method: string,\n handler: (...args: unknown[]) => Promise<unknown>\n ): void {\n this.apiHandlers.set(method, handler);\n }\n\n /**\n * Unregister API handler\n */\n unregisterAPIHandler(method: string): void {\n this.apiHandlers.delete(method);\n }\n\n /**\n * Emit event to plugins\n */\n emitEventToPlugins(eventType: string, data: unknown): void {\n const subscribedPlugins = this.eventSubscriptions.get(eventType);\n if (!subscribedPlugins) {\n return;\n }\n\n for (const pluginId of subscribedPlugins) {\n this.sendPluginMessage(pluginId, {\n type: 'event:emit',\n pluginId,\n payload: { eventType, data },\n }).catch((error) => {\n console.error(`Failed to emit event to plugin ${pluginId}:`, error);\n });\n }\n }\n\n /**\n * Validate plugin manifest\n */\n private validateManifest(manifest: PluginManifest): void {\n if (!manifest.id || !manifest.name || !manifest.version || !manifest.url) {\n throw new Error('Invalid plugin manifest: missing required fields');\n }\n\n if (!Array.isArray(manifest.capabilities)) {\n throw new Error('Invalid plugin manifest: capabilities must be an array');\n }\n }\n\n /**\n * Request capabilities\n */\n private async requestCapabilities(\n pluginId: string,\n capabilities: PluginCapability[],\n required: boolean\n ): Promise<void> {\n const instance = this.plugins.get(pluginId);\n if (!instance) {\n return;\n }\n\n for (const capability of capabilities) {\n // Check if auto-granted\n if (this.config.autoGrantCapabilities?.includes(capability)) {\n this.grantPermission(pluginId, capability);\n continue;\n }\n\n // Request permission from user\n const request: PluginPermissionRequest = {\n pluginId,\n pluginName: instance.manifest.name,\n capability,\n };\n\n this.permissionRequests$.next(request);\n\n // For now, auto-deny if not auto-granted\n // In production, wait for user response\n if (required) {\n throw new Error(`Required capability ${capability} not granted`);\n }\n }\n }\n\n /**\n * Create plugin iframe\n */\n private createPluginIframe(instance: PluginInstance): HTMLIFrameElement {\n const iframe = document.createElement('iframe');\n const manifest = instance.manifest;\n const urlOrigin = this.resolveUrlOrigin(manifest.url);\n const hostOrigin = window.location.origin;\n\n let sandboxTokens = [...(this.config.sandboxAttributes || [])];\n // SECURITY: a plugin served from the host's own origin with both\n // `allow-scripts` and `allow-same-origin` could reach into the parent\n // document and simply remove its own sandbox. For such plugins we strip\n // `allow-same-origin` so they run in an opaque origin (they keep working,\n // postMessage does not need it). Cross-origin plugins keep the configured\n // tokens unchanged.\n if (urlOrigin === hostOrigin) {\n sandboxTokens = sandboxTokens.filter((token) => token !== 'allow-same-origin');\n }\n\n iframe.src = manifest.url;\n iframe.sandbox.add(...sandboxTokens);\n iframe.style.border = 'none';\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n iframe.setAttribute('data-plugin-id', manifest.id);\n\n // A sandboxed document without `allow-same-origin` has an opaque origin:\n // its messages carry event.origin === 'null' and it can only be addressed\n // with targetOrigin '*'. Its identity is then guaranteed by the\n // event.source check alone (see isTrustedPluginMessage).\n const sandboxed = iframe.hasAttribute('sandbox');\n const opaque = urlOrigin === OPAQUE_ORIGIN || (sandboxed && !iframe.sandbox.contains('allow-same-origin'));\n const origin = opaque ? OPAQUE_ORIGIN : urlOrigin;\n this.pluginChannels.set(manifest.id, {\n origin,\n acceptedOrigins: new Set([\n origin,\n ...(manifest.allowedOrigins || []),\n ...(this.config.allowedOrigins || []),\n ]),\n });\n\n return iframe;\n }\n\n /**\n * Origin a plugin URL's document runs in (before sandboxing).\n * about:/javascript: documents inherit the host origin; data: URLs and\n * unparseable URLs are opaque.\n */\n private resolveUrlOrigin(url: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url, document.baseURI);\n } catch {\n return OPAQUE_ORIGIN;\n }\n if (parsed.protocol === 'about:' || parsed.protocol === 'javascript:') {\n return window.location.origin;\n }\n return parsed.origin;\n }\n\n /**\n * Accept a message only if it comes from the claimed plugin's own iframe\n * window AND from an accepted origin of that plugin.\n */\n private isTrustedPluginMessage(\n event: MessageEvent,\n pluginId: string,\n instance: PluginInstance\n ): boolean {\n const contentWindow = instance.iframe?.contentWindow;\n if (!contentWindow || event.source !== contentWindow) {\n return false;\n }\n const channel = this.pluginChannels.get(pluginId);\n return !!channel && channel.acceptedOrigins.has(event.origin);\n }\n\n /**\n * Get plugin context\n */\n private getPluginContext(instance: PluginInstance): unknown {\n return {\n manifest: instance.manifest,\n capabilities: instance.grantedCapabilities,\n playerVersion: '1.0.0', // TODO: Get from package.json\n sessionId: crypto.randomUUID(),\n };\n }\n\n /**\n * Setup message listener\n */\n private setupMessageListener(): void {\n window.addEventListener('message', (event: MessageEvent) => {\n this.handleMessage(event);\n });\n }\n\n /**\n * Handle incoming message\n */\n private handleMessage(event: MessageEvent): void {\n const message = event.data as PluginMessage;\n\n if (!message || !message.type || !message.pluginId) {\n return;\n }\n\n const instance = this.plugins.get(message.pluginId);\n if (!instance) {\n return;\n }\n\n // Verify sender: must be this plugin's own iframe window and origin.\n // Without this any frame knowing a plugin id could spoof its messages.\n if (!this.isTrustedPluginMessage(event, message.pluginId, instance)) {\n return;\n }\n\n // Resolve a pending lifecycle wait of this plugin\n const waiter = this.lifecycleWaiters.get(this.waiterKey(message.pluginId, message.type));\n if (waiter) {\n waiter();\n }\n\n // Handle API calls (only from active plugins)\n if (message.type === 'api:call') {\n if (instance.state === 'mounted' || instance.state === 'updating') {\n void this.handleAPICall(message);\n }\n }\n\n // Handle event subscriptions (only while mounting or active)\n if (\n message.type === 'event:subscribe' &&\n (instance.state === 'mounting' || instance.state === 'mounted' || instance.state === 'updating')\n ) {\n this.handleEventSubscribe(message);\n }\n\n if (message.type === 'event:unsubscribe') {\n this.handleEventUnsubscribe(message);\n }\n }\n\n /**\n * Handle API call\n */\n private async handleAPICall(message: PluginMessage): Promise<void> {\n const call = (message.payload || {}) as PluginAPICall;\n const handler = this.apiHandlers.get(call.method);\n\n let reply: PluginMessage;\n if (!handler) {\n reply = {\n type: 'api:error',\n pluginId: message.pluginId,\n requestId: message.requestId,\n error: `Unknown API method: ${call.method}`,\n };\n } else {\n try {\n const result = await handler(...(call.params || []));\n reply = {\n type: 'api:response',\n pluginId: message.pluginId,\n requestId: message.requestId,\n payload: { result },\n };\n } catch (error) {\n reply = {\n type: 'api:error',\n pluginId: message.pluginId,\n requestId: message.requestId,\n error: (error as Error).message,\n };\n }\n }\n\n try {\n await this.sendPluginMessage(message.pluginId, reply);\n } catch (error) {\n // The plugin may have been unmounted/disposed while the call ran.\n console.error(`Failed to answer API call of plugin ${message.pluginId}:`, error);\n }\n }\n\n /**\n * Handle event subscribe\n */\n private handleEventSubscribe(message: PluginMessage): void {\n const { eventType } = message.payload as { eventType: string };\n \n if (!this.eventSubscriptions.has(eventType)) {\n this.eventSubscriptions.set(eventType, new Set());\n }\n \n this.eventSubscriptions.get(eventType)!.add(message.pluginId);\n }\n\n /**\n * Handle event unsubscribe\n */\n private handleEventUnsubscribe(message: PluginMessage): void {\n const { eventType } = message.payload as { eventType: string };\n \n const subscribers = this.eventSubscriptions.get(eventType);\n if (subscribers) {\n subscribers.delete(message.pluginId);\n }\n }\n\n /**\n * Clean up event subscriptions for plugin\n */\n private cleanupEventSubscriptions(pluginId: string): void {\n for (const [eventType, subscribers] of this.eventSubscriptions.entries()) {\n subscribers.delete(pluginId);\n if (subscribers.size === 0) {\n this.eventSubscriptions.delete(eventType);\n }\n }\n }\n\n /**\n * Send message to plugin\n */\n private async sendPluginMessage(\n pluginId: string,\n message: PluginMessage\n ): Promise<void> {\n const instance = this.plugins.get(pluginId);\n if (!instance || !instance.iframe) {\n throw new Error(`Cannot send message to plugin ${pluginId}`);\n }\n\n // Target the plugin's own origin; only an opaque-origin (sandboxed)\n // document cannot be addressed by origin and needs '*' — the message still\n // only goes to that plugin's own window.\n const origin = this.pluginChannels.get(pluginId)?.origin ?? OPAQUE_ORIGIN;\n const targetOrigin = origin === OPAQUE_ORIGIN ? '*' : origin;\n instance.iframe.contentWindow?.postMessage(message, targetOrigin);\n }\n\n /**\n * Wait for plugin ready\n */\n private waitForPluginReady(pluginId: string): Promise<void> {\n return this.waitForLifecycleMessage(\n pluginId,\n 'plugin:ready',\n `Plugin ${pluginId} did not become ready in time`\n );\n }\n\n /**\n * Wait for plugin mounted\n */\n private waitForPluginMounted(pluginId: string): Promise<void> {\n return this.waitForLifecycleMessage(\n pluginId,\n 'plugin:mounted',\n `Plugin ${pluginId} did not mount in time`\n );\n }\n\n /**\n * Wait for a lifecycle message of ONE plugin. Waits are keyed per plugin and\n * type, and the entry is removed on success and on timeout.\n */\n private waitForLifecycleMessage(\n pluginId: string,\n type: PluginMessageType,\n timeoutMessage: string\n ): Promise<void> {\n const key = this.waiterKey(pluginId, type);\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n if (this.lifecycleWaiters.get(key) === done) {\n this.lifecycleWaiters.delete(key);\n }\n reject(new Error(timeoutMessage));\n }, this.config.loadTimeout);\n\n const done = (): void => {\n clearTimeout(timeout);\n this.lifecycleWaiters.delete(key);\n resolve();\n };\n\n this.lifecycleWaiters.set(key, done);\n });\n }\n\n private waiterKey(pluginId: string, type: string): string {\n return `${pluginId}\\u0000${type}`;\n }\n\n /**\n * Update plugin state\n */\n private updatePluginState(pluginId: string, state: PluginState): void {\n const instance = this.plugins.get(pluginId);\n if (instance) {\n instance.state = state;\n this.emitPluginsUpdate();\n }\n }\n\n /**\n * Handle plugin error\n */\n private handlePluginError(pluginId: string, error: Error): void {\n const instance = this.plugins.get(pluginId);\n if (instance) {\n instance.state = 'error';\n instance.error = error;\n this.emitPluginsUpdate();\n }\n }\n\n /**\n * Emit plugins update\n */\n private emitPluginsUpdate(): void {\n this.plugins$.next(new Map(this.plugins));\n }\n\n /**\n * Register default API handlers\n */\n private registerDefaultAPIHandlers(): void {\n // These will be implemented by the application\n // Just registering placeholders for now\n this.registerAPIHandler('getManifest', async () => ({}));\n this.registerAPIHandler('getPlayerState', async () => ({}));\n this.registerAPIHandler('getCurrentPanel', async () => ({ chapterId: '', panelId: '' }));\n }\n}\n","/**\n * Export Service\n * Generates EDL, JSON, and other export formats from PanelWave content\n */\n\nimport { Injectable } from '@angular/core';\nimport type {\n ExportOptions,\n ExportResult,\n ExportConfig,\n PanelTiming,\n LayerComposition,\n AudioCue,\n EDLDocument,\n EDLEvent,\n JSONExport,\n} from '../types/export.types';\nimport type { Panel, Layer, Chapter, PanelAudioTrack } from '../types';\n\n/** Per-kind layer fields the exporter reads without narrowing on `kind`. */\ninterface LooseLayerFields {\n type?: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n rotation?: number;\n scaleX?: number;\n scaleY?: number;\n blendMode?: string;\n filters?: string[];\n assetRef?: string;\n}\n\n/**\n * Export Service\n * Handles export to various formats\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ExportService {\n private config: ExportConfig = {\n defaultFramerate: 24,\n defaultTimebase: '24',\n includeComments: true,\n prettifyJSON: true,\n csvDelimiter: ',',\n };\n\n /**\n * Configure export service\n */\n configure(config: Partial<ExportConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Export chapters to specified format\n */\n async exportChapters(\n chapters: Chapter[],\n options: ExportOptions\n ): Promise<ExportResult> {\n try {\n const framerate = options.framerate || this.config.defaultFramerate;\n \n // Calculate timings\n const timings = this.calculatePanelTimings(chapters, framerate);\n \n // Extract layer compositions\n const layers = options.includeLayers\n ? this.extractLayerCompositions(chapters, timings)\n : [];\n \n // Extract audio cues\n const audio = options.includeAudio\n ? this.extractAudioCues(chapters, timings)\n : [];\n \n // Generate export based on format\n let result: ExportResult;\n \n switch (options.format) {\n case 'edl':\n result = this.generateEDL(timings, layers, audio, framerate);\n break;\n case 'json':\n result = this.generateJSON(chapters, timings, layers, audio, options);\n break;\n case 'csv':\n result = this.generateCSV(timings, layers, options);\n break;\n case 'xml':\n result = this.generateXML(timings, layers, audio);\n break;\n default:\n throw new Error(`Unsupported export format: ${options.format}`);\n }\n \n return result;\n } catch (error) {\n return {\n success: false,\n format: options.format,\n data: '',\n filename: '',\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Calculate panel timings\n */\n calculatePanelTimings(\n chapters: Chapter[],\n framerate: number\n ): PanelTiming[] {\n const timings: PanelTiming[] = [];\n let currentTime = 0;\n let globalIndex = 0;\n \n for (const chapter of chapters) {\n const panels = Object.values(chapter.panels || {});\n \n for (const panel of panels) {\n const duration = this.getPanelDuration(panel);\n \n const timing: PanelTiming = {\n panelId: `panel-${globalIndex}`,\n chapterId: chapter.id,\n index: globalIndex,\n startTime: currentTime,\n endTime: currentTime + duration,\n duration,\n startFrame: Math.floor(currentTime * framerate),\n endFrame: Math.floor((currentTime + duration) * framerate),\n frameCount: Math.floor(duration * framerate),\n startTimecode: this.secondsToTimecode(currentTime, framerate),\n endTimecode: this.secondsToTimecode(currentTime + duration, framerate),\n };\n \n timings.push(timing);\n currentTime += duration;\n globalIndex++;\n }\n }\n \n return timings;\n }\n\n /**\n * Extract layer compositions\n */\n extractLayerCompositions(\n chapters: Chapter[],\n timings: PanelTiming[]\n ): LayerComposition[] {\n const compositions: LayerComposition[] = [];\n let timingIndex = 0;\n \n for (const chapter of chapters) {\n const panels = Object.values(chapter.panels || {});\n \n for (const panel of panels) {\n if (panel.layers) {\n for (let i = 0; i < panel.layers.length; i++) {\n const layer = panel.layers[i];\n const composition = this.layerToComposition(\n layer,\n i,\n timings[timingIndex]\n );\n compositions.push(composition);\n }\n }\n timingIndex++;\n }\n }\n \n return compositions;\n }\n\n /**\n * Extract audio cues\n */\n extractAudioCues(\n chapters: Chapter[],\n timings: PanelTiming[]\n ): AudioCue[] {\n const cues: AudioCue[] = [];\n let timingIndex = 0;\n \n for (const chapter of chapters) {\n const panels = Object.values(chapter.panels || {});\n \n for (const panel of panels) {\n const timing = timings[timingIndex];\n \n // Extract audio from panel (assuming audio property exists)\n const panelAudio = panel.audio;\n if (Array.isArray(panelAudio)) {\n for (const audioRef of panelAudio) {\n // Schema tracks carry the asset in `assetId`; older manifests\n // listed bare asset refs.\n const track = audioRef as PanelAudioTrack | string;\n const cue: AudioCue = {\n id: `audio-${cues.length}`,\n trackName: `Panel ${timing.index} Audio`,\n assetRef: typeof track === 'string' ? track : track.assetId,\n startTime: timing.startTime,\n duration: timing.duration,\n endTime: timing.endTime,\n startTimecode: timing.startTimecode,\n endTimecode: timing.endTimecode,\n panelId: timing.panelId,\n };\n cues.push(cue);\n }\n }\n \n timingIndex++;\n }\n }\n \n return cues;\n }\n\n /**\n * Generate EDL format\n */\n generateEDL(\n timings: PanelTiming[],\n layers: LayerComposition[],\n audio: AudioCue[],\n framerate: number\n ): ExportResult {\n const edl: EDLDocument = {\n title: 'PanelWave Export',\n framerate,\n events: [],\n };\n \n // Add video events (panels)\n timings.forEach((timing, index) => {\n const event: EDLEvent = {\n eventNumber: index + 1,\n reelName: 'AX',\n trackType: 'V',\n transitionType: 'C',\n sourceIn: timing.startTimecode,\n sourceOut: timing.endTimecode,\n recordIn: timing.startTimecode,\n recordOut: timing.endTimecode,\n clipName: `Panel_${timing.index}`,\n comment: `Chapter: ${timing.chapterId}`,\n };\n edl.events.push(event);\n });\n \n // Add audio events\n audio.forEach((cue, index) => {\n const event: EDLEvent = {\n eventNumber: timings.length + index + 1,\n reelName: 'AX',\n trackType: 'A',\n transitionType: 'C',\n sourceIn: cue.startTimecode,\n sourceOut: cue.endTimecode,\n recordIn: cue.startTimecode,\n recordOut: cue.endTimecode,\n clipName: cue.trackName,\n comment: cue.assetRef,\n };\n edl.events.push(event);\n });\n \n const edlText = this.formatEDL(edl);\n \n return {\n success: true,\n format: 'edl',\n data: edlText,\n filename: 'panelwave_export.edl',\n size: edlText.length,\n };\n }\n\n /**\n * Generate JSON format\n */\n generateJSON(\n chapters: Chapter[],\n timings: PanelTiming[],\n layers: LayerComposition[],\n audio: AudioCue[],\n options: ExportOptions\n ): ExportResult {\n const totalDuration = timings.length > 0\n ? timings[timings.length - 1].endTime\n : 0;\n \n const jsonExport: JSONExport = {\n metadata: {\n workId: chapters[0]?.id || 'unknown',\n workTitle: 'PanelWave Export',\n exportDate: new Date().toISOString(),\n framerate: options.framerate || this.config.defaultFramerate,\n totalDuration,\n },\n timings,\n layers,\n audio,\n };\n \n if (options.includeMetadata) {\n jsonExport.panels = chapters.flatMap(ch => Object.values(ch.panels || {}));\n }\n \n const jsonText = this.config.prettifyJSON\n ? JSON.stringify(jsonExport, null, 2)\n : JSON.stringify(jsonExport);\n \n return {\n success: true,\n format: 'json',\n data: jsonExport,\n filename: 'panelwave_export.json',\n size: jsonText.length,\n };\n }\n\n /**\n * Generate CSV format\n */\n generateCSV(\n timings: PanelTiming[],\n layers: LayerComposition[],\n options: ExportOptions\n ): ExportResult {\n const delimiter = this.config.csvDelimiter;\n let csv = '';\n \n // Timing CSV\n if (options.includeTimings !== false) {\n csv += 'Panel Timings\\n';\n csv += this.generateTimingCSV(timings, delimiter);\n csv += '\\n\\n';\n }\n \n // Layer CSV\n if (options.includeLayers) {\n csv += 'Layer Compositions\\n';\n csv += this.generateLayerCSV(layers, delimiter);\n }\n \n return {\n success: true,\n format: 'csv',\n data: csv,\n filename: 'panelwave_export.csv',\n size: csv.length,\n };\n }\n\n /**\n * Generate XML format\n */\n generateXML(\n timings: PanelTiming[],\n layers: LayerComposition[],\n audio: AudioCue[]\n ): ExportResult {\n let xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\n xml += '<panelwave-export>\\n';\n \n // Timings\n xml += ' <timings>\\n';\n timings.forEach(timing => {\n xml += ` <panel id=\"${timing.panelId}\" chapter=\"${timing.chapterId}\">\\n`;\n xml += ` <start>${timing.startTime}</start>\\n`;\n xml += ` <end>${timing.endTime}</end>\\n`;\n xml += ` <duration>${timing.duration}</duration>\\n`;\n xml += ` <timecode start=\"${timing.startTimecode}\" end=\"${timing.endTimecode}\" />\\n`;\n xml += ' </panel>\\n';\n });\n xml += ' </timings>\\n';\n \n // Layers\n xml += ' <layers>\\n';\n layers.forEach(layer => {\n xml += ` <layer id=\"${layer.layerId}\" type=\"${layer.layerType}\">\\n`;\n xml += ` <position x=\"${layer.x}\" y=\"${layer.y}\" />\\n`;\n xml += ` <size width=\"${layer.width}\" height=\"${layer.height}\" />\\n`;\n if (layer.opacity !== undefined) {\n xml += ` <opacity>${layer.opacity}</opacity>\\n`;\n }\n xml += ' </layer>\\n';\n });\n xml += ' </layers>\\n';\n \n // Audio\n xml += ' <audio>\\n';\n audio.forEach(cue => {\n xml += ` <cue id=\"${cue.id}\" track=\"${cue.trackName}\">\\n`;\n xml += ` <asset>${cue.assetRef}</asset>\\n`;\n xml += ` <time start=\"${cue.startTime}\" end=\"${cue.endTime}\" />\\n`;\n xml += ' </cue>\\n';\n });\n xml += ' </audio>\\n';\n \n xml += '</panelwave-export>';\n \n return {\n success: true,\n format: 'xml',\n data: xml,\n filename: 'panelwave_export.xml',\n size: xml.length,\n };\n }\n\n /**\n * Get panel duration\n */\n private getPanelDuration(panel: Panel): number {\n // Default duration: 3 seconds\n // Can be overridden by panel.duration if it exists\n return (panel as Panel & { duration?: number }).duration || 3.0;\n }\n\n /**\n * Convert layer to composition\n */\n private layerToComposition(\n layer: Layer,\n index: number,\n _timing: PanelTiming\n ): LayerComposition {\n const layerAny = layer as Layer & LooseLayerFields;\n return {\n layerId: layer.id,\n layerType: layerAny['type'] || 'unknown',\n index,\n x: layerAny['x'] || 0,\n y: layerAny['y'] || 0,\n width: layerAny['width'] || 0,\n height: layerAny['height'] || 0,\n rotation: layerAny['rotation'],\n scaleX: layerAny['scaleX'],\n scaleY: layerAny['scaleY'],\n opacity: layer.opacity,\n blendMode: layerAny['blendMode'],\n filters: layerAny['filters'],\n assetRef: layerAny['assetRef'],\n assetType: layerAny['type'],\n };\n }\n\n /**\n * Convert seconds to timecode (HH:MM:SS:FF)\n */\n private secondsToTimecode(seconds: number, framerate: number): string {\n const totalFrames = Math.floor(seconds * framerate);\n const frames = totalFrames % framerate;\n const totalSeconds = Math.floor(totalFrames / framerate);\n const secs = totalSeconds % 60;\n const mins = Math.floor(totalSeconds / 60) % 60;\n const hours = Math.floor(totalSeconds / 3600);\n \n return `${this.pad(hours)}:${this.pad(mins)}:${this.pad(secs)}:${this.pad(frames)}`;\n }\n\n /**\n * Format EDL document\n */\n private formatEDL(edl: EDLDocument): string {\n let text = `TITLE: ${edl.title}\\n`;\n text += `FCM: NON-DROP FRAME\\n\\n`;\n \n edl.events.forEach(event => {\n text += `${this.pad(event.eventNumber, 3)} ${event.reelName} `;\n text += `${event.trackType} ${event.transitionType} `;\n text += `${event.sourceIn} ${event.sourceOut} `;\n text += `${event.recordIn} ${event.recordOut}\\n`;\n \n if (event.clipName && this.config.includeComments) {\n text += `* FROM CLIP NAME: ${event.clipName}\\n`;\n }\n if (event.comment && this.config.includeComments) {\n text += `* COMMENT: ${event.comment}\\n`;\n }\n text += '\\n';\n });\n \n return text;\n }\n\n /**\n * Generate timing CSV\n */\n private generateTimingCSV(timings: PanelTiming[], delimiter: string): string {\n let csv = `Panel ID${delimiter}Chapter${delimiter}Index${delimiter}`;\n csv += `Start Time${delimiter}End Time${delimiter}Duration${delimiter}`;\n csv += `Start Frame${delimiter}End Frame\\n`;\n \n timings.forEach(timing => {\n csv += `${timing.panelId}${delimiter}`;\n csv += `${timing.chapterId}${delimiter}`;\n csv += `${timing.index}${delimiter}`;\n csv += `${timing.startTime}${delimiter}`;\n csv += `${timing.endTime}${delimiter}`;\n csv += `${timing.duration}${delimiter}`;\n csv += `${timing.startFrame}${delimiter}`;\n csv += `${timing.endFrame}\\n`;\n });\n \n return csv;\n }\n\n /**\n * Generate layer CSV\n */\n private generateLayerCSV(layers: LayerComposition[], delimiter: string): string {\n let csv = `Layer ID${delimiter}Type${delimiter}Index${delimiter}`;\n csv += `X${delimiter}Y${delimiter}Width${delimiter}Height${delimiter}`;\n csv += `Opacity${delimiter}Asset Ref\\n`;\n \n layers.forEach(layer => {\n csv += `${layer.layerId}${delimiter}`;\n csv += `${layer.layerType}${delimiter}`;\n csv += `${layer.index}${delimiter}`;\n csv += `${layer.x}${delimiter}`;\n csv += `${layer.y}${delimiter}`;\n csv += `${layer.width}${delimiter}`;\n csv += `${layer.height}${delimiter}`;\n csv += `${layer.opacity || 1}${delimiter}`;\n csv += `${layer.assetRef || ''}\\n`;\n });\n \n return csv;\n }\n\n /**\n * Pad number with zeros\n */\n private pad(num: number, size = 2): string {\n return String(num).padStart(size, '0');\n }\n}\n","/**\n * Translation Service\n * Provides translation functionality for the PanelWave player\n */\n\nimport { inject, Injectable } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport type { LocaleCode } from '../types';\n\n/**\n * Translation Service\n * Manages GUI translations and locale switching\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class TranslationService {\n private readonly translate = inject(TranslateService);\n\n constructor() {\n // Set default language - translations will be loaded via HTTP\n this.translate.setDefaultLang('en');\n this.translate.use('en');\n }\n\n /**\n * Initialize translation service with available languages\n */\n initialize(availableLanguages: string[]): void {\n this.translate.addLangs(availableLanguages);\n }\n\n /**\n * Set the current GUI language\n */\n setLanguage(lang: string): void {\n // Map locale code (e.g., 'en-US') to language code (e.g., 'en')\n const languageCode = this.getLanguageCode(lang);\n this.translate.use(languageCode);\n }\n\n /**\n * Get current GUI language\n */\n getCurrentLanguage(): string {\n return this.translate.currentLang || this.translate.defaultLang || 'en';\n }\n\n /**\n * Extract language code from locale code\n */\n private getLanguageCode(locale: LocaleCode): string {\n // Extract base language from locale (e.g., 'en-US' -> 'en')\n return locale.split('-')[0];\n }\n\n /**\n * Get translation for a key\n */\n instant(key: string, params?: Record<string, unknown>): string {\n return this.translate.instant(key, params);\n }\n\n /**\n * Get translation observable for a key\n */\n get(key: string, params?: Record<string, unknown>) {\n return this.translate.get(key, params);\n }\n}\n","import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class PlayerService {\r\n}\r\n","/**\r\n * Inlined Lucide icon set for the PanelWave player.\r\n *\r\n * The player is a published, MIT-licensed library, so it deliberately carries\r\n * no icon-library dependency: only the handful of glyphs the player UI needs\r\n * are inlined here as raw SVG markup. Icons are from Lucide (https://lucide.dev),\r\n * ISC License (c) Lucide Contributors. Each glyph uses `stroke=\"currentColor\"`,\r\n * so colour follows CSS `color`; size follows the `PwIconComponent` host font-size.\r\n *\r\n * To add an icon: copy the corresponding Lucide SVG markup here, keyed by its\r\n * `lucide<Name>` identifier. Do NOT add a runtime dependency on an icon library.\r\n */\r\nexport const PW_ICONS: Record<string, string> = {\r\n lucideBookmark: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z\"></path></svg>',\r\n lucideBookmarkCheck: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z\"></path><path d=\"m9 10 2 2 4-4\"></path></svg>',\r\n lucideCheck: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M20 6 9 17l-5-5\"></path></svg>',\r\n lucideChevronDown: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m6 9 6 6 6-6\"></path></svg>',\r\n lucideChevronLeft: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m15 18-6-6 6-6\"></path></svg>',\r\n lucideChevronRight: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m9 18 6-6-6-6\"></path></svg>',\r\n lucideChevronUp: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m18 15-6-6-6 6\"></path></svg>',\r\n lucideCircle: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle></svg>',\r\n lucideClapperboard: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z\"></path><path d=\"m6.2 5.3 3.1 3.9\"></path><path d=\"m12.4 3.4 3.1 4\"></path><path d=\"M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\"></path></svg>',\r\n lucideClipboard: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\"></rect><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"></path></svg>',\r\n lucideFileText: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"></path><path d=\"M14 2v5a1 1 0 0 0 1 1h5\"></path><path d=\"M10 9H8\"></path><path d=\"M16 13H8\"></path><path d=\"M16 17H8\"></path></svg>',\r\n lucideGlobe: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\"></path><path d=\"M2 12h20\"></path></svg>',\r\n lucideHeart: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5\"></path></svg>',\r\n lucideImage: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\"></rect><circle cx=\"9\" cy=\"9\" r=\"2\"></circle><path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"></path></svg>',\r\n lucideImages: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m22 11-1.296-1.296a2.4 2.4 0 0 0-3.408 0L11 16\"></path><path d=\"M4 8a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2\"></path><circle cx=\"13\" cy=\"7\" r=\"1\" fill=\"currentColor\"></circle><rect x=\"8\" y=\"2\" width=\"14\" height=\"14\" rx=\"2\"></rect></svg>',\r\n lucideInfo: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M12 16v-4\"></path><path d=\"M12 8h.01\"></path></svg>',\r\n lucideLayoutGrid: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect width=\"7\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"></rect><rect width=\"7\" height=\"7\" x=\"14\" y=\"3\" rx=\"1\"></rect><rect width=\"7\" height=\"7\" x=\"14\" y=\"14\" rx=\"1\"></rect><rect width=\"7\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"></rect></svg>',\r\n lucideList: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M3 5h.01\"></path><path d=\"M3 12h.01\"></path><path d=\"M3 19h.01\"></path><path d=\"M8 5h13\"></path><path d=\"M8 12h13\"></path><path d=\"M8 19h13\"></path></svg>',\r\n lucideLock: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path></svg>',\r\n lucideMail: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"></path><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\"></rect></svg>',\r\n lucideMessageCircle: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719\"></path></svg>',\r\n lucideMessageSquare: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z\"></path></svg>',\r\n lucideMusic: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M9 18V5l12-2v13\"></path><circle cx=\"6\" cy=\"18\" r=\"3\"></circle><circle cx=\"18\" cy=\"16\" r=\"3\"></circle></svg>',\r\n lucidePaperclip: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551\"></path></svg>',\r\n lucidePause: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect x=\"14\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\"></rect><rect x=\"5\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\"></rect></svg>',\r\n lucidePlay: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"></path></svg>',\r\n lucideRefreshCw: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\"></path><path d=\"M21 3v5h-5\"></path><path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\"></path><path d=\"M8 16H3v5\"></path></svg>',\r\n lucideRotateCcw: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"></path><path d=\"M3 3v5h5\"></path></svg>',\r\n lucideSearch: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m21 21-4.34-4.34\"></path><circle cx=\"11\" cy=\"11\" r=\"8\"></circle></svg>',\r\n lucideSettings: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915\"></path><circle cx=\"12\" cy=\"12\" r=\"3\"></circle></svg>',\r\n lucideShare2: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><circle cx=\"18\" cy=\"5\" r=\"3\"></circle><circle cx=\"6\" cy=\"12\" r=\"3\"></circle><circle cx=\"18\" cy=\"19\" r=\"3\"></circle><line x1=\"8.59\" x2=\"15.42\" y1=\"13.51\" y2=\"17.49\"></line><line x1=\"15.41\" x2=\"8.59\" y1=\"6.51\" y2=\"10.49\"></line></svg>',\r\n lucideSparkles: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z\"></path><path d=\"M20 2v4\"></path><path d=\"M22 4h-4\"></path><circle cx=\"4\" cy=\"20\" r=\"2\"></circle></svg>',\r\n lucideSplit: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M16 3h5v5\"></path><path d=\"M8 3H3v5\"></path><path d=\"M12 22v-8.3a4 4 0 0 0-1.172-2.872L3 3\"></path><path d=\"m15 9 6-6\"></path></svg>',\r\n lucideSquare: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"></rect></svg>',\r\n lucideTriangleAlert: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"></path><path d=\"M12 9v4\"></path><path d=\"M12 17h.01\"></path></svg>',\r\n lucideUsers: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\"></path><path d=\"M16 3.128a4 4 0 0 1 0 7.744\"></path><path d=\"M22 21v-2a4 4 0 0 0-3-3.87\"></path><circle cx=\"9\" cy=\"7\" r=\"4\"></circle></svg>',\r\n lucideVolume2: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z\"></path><path d=\"M16 9a5 5 0 0 1 0 6\"></path><path d=\"M19.364 18.364a9 9 0 0 0 0-12.728\"></path></svg>',\r\n lucideVolumeX: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z\"></path><line x1=\"22\" x2=\"16\" y1=\"9\" y2=\"15\"></line><line x1=\"16\" x2=\"22\" y1=\"9\" y2=\"15\"></line></svg>',\r\n lucideX: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path d=\"M18 6 6 18\"></path><path d=\"m6 6 12 12\"></path></svg>',\r\n};\r\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\r\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\r\nimport { PW_ICONS } from './pw-icon.data';\r\n\r\n/**\r\n * Renders an inlined Lucide icon by name (e.g. `lucideX`).\r\n *\r\n * Zero-dependency: the SVG markup lives in {@link PW_ICONS}, so the published\r\n * player library does not depend on an icon library. Glyphs use\r\n * `stroke=\"currentColor\"` and are sized to `1em`, so colour follows CSS `color`\r\n * and size follows the surrounding font-size — matching the emoji they replace.\r\n * The host is an inline-flex box so glyphs stay vertically centred and never\r\n * clip at the bottom inside flex rows, buttons or menus.\r\n */\r\n@Component({\r\n selector: 'pw-icon',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n template: `<span class=\"pw-icon__svg\" [innerHTML]=\"svg()\"></span>`,\r\n styles: [\r\n `\r\n :host {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n vertical-align: middle;\r\n line-height: 1;\r\n }\r\n\r\n .pw-icon__svg {\r\n display: inline-flex;\r\n }\r\n\r\n :host ::ng-deep svg {\r\n display: block;\r\n width: 1em;\r\n height: 1em;\r\n }\r\n `,\r\n ],\r\n host: {\r\n 'aria-hidden': 'true',\r\n },\r\n})\r\nexport class PwIconComponent {\r\n private readonly sanitizer = inject(DomSanitizer);\r\n\r\n /** Lucide icon identifier, e.g. `lucideX`, `lucideSettings`. */\r\n readonly name = input.required<string>();\r\n\r\n protected readonly svg = computed<SafeHtml>(() =>\r\n this.sanitizer.bypassSecurityTrustHtml(PW_ICONS[this.name()] ?? ''),\r\n );\r\n}\r\n","/**\n * Translation Loader\n * Loads translation files via HTTP\n */\n\nimport { HttpClient } from '@angular/common/http';\nimport { TranslateLoader, type TranslationObject } from '@ngx-translate/core';\nimport { Observable } from 'rxjs';\n\n/**\n * Custom Translation Loader\n * Loads translations from JSON files via HTTP\n */\nexport class CustomTranslateLoader implements TranslateLoader {\n constructor(private http: HttpClient) {}\n\n getTranslation(lang: string): Observable<TranslationObject> {\n return this.http.get<TranslationObject>(`./assets/i18n/${lang}.json`);\n }\n}\n","/**\n * Map the manifest's keyed `extras` blocks (schema $defs/ExtraBlock) to the\n * flat list the extras viewer renders — including the media each block\n * carries, resolved through the asset catalog.\n *\n * ExtraBlock media, in schema terms:\n * - `images[] { assetId, caption }`, `video[] (VideoLayer)`, `audio[] (AudioTrack)`\n * reference catalog assets by id;\n * - `url` / `thumbnail` are direct links (thumbnail may also be an asset id);\n * - `contentType` (image | video | audio | pdf | text) states the kind explicitly.\n * Previously only id/title/text were passed on, so every extra rendered as an\n * empty image.\n */\nimport type { Extra, ExtraType } from '../components/modals/extras-viewer/extras-viewer.component';\nimport type { LocalizedString } from '../types';\nimport { selectImageVariantForWidth } from './image-variant-utils';\nimport type { ImageVariant } from '../types';\n\n/** Just the catalog shape this module reads (image / video / audio items). */\nexport interface CatalogLike {\n category?: string;\n variants?: { src: string; w?: number; direction?: string }[];\n poster?: { src: string };\n}\n\nexport type AssetLookup = (assetId: string) => CatalogLike | null | undefined;\n\ninterface ExtraBlockLike {\n id?: string;\n title?: LocalizedString;\n text?: LocalizedString;\n images?: { assetId?: string }[];\n video?: { assetId?: string }[];\n audio?: { assetId?: string }[];\n contentType?: 'image' | 'video' | 'audio' | 'pdf' | 'text';\n url?: string;\n thumbnail?: string;\n gated?: boolean;\n}\n\n/** Thumbnail width to aim for (the grid tiles are small). */\nconst THUMB_WIDTH = 320;\n\nfunction firstId(list: { assetId?: string }[] | undefined): string | undefined {\n return list?.find((item) => typeof item?.assetId === 'string' && item.assetId.length > 0)?.assetId;\n}\n\n/** Source URL of a catalog asset: forward video variant, else the image variant for `width`, else the first. */\nexport function catalogSrc(lookup: AssetLookup, assetId: string | undefined, width = 0): string {\n if (!assetId) return '';\n const asset = lookup(assetId);\n const variants = asset?.variants ?? [];\n if (variants.length === 0) return '';\n if (asset?.category === 'video') {\n return (variants.find((v) => v.direction !== 'reverse') ?? variants[0]).src ?? '';\n }\n return selectImageVariantForWidth(variants as unknown as ImageVariant[], width)?.src ?? variants[0].src ?? '';\n}\n\nexport function extraFromBlock(block: ExtraBlockLike, type: ExtraType, lookup: AssetLookup): Extra {\n const imageId = firstId(block.images);\n const videoId = firstId(block.video);\n const audioId = firstId(block.audio);\n const ct = block.contentType;\n\n let mediaType: Extra['mediaType'];\n if (ct === 'video' || (!ct && videoId)) mediaType = 'video';\n else if (ct === 'audio' || (!ct && audioId)) mediaType = 'audio';\n else if (ct === 'pdf' || ct === 'text') mediaType = 'document';\n else if (ct === 'image' || imageId || block.url) mediaType = 'image';\n else mediaType = 'document'; // text-only block (e.g. author info)\n\n const mediaId = mediaType === 'video' ? videoId : mediaType === 'audio' ? audioId : imageId;\n const asset = block.url || catalogSrc(lookup, mediaId) || undefined;\n\n // Thumbnail: explicit (asset id or URL), else a small rendition of the first\n // image, else the video's poster.\n let thumbnail: string | undefined;\n if (block.thumbnail) {\n thumbnail = catalogSrc(lookup, block.thumbnail, THUMB_WIDTH) || block.thumbnail;\n } else if (imageId) {\n thumbnail = catalogSrc(lookup, imageId, THUMB_WIDTH) || undefined;\n } else if (videoId) {\n thumbnail = lookup(videoId)?.poster?.src || undefined;\n }\n\n return {\n id: block.id ?? '',\n type,\n title: block.title ?? {},\n description: block.text,\n mediaType,\n // An image extra whose media cannot be resolved is shown as text only.\n ...(mediaType === 'image' && !asset ? { mediaType: 'document' as const } : {}),\n asset,\n thumbnail,\n gated: block.gated === true,\n };\n}\n\n/** Flatten the keyed extras object in the order the viewer lists it. */\nexport function extrasFromManifest(extras: Record<string, unknown> | undefined, lookup: AssetLookup): Extra[] {\n if (!extras) return [];\n const out: Extra[] = [];\n const push = (block: unknown, type: ExtraType): void => {\n const b = block as ExtraBlockLike | null;\n if (b && typeof b === 'object' && b.id) out.push(extraFromBlock(b, type, lookup));\n };\n const each = (key: string, type: ExtraType): void => {\n const list = extras[key];\n if (Array.isArray(list)) list.forEach((b) => push(b, type));\n };\n push(extras['cover'], 'cover');\n push(extras['alt_cover'], 'cover');\n push(extras['author_info'], 'other');\n each('author_interviews', 'interview');\n each('bonus_art', 'art');\n each('fan_art', 'art');\n each('behind_the_scenes', 'bts');\n each('character_sheets', 'other');\n return out;\n}\n","/**\r\n * Video Layer Component\r\n * Renders a video layer and implements the PanelWave playback core:\r\n * play modes (once / loop / pingpong / loop-from), start modes\r\n * (on-view / on-hover / on-click), the browser autoplay policy (start muted\r\n * until a user gesture, with an unmute affordance) and reduced-motion\r\n * degradation.\r\n *\r\n * The component exposes a small programmatic surface (`viewActive` input plus\r\n * `play()`/`pause()`/`stop()` methods and a `passComplete` output) so a future\r\n * page-view sequencer can drive it without knowing the playback internals.\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ViewChild,\r\n ElementRef,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n OnInit,\r\n OnChanges,\r\n OnDestroy,\r\n SimpleChanges,\r\n inject,\r\n} from '@angular/core';\r\nimport type {\r\n VideoPlayMode,\r\n VideoStartMode,\r\n VideoTrigger,\r\n VideoTrackingPayload,\r\n} from '../../../types';\r\nimport { PlayerEvent } from '../../../types';\r\nimport type { Subscription } from 'rxjs';\r\nimport { VideoControllerService } from '../../../services/video-controller.service';\r\nimport { UserGestureService } from '../../../services/user-gesture.service';\r\nimport { AudioEngineService } from '../../../services/audio-engine.service';\r\nimport { TrackingService } from '../../../services/tracking.service';\r\nimport {\r\n VideoSequencerService,\r\n type SequencedVideo,\r\n} from '../../../services/video-sequencer.service';\r\nimport { shouldReduceMotion } from '../../../utils/animation-utils';\r\n\r\n/** View mode the layer is rendered in. */\r\nexport type LayerViewMode = 'panel' | 'page';\r\n\r\nlet nextVideoInstanceId = 0;\r\n\r\n/**\r\n * Video Layer Component\r\n */\r\n@Component({\r\n selector: 'pw-video-layer',\r\n imports: [],\r\n templateUrl: './video-layer.component.html',\r\n styleUrls: ['./video-layer.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class VideoLayerComponent implements OnInit, OnChanges, OnDestroy {\r\n private readonly controller = inject(VideoControllerService);\r\n private readonly gesture = inject(UserGestureService);\r\n private readonly tracking = inject(TrackingService);\r\n private readonly sequencer = inject(VideoSequencerService);\r\n private readonly audioEngine = inject(AudioEngineService);\r\n private readonly cdr = inject(ChangeDetectorRef);\r\n\r\n /** Follows the player-wide Audio toggle (engine master mute). */\r\n private masterMuteSub?: Subscription;\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n\r\n /** Video source URL (forward variant). */\r\n @Input() src = '';\r\n\r\n /** Reverse-variant URL used for the pingpong backward pass (empty if none). */\r\n @Input() reverseSrc = '';\r\n\r\n /** Base URL for resolving relative paths. */\r\n @Input() baseUrl = '';\r\n\r\n /** Poster image URL. */\r\n @Input() poster = '';\r\n\r\n /** Show native controls. */\r\n @Input() controls = true;\r\n\r\n /** Effective playback mode. */\r\n @Input() playMode: VideoPlayMode = 'once';\r\n\r\n /** Effective start trigger. */\r\n @Input() startMode: VideoStartMode = 'on-view';\r\n\r\n /** Effective muted state as authored (may be overridden by autoplay policy). */\r\n @Input() muted = true;\r\n\r\n /** Media-timeline start offset in milliseconds. */\r\n @Input() startAtMs = 0;\r\n\r\n /** Loop re-entry point in ms (only for playMode 'loop-from'). */\r\n @Input() loopFromMs?: number;\r\n\r\n /** Active source is a streaming/HLS variant (disables seamless pingpong). */\r\n @Input() streaming = false;\r\n\r\n /** View mode (`on-hover` only applies in page view). */\r\n @Input() viewMode: LayerViewMode = 'panel';\r\n\r\n /**\r\n * Sequencer surface: whether this panel is currently visible / current.\r\n * `on-view` videos play when this becomes true and pause+reset when false.\r\n */\r\n @Input() viewActive = false;\r\n\r\n /** Reduced-motion preference (falls back to media query when not provided). */\r\n @Input() reducedMotion?: boolean;\r\n\r\n /** Accessible label (from asset alt/caption where available). */\r\n @Input() ariaLabel = '';\r\n\r\n /** Unique id for controller registration; auto-generated when absent. */\r\n @Input() videoId = `pw-video-${nextVideoInstanceId++}`;\r\n\r\n /** Panel id this video belongs to (for tracking + sequencer slotting). */\r\n @Input() panelId = '';\r\n\r\n /** Catalog asset id of this video (for tracking payloads). */\r\n @Input() assetId = '';\r\n\r\n /** Placement id used for page-view visibility observation (defaults to panelId). */\r\n @Input() placementId = '';\r\n\r\n /** Index in `Page.readingOrder` for sequencing, or -1 when absent. */\r\n @Input() readingOrderIndex = -1;\r\n\r\n /** Placement z-index (sequencer fallback ordering). */\r\n @Input() placementZ = 0;\r\n\r\n /** Placement y position 0-1 (sequencer fallback ordering). */\r\n @Input() placementY = 0;\r\n\r\n /** Placement x position 0-1 (sequencer fallback ordering). */\r\n @Input() placementX = 0;\r\n\r\n /** Video started playing. */\r\n @Output() videoPlay = new EventEmitter<void>();\r\n\r\n /** Video paused. */\r\n @Output() videoPause = new EventEmitter<void>();\r\n\r\n /** Video reached the end of a forward pass (native `ended`). */\r\n @Output() videoEnd = new EventEmitter<void>();\r\n\r\n /** A loop / pingpong iteration restarted. */\r\n @Output() videoLoop = new EventEmitter<void>();\r\n\r\n /**\r\n * One full pass completed (once → ended; loop/loop-from/pingpong → one full\r\n * cycle). Intended for a future sequencer to advance its queue.\r\n */\r\n @Output() passComplete = new EventEmitter<void>();\r\n\r\n /** Video failed to load. */\r\n @Output() videoError = new EventEmitter<ErrorEvent>();\r\n\r\n /** Reference to the video element. */\r\n @ViewChild('videoElement') videoElement?: ElementRef<HTMLVideoElement>;\r\n\r\n /** Whether an unmute affordance should be shown (autoplay-policy override). */\r\n showUnmuteButton = false;\r\n\r\n /** Muted state reflected onto the <video> element (see setElementMuted). */\r\n displayMuted = true;\r\n\r\n /** Whether pingpong is currently in its backward phase. */\r\n private reversePhase = false;\r\n\r\n /** Whether a reversed variant is being used for the backward pass. */\r\n private usingReverseVariant = false;\r\n\r\n /** requestVideoFrameCallback / raf handle for frame-stepping fallback. */\r\n private frameStepHandle: number | null = null;\r\n\r\n /** Whether pingpong degraded to loop (streaming, no reverse variant). */\r\n private pingpongDegraded = false;\r\n\r\n /**\r\n * True while a `video.src` swap (reverse ↔ forward variant, seamless\r\n * pingpong) is in flight. Guards `onLoadedMetadata` so the initial-setup\r\n * path (attach listeners, seek to start, maybe autoplay) does not re-run\r\n * when the swap's own `loadedmetadata` fires — that event is instead\r\n * consumed by a dedicated one-time listener that performs the post-swap\r\n * seek/play once the new source's metadata is actually ready.\r\n */\r\n private swapInProgress = false;\r\n\r\n /**\r\n * Pending one-time `loadedmetadata` listener registered by a src swap (see\r\n * `startReversePass`/`finishReversePass`). Held so `stop()`/`pause()`/\r\n * `ngOnDestroy` can remove it and clear `swapInProgress`, preventing an\r\n * orphaned listener from calling `play()` on an already-stopped video when\r\n * the swapped source's metadata finally loads.\r\n */\r\n private pendingSwapListener: (() => void) | null = null;\r\n\r\n /** Whether we already warned about pingpong degradation (warn once). */\r\n private static pingpongWarned = false;\r\n\r\n /** Whether this component is currently registered with the sequencer. */\r\n private registeredWithSequencer = false;\r\n\r\n /** Whether this video is currently the sequencer's active slot member. */\r\n private activatedBySequencer = false;\r\n\r\n /**\r\n * What triggered the most recent playback, for tracking payloads. Set when\r\n * playback starts (sequencer / view / hover / click).\r\n */\r\n private currentTrigger: VideoTrigger = 'view';\r\n\r\n /** Bound media-event handlers (so they can be detached). */\r\n private readonly onEndedBound = (): void => this.handleEnded();\r\n private readonly onPlayBound = (): void => this.handleNativePlay();\r\n private readonly onPauseBound = (): void => this.handleNativePause();\r\n private readonly onWaitingBound = (): void =>\r\n this.sequencer.notifyStalling(this.videoId);\r\n private readonly onTimeUpdateBound = (): void =>\r\n this.sequencer.notifyProgress(this.videoId);\r\n\r\n // ---------------------------------------------------------------------------\r\n // URL resolution\r\n // ---------------------------------------------------------------------------\r\n\r\n getVideoUrl(): string {\r\n return this.resolveUrl(this.src);\r\n }\r\n\r\n getPosterUrl(): string {\r\n return this.resolveUrl(this.poster);\r\n }\r\n\r\n private resolveUrl(value: string): string {\r\n if (!value) return '';\r\n if (value.startsWith('http://') || value.startsWith('https://')) {\r\n return value;\r\n }\r\n return this.baseUrl + value;\r\n }\r\n\r\n private get video(): HTMLVideoElement | undefined {\r\n return this.videoElement?.nativeElement;\r\n }\r\n\r\n private get startTimeSec(): number {\r\n return Math.max(0, this.startAtMs) / 1000;\r\n }\r\n\r\n private get loopFromSec(): number | undefined {\r\n return this.loopFromMs !== undefined ? this.loopFromMs / 1000 : undefined;\r\n }\r\n\r\n private isReducedMotion(): boolean {\r\n return this.reducedMotion ?? shouldReduceMotion();\r\n }\r\n\r\n /**\r\n * The effective start mode after context degradation:\r\n * - reduced motion degrades `on-view` to `on-click`.\r\n * - `on-hover` degrades to `on-click` outside page view or on touch devices.\r\n */\r\n effectiveStartMode(): VideoStartMode {\r\n if (this.startMode === 'on-view' && this.isReducedMotion()) {\r\n return 'on-click';\r\n }\r\n if (this.startMode === 'on-hover' && (this.viewMode !== 'page' || this.isTouchDevice())) {\r\n return 'on-click';\r\n }\r\n return this.startMode;\r\n }\r\n\r\n private isTouchDevice(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n return (\r\n 'ontouchstart' in window ||\r\n (typeof navigator !== 'undefined' && navigator.maxTouchPoints > 0)\r\n );\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Lifecycle\r\n // ---------------------------------------------------------------------------\r\n\r\n ngOnInit(): void {\r\n this.syncSequencerRegistration();\r\n // The toolbar's Audio toggle silences video sound too: while the engine\r\n // is master-muted the element stays muted whatever was authored; on\r\n // unmute the authored/gesture-derived state is restored.\r\n this.masterMuteSub = this.audioEngine.masterMuted$.subscribe((masterMuted) => {\r\n const effective = this.computeEffectiveMuted();\r\n this.setElementMuted(effective);\r\n if (masterMuted) {\r\n this.showUnmuteButton = false;\r\n } else if (this.video && !this.video.paused) {\r\n this.showUnmuteButton = this.wantsSound() && effective;\r\n }\r\n this.cdr.markForCheck();\r\n });\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n // React to viewActive changes for on-view start mode.\r\n if (changes['viewActive'] && !changes['viewActive'].firstChange) {\r\n this.handleViewActiveChange();\r\n }\r\n // Re-evaluate sequencer participation when a relevant input changes\r\n // (the initial registration happens in ngOnInit).\r\n const relevant =\r\n changes['viewMode'] ?? changes['startMode'] ?? changes['panelId'];\r\n if (relevant && !relevant.firstChange) {\r\n this.syncSequencerRegistration();\r\n }\r\n }\r\n\r\n /**\r\n * Register/unregister with the {@link VideoSequencerService} depending on\r\n * context. Only page-view videos participate; `on-view` videos are queued\r\n * (sequenced) while hover/click videos are not (they play independently).\r\n * In panel view the sequencer is bypassed entirely — `viewActive` drives\r\n * playback directly. Re-syncing while registered refreshes the handle\r\n * (e.g. a changed start mode flips the `sequenced` flag).\r\n */\r\n private syncSequencerRegistration(): void {\r\n if (this.registeredWithSequencer) {\r\n this.sequencer.unregister(this.videoId);\r\n this.registeredWithSequencer = false;\r\n }\r\n if (this.viewMode === 'page') {\r\n this.sequencer.register(this.asSequencedVideo());\r\n this.registeredWithSequencer = true;\r\n }\r\n }\r\n\r\n /** Build the sequencer control handle for this component. */\r\n private asSequencedVideo(): SequencedVideo {\r\n return {\r\n id: this.videoId,\r\n panelId: this.panelId,\r\n placementId: this.placementId || this.panelId,\r\n readingOrderIndex: this.readingOrderIndex,\r\n z: this.placementZ,\r\n y: this.placementY,\r\n x: this.placementX,\r\n sequenced: this.effectiveStartMode() === 'on-view',\r\n element: this.host.nativeElement,\r\n activate: () => this.activateFromSequencer(),\r\n deactivate: () => this.deactivateFromSequencer(),\r\n // §4.2: hover/click videos leaving the viewport pause keeping position.\r\n suspend: () => this.pause(),\r\n onStallSkip: () => this.emitStallSkip(),\r\n };\r\n }\r\n\r\n /** Sequencer asks this video to play (it is the active slot). */\r\n private activateFromSequencer(): void {\r\n this.activatedBySequencer = true;\r\n this.currentTrigger = 'sequencer';\r\n void this.play();\r\n }\r\n\r\n /** Sequencer removes this video from the active slot / queue. */\r\n private deactivateFromSequencer(): void {\r\n this.activatedBySequencer = false;\r\n this.stop();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.masterMuteSub?.unsubscribe();\r\n this.stopFrameStepping();\r\n this.cancelPendingSwap();\r\n this.detachReverseVariantListener();\r\n this.detachMediaListeners();\r\n this.controller.unregister(this.videoId);\r\n this.sequencer.unregister(this.videoId);\r\n }\r\n\r\n /** Native video error handler. */\r\n onError(event: Event): void {\r\n this.videoError.emit(event as ErrorEvent);\r\n }\r\n\r\n /** Called from the template once the <video> element is available. */\r\n onLoadedMetadata(): void {\r\n // A pingpong src swap (reverse <-> forward variant) also fires\r\n // `loadedmetadata`; that occurrence is handled by a dedicated one-time\r\n // listener registered by the swap itself, so the initial-setup path\r\n // below must not re-run (it would re-attach listeners and could\r\n // re-trigger autoplay).\r\n if (this.swapInProgress) {\r\n return;\r\n }\r\n this.attachMediaListeners();\r\n this.seekToStart();\r\n // If on-view and already active at init, kick off playback.\r\n if (this.effectiveStartMode() === 'on-view' && this.viewActive) {\r\n void this.play();\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Start-mode triggers (template-facing)\r\n // ---------------------------------------------------------------------------\r\n\r\n private handleViewActiveChange(): void {\r\n if (this.effectiveStartMode() !== 'on-view') {\r\n // hover/click videos keep their position when visibility is lost.\r\n if (!this.viewActive) {\r\n this.pause();\r\n }\r\n return;\r\n }\r\n if (this.viewActive) {\r\n this.currentTrigger = 'view';\r\n void this.play();\r\n } else {\r\n // on-view: pause and reset so re-entry replays from the start.\r\n this.stop();\r\n }\r\n }\r\n\r\n /** Click / tap handler (on-click toggle). */\r\n onClick(): void {\r\n if (this.effectiveStartMode() !== 'on-click') {\r\n return;\r\n }\r\n this.togglePlayback();\r\n }\r\n\r\n /** Keyboard handler (Enter / Space) for on-click layers. */\r\n onKeydown(event: KeyboardEvent): void {\r\n if (this.effectiveStartMode() !== 'on-click') {\r\n return;\r\n }\r\n if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {\r\n event.preventDefault();\r\n this.togglePlayback();\r\n }\r\n }\r\n\r\n /** Mouse enter — on-hover start (page view only). */\r\n onMouseEnter(): void {\r\n if (this.effectiveStartMode() !== 'on-hover') {\r\n return;\r\n }\r\n this.currentTrigger = 'hover';\r\n void this.play();\r\n }\r\n\r\n /** Mouse leave — on-hover pause keeping position. */\r\n onMouseLeave(): void {\r\n if (this.effectiveStartMode() !== 'on-hover') {\r\n return;\r\n }\r\n this.pause();\r\n }\r\n\r\n private togglePlayback(): void {\r\n const video = this.video;\r\n if (video && !video.paused) {\r\n this.pause();\r\n } else {\r\n this.currentTrigger = 'click';\r\n void this.play();\r\n }\r\n }\r\n\r\n /** Whether this layer participates in keyboard interaction. */\r\n isKeyboardInteractive(): boolean {\r\n return this.effectiveStartMode() === 'on-click';\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Playback core\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Start (or resume) playback, applying play mode and the autoplay policy.\r\n */\r\n async play(): Promise<void> {\r\n const video = this.video;\r\n if (!video) return;\r\n\r\n this.resolvePingpongStrategy();\r\n\r\n // Apply autoplay policy: non-gesture playback must start muted.\r\n const effectiveMuted = this.computeEffectiveMuted();\r\n this.setElementMuted(effectiveMuted);\r\n // No affordance while the reader muted the whole player: unmuting one\r\n // video would contradict the toolbar's Audio toggle.\r\n this.showUnmuteButton =\r\n this.wantsSound() && effectiveMuted && !this.audioEngine.isMasterMuted();\r\n\r\n // Ensure we start from the configured offset when at the beginning.\r\n if (video.currentTime < this.startTimeSec || video.ended) {\r\n this.seekToStart();\r\n }\r\n\r\n try {\r\n await this.controller.play(video, this.videoId, effectiveMuted, () =>\r\n this.handlePreempted()\r\n );\r\n this.cdr.markForCheck();\r\n } catch {\r\n // Controller already logs/handles retries.\r\n }\r\n }\r\n\r\n /**\r\n * Invoked by the controller when it pauses this video to enforce the\r\n * single-unmuted-video rule (some other layer started unmuted). The\r\n * element itself is already paused by the controller at this point;\r\n * this brings the component's own state in line: stop any pingpong\r\n * frame-stepping timer (it would otherwise keep ticking against a paused\r\n * element) and drop the unmute affordance. The native `pause` media event\r\n * (fired by the element itself when `.pause()` is called) drives the\r\n * `videoPause` output via the existing `onPauseBound` listener, so it is\r\n * not re-emitted here.\r\n */\r\n private handlePreempted(): void {\r\n this.stopFrameStepping();\r\n this.showUnmuteButton = false;\r\n this.cdr.markForCheck();\r\n }\r\n\r\n /**\r\n * Native `play` event handler: emits the `videoPlay` output + a\r\n * `VIDEO_PLAY` tracking event, and (for a user-initiated *unmuted* video)\r\n * pauses the sequencer so at most one unmuted video plays and the sequence\r\n * resumes afterwards (§4.3.4).\r\n */\r\n private handleNativePlay(): void {\r\n this.videoPlay.emit();\r\n this.trackVideoEvent(PlayerEvent.VIDEO_PLAY);\r\n if (this.isUnmutedUserVideo()) {\r\n this.sequencer.pause();\r\n }\r\n }\r\n\r\n /**\r\n * Native `pause` event handler: emits `videoPause` + a `VIDEO_PAUSE`\r\n * tracking event, and resumes the sequencer if this was the unmuted\r\n * user-initiated video that had paused it.\r\n */\r\n private handleNativePause(): void {\r\n this.videoPause.emit();\r\n // Track only user-driven pauses: on-view / sequencer videos are paused\r\n // constantly as slots rotate (deactivate/reset), which would flood\r\n // analytics with VIDEO_PAUSE noise. A pause of a hover/click video is the\r\n // only meaningful \"user paused\" signal.\r\n if (this.isUserDrivenVideo()) {\r\n this.trackVideoEvent(PlayerEvent.VIDEO_PAUSE);\r\n }\r\n if (this.isUnmutedUserVideo()) {\r\n this.sequencer.resume();\r\n }\r\n }\r\n\r\n /**\r\n * Whether this is a user-initiated (hover/click) video — i.e. not driven by\r\n * the page-view sequencer.\r\n */\r\n private isUserDrivenVideo(): boolean {\r\n return (\r\n !this.activatedBySequencer &&\r\n (this.currentTrigger === 'hover' || this.currentTrigger === 'click')\r\n );\r\n }\r\n\r\n /**\r\n * Whether this is a user-initiated video currently playing unmuted — the\r\n * case that must pause/resume the sequencer.\r\n */\r\n private isUnmutedUserVideo(): boolean {\r\n return this.isUserDrivenVideo() && !this.displayMuted;\r\n }\r\n\r\n /** Emit a video tracking event through the consent/whitelist pipeline. */\r\n private trackVideoEvent(\r\n event: PlayerEvent,\r\n reason?: VideoTrackingPayload['reason']\r\n ): void {\r\n const payload: VideoTrackingPayload = {\r\n panelId: this.panelId || undefined,\r\n assetId: this.assetId || undefined,\r\n trigger: this.currentTrigger,\r\n reason,\r\n };\r\n this.tracking.track(event, payload as unknown as Record<string, unknown>);\r\n }\r\n\r\n /**\r\n * Sequencer stall-skip hook: emit a `VIDEO_ENDED` tracking event with a\r\n * `stall-skip` reason (keeps the event surface minimal — reuses the ended\r\n * event with a reason rather than adding a new event type).\r\n */\r\n private emitStallSkip(): void {\r\n this.trackVideoEvent(PlayerEvent.VIDEO_ENDED, 'stall-skip');\r\n }\r\n\r\n /** Pause keeping the current position. */\r\n pause(): void {\r\n this.stopFrameStepping();\r\n this.cancelPendingSwap();\r\n this.detachReverseVariantListener();\r\n const video = this.video;\r\n if (video) {\r\n video.pause();\r\n }\r\n this.controller.unregister(this.videoId);\r\n this.showUnmuteButton = false;\r\n this.cdr.markForCheck();\r\n }\r\n\r\n /** Pause and reset to the configured start offset. */\r\n stop(): void {\r\n this.stopFrameStepping();\r\n this.cancelPendingSwap();\r\n this.detachReverseVariantListener();\r\n this.reversePhase = false;\r\n const video = this.video;\r\n if (video) {\r\n video.pause();\r\n this.seekToStart();\r\n }\r\n this.controller.unregister(this.videoId);\r\n this.showUnmuteButton = false;\r\n this.cdr.markForCheck();\r\n }\r\n\r\n /** Unmute affordance clicked: count the gesture and unmute. */\r\n onUnmuteClick(event: Event): void {\r\n event.stopPropagation();\r\n this.gesture.markInteracted();\r\n const video = this.video;\r\n if (video) {\r\n this.setElementMuted(false);\r\n this.controller.notifyMutedChanged(this.videoId, false);\r\n }\r\n this.showUnmuteButton = false;\r\n this.cdr.markForCheck();\r\n }\r\n\r\n private wantsSound(): boolean {\r\n // pingpong is always silent; only non-muted authored config wants sound.\r\n return !this.muted && this.playMode !== 'pingpong';\r\n }\r\n\r\n private computeEffectiveMuted(): boolean {\r\n // Player-wide Audio toggle off: silent, whatever is authored.\r\n if (this.audioEngine.isMasterMuted()) {\r\n return true;\r\n }\r\n // Pingpong: muted during the reverse phase regardless of setting, and\r\n // muted before any user gesture (autoplay policy) even though pingpong\r\n // is otherwise excluded from the unmute affordance (see wantsSound()).\r\n if (this.playMode === 'pingpong' && !this.pingpongDegraded) {\r\n return this.muted || this.reversePhase || !this.gesture.hasInteracted();\r\n }\r\n if (this.muted) {\r\n return true;\r\n }\r\n // Wants sound but no gesture yet → forced muted (with affordance).\r\n return !this.gesture.hasInteracted();\r\n }\r\n\r\n private setElementMuted(muted: boolean): void {\r\n this.displayMuted = muted;\r\n const video = this.video;\r\n if (video) {\r\n video.muted = muted;\r\n }\r\n }\r\n\r\n private seekToStart(): void {\r\n const video = this.video;\r\n if (video && Number.isFinite(this.startTimeSec)) {\r\n try {\r\n video.currentTime = this.startTimeSec;\r\n } catch {\r\n // currentTime may throw before metadata is ready; ignored.\r\n }\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Media event handling (play-mode engine)\r\n // ---------------------------------------------------------------------------\r\n\r\n private attachMediaListeners(): void {\r\n const video = this.video;\r\n if (!video) return;\r\n video.addEventListener('ended', this.onEndedBound);\r\n video.addEventListener('play', this.onPlayBound);\r\n video.addEventListener('pause', this.onPauseBound);\r\n video.addEventListener('waiting', this.onWaitingBound);\r\n video.addEventListener('timeupdate', this.onTimeUpdateBound);\r\n }\r\n\r\n private detachMediaListeners(): void {\r\n const video = this.video;\r\n if (!video) return;\r\n video.removeEventListener('ended', this.onEndedBound);\r\n video.removeEventListener('play', this.onPlayBound);\r\n video.removeEventListener('pause', this.onPauseBound);\r\n video.removeEventListener('waiting', this.onWaitingBound);\r\n video.removeEventListener('timeupdate', this.onTimeUpdateBound);\r\n }\r\n\r\n private handleEnded(): void {\r\n const mode = this.pingpongDegraded ? 'loop' : this.playMode;\r\n\r\n // `videoEnd` means \"the video is finished\" (once mode). Loop /\r\n // loop-from / pingpong all restart internally on the native `ended`\r\n // event, so it must not fire at those internal boundaries.\r\n if (mode === 'once') {\r\n this.videoEnd.emit();\r\n this.trackVideoEvent(PlayerEvent.VIDEO_ENDED, 'ended');\r\n }\r\n\r\n switch (mode) {\r\n case 'once':\r\n // Freeze on last frame — do not rewind.\r\n this.controller.unregister(this.videoId);\r\n this.emitPassComplete();\r\n break;\r\n case 'loop':\r\n this.seekToStart();\r\n this.emitLoop();\r\n this.emitPassComplete();\r\n void this.video?.play();\r\n break;\r\n case 'loop-from':\r\n this.seekToLoopFrom();\r\n this.emitLoop();\r\n this.emitPassComplete();\r\n void this.video?.play();\r\n break;\r\n case 'pingpong':\r\n // Forward pass ended; the reverse pass begins now and completes\r\n // the cycle. `videoLoop`/`passComplete` for this cycle are emitted\r\n // once, from `finishReversePass`, when the cycle actually completes.\r\n this.startReversePass();\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Emit the `passComplete` output and notify the sequencer that this video\r\n * finished one full pass, so the queue can advance.\r\n */\r\n private emitPassComplete(): void {\r\n this.passComplete.emit();\r\n this.sequencer.notifyPassComplete(this.videoId);\r\n this.controller.notifyPassComplete(this.videoId);\r\n }\r\n\r\n /** Emit the `videoLoop` output and a `VIDEO_LOOP` tracking event. */\r\n private emitLoop(): void {\r\n this.videoLoop.emit();\r\n this.trackVideoEvent(PlayerEvent.VIDEO_LOOP);\r\n }\r\n\r\n private seekToLoopFrom(): void {\r\n const video = this.video;\r\n if (!video) return;\r\n const loopFrom = this.loopFromSec;\r\n const duration = video.duration || 0;\r\n // Clamp invalid loopFrom (>= duration or < startAt) to startAt.\r\n if (\r\n loopFrom === undefined ||\r\n !Number.isFinite(loopFrom) ||\r\n loopFrom < this.startTimeSec ||\r\n (duration > 0 && loopFrom >= duration)\r\n ) {\r\n this.seekToStart();\r\n return;\r\n }\r\n try {\r\n video.currentTime = loopFrom;\r\n } catch {\r\n this.seekToStart();\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Ping-pong engine\r\n // ---------------------------------------------------------------------------\r\n\r\n private resolvePingpongStrategy(): void {\r\n if (this.playMode !== 'pingpong') {\r\n this.pingpongDegraded = false;\r\n return;\r\n }\r\n // Streaming assets cannot frame-step or swap seamlessly → degrade to loop.\r\n if (this.streaming) {\r\n this.pingpongDegraded = true;\r\n this.warnPingpongDegraded('streaming/HLS video');\r\n return;\r\n }\r\n this.pingpongDegraded = false;\r\n this.usingReverseVariant = !!this.reverseSrc;\r\n }\r\n\r\n private warnPingpongDegraded(reason: string): void {\r\n if (!VideoLayerComponent.pingpongWarned) {\r\n VideoLayerComponent.pingpongWarned = true;\r\n console.warn(\r\n `[pw-video-layer] pingpong not supported for ${reason}; falling back to loop.`\r\n );\r\n }\r\n }\r\n\r\n /** Begin the backward pass of a pingpong cycle. */\r\n private startReversePass(): void {\r\n const video = this.video;\r\n if (!video) return;\r\n this.reversePhase = true;\r\n\r\n if (this.usingReverseVariant && this.reverseSrc) {\r\n // Seamless swap: play the pre-rendered reverse encode (muted). The\r\n // new source's metadata (and therefore a meaningful `currentTime`)\r\n // is not available synchronously after assigning `src` — seeking/\r\n // playing must wait for `loadedmetadata` on some browsers, so defer\r\n // via a dedicated one-time listener rather than the template's\r\n // persistent `onLoadedMetadata` (guarded off via swapInProgress).\r\n this.setElementMuted(true);\r\n this.beginSwap(video, () => {\r\n const v = this.video;\r\n if (!v) return;\r\n try {\r\n v.currentTime = 0;\r\n } catch {\r\n // currentTime may throw if metadata still isn't ready; ignored.\r\n }\r\n void v.play();\r\n });\r\n video.src = this.resolveUrl(this.reverseSrc);\r\n video.addEventListener('ended', this.onReverseVariantEndedBound, { once: true });\r\n return;\r\n }\r\n\r\n // Fallback: frame-step currentTime backward toward startAtMs.\r\n this.setElementMuted(true);\r\n video.pause();\r\n this.startFrameStepping();\r\n }\r\n\r\n private readonly onReverseVariantEndedBound = (): void =>\r\n this.finishReversePass();\r\n\r\n /**\r\n * Complete the backward pass: swap back to the forward variant (if a\r\n * seamless reverse variant was used) and start the next forward pass.\r\n * This marks the completion of one full pingpong cycle, so the cycle's\r\n * single `videoLoop`/`passComplete` emissions happen here.\r\n */\r\n private finishReversePass(): void {\r\n this.reversePhase = false;\r\n const video = this.video;\r\n if (!video) return;\r\n\r\n if (this.usingReverseVariant && this.reverseSrc) {\r\n // Swap back to the forward variant. Same metadata-timing hazard as\r\n // the reverse swap: defer the seek/play until the new source's\r\n // `loadedmetadata`, guarding the template's initial-setup handler.\r\n this.beginSwap(video, () => {\r\n const v = this.video;\r\n if (!v) return;\r\n this.setElementMuted(this.computeEffectiveMuted());\r\n this.seekToStart();\r\n void v.play();\r\n });\r\n video.src = this.getVideoUrl();\r\n } else {\r\n // Frame-stepping fallback: already on the forward source, already at\r\n // the start offset (set by startFrameStepping's tick loop).\r\n this.setElementMuted(this.computeEffectiveMuted());\r\n void video.play();\r\n }\r\n\r\n this.emitLoop();\r\n this.emitPassComplete();\r\n }\r\n\r\n /**\r\n * Register a one-time `loadedmetadata` listener for a src swap and mark\r\n * `swapInProgress`. The stored reference lets `cancelPendingSwap()` remove\r\n * it (and clear the flag) if playback is stopped mid-swap, avoiding an\r\n * orphaned callback that would `play()` a stopped video.\r\n */\r\n private beginSwap(video: HTMLVideoElement, afterLoad: () => void): void {\r\n this.cancelPendingSwap();\r\n this.swapInProgress = true;\r\n const listener = (): void => {\r\n this.swapInProgress = false;\r\n this.pendingSwapListener = null;\r\n afterLoad();\r\n };\r\n this.pendingSwapListener = listener;\r\n video.addEventListener('loadedmetadata', listener, { once: true });\r\n }\r\n\r\n /**\r\n * Remove any pending swap `loadedmetadata` listener and clear the\r\n * in-progress flag. Safe to call when no swap is pending.\r\n */\r\n private cancelPendingSwap(): void {\r\n if (this.pendingSwapListener) {\r\n this.video?.removeEventListener('loadedmetadata', this.pendingSwapListener);\r\n this.pendingSwapListener = null;\r\n }\r\n this.swapInProgress = false;\r\n }\r\n\r\n /**\r\n * Remove the one-time `ended` listener registered for the reverse-variant\r\n * pass, so a stop mid-reverse-pass cannot later trigger `finishReversePass`.\r\n */\r\n private detachReverseVariantListener(): void {\r\n this.video?.removeEventListener('ended', this.onReverseVariantEndedBound);\r\n }\r\n\r\n private startFrameStepping(): void {\r\n const video = this.video;\r\n if (!video) return;\r\n const step = 1 / 30; // ~30fps backward stepping\r\n const tick = (): void => {\r\n if (!this.reversePhase || !this.video) {\r\n return;\r\n }\r\n const next = this.video.currentTime - step;\r\n if (next <= this.startTimeSec) {\r\n this.video.currentTime = this.startTimeSec;\r\n this.finishReversePass();\r\n return;\r\n }\r\n this.video.currentTime = next;\r\n this.scheduleFrameStep(tick);\r\n };\r\n this.scheduleFrameStep(tick);\r\n }\r\n\r\n private scheduleFrameStep(cb: () => void): void {\r\n const video = this.video as (HTMLVideoElement & {\r\n requestVideoFrameCallback?: (fn: () => void) => number;\r\n }) | undefined;\r\n if (video?.requestVideoFrameCallback) {\r\n this.frameStepHandle = video.requestVideoFrameCallback(() => cb());\r\n } else if (typeof requestAnimationFrame !== 'undefined') {\r\n this.frameStepHandle = requestAnimationFrame(() => cb());\r\n } else {\r\n this.frameStepHandle = setTimeout(cb, 33) as unknown as number;\r\n }\r\n }\r\n\r\n private stopFrameStepping(): void {\r\n if (this.frameStepHandle === null) return;\r\n const video = this.video as (HTMLVideoElement & {\r\n cancelVideoFrameCallback?: (h: number) => void;\r\n }) | undefined;\r\n if (video?.cancelVideoFrameCallback) {\r\n video.cancelVideoFrameCallback(this.frameStepHandle);\r\n } else if (typeof cancelAnimationFrame !== 'undefined') {\r\n cancelAnimationFrame(this.frameStepHandle);\r\n } else {\r\n clearTimeout(this.frameStepHandle);\r\n }\r\n this.frameStepHandle = null;\r\n }\r\n}\r\n","<div\r\n class=\"video-layer-container\"\r\n [class.interactive]=\"isKeyboardInteractive()\"\r\n [attr.tabindex]=\"isKeyboardInteractive() ? 0 : null\"\r\n [attr.role]=\"isKeyboardInteractive() ? 'button' : null\"\r\n [attr.aria-label]=\"ariaLabel || null\"\r\n (click)=\"onClick()\"\r\n (keydown)=\"onKeydown($event)\"\r\n (mouseenter)=\"onMouseEnter()\"\r\n (mouseleave)=\"onMouseLeave()\">\r\n <video\r\n #videoElement\r\n class=\"video-layer\"\r\n [src]=\"getVideoUrl()\"\r\n [poster]=\"getPosterUrl()\"\r\n [muted]=\"displayMuted\"\r\n [controls]=\"controls\"\r\n playsinline\r\n preload=\"metadata\"\r\n (loadedmetadata)=\"onLoadedMetadata()\"\r\n (error)=\"onError($event)\">\r\n Your browser does not support the video tag.\r\n </video>\r\n\r\n @if (showUnmuteButton) {\r\n <button\r\n type=\"button\"\r\n class=\"video-unmute-affordance\"\r\n aria-label=\"Unmute video\"\r\n (click)=\"onUnmuteClick($event)\">\r\n <span class=\"video-unmute-icon\" aria-hidden=\"true\">🔊</span>\r\n <span class=\"video-unmute-label\">Unmute</span>\r\n </button>\r\n }\r\n</div>\r\n","/**\r\n * Layer Renderer Component\r\n * Renders individual layers based on their type\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n inject,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport type {\r\n Layer,\r\n LocaleCode,\r\n VideoLayer,\r\n VideoPlayMode,\r\n VideoStartMode,\r\n AssetCatalogItemVideo,\r\n VideoVariant,\r\n ImageVariant,\r\n} from '../../types';\r\nimport { ManifestService } from '../../services/manifest.service';\r\nimport { VideoLayerComponent, type LayerViewMode } from '../layers/video-layer/video-layer.component';\r\nimport {\r\n resolvePlayMode,\r\n resolveStartMode,\r\n resolveMuted,\r\n} from '../../utils/video-config-utils';\r\nimport { selectImageVariantForWidth } from '../../utils/image-variant-utils';\r\n\r\n/**\r\n * Layer Renderer Component\r\n * Dynamically renders layers based on their kind\r\n */\r\n@Component({\r\n selector: 'pw-layer-renderer',\r\n imports: [CommonModule, VideoLayerComponent],\r\n templateUrl: './layer-renderer.component.html',\r\n styleUrls: ['./layer-renderer.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class LayerRendererComponent {\r\n private manifestService = inject(ManifestService);\r\n\r\n /**\r\n * Layer to render\r\n */\r\n @Input() layer!: Layer;\r\n\r\n /**\r\n * Current locale for localized content\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Base URL for resolving asset paths\r\n */\r\n @Input() baseUrl = '';\r\n\r\n /**\r\n * Required display width in physical pixels for image variant selection\r\n * (canvas view variant-by-zoom). 0 keeps the legacy first-variant pick.\r\n */\r\n @Input() targetWidth = 0;\r\n\r\n /**\r\n * Alt text for image layers (localized)\r\n */\r\n @Input() altText = '';\r\n\r\n /**\r\n * View mode of the surrounding viewport (`on-hover` only applies to page view).\r\n */\r\n @Input() viewMode: LayerViewMode = 'panel';\r\n\r\n /**\r\n * Whether the owning panel is currently visible / current. Drives `on-view`\r\n * playback for video layers (sequencer surface), and makes the panel's\r\n * images load eagerly at high fetch priority — the current panel's art is\r\n * the page's largest paint, and `loading=\"lazy\"` delayed it (Lighthouse\r\n * LCP 5.4 s on the demo). Every other panel stays lazy.\r\n */\r\n @Input() viewActive = false;\r\n\r\n /**\r\n * Reduced-motion preference (degrades video `on-view` to `on-click`).\r\n */\r\n @Input() reducedMotion = false;\r\n\r\n /**\r\n * Panel id the current layer belongs to (for video tracking + sequencing).\r\n */\r\n @Input() panelId = '';\r\n\r\n /**\r\n * Placement id used for page-view visibility observation (video sequencing).\r\n */\r\n @Input() placementId = '';\r\n\r\n /**\r\n * Index of the owning panel in `Page.readingOrder` (or -1). Drives video\r\n * sequencing order in page view.\r\n */\r\n @Input() readingOrderIndex = -1;\r\n\r\n /** Placement z-index (video sequencer fallback ordering). */\r\n @Input() placementZ = 0;\r\n\r\n /** Placement y position 0-1 (video sequencer fallback ordering). */\r\n @Input() placementY = 0;\r\n\r\n /** Placement x position 0-1 (video sequencer fallback ordering). */\r\n @Input() placementX = 0;\r\n\r\n /**\r\n * Layer clicked\r\n */\r\n @Output() layerClick = new EventEmitter<{ layerId: string; x: number; y: number }>();\r\n\r\n /**\r\n * Get layer position and size styles\r\n */\r\n getLayerStyles(): Record<string, string> {\r\n const styles: Record<string, string> = {\r\n position: 'absolute',\r\n };\r\n\r\n const layer = this.layer as Record<string, unknown>;\r\n\r\n // Position\r\n if (layer['x'] !== undefined) {\r\n styles['left'] = `${layer['x']}px`;\r\n } else {\r\n styles['left'] = '0';\r\n }\r\n \r\n if (layer['y'] !== undefined) {\r\n styles['top'] = `${layer['y']}px`;\r\n } else {\r\n styles['top'] = '0';\r\n }\r\n\r\n // Size\r\n if (layer['w'] !== undefined) {\r\n styles['width'] = `${layer['w']}px`;\r\n } else {\r\n styles['width'] = '100%';\r\n }\r\n \r\n if (layer['h'] !== undefined) {\r\n styles['height'] = `${layer['h']}px`;\r\n } else {\r\n styles['height'] = '100%';\r\n }\r\n\r\n // Z-index\r\n if (this.layer.z !== undefined) {\r\n styles['z-index'] = `${this.layer.z}`;\r\n }\r\n\r\n // Opacity\r\n if (this.layer.opacity !== undefined) {\r\n styles['opacity'] = `${this.layer.opacity}`;\r\n }\r\n\r\n return styles;\r\n }\r\n\r\n /**\r\n * Get transform style\r\n */\r\n getTransformStyle(): string {\r\n if (!this.layer.transform) {\r\n return '';\r\n }\r\n\r\n const t = this.layer.transform as Record<string, unknown>;\r\n const transforms: string[] = [];\r\n\r\n if (t['translateX'] || t['translateY']) {\r\n transforms.push(`translate(${t['translateX'] || 0}px, ${t['translateY'] || 0}px)`);\r\n }\r\n\r\n if (t['rotate']) {\r\n transforms.push(`rotate(${t['rotate']}deg)`);\r\n }\r\n\r\n if (t['scale']) {\r\n transforms.push(`scale(${t['scale']})`);\r\n }\r\n\r\n return transforms.join(' ');\r\n }\r\n\r\n /**\r\n * Get image source URL\r\n */\r\n getImageSrc(): string {\r\n if (this.layer.kind !== 'image') return '';\r\n\r\n // Try to get assetId first (from manifest reference)\r\n const assetId = (this.layer as Record<string, unknown>)['assetId'];\r\n if (assetId && typeof assetId === 'string') {\r\n const asset = this.manifestService.getAsset(assetId);\r\n if (asset && asset.variants && asset.variants.length > 0) {\r\n // Variant-by-zoom (canvas view): the smallest variant covering the\r\n // required display width; targetWidth 0 keeps the legacy first pick.\r\n const variant = selectImageVariantForWidth(\r\n asset.variants as ImageVariant[],\r\n this.targetWidth\r\n );\r\n return variant?.src ?? asset.variants[0].src;\r\n }\r\n }\r\n\r\n // Fall back to direct src if provided\r\n const src = (this.layer as Record<string, unknown>)['src'];\r\n return src ? `${this.baseUrl}${src}` : '';\r\n }\r\n\r\n /**\r\n * Get the video catalog item for the current layer (if any).\r\n */\r\n private getVideoAsset(): AssetCatalogItemVideo | null {\r\n if (this.layer.kind !== 'video') return null;\r\n const assetId = (this.layer as Record<string, unknown>)['assetId'];\r\n if (assetId && typeof assetId === 'string') {\r\n const asset = this.manifestService.getAsset(assetId);\r\n if (asset && (asset as AssetCatalogItemVideo).category === 'video') {\r\n return asset as AssetCatalogItemVideo;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * The forward (non-reverse) video variant, falling back to the first\r\n * variant. Single source of truth for forward-variant selection (used by\r\n * both {@link getVideoSrc} and {@link getVideoStreaming}).\r\n */\r\n private forwardVideoVariant(\r\n asset: AssetCatalogItemVideo | null\r\n ): VideoVariant | undefined {\r\n return (\r\n asset?.variants?.find((v) => v.direction !== 'reverse') ??\r\n asset?.variants?.[0]\r\n );\r\n }\r\n\r\n /** The reverse video variant for pingpong, if any. */\r\n private reverseVideoVariant(\r\n asset: AssetCatalogItemVideo | null\r\n ): VideoVariant | undefined {\r\n return asset?.variants?.find((v) => v.direction === 'reverse');\r\n }\r\n\r\n /**\r\n * Get the forward (default) video source URL. Catalog and direct-src paths\r\n * both return the RAW src — baseUrl resolution (and skipping already-absolute\r\n * URLs) is owned downstream by `pw-video-layer` (`resolveUrl`), so prefixing\r\n * here would double-apply it.\r\n */\r\n getVideoSrc(): string {\r\n if (this.layer.kind !== 'video') return '';\r\n\r\n const forward = this.forwardVideoVariant(this.getVideoAsset());\r\n if (forward) {\r\n return forward.src;\r\n }\r\n\r\n // Fall back to direct src if provided.\r\n const src = (this.layer as Record<string, unknown>)['src'];\r\n return typeof src === 'string' ? src : '';\r\n }\r\n\r\n /**\r\n * Get the reverse-variant URL for pingpong (empty string if none). Raw src;\r\n * resolved downstream by `pw-video-layer`, same as {@link getVideoSrc}.\r\n */\r\n getVideoReverseSrc(): string {\r\n return this.reverseVideoVariant(this.getVideoAsset())?.src ?? '';\r\n }\r\n\r\n /**\r\n * Get the poster URL for the video (empty string if none). Sourced from\r\n * the catalog asset's `poster.src` (schema 1.1+); resolved against the\r\n * renderer's `baseUrl` downstream by `pw-video-layer`, same as\r\n * `getVideoSrc()`.\r\n */\r\n getVideoPoster(): string {\r\n const asset = this.getVideoAsset();\r\n return asset?.poster?.src ?? '';\r\n }\r\n\r\n /**\r\n * Whether the active (forward) video variant is streaming/HLS.\r\n */\r\n getVideoStreaming(): boolean {\r\n return this.forwardVideoVariant(this.getVideoAsset())?.streaming === true;\r\n }\r\n\r\n /**\r\n * Effective video play mode (layer → settings.ui default → built-in).\r\n */\r\n getVideoPlayMode(): VideoPlayMode {\r\n return resolvePlayMode(this.layer as Partial<VideoLayer>, this.uiDefaults());\r\n }\r\n\r\n /**\r\n * Effective video start mode (layer → settings.ui default → built-in).\r\n */\r\n getVideoStartMode(): VideoStartMode {\r\n return resolveStartMode(this.layer as Partial<VideoLayer>, this.uiDefaults());\r\n }\r\n\r\n /**\r\n * Effective video muted state (layer → settings.ui default → built-in true).\r\n */\r\n getVideoMuted(): boolean {\r\n return resolveMuted(this.layer as Partial<VideoLayer>, this.uiDefaults());\r\n }\r\n\r\n /**\r\n * Effective startAtMs offset.\r\n */\r\n getVideoStartAtMs(): number {\r\n const value = (this.layer as Record<string, unknown>)['startAtMs'];\r\n return typeof value === 'number' ? value : 0;\r\n }\r\n\r\n /**\r\n * loopFromMs (only meaningful for playMode 'loop-from').\r\n */\r\n getVideoLoopFromMs(): number | undefined {\r\n const value = (this.layer as Record<string, unknown>)['loopFromMs'];\r\n return typeof value === 'number' ? value : undefined;\r\n }\r\n\r\n /**\r\n * Work-level UI defaults from the loaded manifest, if any.\r\n */\r\n private uiDefaults() {\r\n return this.manifestService.getManifest()?.settings?.ui;\r\n }\r\n\r\n /**\r\n * Get image alt text\r\n */\r\n getAltText(): string {\r\n // Use provided altText input first, then check layer property\r\n if (this.altText) {\r\n return this.altText;\r\n }\r\n const alt = (this.layer as Record<string, unknown>)['alt'];\r\n return alt ? String(alt) : '';\r\n }\r\n\r\n /**\r\n * Catalog asset id of the current video layer (empty string if none).\r\n */\r\n getVideoAssetId(): string {\r\n const assetId = (this.layer as Record<string, unknown>)['assetId'];\r\n return typeof assetId === 'string' ? assetId : '';\r\n }\r\n\r\n /**\r\n * Get video controls setting (defaults to false; native controls hidden\r\n * unless the layer explicitly enables them).\r\n */\r\n getVideoControls(): boolean {\r\n const controls = (this.layer as Record<string, unknown>)['controls'];\r\n return controls === true;\r\n }\r\n\r\n /**\r\n * Get SVG content\r\n */\r\n getSvgContent(): string {\r\n const svg = (this.layer as Record<string, unknown>)['svg'];\r\n return svg ? String(svg) : '';\r\n }\r\n\r\n /**\r\n * Get shape type\r\n */\r\n getShapeType(): string {\r\n const shape = (this.layer as Record<string, unknown>)['shape'];\r\n return shape ? String(shape) : '';\r\n }\r\n\r\n /**\r\n * Get localized text content\r\n */\r\n getTextContent(): string {\r\n if (this.layer.kind !== 'text') return '';\r\n \r\n const text = (this.layer as Record<string, unknown>)['text'];\r\n if (!text || typeof text !== 'object') return '';\r\n\r\n const textObj = text as Record<string, string>;\r\n\r\n // Try exact locale match\r\n if (textObj[this.locale]) {\r\n return textObj[this.locale];\r\n }\r\n\r\n // Try base language (e.g., 'en' from 'en-US')\r\n const baseLocale = this.locale.split('-')[0];\r\n const baseMatch = Object.keys(textObj).find(\r\n (key) => key.startsWith(baseLocale)\r\n );\r\n if (baseMatch) {\r\n return textObj[baseMatch];\r\n }\r\n\r\n // Return first available\r\n const firstKey = Object.keys(textObj)[0];\r\n return firstKey ? textObj[firstKey] : '';\r\n }\r\n\r\n /**\r\n * Effective TextStyle for a text layer: styleRef preset from\r\n * settings.typography.textStyles (schema 1.3+) merged with the layer's\r\n * inline `style` object (inline fields win). Unknown styleRefs are ignored.\r\n */\r\n private resolveTextStyle(): Record<string, unknown> {\r\n const layer = this.layer as Record<string, unknown>;\r\n const styleRef = layer['styleRef'];\r\n const preset = typeof styleRef === 'string'\r\n ? this.manifestService.getManifest()?.settings?.typography?.textStyles?.[styleRef]\r\n : undefined;\r\n const inline = layer['style'];\r\n return {\r\n ...(preset ?? {}),\r\n ...(inline && typeof inline === 'object' ? inline as Record<string, unknown> : {}),\r\n };\r\n }\r\n\r\n /**\r\n * Get text styles\r\n */\r\n getTextStyles(): Record<string, string> {\r\n if (this.layer.kind !== 'text') return {};\r\n\r\n const styles: Record<string, string> = {};\r\n const layer = this.layer as Record<string, unknown>;\r\n\r\n // Schema TextStyle (styleRef preset + inline style object) first; flat\r\n // editor props below keep their historical precedence and win over it.\r\n const textStyle = this.resolveTextStyle();\r\n if (textStyle['font']) {\r\n styles['font-family'] = textStyle['font'] as string;\r\n }\r\n if (textStyle['sizePt']) {\r\n styles['font-size'] = `${textStyle['sizePt']}pt`;\r\n }\r\n if (textStyle['color']) {\r\n styles['color'] = textStyle['color'] as string;\r\n }\r\n if (textStyle['weight']) {\r\n styles['font-weight'] = `${textStyle['weight']}`;\r\n }\r\n if (textStyle['align']) {\r\n styles['text-align'] = textStyle['align'] as string;\r\n }\r\n if (textStyle['strokeColor'] && textStyle['strokeWidth']) {\r\n styles['-webkit-text-stroke'] = `${textStyle['strokeWidth']}px ${textStyle['strokeColor']}`;\r\n styles['paint-order'] = 'stroke fill';\r\n }\r\n\r\n if (layer['fontSize']) {\r\n styles['font-size'] = `${layer['fontSize']}px`;\r\n }\r\n\r\n if (layer['fontFamily']) {\r\n styles['font-family'] = layer['fontFamily'] as string;\r\n }\r\n\r\n if (layer['fontWeight']) {\r\n styles['font-weight'] = `${layer['fontWeight']}`;\r\n }\r\n\r\n if (layer['color']) {\r\n styles['color'] = layer['color'] as string;\r\n }\r\n\r\n if (layer['textAlign']) {\r\n styles['text-align'] = layer['textAlign'] as string;\r\n }\r\n\r\n if (layer['lineHeight']) {\r\n styles['line-height'] = `${layer['lineHeight']}`;\r\n }\r\n\r\n return styles;\r\n }\r\n\r\n /**\r\n * Handle layer click\r\n */\r\n onLayerClick(event: MouseEvent): void {\r\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n\r\n this.layerClick.emit({\r\n layerId: this.layer.id,\r\n x,\r\n y,\r\n });\r\n }\r\n\r\n /**\r\n * Check if layer is interactive\r\n */\r\n isInteractive(): boolean {\r\n // Note: 'hotspot' and 'button' are not in the current LayerKind type\r\n // This method is kept for future compatibility\r\n const kind = this.layer.kind as string;\r\n return kind === 'hotspot' || kind === 'button';\r\n }\r\n}\r\n","<div \r\n class=\"layer-wrapper\"\r\n [ngStyle]=\"getLayerStyles()\"\r\n [style.transform]=\"getTransformStyle()\"\r\n [class.interactive]=\"isInteractive()\"\r\n [attr.data-layer-id]=\"layer.id\"\r\n [attr.data-layer-kind]=\"layer.kind\"\r\n [tabindex]=\"isInteractive() ? 0 : -1\"\r\n (click)=\"isInteractive() ? onLayerClick($event) : null\"\r\n (keydown.enter)=\"isInteractive() ? onLayerClick($any($event)) : null\">\r\n\r\n <!-- Image Layer -->\r\n @if (layer.kind === 'image') {\r\n <img \r\n [src]=\"getImageSrc()\"\r\n [alt]=\"getAltText()\"\r\n class=\"layer-image\"\r\n [attr.loading]=\"viewActive ? 'eager' : 'lazy'\"\r\n [attr.fetchpriority]=\"viewActive ? 'high' : null\" />\r\n }\r\n\r\n <!-- Video Layer -->\r\n @if (layer.kind === 'video') {\r\n <pw-video-layer\r\n class=\"layer-video\"\r\n [src]=\"getVideoSrc()\"\r\n [reverseSrc]=\"getVideoReverseSrc()\"\r\n [baseUrl]=\"baseUrl\"\r\n [poster]=\"getVideoPoster()\"\r\n [controls]=\"getVideoControls()\"\r\n [playMode]=\"getVideoPlayMode()\"\r\n [startMode]=\"getVideoStartMode()\"\r\n [muted]=\"getVideoMuted()\"\r\n [startAtMs]=\"getVideoStartAtMs()\"\r\n [loopFromMs]=\"getVideoLoopFromMs()\"\r\n [streaming]=\"getVideoStreaming()\"\r\n [viewMode]=\"viewMode\"\r\n [viewActive]=\"viewActive\"\r\n [reducedMotion]=\"reducedMotion\"\r\n [videoId]=\"layer.id\"\r\n [panelId]=\"panelId\"\r\n [assetId]=\"getVideoAssetId()\"\r\n [placementId]=\"placementId || panelId\"\r\n [readingOrderIndex]=\"readingOrderIndex\"\r\n [placementZ]=\"placementZ\"\r\n [placementY]=\"placementY\"\r\n [placementX]=\"placementX\"\r\n [ariaLabel]=\"getAltText()\">\r\n </pw-video-layer>\r\n }\r\n\r\n <!-- Text Layer -->\r\n @if (layer.kind === 'text') {\r\n <div \r\n class=\"layer-text\"\r\n [ngStyle]=\"getTextStyles()\"\r\n [innerHTML]=\"getTextContent()\">\r\n </div>\r\n }\r\n\r\n <!-- Hotspot Layer -->\r\n @if (layer.kind === 'hotspot') {\r\n <div \r\n class=\"layer-hotspot\"\r\n role=\"button\"\r\n tabindex=\"0\"\r\n [attr.aria-label]=\"'Interactive hotspot'\">\r\n <div class=\"hotspot-indicator\"></div>\r\n </div>\r\n }\r\n\r\n <!-- Button Layer -->\r\n @if (layer.kind === 'button') {\r\n <button \r\n class=\"layer-button\"\r\n type=\"button\">\r\n {{ getTextContent() }}\r\n </button>\r\n }\r\n\r\n <!-- SVG Layer -->\r\n @if (layer.kind === 'svg') {\r\n <div \r\n class=\"layer-svg\"\r\n [innerHTML]=\"getSvgContent()\">\r\n </div>\r\n }\r\n\r\n <!-- Shape Layer -->\r\n @if (layer.kind === 'shape') {\r\n <div class=\"layer-shape\" [attr.data-shape]=\"getShapeType()\">\r\n <!-- Shape rendering would be implemented here -->\r\n </div>\r\n }\r\n\r\n <!-- Group Layer (container for nested layers) -->\r\n @if (layer.kind === 'group') {\r\n <div class=\"layer-group\">\r\n <!-- Nested layers would be rendered here -->\r\n </div>\r\n }\r\n</div>\r\n","/**\r\n * Speech Bubbles Component\r\n * Renders speech bubbles using the ComicBalloon SVG renderer.\r\n * Supports all balloon types (normal, thought, shout, whisper, connector, cut-top variants),\r\n * configurable tails, hide-border effects, and per-character/per-bubble style overrides.\r\n * Works in both panel view and page view with normalized coordinate positioning.\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ElementRef,\r\n ChangeDetectionStrategy,\r\n OnChanges,\r\n SimpleChanges,\r\n AfterViewInit,\r\n OnDestroy,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport type {\r\n LocaleCode,\r\n SpeechBubble,\r\n BalloonConfig,\r\n BalloonConfigOverride,\r\n Character,\r\n} from '../../../types';\r\nimport { ComicBalloon } from '../../../utils/comic-balloon';\r\nimport type { TailOptions } from '../../../utils/comic-balloon';\r\nimport { DEFAULT_BALLOON_CONFIG, mergeBalloonConfig, balloonConfigToRenderOptions, balloonConfigToTailOptions } from '../../../utils/balloon-config';\r\nimport { ManifestService } from '../../../services/manifest.service';\r\n\r\n/**\r\n * Speech Bubbles Component\r\n * Renders speech bubbles with SVG balloon shapes, tails, and localized text.\r\n * Positions bubbles using normalized coordinates relative to the container.\r\n */\r\n@Component({\r\n selector: 'pw-speech-bubbles',\r\n imports: [],\r\n templateUrl: './speech-bubbles.component.html',\r\n styleUrls: ['./speech-bubbles.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class SpeechBubblesComponent implements OnChanges, AfterViewInit, OnDestroy {\r\n /**\r\n * Array of speech bubbles from the manifest (schema format)\r\n */\r\n @Input() bubbles: SpeechBubble[] = [];\r\n\r\n /**\r\n * Current locale for text resolution\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Container width in pixels (for converting normalized coords)\r\n */\r\n @Input() containerWidth = 0;\r\n\r\n /**\r\n * Container height in pixels (for converting normalized coords)\r\n */\r\n @Input() containerHeight = 0;\r\n\r\n /**\r\n * Per-screen lettering scale (player viewport height relative to the DIN A4\r\n * authoring frame). Balloon text keeps the same comfortable reading size on\r\n * every screen — it does NOT grow proportionally with the panel; only small\r\n * screens (phones) get smaller lettering.\r\n */\r\n @Input() readingScale = 1;\r\n\r\n /**\r\n * Work-level balloon config defaults (from settings.typography.balloon_config)\r\n */\r\n @Input() workBalloonConfig: BalloonConfig | null = null;\r\n\r\n /**\r\n * Characters array for resolving character-level balloon overrides\r\n */\r\n @Input() characters: Character[] = [];\r\n\r\n /**\r\n * Bubble clicked\r\n */\r\n @Output() bubbleClick = new EventEmitter<SpeechBubble>();\r\n\r\n /**\r\n * Bubble audio play requested\r\n */\r\n @Output() bubbleAudioPlay = new EventEmitter<{ bubble: SpeechBubble; audioAssetId: string }>();\r\n\r\n /** Rendered balloon containers, keyed by bubble ID */\r\n private renderedBalloons = new Map<string, HTMLElement>();\r\n\r\n /** ResizeObserver for container size tracking */\r\n private resizeObserver: ResizeObserver | null = null;\r\n\r\n private initialized = false;\r\n\r\n private elementRef = inject(ElementRef<HTMLElement>);\r\n\r\n private manifestService = inject(ManifestService);\r\n\r\n ngAfterViewInit(): void {\r\n this.initialized = true;\r\n // First paint without blocking on fonts (font-display: swap shows a\r\n // fallback), small delay to ensure container dimensions are available.\r\n setTimeout(() => this.renderAllBalloons(), 50);\r\n // Re-render once the comic fonts are loaded so text measurement is exact\r\n // even when the balloon fonts arrive late.\r\n if (typeof document !== 'undefined' && document.fonts) {\r\n document.fonts.ready.then(() => {\r\n if (this.initialized) {\r\n this.renderAllBalloons();\r\n }\r\n });\r\n }\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (!this.initialized) return;\r\n\r\n const needsRerender =\r\n changes['bubbles'] ||\r\n changes['locale'] ||\r\n changes['containerWidth'] ||\r\n changes['containerHeight'] ||\r\n changes['readingScale'] ||\r\n changes['workBalloonConfig'] ||\r\n changes['characters'];\r\n\r\n if (needsRerender) {\r\n this.renderAllBalloons();\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.initialized = false;\r\n this.resizeObserver?.disconnect();\r\n this.renderedBalloons.clear();\r\n }\r\n\r\n /**\r\n * Resolve the effective BalloonConfig for a bubble.\r\n * Merges: work defaults -> character overrides -> styleRef preset -> bubble overrides\r\n */\r\n resolveEffectiveConfig(bubble: SpeechBubble): BalloonConfig {\r\n const manifest = this.manifestService.getManifest();\r\n\r\n // Start with work-level defaults (input, else manifest) layered onto the\r\n // library defaults, so partial work configs keep sane values for the rest\r\n const workConfig = this.workBalloonConfig\r\n ?? manifest?.settings?.typography?.balloon_config\r\n ?? null;\r\n const baseConfig = workConfig\r\n ? mergeBalloonConfig(DEFAULT_BALLOON_CONFIG, workConfig as BalloonConfigOverride)\r\n : { ...DEFAULT_BALLOON_CONFIG };\r\n\r\n // Apply character-level overrides if characterId is set\r\n let config = baseConfig;\r\n if (bubble.characterId) {\r\n const characters = this.characters.length > 0\r\n ? this.characters\r\n : manifest?.meta?.characters ?? [];\r\n const character = characters.find(c => c.id === bubble.characterId);\r\n if (character?.balloonConfig) {\r\n config = mergeBalloonConfig(config, character.balloonConfig);\r\n }\r\n }\r\n\r\n // Apply the named preset from settings.typography.balloonPresets (schema 1.3+).\r\n // Unknown styleRefs are ignored.\r\n if (bubble.styleRef) {\r\n const preset = manifest?.settings?.typography?.balloonPresets?.[bubble.styleRef];\r\n if (preset) {\r\n config = mergeBalloonConfig(config, preset);\r\n }\r\n }\r\n\r\n // Apply bubble-level overrides\r\n if (bubble.balloonConfig) {\r\n return mergeBalloonConfig(config, bubble.balloonConfig as BalloonConfigOverride);\r\n }\r\n\r\n return config;\r\n }\r\n\r\n /**\r\n * Get localized text for a bubble\r\n */\r\n getLocalizedText(bubble: SpeechBubble): string {\r\n if (!bubble.text || typeof bubble.text !== 'object') {\r\n return '';\r\n }\r\n\r\n // Try exact locale match\r\n if (bubble.text[this.locale]) {\r\n return bubble.text[this.locale];\r\n }\r\n\r\n // Try base language\r\n const baseLocale = this.locale.split('-')[0];\r\n const baseMatch = Object.keys(bubble.text).find(\r\n (key) => key.startsWith(baseLocale)\r\n );\r\n\r\n if (baseMatch && bubble.text[baseMatch]) {\r\n return bubble.text[baseMatch];\r\n }\r\n\r\n // Return first available\r\n const firstKey = Object.keys(bubble.text)[0];\r\n return firstKey ? bubble.text[firstKey] : '';\r\n }\r\n\r\n /**\r\n * Compute the pixel position of a bubble from its normalized bounding box\r\n */\r\n computeBubblePosition(bubble: SpeechBubble): { left: number; top: number; width: number; height: number } {\r\n const cw = this.containerWidth || 1;\r\n const ch = this.containerHeight || 1;\r\n const shape = bubble.shape;\r\n\r\n if (!shape) {\r\n return { left: 0, top: 0, width: 120, height: 80 };\r\n }\r\n\r\n return {\r\n left: shape.x * cw + (shape.w * cw) / 2,\r\n top: shape.y * ch + (shape.h * ch) / 2,\r\n width: shape.w * cw,\r\n height: shape.h * ch,\r\n };\r\n }\r\n\r\n /**\r\n * Render all speech balloons into the DOM\r\n */\r\n renderAllBalloons(): void {\r\n const container = this.elementRef.nativeElement.querySelector('.speech-bubbles-container');\r\n if (!container) return;\r\n\r\n // Clear existing rendered balloons\r\n container.innerHTML = '';\r\n this.renderedBalloons.clear();\r\n\r\n if (!this.bubbles || this.bubbles.length === 0) return;\r\n if (this.containerWidth <= 0 || this.containerHeight <= 0) return;\r\n\r\n for (const bubble of this.bubbles) {\r\n const text = this.getLocalizedText(bubble);\r\n if (!text) continue;\r\n\r\n const config = this.resolveEffectiveConfig(bubble);\r\n const pos = this.computeBubblePosition(bubble);\r\n\r\n // Create wrapper div for positioning\r\n const wrapper = document.createElement('div');\r\n wrapper.classList.add('speech-bubble-wrapper');\r\n wrapper.setAttribute('data-bubble-id', bubble.id);\r\n wrapper.style.position = 'absolute';\r\n\r\n // Create balloon container\r\n const balloonContainer = document.createElement('div');\r\n balloonContainer.classList.add('balloon-container');\r\n\r\n // Build ComicBalloon render options from config\r\n const renderOpts = balloonConfigToRenderOptions(config);\r\n const tailOpts = balloonConfigToTailOptions(config);\r\n\r\n try {\r\n const balloonInstance = new ComicBalloon(balloonContainer, renderOpts);\r\n const result = balloonInstance.render(text, tailOpts as TailOptions | null);\r\n\r\n // The SVG is self-sized (natural, text-fitting balloon size)\r\n const svgWidth = result.svg?.style.width ? parseFloat(result.svg.style.width) : config.maxWidth;\r\n const svgHeight = result.svg?.style.height ? parseFloat(result.svg.style.height) : config.maxHeight;\r\n\r\n // Per-screen lettering: the natural-size balloon is scaled by the\r\n // reading scale — the same comfortable text size on every screen —\r\n // NOT proportionally with the authored shape box (which would blow\r\n // text up on large screens). Capped so a balloon never exceeds its\r\n // panel container, and clamped against broken measurements.\r\n let scale = Math.min(4, Math.max(0.25, this.readingScale || 1));\r\n if (svgWidth > 0 && svgHeight > 0) {\r\n scale = Math.max(0.25, Math.min(scale, this.containerWidth / svgWidth, this.containerHeight / svgHeight));\r\n }\r\n const visualW = svgWidth * scale;\r\n const visualH = svgHeight * scale;\r\n\r\n // Anchor at the shape box's center — but edges the authored box\r\n // touches stay glued to the panel border (narrator / Panel-Top\r\n // caption boxes keep sitting exactly on the border even though the\r\n // visual size no longer equals the stored box).\r\n const boxLeft = (bubble.shape?.x ?? 0) * this.containerWidth;\r\n const boxTop = (bubble.shape?.y ?? 0) * this.containerHeight;\r\n const boxRight = boxLeft + (bubble.shape?.w ?? 0) * this.containerWidth;\r\n const boxBottom = boxTop + (bubble.shape?.h ?? 0) * this.containerHeight;\r\n const eps = Math.max(4, 0.02 * Math.min(this.containerWidth, this.containerHeight));\r\n let centerX = pos.left;\r\n let centerY = pos.top;\r\n if (boxLeft <= eps) centerX = visualW / 2;\r\n else if (boxRight >= this.containerWidth - eps) centerX = this.containerWidth - visualW / 2;\r\n if (boxTop <= eps) centerY = visualH / 2;\r\n else if (boxBottom >= this.containerHeight - eps) centerY = this.containerHeight - visualH / 2;\r\n\r\n // The wrapper is scaled about its center, so its visual center lands\r\n // exactly on (centerX, centerY).\r\n wrapper.style.left = `${centerX - svgWidth / 2}px`;\r\n wrapper.style.top = `${centerY - svgHeight / 2}px`;\r\n if (Math.abs(scale - 1) > 0.01) {\r\n wrapper.style.transform = `scale(${scale})`;\r\n wrapper.style.transformOrigin = 'center center';\r\n }\r\n\r\n // Click handler\r\n wrapper.addEventListener('click', (event: MouseEvent) => {\r\n event.stopPropagation();\r\n this.bubbleClick.emit(bubble);\r\n\r\n // Emit audio play if bubble has an audio asset\r\n if (bubble.audioAssetId) {\r\n this.bubbleAudioPlay.emit({ bubble, audioAssetId: bubble.audioAssetId as string });\r\n }\r\n });\r\n\r\n // Accessibility\r\n wrapper.setAttribute('role', 'img');\r\n wrapper.setAttribute('aria-label', text);\r\n wrapper.setAttribute('tabindex', '0');\r\n\r\n // Keyboard support\r\n wrapper.addEventListener('keydown', (event: KeyboardEvent) => {\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n this.bubbleClick.emit(bubble);\r\n }\r\n });\r\n\r\n wrapper.appendChild(balloonContainer);\r\n container.appendChild(wrapper);\r\n this.renderedBalloons.set(bubble.id, wrapper);\r\n } catch (e) {\r\n console.warn(`[pw-speech-bubbles] Failed to render balloon \"${bubble.id}\":`, e);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle bubble click (called from template for any fallback interaction)\r\n */\r\n onBubbleClick(bubble: SpeechBubble, event: MouseEvent): void {\r\n event.stopPropagation();\r\n this.bubbleClick.emit(bubble);\r\n }\r\n}\r\n","<!-- Speech bubbles are rendered imperatively via ComicBalloon SVG renderer -->\n<div class=\"speech-bubbles-container\"></div>\n","/**\r\n * Hotspots Overlay Component\r\n * Renders a panel's interactive hotspots (manifest shape, normalized 0-1\r\n * geometry) on top of the panel content, mirroring the speech-bubbles\r\n * overlay contract: absolutely positioned host, container dimensions from\r\n * the parent, pointer events enabled per shape only.\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n OnChanges,\r\n} from '@angular/core';\r\n\r\nimport type {\r\n Hotspot,\r\n HotspotShape,\r\n HotspotRect,\r\n HotspotCircle,\r\n HotspotPolygon,\r\n LocalizedString,\r\n} from '../../../types';\r\nimport type { VariableContext } from '../../../types';\r\nimport { evaluateJsonLogic, resolveLocalizedString } from '../../../utils';\r\n\r\n/**\r\n * Hotspots Overlay Component\r\n * Displays interactive clickable areas over panel content\r\n */\r\n@Component({\r\n selector: 'pw-hotspots-overlay',\r\n imports: [],\r\n templateUrl: './hotspots-overlay.component.html',\r\n styleUrls: ['./hotspots-overlay.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class HotspotsOverlayComponent implements OnChanges {\r\n /**\r\n * Hotspots of the current panel (manifest shape)\r\n */\r\n @Input() hotspots: Hotspot[] = [];\r\n\r\n /**\r\n * Current locale for label resolution\r\n */\r\n @Input() locale = 'en-US';\r\n\r\n /**\r\n * Container width. Pixels in panel/page view, world units in canvas view —\r\n * both work because the SVG viewBox scales with the element.\r\n */\r\n @Input() containerWidth = 0;\r\n\r\n /**\r\n * Container height (same unit as containerWidth)\r\n */\r\n @Input() containerHeight = 0;\r\n\r\n /**\r\n * Variable context for visibleIf evaluation (null shows all hotspots)\r\n */\r\n @Input() context: VariableContext | null = null;\r\n\r\n /**\r\n * When false the overlay is render-only: no pointer events, no tab stops\r\n */\r\n @Input() interactive = true;\r\n\r\n /**\r\n * Show the pulsing indicator animation\r\n */\r\n @Input() showIndicators = true;\r\n\r\n /**\r\n * Hotspot activated (click or keyboard). x/y are normalized 0-1\r\n * panel-relative coordinates of the activation point.\r\n */\r\n @Output() hotspotActivate = new EventEmitter<{ hotspot: Hotspot; x: number; y: number }>();\r\n\r\n /**\r\n * Hotspots passing their visibleIf condition\r\n */\r\n visibleHotspots: Hotspot[] = [];\r\n\r\n ngOnChanges(): void {\r\n const ctx = this.context;\r\n this.visibleHotspots = (this.hotspots ?? []).filter(\r\n (h) => !h.visibleIf || !ctx || evaluateJsonLogic(h.visibleIf, ctx)\r\n );\r\n }\r\n\r\n /**\r\n * Accessible label: ariaLabel wins over label, falls back to the id\r\n */\r\n resolveLabel(h: Hotspot): string {\r\n return (\r\n this.resolveLocalized(h.ariaLabel) || this.resolveLocalized(h.label) || h.id\r\n );\r\n }\r\n\r\n private resolveLocalized(ls?: LocalizedString): string {\r\n return resolveLocalizedString(ls, this.locale, 'en-US');\r\n }\r\n\r\n /**\r\n * Denormalizers used by the template\r\n */\r\n rectAttrs(s: HotspotRect): { x: number; y: number; width: number; height: number } {\r\n return {\r\n x: s.x * this.containerWidth,\r\n y: s.y * this.containerHeight,\r\n width: s.w * this.containerWidth,\r\n height: s.h * this.containerHeight,\r\n };\r\n }\r\n\r\n circleAttrs(s: HotspotCircle): { cx: number; cy: number; r: number } {\r\n // r is normalized to the container WIDTH by convention\r\n return {\r\n cx: s.cx * this.containerWidth,\r\n cy: s.cy * this.containerHeight,\r\n r: s.r * this.containerWidth,\r\n };\r\n }\r\n\r\n polygonPoints(s: HotspotPolygon): string {\r\n return s.points\r\n .map(([px, py]) => `${px * this.containerWidth},${py * this.containerHeight}`)\r\n .join(' ');\r\n }\r\n\r\n /**\r\n * Pointer activation: emit the normalized click point\r\n */\r\n onShapeClick(h: Hotspot, event: MouseEvent): void {\r\n if (!this.interactive) return;\r\n event.preventDefault();\r\n // The upstream dead-click handler must NOT also fire for hotspot hits.\r\n event.stopPropagation();\r\n const target = event.currentTarget as SVGElement;\r\n const svg = target.ownerSVGElement ?? (target as unknown as SVGSVGElement);\r\n const r = svg.getBoundingClientRect();\r\n const x = r.width > 0 ? (event.clientX - r.left) / r.width : 0;\r\n const y = r.height > 0 ? (event.clientY - r.top) / r.height : 0;\r\n this.hotspotActivate.emit({ hotspot: h, x: this.clamp01(x), y: this.clamp01(y) });\r\n }\r\n\r\n /**\r\n * Keyboard activation: emit the shape centroid\r\n */\r\n activateByKeyboard(h: Hotspot): void {\r\n if (!this.interactive) return;\r\n const c = this.centroidOf(h.shape);\r\n this.hotspotActivate.emit({ hotspot: h, x: c.x, y: c.y });\r\n }\r\n\r\n onKeyDown(h: Hotspot, event: KeyboardEvent): void {\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.activateByKeyboard(h);\r\n }\r\n }\r\n\r\n private centroidOf(s: HotspotShape): { x: number; y: number } {\r\n switch (s.type) {\r\n case 'rect':\r\n return { x: s.x + s.w / 2, y: s.y + s.h / 2 };\r\n case 'circle':\r\n return { x: s.cx, y: s.cy };\r\n case 'polygon': {\r\n const n = s.points.length || 1;\r\n return {\r\n x: s.points.reduce((a, p) => a + p[0], 0) / n,\r\n y: s.points.reduce((a, p) => a + p[1], 0) / n,\r\n };\r\n }\r\n }\r\n }\r\n\r\n private clamp01(v: number): number {\r\n return Math.min(1, Math.max(0, v));\r\n }\r\n}\r\n","<svg\r\n class=\"hotspots-svg\"\r\n [class.non-interactive]=\"!interactive\"\r\n [attr.viewBox]=\"'0 0 ' + containerWidth + ' ' + containerHeight\"\r\n preserveAspectRatio=\"none\"\r\n aria-hidden=\"false\"\r\n>\r\n @for (h of visibleHotspots; track h.id) {\r\n <g\r\n class=\"hotspot-shape\"\r\n [class.indicator]=\"showIndicators\"\r\n [attr.role]=\"interactive ? 'button' : null\"\r\n [attr.tabindex]=\"interactive ? 0 : null\"\r\n [attr.aria-label]=\"resolveLabel(h)\"\r\n (click)=\"onShapeClick(h, $event)\"\r\n (keydown)=\"onKeyDown(h, $event)\"\r\n >\r\n @switch (h.shape.type) {\r\n @case ('rect') {\r\n <rect\r\n [attr.x]=\"rectAttrs($any(h.shape)).x\"\r\n [attr.y]=\"rectAttrs($any(h.shape)).y\"\r\n [attr.width]=\"rectAttrs($any(h.shape)).width\"\r\n [attr.height]=\"rectAttrs($any(h.shape)).height\"\r\n rx=\"6\"\r\n />\r\n }\r\n @case ('circle') {\r\n <circle\r\n [attr.cx]=\"circleAttrs($any(h.shape)).cx\"\r\n [attr.cy]=\"circleAttrs($any(h.shape)).cy\"\r\n [attr.r]=\"circleAttrs($any(h.shape)).r\"\r\n />\r\n }\r\n @case ('polygon') {\r\n <polygon [attr.points]=\"polygonPoints($any(h.shape))\" />\r\n }\r\n }\r\n </g>\r\n }\r\n</svg>\r\n","/**\r\n * Viewport Component\r\n * Main rendering container for panels with pan/zoom support\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n OnChanges,\r\n OnDestroy,\r\n SimpleChanges,\r\n HostListener,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n ElementRef,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport { LayerRendererComponent } from '../layer-renderer/layer-renderer.component';\r\nimport { SpeechBubblesComponent } from '../overlays/speech-bubbles/speech-bubbles.component';\r\nimport { HotspotsOverlayComponent } from '../overlays/hotspots-overlay/hotspots-overlay.component';\r\nimport { PwIconComponent } from '../icon/pw-icon.component';\r\nimport type { Panel, ViewMode, LocaleCode, Page, PanelPlacement, Layer, LocalizedString, AssetCatalogItem, BalloonConfig, Character, Graph, PreloadSettings, Transition, Hotspot, VariableContext } from '../../types';\r\nimport { ManifestService } from '../../services/manifest.service';\r\nimport { PreloadService } from '../../services/preload.service';\r\nimport { quantizeTargetWidth, selectImageVariantForWidth } from '../../utils/image-variant-utils';\r\n\r\n/**\r\n * Performance metrics interface\r\n */\r\nexport interface PerformanceMetrics {\r\n renderTime: number;\r\n panelCount: number;\r\n visiblePanelCount: number;\r\n culledPanelCount: number;\r\n memoryUsage?: number;\r\n transformCalculationTime: number;\r\n}\r\n\r\n/**\r\n * Debounce before re-resolving image variants after a zoom or resize change\r\n * (mirrors the canvas stage's camera-settle debounce) — never per frame.\r\n */\r\nconst VARIANT_SETTLE_MS = 180;\r\n\r\n/**\r\n * Viewport Component\r\n * Renders a panel with pan/zoom/transform capabilities\r\n */\r\n@Component({\r\n selector: 'pw-viewport',\r\n imports: [LayerRendererComponent, SpeechBubblesComponent, HotspotsOverlayComponent, PwIconComponent],\r\n templateUrl: './viewport.component.html',\r\n styleUrls: ['./viewport.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class ViewportComponent implements OnChanges, OnDestroy {\r\n private manifestService = inject(ManifestService);\r\n private preloadService = inject(PreloadService);\r\n private elementRef = inject(ElementRef<HTMLElement>);\r\n private cdr = inject(ChangeDetectorRef);\r\n\r\n /**\r\n * Panel to render (panel view)\r\n */\r\n @Input() panel: Panel | null = null;\r\n\r\n /**\r\n * Page to render (page view)\r\n */\r\n @Input() page: Page | null = null;\r\n\r\n /**\r\n * Panels map for page view lookup\r\n */\r\n @Input() panels: Record<string, Panel> = {};\r\n\r\n /**\r\n * View mode (panel or page)\r\n */\r\n @Input() viewMode: ViewMode = 'panel';\r\n\r\n /**\r\n * Id of the current panel (panel view). Passed to the layer renderer so\r\n * video layers carry their panel id for tracking / sequencing.\r\n */\r\n @Input() currentPanelId: string | null = null;\r\n\r\n /**\r\n * Current locale for localized content\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Variable context for hotspot visibleIf evaluation\r\n */\r\n @Input() variableContext: VariableContext | null = null;\r\n\r\n /**\r\n * Pan X offset (pixels)\r\n */\r\n @Input() panX = 0;\r\n\r\n /**\r\n * Pan Y offset (pixels)\r\n */\r\n @Input() panY = 0;\r\n\r\n /**\r\n * Zoom level (1.0 = 100%)\r\n */\r\n @Input() zoom = 1;\r\n\r\n /**\r\n * Enable reduced motion\r\n */\r\n @Input() reducedMotion = false;\r\n\r\n /**\r\n * Transition to play when the panel changes (manifest edge transition,\r\n * already resolved against settings.outputPresets defaultTransition by\r\n * the flow engine). Null/`none`/`cut` swap instantly.\r\n */\r\n @Input() transition: Transition | null = null;\r\n\r\n /**\r\n * Enable interactive mode (hotspots, etc.)\r\n */\r\n @Input() interactive = true;\r\n\r\n /**\r\n * Show overflow arrows\r\n */\r\n @Input() showOverflowArrows = true;\r\n\r\n /**\r\n * Enable viewport culling (hide off-screen panels)\r\n */\r\n @Input() enableViewportCulling = false;\r\n\r\n /**\r\n * Enable lazy loading for images\r\n */\r\n @Input() enableLazyLoading = true;\r\n\r\n /**\r\n * Work-level balloon config defaults (from settings.typography.balloon_config)\r\n */\r\n @Input() workBalloonConfig: BalloonConfig | null = null;\r\n\r\n /**\r\n * Characters array for resolving character-level balloon overrides\r\n */\r\n @Input() characters: Character[] = [];\r\n\r\n /**\r\n * Global speech toggle. Every speech bubble is implicitly subject to it\r\n * (schema 1.3+); when false, no bubbles are rendered regardless of their\r\n * story-logic visibleIf.\r\n */\r\n @Input() speechEnabled = true;\r\n\r\n /**\r\n * The chapter's graph (panel view warms the current panel's out-edge\r\n * targets); null disables out-edge preloading.\r\n */\r\n @Input() graph: Graph | null = null;\r\n\r\n /**\r\n * Manifest preload settings (settings.preload); null = defaults.\r\n */\r\n @Input() preload: PreloadSettings | null = null;\r\n\r\n /**\r\n * Viewport clicked\r\n */\r\n @Output() viewportClick = new EventEmitter<{ x: number; y: number }>();\r\n\r\n /**\r\n * Performance metrics event\r\n */\r\n @Output() performanceMetrics = new EventEmitter<PerformanceMetrics>();\r\n\r\n /**\r\n * Pan/zoom changed\r\n */\r\n @Output() transformChange = new EventEmitter<{ panX: number; panY: number; zoom: number }>();\r\n\r\n /**\r\n * Layer clicked\r\n */\r\n @Output() layerClick = new EventEmitter<{ layerId: string; x: number; y: number }>();\r\n\r\n /**\r\n * Swipe gesture detected\r\n */\r\n @Output() swipe = new EventEmitter<'left' | 'right' | 'up' | 'down'>();\r\n\r\n /**\r\n * Navigate to previous panel\r\n */\r\n @Output() navigatePrevious = new EventEmitter<void>();\r\n\r\n /**\r\n * Navigate to next panel\r\n */\r\n @Output() navigateNext = new EventEmitter<void>();\r\n\r\n /**\r\n * Panel focus changed\r\n */\r\n @Output() panelFocus = new EventEmitter<string | null>();\r\n\r\n /**\r\n * Hotspot activated (click or keyboard); x/y normalized, panel-relative\r\n */\r\n @Output() hotspotActivate = new EventEmitter<{\r\n hotspot: Hotspot;\r\n x: number;\r\n y: number;\r\n panelId: string | null;\r\n }>();\r\n\r\n /**\r\n * Click on panel content that hit no hotspot (dead click); x/y normalized\r\n */\r\n @Output() deadClick = new EventEmitter<{ x: number; y: number; panelId: string | null }>();\r\n\r\n // Focus state for navigation\r\n focusedPanelId: string | null = null;\r\n focusedPanelIndex = -1;\r\n\r\n // Performance tracking\r\n private performanceStartTime = 0;\r\n private renderCount = 0;\r\n private visiblePanels = new Set<string>();\r\n\r\n // Internal state - Mouse\r\n isDragging = false;\r\n dragStartX = 0;\r\n dragStartY = 0;\r\n lastPanX = 0;\r\n lastPanY = 0;\r\n\r\n // Navigation arrows state\r\n showLeftArrow = false;\r\n showRightArrow = false;\r\n private hoverZonePercent = 0.15; // 15% on each side\r\n\r\n // Internal state - Touch\r\n isTouching = false;\r\n touchStartX = 0;\r\n touchStartY = 0;\r\n lastTouchPanX = 0;\r\n lastTouchPanY = 0;\r\n \r\n // Pinch zoom state\r\n isPinching = false;\r\n initialPinchDistance = 0;\r\n lastPinchZoom = 1;\r\n\r\n // Swipe detection\r\n swipeStartX = 0;\r\n swipeStartY = 0;\r\n swipeStartTime = 0;\r\n minSwipeDistance = 50; // pixels\r\n maxSwipeTime = 300; // milliseconds\r\n minSwipeVelocity = 0.3; // pixels per millisecond\r\n\r\n // Overflow detection\r\n hasOverflowLeft = false;\r\n hasOverflowRight = false;\r\n hasOverflowTop = false;\r\n hasOverflowBottom = false;\r\n\r\n // Panel-change transition state (panel view). While a transition runs the\r\n // outgoing panel stays rendered in a `.t-frame-leave` overlay and both\r\n // frames carry CSS keyframe animation classes.\r\n leavingPanel: Panel | null = null;\r\n leavingPanelId = '';\r\n enterAnimationClass = '';\r\n leaveAnimationClass = '';\r\n transitionDuration = '400ms';\r\n transitionEasing = 'ease';\r\n private transitionTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // Page-change transition state (page view). Driven by the pages' own\r\n // declared `transitions.in` / `transitions.out` (schema Page.transitions):\r\n // the outgoing page plays its `out` effect in `.pt-frame-leave` while the\r\n // incoming page plays its `in` effect.\r\n leavingPage: Page | null = null;\r\n leavingPagePanels: Record<string, Panel> = {};\r\n pageEnterClass = '';\r\n pageLeaveClass = '';\r\n pageEnterDuration = '400ms';\r\n pageEnterEasing = 'ease';\r\n pageLeaveDuration = '400ms';\r\n pageLeaveEasing = 'ease';\r\n /** Leave frame stacks above the entering page (out-effect without in-effect). */\r\n pageLeaveAbove = false;\r\n private pageTransitionTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n /**\r\n * Required display width per mounted panel (physical px, quantized) for\r\n * image variant selection. Upgrade-only while mounted so an already-loaded\r\n * high-res variant is never swapped back to a smaller rung (no refetch\r\n * thrash on zoom-out); entries are dropped when their panel unmounts.\r\n */\r\n private readonly variantWidths = new Map<string, number>();\r\n private variantSettleTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['panel']) {\r\n // Reset pan/zoom when panel changes\r\n if (changes['panel'].currentValue !== changes['panel'].previousValue) {\r\n this.resetTransform();\r\n\r\n const previousPanel = changes['panel'].previousValue as Panel | null;\r\n const animations = this.getTransitionAnimationClasses(this.transition);\r\n if (previousPanel && animations && this.viewMode === 'panel' && !this.reducedMotion) {\r\n this.beginPanelTransition(\r\n previousPanel,\r\n (changes['currentPanelId']?.previousValue as string | null) ?? this.leavingPanelId,\r\n animations\r\n );\r\n } else {\r\n this.endPanelTransition();\r\n }\r\n }\r\n }\r\n\r\n if (changes['page']) {\r\n const previousPage = changes['page'].previousValue as Page | null;\r\n const nextPage = changes['page'].currentValue as Page | null;\r\n if (\r\n previousPage &&\r\n nextPage &&\r\n previousPage.id !== nextPage.id &&\r\n this.viewMode === 'page' &&\r\n !this.reducedMotion\r\n ) {\r\n this.beginPageTransition(\r\n previousPage,\r\n nextPage,\r\n (changes['panels']?.previousValue as Record<string, Panel> | undefined) ?? this.panels\r\n );\r\n } else {\r\n this.endPageTransition();\r\n }\r\n }\r\n\r\n // Responsive image variants: recompute per-panel target widths when the\r\n // mounted content changes; zoom-only changes go through the settle\r\n // debounce so continuous pinch/wheel zoom never re-resolves per frame.\r\n const panelChanged =\r\n changes['panel'] && changes['panel'].currentValue !== changes['panel'].previousValue;\r\n const pageChanged =\r\n changes['page'] && changes['page'].currentValue !== changes['page'].previousValue;\r\n if (panelChanged || pageChanged || changes['viewMode']) {\r\n this.pruneVariantWidths();\r\n this.updateVariantWidths();\r\n this.preloadOutEdgeTargets();\r\n this.scheduleVariantSettle();\r\n } else if (changes['zoom']) {\r\n this.scheduleVariantSettle();\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.transitionTimer !== null) {\r\n clearTimeout(this.transitionTimer);\r\n this.transitionTimer = null;\r\n }\r\n if (this.pageTransitionTimer !== null) {\r\n clearTimeout(this.pageTransitionTimer);\r\n this.pageTransitionTimer = null;\r\n }\r\n if (this.variantSettleTimer !== null) {\r\n clearTimeout(this.variantSettleTimer);\r\n this.variantSettleTimer = null;\r\n }\r\n }\r\n\r\n /**\r\n * Re-resolve variants after the viewport size changed (debounced like the\r\n * canvas stage's camera settle).\r\n */\r\n @HostListener('window:resize')\r\n onWindowResize(): void {\r\n this.scheduleVariantSettle();\r\n }\r\n\r\n // --------------------------------------------------------------------------\r\n // Responsive image variants (spec §3.4 — page/panel view)\r\n // --------------------------------------------------------------------------\r\n\r\n /** Variant-selection width for a mounted panel (0 = legacy first variant). */\r\n targetWidthFor(panelId: string | null | undefined): number {\r\n if (!panelId) {\r\n return 0;\r\n }\r\n return this.variantWidths.get(panelId) ?? 0;\r\n }\r\n\r\n /** Arm (or re-arm) the debounced variant/preload pass. */\r\n private scheduleVariantSettle(): void {\r\n if (this.variantSettleTimer !== null) {\r\n clearTimeout(this.variantSettleTimer);\r\n }\r\n this.variantSettleTimer = setTimeout(() => {\r\n this.variantSettleTimer = null;\r\n this.onVariantSettled();\r\n }, VARIANT_SETTLE_MS);\r\n }\r\n\r\n /** Zoom/resize settled: re-resolve image variants and warm out-edges. */\r\n private onVariantSettled(): void {\r\n this.updateVariantWidths();\r\n this.preloadOutEdgeTargets();\r\n this.cdr.markForCheck();\r\n }\r\n\r\n /**\r\n * Required display width per mounted panel (physical px, quantized).\r\n * Panel view: container CSS width × zoom × devicePixelRatio.\r\n * Page view: placement fraction of the page canvas × devicePixelRatio\r\n * (no per-panel zoom in page view). Upgrade-only while mounted.\r\n */\r\n private updateVariantWidths(): void {\r\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\r\n if (this.viewMode === 'panel') {\r\n if (!this.currentPanelId) {\r\n return;\r\n }\r\n const cssWidth = this.getContainerWidth();\r\n if (cssWidth > 0) {\r\n this.bumpVariantWidth(this.currentPanelId, quantizeTargetWidth(cssWidth * this.zoom * dpr));\r\n }\r\n return;\r\n }\r\n if (this.viewMode === 'page' && this.page) {\r\n for (const placement of this.page.layout?.placements ?? []) {\r\n const cssWidth = this.getPagePanelWidth(placement);\r\n if (cssWidth > 0) {\r\n this.bumpVariantWidth(placement.panelId, quantizeTargetWidth(cssWidth * dpr));\r\n }\r\n }\r\n }\r\n }\r\n\r\n /** Upgrade-only write: a mounted panel's width never decreases. */\r\n private bumpVariantWidth(panelId: string, needed: number): void {\r\n const current = this.variantWidths.get(panelId) ?? 0;\r\n if (needed > current) {\r\n this.variantWidths.set(panelId, needed);\r\n }\r\n }\r\n\r\n /**\r\n * Drop widths of panels that are no longer mounted so a revisit starts\r\n * fresh (the upgrade-only rule applies per mount, not per session).\r\n */\r\n private pruneVariantWidths(): void {\r\n const mounted = new Set<string>();\r\n if (this.viewMode === 'panel') {\r\n if (this.currentPanelId) {\r\n mounted.add(this.currentPanelId);\r\n }\r\n if (this.leavingPanelId) {\r\n mounted.add(this.leavingPanelId);\r\n }\r\n } else if (this.viewMode === 'page') {\r\n for (const placement of this.page?.layout?.placements ?? []) {\r\n mounted.add(placement.panelId);\r\n }\r\n for (const placement of this.leavingPage?.layout?.placements ?? []) {\r\n mounted.add(placement.panelId);\r\n }\r\n }\r\n for (const panelId of [...this.variantWidths.keys()]) {\r\n if (!mounted.has(panelId)) {\r\n this.variantWidths.delete(panelId);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Warm the current panel's out-edge target panels' image variants at the\r\n * current panel-view target width (same pattern as the canvas stage's\r\n * preloadNeighbors, minus its spatial neighbors). Honors settings.preload:\r\n * strategy `none` disables, panelsAhead caps the edge count, maxConcurrent\r\n * is passed through to the preload service.\r\n */\r\n private preloadOutEdgeTargets(): void {\r\n if (this.viewMode !== 'panel' || this.preload?.strategy === 'none') {\r\n return;\r\n }\r\n const currentId = this.currentPanelId;\r\n if (!currentId) {\r\n return;\r\n }\r\n if (this.preload?.maxConcurrent) {\r\n this.preloadService.setMaxConcurrent(this.preload.maxConcurrent);\r\n }\r\n const panelsAhead = this.preload?.panelsAhead ?? 2;\r\n\r\n const edgeTargets = (this.graph?.edges ?? [])\r\n .filter((edge) => edge.from === currentId)\r\n .map((edge) => edge.to)\r\n .slice(0, Math.max(panelsAhead, 1));\r\n\r\n const width = this.targetWidthFor(currentId);\r\n for (const panelId of edgeTargets) {\r\n const panel = this.panels[panelId];\r\n if (!panel) {\r\n continue;\r\n }\r\n for (const layer of panel.layers ?? []) {\r\n if (layer.kind !== 'image' || typeof layer.assetId !== 'string') {\r\n continue;\r\n }\r\n const asset = this.manifestService.getAsset(layer.assetId);\r\n const variant = selectImageVariantForWidth(asset?.variants as never, width);\r\n if (variant?.src) {\r\n this.preloadService.add({\r\n id: variant.src,\r\n type: 'image',\r\n url: variant.src,\r\n priority: 'high',\r\n panelId,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Map a manifest Transition onto the enter/leave CSS animation classes.\r\n * Returns null when nothing should animate (`none`, `cut`, or no type).\r\n *\r\n * `dir` is the direction of motion (schema semantics): `left` means the\r\n * content moves leftward, i.e. the new panel enters from the right.\r\n * Mapping: `fade`/`zoom` enter over the static old panel; `slide`/`push`\r\n * move both panels; `cover` slides the new panel over the static old one.\r\n */\r\n getTransitionAnimationClasses(\r\n transition: Transition | null | undefined\r\n ): { enter: string; leave: string } | null {\r\n const type = transition?.type;\r\n if (!type || type === 'none' || type === 'cut') {\r\n return null;\r\n }\r\n\r\n const dir = transition?.dir ?? 'left';\r\n const from: Record<string, string> = {\r\n left: 't-from-right',\r\n right: 't-from-left',\r\n up: 't-from-bottom',\r\n down: 't-from-top',\r\n };\r\n const to: Record<string, string> = {\r\n left: 't-to-left',\r\n right: 't-to-right',\r\n up: 't-to-top',\r\n down: 't-to-bottom',\r\n };\r\n\r\n switch (type) {\r\n case 'fade':\r\n return { enter: 't-fade-in', leave: '' };\r\n case 'zoom':\r\n return { enter: 't-zoom-in', leave: '' };\r\n case 'cover':\r\n return { enter: from[dir], leave: '' };\r\n case 'slide':\r\n case 'push':\r\n return { enter: from[dir], leave: to[dir] };\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Start rendering the outgoing panel in the leave frame and arm the\r\n * cleanup timer for the transition duration.\r\n */\r\n private beginPanelTransition(\r\n previousPanel: Panel,\r\n previousPanelId: string,\r\n animations: { enter: string; leave: string }\r\n ): void {\r\n this.leavingPanel = previousPanel;\r\n this.leavingPanelId = previousPanelId;\r\n this.enterAnimationClass = animations.enter;\r\n this.leaveAnimationClass = animations.leave;\r\n\r\n const durationMs = this.transition?.durationMs ?? 400;\r\n this.transitionDuration = `${durationMs}ms`;\r\n this.transitionEasing = this.transition?.easing ?? 'ease';\r\n\r\n if (this.transitionTimer !== null) {\r\n clearTimeout(this.transitionTimer);\r\n }\r\n this.transitionTimer = setTimeout(() => {\r\n this.endPanelTransition();\r\n this.cdr.markForCheck();\r\n }, durationMs);\r\n }\r\n\r\n /**\r\n * Drop the leave frame and animation classes (transition finished,\r\n * interrupted, or not applicable).\r\n */\r\n private endPanelTransition(): void {\r\n if (this.transitionTimer !== null) {\r\n clearTimeout(this.transitionTimer);\r\n this.transitionTimer = null;\r\n }\r\n this.leavingPanel = null;\r\n this.leavingPanelId = '';\r\n this.enterAnimationClass = '';\r\n this.leaveAnimationClass = '';\r\n }\r\n\r\n /**\r\n * Map a page `out` transition onto its leave-frame CSS animation class.\r\n * Mirrors getTransitionAnimationClasses(): `dir` is the direction of\r\n * motion, so an out-slide to the left plays `t-to-left`. Returns '' when\r\n * nothing should animate (`none`, `cut`, or no type).\r\n */\r\n getPageOutAnimationClass(transition: Transition | null | undefined): string {\r\n const type = transition?.type;\r\n if (!type || type === 'none' || type === 'cut') {\r\n return '';\r\n }\r\n\r\n const dir = transition?.dir ?? 'left';\r\n const to: Record<string, string> = {\r\n left: 't-to-left',\r\n right: 't-to-right',\r\n up: 't-to-top',\r\n down: 't-to-bottom',\r\n };\r\n\r\n switch (type) {\r\n case 'fade':\r\n return 't-fade-out';\r\n case 'zoom':\r\n return 't-zoom-out';\r\n case 'slide':\r\n case 'push':\r\n case 'cover':\r\n return to[dir];\r\n default:\r\n return '';\r\n }\r\n }\r\n\r\n /**\r\n * Start a page change animation: the outgoing page keeps rendering in the\r\n * `.pt-frame-leave` overlay with its own `transitions.out` effect while\r\n * the incoming page plays its `transitions.in` effect. Without declared\r\n * page transitions the swap stays instant.\r\n */\r\n private beginPageTransition(\r\n previousPage: Page,\r\n nextPage: Page,\r\n previousPanels: Record<string, Panel>\r\n ): void {\r\n const inTransition = nextPage.transitions?.in;\r\n const outTransition = previousPage.transitions?.out;\r\n\r\n const enterClass = inTransition\r\n ? (this.getTransitionAnimationClasses(inTransition)?.enter ?? '')\r\n : '';\r\n const leaveClass = this.getPageOutAnimationClass(outTransition);\r\n\r\n if (!enterClass && !leaveClass) {\r\n this.endPageTransition();\r\n return;\r\n }\r\n\r\n this.leavingPage = previousPage;\r\n this.leavingPagePanels = previousPanels;\r\n this.pageEnterClass = enterClass;\r\n this.pageLeaveClass = leaveClass;\r\n // An out-effect without an in-effect must play above the (static) new\r\n // page - e.g. the old page slides away and reveals the new one.\r\n this.pageLeaveAbove = !!leaveClass && !enterClass;\r\n\r\n const enterDurationMs = enterClass ? (inTransition?.durationMs ?? 400) : 0;\r\n const leaveDurationMs = leaveClass ? (outTransition?.durationMs ?? 400) : 0;\r\n this.pageEnterDuration = `${enterDurationMs}ms`;\r\n this.pageEnterEasing = inTransition?.easing ?? 'ease';\r\n this.pageLeaveDuration = `${leaveDurationMs}ms`;\r\n this.pageLeaveEasing = outTransition?.easing ?? 'ease';\r\n\r\n if (this.pageTransitionTimer !== null) {\r\n clearTimeout(this.pageTransitionTimer);\r\n }\r\n this.pageTransitionTimer = setTimeout(() => {\r\n this.endPageTransition();\r\n this.cdr.markForCheck();\r\n }, Math.max(enterDurationMs, leaveDurationMs));\r\n }\r\n\r\n /**\r\n * Drop the page leave frame and animation classes (page transition\r\n * finished, interrupted, or not applicable).\r\n */\r\n private endPageTransition(): void {\r\n if (this.pageTransitionTimer !== null) {\r\n clearTimeout(this.pageTransitionTimer);\r\n this.pageTransitionTimer = null;\r\n }\r\n this.leavingPage = null;\r\n this.leavingPagePanels = {};\r\n this.pageEnterClass = '';\r\n this.pageLeaveClass = '';\r\n this.pageLeaveAbove = false;\r\n }\r\n\r\n /**\r\n * Sorted placements of the leaving page (ascending z), resolved against\r\n * the panels snapshot taken when the transition started.\r\n */\r\n getLeavingPagePlacements(): PanelPlacement[] {\r\n const placements = this.leavingPage?.layout?.placements ?? [];\r\n return [...placements].sort((a, b) => (a.z ?? 0) - (b.z ?? 0));\r\n }\r\n\r\n /**\r\n * Panel lookup for the leaving page's placements.\r\n */\r\n getLeavingPanel(panelId: string): Panel | undefined {\r\n return this.leavingPagePanels[panelId];\r\n }\r\n\r\n /**\r\n * Get transform style for viewport\r\n */\r\n getTransformStyle(): string {\r\n if (this.reducedMotion) {\r\n // No transform in reduced motion mode\r\n return 'translate(-50%, -50%) scale(1)';\r\n }\r\n\r\n // First translate centers the panel (-50%, -50%)\r\n // Then apply pan offsets and zoom\r\n return `translate(-50%, -50%) translate(${this.panX}px, ${this.panY}px) scale(${this.zoom})`;\r\n }\r\n\r\n /**\r\n * Get CSS class for view mode\r\n */\r\n getViewModeClass(): string {\r\n return `viewport-${this.viewMode}`;\r\n }\r\n\r\n /**\r\n * Balloon lettering scale: the player viewport height relative to the DIN A4\r\n * authoring frame (1123 px). Bubble text keeps the same comfortable reading\r\n * size on every screen — larger players get moderately larger lettering,\r\n * phones get smaller — instead of growing proportionally with the panel.\r\n */\r\n getReadingScale(): number {\r\n const h = this.elementRef.nativeElement.clientHeight || 0;\r\n return h > 0 ? h / 1123 : 1;\r\n }\r\n\r\n /**\r\n * Get the container width in pixels (panel view).\r\n * Used by pw-speech-bubbles to convert normalized coordinates to pixels.\r\n */\r\n getContainerWidth(): number {\r\n const container = this.elementRef.nativeElement.querySelector('.panel-container');\r\n return container ? container.clientWidth : 0;\r\n }\r\n\r\n /**\r\n * Get the container height in pixels (panel view).\r\n */\r\n getContainerHeight(): number {\r\n const container = this.elementRef.nativeElement.querySelector('.panel-container');\r\n return container ? container.clientHeight : 0;\r\n }\r\n\r\n /**\r\n * Get a page-view panel's rendered width in pixels.\r\n */\r\n getPagePanelWidth(placement: PanelPlacement): number {\r\n const pageCanvas = this.elementRef.nativeElement.querySelector('.page-canvas');\r\n if (!pageCanvas) return 0;\r\n return placement.w * pageCanvas.clientWidth;\r\n }\r\n\r\n /**\r\n * Get a page-view panel's rendered height in pixels.\r\n */\r\n getPagePanelHeight(placement: PanelPlacement): number {\r\n const pageCanvas = this.elementRef.nativeElement.querySelector('.page-canvas');\r\n if (!pageCanvas) return 0;\r\n return placement.h * pageCanvas.clientHeight;\r\n }\r\n\r\n /**\r\n * Re-emit a hotspot activation with the owning panel id attached\r\n */\r\n onHotspotActivate(evt: { hotspot: Hotspot; x: number; y: number }, panelId: string | null): void {\r\n this.hotspotActivate.emit({ ...evt, panelId });\r\n }\r\n\r\n /**\r\n * Dead-click capture: clicks on panel content that hit no hotspot\r\n * (hotspot hits stop propagation in the overlay and never reach this).\r\n * Does NOT stop propagation itself — tap-to-advance keeps working.\r\n */\r\n onPanelContainerClick(event: MouseEvent, panelId: string | null): void {\r\n if (!this.interactive) return;\r\n const el = event.currentTarget as HTMLElement;\r\n const r = el.getBoundingClientRect();\r\n if (r.width <= 0 || r.height <= 0) return;\r\n this.deadClick.emit({\r\n x: Math.min(1, Math.max(0, (event.clientX - r.left) / r.width)),\r\n y: Math.min(1, Math.max(0, (event.clientY - r.top) / r.height)),\r\n panelId,\r\n });\r\n }\r\n\r\n /**\r\n * Handle viewport click\r\n */\r\n onViewportClick(event: MouseEvent): void {\r\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n\r\n this.viewportClick.emit({ x, y });\r\n }\r\n\r\n /**\r\n * Handle keyboard activation\r\n */\r\n onKeyboardActivate(event: Event): void {\r\n event.preventDefault();\r\n // Emit click at center of viewport\r\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\r\n const x = rect.width / 2;\r\n const y = rect.height / 2;\r\n\r\n this.viewportClick.emit({ x, y });\r\n }\r\n\r\n /**\r\n * Handle mouse down for pan\r\n */\r\n @HostListener('mousedown', ['$event'])\r\n onMouseDown(event: MouseEvent): void {\r\n if (event.button !== 0) return; // Left button only\r\n\r\n this.isDragging = true;\r\n this.dragStartX = event.clientX;\r\n this.dragStartY = event.clientY;\r\n this.lastPanX = this.panX;\r\n this.lastPanY = this.panY;\r\n\r\n // Track for swipe detection\r\n this.swipeStartX = event.clientX;\r\n this.swipeStartY = event.clientY;\r\n this.swipeStartTime = Date.now();\r\n\r\n event.preventDefault();\r\n }\r\n\r\n /**\r\n * Handle mouse move for pan\r\n */\r\n @HostListener('document:mousemove', ['$event'])\r\n onMouseMove(event: MouseEvent): void {\r\n if (!this.isDragging) return;\r\n\r\n const deltaX = event.clientX - this.dragStartX;\r\n const deltaY = event.clientY - this.dragStartY;\r\n\r\n const newPanX = this.lastPanX + deltaX;\r\n const newPanY = this.lastPanY + deltaY;\r\n\r\n this.transformChange.emit({\r\n panX: newPanX,\r\n panY: newPanY,\r\n zoom: this.zoom,\r\n });\r\n }\r\n\r\n /**\r\n * Handle mouse up for pan\r\n */\r\n @HostListener('document:mouseup', ['$event'])\r\n onMouseUp(event: MouseEvent): void {\r\n // Detect swipe before resetting drag state\r\n if (this.isDragging) {\r\n this.detectSwipe(event.clientX, event.clientY);\r\n }\r\n \r\n this.isDragging = false;\r\n }\r\n\r\n /**\r\n * Handle mouse wheel for zoom\r\n */\r\n @HostListener('wheel', ['$event'])\r\n onWheel(event: WheelEvent): void {\r\n if (!event.ctrlKey && !event.metaKey) return; // Zoom only with Ctrl/Cmd\r\n\r\n event.preventDefault();\r\n\r\n const delta = -event.deltaY;\r\n const zoomFactor = 0.001;\r\n const newZoom = Math.max(0.1, Math.min(5, this.zoom + delta * zoomFactor));\r\n\r\n this.transformChange.emit({\r\n panX: this.panX,\r\n panY: this.panY,\r\n zoom: newZoom,\r\n });\r\n }\r\n\r\n /**\r\n * Handle touch start\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n onTouchStart(event: TouchEvent): void {\r\n if (event.touches.length === 1) {\r\n // Single touch - pan\r\n this.isTouching = true;\r\n this.isPinching = false;\r\n \r\n const touch = event.touches[0];\r\n this.touchStartX = touch.clientX;\r\n this.touchStartY = touch.clientY;\r\n this.lastTouchPanX = this.panX;\r\n this.lastTouchPanY = this.panY;\r\n \r\n // Track for swipe detection\r\n this.swipeStartX = touch.clientX;\r\n this.swipeStartY = touch.clientY;\r\n this.swipeStartTime = Date.now();\r\n } else if (event.touches.length === 2) {\r\n // Two touches - pinch zoom\r\n this.isTouching = false;\r\n this.isPinching = true;\r\n \r\n this.initialPinchDistance = this.getPinchDistance(event.touches);\r\n this.lastPinchZoom = this.zoom;\r\n }\r\n }\r\n\r\n /**\r\n * Handle touch move\r\n */\r\n @HostListener('touchmove', ['$event'])\r\n onTouchMove(event: TouchEvent): void {\r\n if (this.isTouching && event.touches.length === 1) {\r\n // Pan with single touch\r\n event.preventDefault();\r\n \r\n const touch = event.touches[0];\r\n const deltaX = touch.clientX - this.touchStartX;\r\n const deltaY = touch.clientY - this.touchStartY;\r\n\r\n const newPanX = this.lastTouchPanX + deltaX;\r\n const newPanY = this.lastTouchPanY + deltaY;\r\n\r\n this.transformChange.emit({\r\n panX: newPanX,\r\n panY: newPanY,\r\n zoom: this.zoom,\r\n });\r\n } else if (this.isPinching && event.touches.length === 2) {\r\n // Pinch zoom with two touches\r\n event.preventDefault();\r\n \r\n const currentDistance = this.getPinchDistance(event.touches);\r\n const scale = currentDistance / this.initialPinchDistance;\r\n const newZoom = Math.max(0.1, Math.min(5, this.lastPinchZoom * scale));\r\n\r\n this.transformChange.emit({\r\n panX: this.panX,\r\n panY: this.panY,\r\n zoom: newZoom,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Handle touch end\r\n */\r\n @HostListener('touchend', ['$event'])\r\n @HostListener('touchcancel', ['$event'])\r\n onTouchEnd(event: TouchEvent): void {\r\n // Detect swipe before resetting touch state\r\n if (event.changedTouches.length > 0 && this.isTouching) {\r\n const touch = event.changedTouches[0];\r\n this.detectSwipe(touch.clientX, touch.clientY);\r\n }\r\n\r\n if (event.touches.length === 0) {\r\n this.isTouching = false;\r\n this.isPinching = false;\r\n } else if (event.touches.length === 1 && this.isPinching) {\r\n // Switched from pinch to pan\r\n this.isPinching = false;\r\n this.isTouching = true;\r\n \r\n const touch = event.touches[0];\r\n this.touchStartX = touch.clientX;\r\n this.touchStartY = touch.clientY;\r\n this.lastTouchPanX = this.panX;\r\n this.lastTouchPanY = this.panY;\r\n \r\n // Reset swipe tracking\r\n this.swipeStartX = touch.clientX;\r\n this.swipeStartY = touch.clientY;\r\n this.swipeStartTime = Date.now();\r\n }\r\n }\r\n\r\n /**\r\n * Calculate distance between two touch points\r\n */\r\n private getPinchDistance(touches: TouchList): number {\r\n const touch1 = touches[0];\r\n const touch2 = touches[1];\r\n \r\n const dx = touch2.clientX - touch1.clientX;\r\n const dy = touch2.clientY - touch1.clientY;\r\n \r\n return Math.sqrt(dx * dx + dy * dy);\r\n }\r\n\r\n /**\r\n * Reset transform to default\r\n */\r\n resetTransform(): void {\r\n this.transformChange.emit({\r\n panX: 0,\r\n panY: 0,\r\n zoom: 1,\r\n });\r\n }\r\n\r\n /**\r\n * Fit panel to viewport\r\n */\r\n fitToViewport(): void {\r\n if (!this.panel) return;\r\n\r\n // Calculate zoom to fit\r\n // This would need viewport dimensions - simplified for now\r\n this.transformChange.emit({\r\n panX: 0,\r\n panY: 0,\r\n zoom: 1,\r\n });\r\n }\r\n\r\n /**\r\n * Get panel dimensions\r\n */\r\n getPanelDimensions(): { width: number; height: number } {\r\n if (!this.panel) {\r\n return { width: 0, height: 0 };\r\n }\r\n\r\n // Calculate from layers - simplified\r\n return { width: 800, height: 600 };\r\n }\r\n\r\n /**\r\n * Detect overflow in all directions\r\n */\r\n detectOverflow(): void {\r\n if (!this.panel) {\r\n this.hasOverflowLeft = false;\r\n this.hasOverflowRight = false;\r\n this.hasOverflowTop = false;\r\n this.hasOverflowBottom = false;\r\n return;\r\n }\r\n\r\n const panelDim = this.getPanelDimensions();\r\n const viewportWidth = 800; // Would get from actual viewport element\r\n const viewportHeight = 600;\r\n\r\n // Check if content can scroll in each direction\r\n this.hasOverflowLeft = this.panX < 0;\r\n this.hasOverflowRight = this.panX + panelDim.width * this.zoom > viewportWidth;\r\n this.hasOverflowTop = this.panY < 0;\r\n this.hasOverflowBottom = this.panY + panelDim.height * this.zoom > viewportHeight;\r\n }\r\n\r\n /**\r\n * Navigate left (show more content on the right)\r\n */\r\n navigateLeft(): void {\r\n const step = 200;\r\n this.transformChange.emit({\r\n panX: this.panX + step,\r\n panY: this.panY,\r\n zoom: this.zoom,\r\n });\r\n }\r\n\r\n /**\r\n * Navigate right (show more content on the left)\r\n */\r\n navigateRight(): void {\r\n const step = 200;\r\n this.transformChange.emit({\r\n panX: this.panX - step,\r\n panY: this.panY,\r\n zoom: this.zoom,\r\n });\r\n }\r\n\r\n /**\r\n * Navigate up (show more content below)\r\n */\r\n navigateUp(): void {\r\n const step = 200;\r\n this.transformChange.emit({\r\n panX: this.panX,\r\n panY: this.panY + step,\r\n zoom: this.zoom,\r\n });\r\n }\r\n\r\n /**\r\n * Navigate down (show more content above)\r\n */\r\n navigateDown(): void {\r\n const step = 200;\r\n this.transformChange.emit({\r\n panX: this.panX,\r\n panY: this.panY - step,\r\n zoom: this.zoom,\r\n });\r\n }\r\n\r\n /**\r\n * Index of a panel in the current page's reading order, or -1 when absent.\r\n * Used to order the page-view video sequencer.\r\n */\r\n readingOrderIndexOf(panelId: string): number {\r\n return this.page?.readingOrder ? this.page.readingOrder.indexOf(panelId) : -1;\r\n }\r\n\r\n /**\r\n * Get panels sorted by z-index (lowest to highest for rendering order)\r\n */\r\n getSortedPanels(): PanelPlacement[] {\r\n if (!this.page?.layout.placements) return [];\r\n \r\n return [...this.page.layout.placements].sort((a, b) => {\r\n const zA = a.z ?? 0;\r\n const zB = b.z ?? 0;\r\n return zA - zB;\r\n });\r\n }\r\n\r\n /**\r\n * Convert normalized value (0-1) to percentage\r\n */\r\n toPercent(value: number): number {\r\n return value * 100;\r\n }\r\n\r\n /**\r\n * Get CSS transform for panel (rotation)\r\n */\r\n getPanelTransform(placement: PanelPlacement): string {\r\n if (!placement.r || placement.r === 0) {\r\n return 'none';\r\n }\r\n return `rotate(${placement.r}deg)`;\r\n }\r\n\r\n /**\r\n * Get transform origin CSS for panel\r\n */\r\n getTransformOrigin(placement: PanelPlacement): string {\r\n if (!placement.origin) {\r\n return 'center center'; // Default\r\n }\r\n \r\n const x = placement.origin.x * 100;\r\n const y = placement.origin.y * 100;\r\n return `${x}% ${y}%`;\r\n }\r\n\r\n /**\r\n * Get clip-path CSS for panel content (visible area)\r\n * Returns inset values to show only the visible portion of the panel\r\n */\r\n getPanelContentClipPath(placement: PanelPlacement): string {\r\n const vx = placement.vx ?? 0;\r\n const vy = placement.vy ?? 0;\r\n const vw = placement.vw ?? 1;\r\n const vh = placement.vh ?? 1;\r\n \r\n // If full panel is visible, no clipping needed\r\n if (vx === 0 && vy === 0 && vw === 1 && vh === 1) {\r\n return 'none';\r\n }\r\n \r\n // Calculate inset values as percentages\r\n // inset(top right bottom left)\r\n const top = vy * 100;\r\n const right = (1 - (vx + vw)) * 100;\r\n const bottom = (1 - (vy + vh)) * 100;\r\n const left = vx * 100;\r\n \r\n return `inset(${top}% ${right}% ${bottom}% ${left}%)`;\r\n }\r\n\r\n /**\r\n * Get position offset for panel content (visible area)\r\n * Returns translate transform to shift content when visible area is cropped\r\n */\r\n getPanelContentTransform(placement: PanelPlacement): string {\r\n const vx = placement.vx ?? 0;\r\n const vy = placement.vy ?? 0;\r\n \r\n // If no offset, return none\r\n if (vx === 0 && vy === 0) {\r\n return 'none';\r\n }\r\n \r\n // Translate content by negative offset to show the visible portion\r\n const translateX = -vx * 100;\r\n const translateY = -vy * 100;\r\n \r\n return `translate(${translateX}%, ${translateY}%)`;\r\n }\r\n\r\n /**\r\n * Handle panel click in page view\r\n */\r\n onPanelClick(event: MouseEvent, panelId: string): void {\r\n event.stopPropagation();\r\n \r\n // Get click coordinates relative to panel\r\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n\r\n // Emit viewport click with panel context\r\n this.viewportClick.emit({ x, y });\r\n\r\n console.log(`Panel clicked: ${panelId} at (${x.toFixed(0)}, ${y.toFixed(0)})`);\r\n }\r\n\r\n /**\r\n * Keyboard activation (Enter/Space) of a focusable page-view panel —\r\n * mirrors onPanelClick with the panel center as the activation point.\r\n */\r\n onPanelKeyboardActivate(event: Event, panelId: string): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\r\n this.viewportClick.emit({ x: rect.width / 2, y: rect.height / 2 });\r\n console.log(`Panel activated via keyboard: ${panelId}`);\r\n }\r\n\r\n /**\r\n * Check if point is inside a rotated panel\r\n * Used for precise hit testing when panels have rotation\r\n */\r\n isPointInRotatedPanel(\r\n point: { x: number; y: number },\r\n placement: PanelPlacement,\r\n canvasWidth: number,\r\n canvasHeight: number\r\n ): boolean {\r\n // Convert normalized placement to pixel coordinates\r\n const panelX = placement.x * canvasWidth;\r\n const panelY = placement.y * canvasHeight;\r\n const panelWidth = placement.w * canvasWidth;\r\n const panelHeight = placement.h * canvasHeight;\r\n\r\n // If no rotation, simple bounding box check\r\n if (!placement.r || placement.r === 0) {\r\n return (\r\n point.x >= panelX &&\r\n point.x <= panelX + panelWidth &&\r\n point.y >= panelY &&\r\n point.y <= panelY + panelHeight\r\n );\r\n }\r\n\r\n // For rotated panels, transform point to panel's local space\r\n const origin = placement.origin || { x: 0.5, y: 0.5 };\r\n const originX = panelX + panelWidth * origin.x;\r\n const originY = panelY + panelHeight * origin.y;\r\n\r\n // Translate point to origin\r\n const translatedX = point.x - originX;\r\n const translatedY = point.y - originY;\r\n\r\n // Rotate point by negative rotation angle (inverse rotation)\r\n const angleRad = (-placement.r * Math.PI) / 180;\r\n const cos = Math.cos(angleRad);\r\n const sin = Math.sin(angleRad);\r\n\r\n const rotatedX = translatedX * cos - translatedY * sin;\r\n const rotatedY = translatedX * sin + translatedY * cos;\r\n\r\n // Translate back and check if in axis-aligned bounding box\r\n const localX = rotatedX + panelWidth * origin.x;\r\n const localY = rotatedY + panelHeight * origin.y;\r\n\r\n return (\r\n localX >= 0 &&\r\n localX <= panelWidth &&\r\n localY >= 0 &&\r\n localY <= panelHeight\r\n );\r\n }\r\n\r\n /**\r\n * Get the panel at a specific point, considering rotation and z-index\r\n * Returns the top-most panel (highest z-index) at the given point\r\n */\r\n getPanelAtPoint(point: { x: number; y: number }): PanelPlacement | null {\r\n if (!this.page?.layout.placements) return null;\r\n\r\n const canvas = document.querySelector('.page-canvas') as HTMLElement;\r\n if (!canvas) return null;\r\n\r\n const canvasWidth = canvas.offsetWidth;\r\n const canvasHeight = canvas.offsetHeight;\r\n\r\n // Check from highest z-index to lowest (reverse of render order)\r\n const sortedPanels = this.getSortedPanels().reverse();\r\n\r\n for (const placement of sortedPanels) {\r\n if (this.isPointInRotatedPanel(point, placement, canvasWidth, canvasHeight)) {\r\n return placement;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Get panel by ID from panels map\r\n */\r\n getPanel(panelId: string): Panel | undefined {\r\n if (!this.panels || !this.panels[panelId]) {\r\n console.warn(`Panel not found: ${panelId}`);\r\n return undefined;\r\n }\r\n return this.panels[panelId];\r\n }\r\n\r\n /**\r\n * Whether a page-view panel renders interactive hotspots. Such panels\r\n * must not be buttons themselves — nesting the hotspot buttons inside\r\n * an interactive container breaks screen readers (axe: nested-interactive).\r\n */\r\n panelHasHotspots(panelId: string): boolean {\r\n const panel = this.panels?.[panelId];\r\n return this.interactive && !!panel?.hotspots?.length;\r\n }\r\n\r\n /**\r\n * Get alt text for a layer from the asset catalog\r\n */\r\n getAltText(layer: Layer): string {\r\n if (!layer.assetId) return '';\r\n \r\n // Get manifest and asset catalog\r\n const manifest = this.manifestService.getManifest();\r\n if (!manifest?.assets?.catalog) return '';\r\n \r\n // Find asset by ID\r\n const asset = manifest.assets.catalog.find((a: AssetCatalogItem) => a.id === layer.assetId);\r\n if (!asset?.alt) return '';\r\n \r\n // Get localized alt text\r\n return this.getLocalizedString(asset.alt);\r\n }\r\n\r\n /**\r\n * Get localized string based on current locale\r\n */\r\n private getLocalizedString(text: LocalizedString): string {\r\n if (!text || typeof text !== 'object') return '';\r\n \r\n // Try exact locale match\r\n if (text[this.locale]) return text[this.locale];\r\n \r\n // Try base language (e.g., en-US -> en)\r\n const baseLocale = this.locale.split('-')[0];\r\n const baseMatch = Object.keys(text).find(key => key.startsWith(baseLocale));\r\n if (baseMatch && text[baseMatch]) return text[baseMatch];\r\n \r\n // Fallback to first available\r\n const firstKey = Object.keys(text)[0];\r\n return firstKey ? text[firstKey] : '';\r\n }\r\n\r\n /**\r\n * Detect swipe gesture\r\n */\r\n private detectSwipe(endX: number, endY: number): void {\r\n const deltaX = endX - this.swipeStartX;\r\n const deltaY = endY - this.swipeStartY;\r\n const deltaTime = Date.now() - this.swipeStartTime;\r\n \r\n // Calculate distance and velocity\r\n const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r\n const velocity = distance / deltaTime; // pixels per millisecond\r\n \r\n // Check if it's a valid swipe (fast enough and far enough)\r\n if (deltaTime > this.maxSwipeTime || distance < this.minSwipeDistance) {\r\n return; // Not a swipe, just a slow drag\r\n }\r\n \r\n if (velocity < this.minSwipeVelocity) {\r\n return; // Too slow to be considered a swipe\r\n }\r\n \r\n // Determine swipe direction (prioritize horizontal or vertical)\r\n const absDeltaX = Math.abs(deltaX);\r\n const absDeltaY = Math.abs(deltaY);\r\n \r\n if (absDeltaX > absDeltaY) {\r\n // Horizontal swipe\r\n if (deltaX > 0) {\r\n this.swipe.emit('right');\r\n } else {\r\n this.swipe.emit('left');\r\n }\r\n } else {\r\n // Vertical swipe\r\n if (deltaY > 0) {\r\n this.swipe.emit('down');\r\n } else {\r\n this.swipe.emit('up');\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle viewport mouse move for navigation arrows\r\n */\r\n onViewportMouseMove(event: MouseEvent): void {\r\n // Only show arrows in panel view\r\n if (this.viewMode !== 'panel') {\r\n this.showLeftArrow = false;\r\n this.showRightArrow = false;\r\n return;\r\n }\r\n\r\n const target = event.currentTarget as HTMLElement;\r\n if (!target) return;\r\n\r\n const rect = target.getBoundingClientRect();\r\n const x = event.clientX - rect.left;\r\n const width = rect.width;\r\n\r\n const leftZoneWidth = width * this.hoverZonePercent;\r\n const rightZoneStart = width - (width * this.hoverZonePercent);\r\n\r\n this.showLeftArrow = x <= leftZoneWidth;\r\n this.showRightArrow = x >= rightZoneStart;\r\n }\r\n\r\n /**\r\n * Handle viewport mouse leave - hide arrows\r\n */\r\n onViewportMouseLeave(): void {\r\n this.showLeftArrow = false;\r\n this.showRightArrow = false;\r\n }\r\n\r\n /**\r\n * Navigate to previous panel\r\n */\r\n onNavigatePrevious(): void {\r\n this.navigatePrevious.emit();\r\n }\r\n\r\n /**\r\n * Navigate to next panel\r\n */\r\n onNavigateNext(): void {\r\n this.navigateNext.emit();\r\n }\r\n\r\n /**\r\n * Set focus on a specific panel\r\n */\r\n focusPanel(panelId: string | null): void {\r\n this.focusedPanelId = panelId;\r\n \r\n if (panelId && this.page?.readingOrder) {\r\n this.focusedPanelIndex = this.page.readingOrder.indexOf(panelId);\r\n } else {\r\n this.focusedPanelIndex = -1;\r\n }\r\n \r\n this.panelFocus.emit(panelId);\r\n }\r\n\r\n /**\r\n * Handle keyboard navigation (Tab key)\r\n */\r\n @HostListener('keydown.tab', ['$event'])\r\n onKeydownTab(event: KeyboardEvent): void {\r\n if (this.viewMode !== 'page' || !this.page?.readingOrder) return;\r\n \r\n event.preventDefault();\r\n \r\n const readingOrder = this.page.readingOrder;\r\n const currentIndex = this.focusedPanelIndex;\r\n \r\n if (event.shiftKey) {\r\n // Navigate backwards (Shift+Tab)\r\n const newIndex = currentIndex <= 0 ? readingOrder.length - 1 : currentIndex - 1;\r\n this.focusPanel(readingOrder[newIndex]);\r\n } else {\r\n // Navigate forwards (Tab)\r\n const newIndex = currentIndex >= readingOrder.length - 1 ? 0 : currentIndex + 1;\r\n this.focusPanel(readingOrder[newIndex]);\r\n }\r\n }\r\n\r\n /**\r\n * Handle arrow key navigation\r\n */\r\n @HostListener('keydown.arrowRight', ['$event'])\r\n @HostListener('keydown.arrowDown', ['$event'])\r\n onKeydownNext(event: KeyboardEvent): void {\r\n if (this.viewMode !== 'page' || !this.page?.readingOrder) return;\r\n \r\n event.preventDefault();\r\n \r\n const readingOrder = this.page.readingOrder;\r\n const currentIndex = this.focusedPanelIndex;\r\n const newIndex = currentIndex >= readingOrder.length - 1 ? 0 : currentIndex + 1;\r\n \r\n this.focusPanel(readingOrder[newIndex]);\r\n }\r\n\r\n @HostListener('keydown.arrowLeft', ['$event'])\r\n @HostListener('keydown.arrowUp', ['$event'])\r\n onKeydownPrevious(event: KeyboardEvent): void {\r\n if (this.viewMode !== 'page' || !this.page?.readingOrder) return;\r\n \r\n event.preventDefault();\r\n \r\n const readingOrder = this.page.readingOrder;\r\n const currentIndex = this.focusedPanelIndex;\r\n const newIndex = currentIndex <= 0 ? readingOrder.length - 1 : currentIndex - 1;\r\n \r\n this.focusPanel(readingOrder[newIndex]);\r\n }\r\n\r\n /**\r\n * Handle panel click with overlap handling\r\n * Enhanced to set focus on clicked panel\r\n */\r\n onPanelClickWithFocus(event: MouseEvent): void {\r\n if (this.viewMode !== 'page') return;\r\n \r\n const canvas = event.currentTarget as HTMLElement;\r\n if (!canvas) return;\r\n \r\n // Determine which panel was clicked\r\n const rect = canvas.getBoundingClientRect();\r\n const point = {\r\n x: event.clientX - rect.left,\r\n y: event.clientY - rect.top\r\n };\r\n \r\n // Find the top-most panel at click position\r\n const clickedPanel = this.getPanelAtPoint(point);\r\n \r\n if (clickedPanel) {\r\n this.focusPanel(clickedPanel.panelId);\r\n console.log(`Panel focused: ${clickedPanel.panelId} (z-index: ${clickedPanel.z || 0})`);\r\n } else {\r\n // Clicked on empty space - clear focus\r\n this.focusPanel(null);\r\n }\r\n }\r\n\r\n /**\r\n * Handle keyboard activation of canvas (Enter/Space)\r\n * Focuses on the first panel in reading order if nothing is focused\r\n */\r\n onCanvasKeyboardActivate(event: Event): void {\r\n if (this.viewMode !== 'page') return;\r\n \r\n event.preventDefault();\r\n \r\n // If nothing is focused, focus on the first panel in reading order\r\n if (!this.focusedPanelId && this.page?.readingOrder && this.page.readingOrder.length > 0) {\r\n this.focusPanel(this.page.readingOrder[0]);\r\n }\r\n }\r\n\r\n /**\r\n * Get focus rect for a panel (accounting for rotation)\r\n * Returns the bounding box coordinates for focus visualization\r\n */\r\n getFocusRect(placement: PanelPlacement): {\r\n left: number;\r\n top: number;\r\n width: number;\r\n height: number;\r\n rotation: number;\r\n } | null {\r\n const canvas = document.querySelector('.page-canvas') as HTMLElement;\r\n if (!canvas) return null;\r\n \r\n const canvasWidth = canvas.offsetWidth;\r\n const canvasHeight = canvas.offsetHeight;\r\n \r\n // Convert normalized to pixel coordinates\r\n const left = placement.x * canvasWidth;\r\n const top = placement.y * canvasHeight;\r\n const width = placement.w * canvasWidth;\r\n const height = placement.h * canvasHeight;\r\n \r\n return {\r\n left,\r\n top,\r\n width,\r\n height,\r\n rotation: placement.r || 0\r\n };\r\n }\r\n\r\n /**\r\n * Check if a panel is currently focused\r\n */\r\n isPanelFocused(panelId: string): boolean {\r\n return this.focusedPanelId === panelId;\r\n }\r\n\r\n /**\r\n * Check if a panel is visible in viewport (for culling)\r\n */\r\n isPanelVisible(placement: PanelPlacement): boolean {\r\n if (!this.enableViewportCulling) {\r\n return true; // Always visible if culling disabled\r\n }\r\n\r\n const canvas = document.querySelector('.page-canvas') as HTMLElement;\r\n if (!canvas) return true;\r\n \r\n // Convert normalized to pixel coordinates\r\n const panelLeft = placement.x * canvas.offsetWidth;\r\n const panelTop = placement.y * canvas.offsetHeight;\r\n const panelWidth = placement.w * canvas.offsetWidth;\r\n const panelHeight = placement.h * canvas.offsetHeight;\r\n\r\n // Simple bounding box check (could be enhanced for rotation)\r\n const panelRight = panelLeft + panelWidth;\r\n const panelBottom = panelTop + panelHeight;\r\n\r\n // Check if panel intersects viewport\r\n const isVisible = !(\r\n panelRight < 0 ||\r\n panelBottom < 0 ||\r\n panelLeft > canvas.offsetWidth ||\r\n panelTop > canvas.offsetHeight\r\n );\r\n\r\n // Track visible panels\r\n if (isVisible) {\r\n this.visiblePanels.add(placement.panelId);\r\n } else {\r\n this.visiblePanels.delete(placement.panelId);\r\n }\r\n\r\n return isVisible;\r\n }\r\n\r\n /**\r\n * Start performance measurement\r\n */\r\n startPerformanceMeasurement(): void {\r\n this.performanceStartTime = performance.now();\r\n }\r\n\r\n /**\r\n * End performance measurement and emit metrics\r\n */\r\n endPerformanceMeasurement(): void {\r\n if (this.performanceStartTime === 0) return;\r\n\r\n const renderTime = performance.now() - this.performanceStartTime;\r\n const panelCount = this.page?.layout.placements.length || 0;\r\n const visiblePanelCount = this.visiblePanels.size;\r\n const culledPanelCount = panelCount - visiblePanelCount;\r\n\r\n // Calculate memory usage if available\r\n let memoryUsage: number | undefined;\r\n if ('memory' in performance) {\r\n const perfMemory = (performance as unknown as { memory?: { usedJSHeapSize: number } }).memory;\r\n if (perfMemory) {\r\n memoryUsage = perfMemory.usedJSHeapSize / 1024 / 1024; // MB\r\n }\r\n }\r\n\r\n const metrics: PerformanceMetrics = {\r\n renderTime,\r\n panelCount,\r\n visiblePanelCount,\r\n culledPanelCount,\r\n memoryUsage,\r\n transformCalculationTime: 0 // Updated separately if needed\r\n };\r\n\r\n this.performanceMetrics.emit(metrics);\r\n this.renderCount++;\r\n }\r\n\r\n /**\r\n * Get lazy loading state for images\r\n * Returns 'lazy' if lazy loading is enabled, 'eager' otherwise\r\n */\r\n getImageLoadingStrategy(): 'lazy' | 'eager' {\r\n return this.enableLazyLoading ? 'lazy' : 'eager';\r\n }\r\n\r\n /**\r\n * Measure transform calculation performance\r\n */\r\n measureTransformPerformance(callback: () => void): number {\r\n const start = performance.now();\r\n callback();\r\n const end = performance.now();\r\n return end - start;\r\n }\r\n\r\n /**\r\n * Get performance statistics\r\n */\r\n getPerformanceStats(): {\r\n totalRenders: number;\r\n averageRenderTime: number;\r\n visiblePanelCount: number;\r\n memoryUsage?: number;\r\n } {\r\n let memoryUsage: number | undefined;\r\n if ('memory' in performance) {\r\n const perfMemory = (performance as unknown as { memory?: { usedJSHeapSize: number } }).memory;\r\n if (perfMemory) {\r\n memoryUsage = perfMemory.usedJSHeapSize / 1024 / 1024; // MB\r\n }\r\n }\r\n\r\n return {\r\n totalRenders: this.renderCount,\r\n averageRenderTime: 0, // Would need to track average over time\r\n visiblePanelCount: this.visiblePanels.size,\r\n memoryUsage\r\n };\r\n }\r\n\r\n /**\r\n * Force garbage collection (if available)\r\n * Note: This is only available in dev mode or with specific flags\r\n */\r\n forceGarbageCollection(): void {\r\n const globalWithGC = globalThis as unknown as { gc?: () => void };\r\n if ('gc' in globalThis && typeof globalWithGC.gc === 'function') {\r\n globalWithGC.gc();\r\n console.log('[Performance] Garbage collection triggered');\r\n } else {\r\n console.warn('[Performance] Garbage collection not available');\r\n }\r\n }\r\n\r\n /**\r\n * Profile memory usage\r\n */\r\n profileMemory(): {\r\n totalJSHeapSize?: number;\r\n usedJSHeapSize?: number;\r\n jsHeapSizeLimit?: number;\r\n } {\r\n if ('memory' in performance) {\r\n const perfMemory = (performance as unknown as { \r\n memory?: { \r\n totalJSHeapSize: number; \r\n usedJSHeapSize: number; \r\n jsHeapSizeLimit: number \r\n } \r\n }).memory;\r\n \r\n if (perfMemory) {\r\n return {\r\n totalJSHeapSize: perfMemory.totalJSHeapSize / 1024 / 1024, // MB\r\n usedJSHeapSize: perfMemory.usedJSHeapSize / 1024 / 1024, // MB\r\n jsHeapSizeLimit: perfMemory.jsHeapSizeLimit / 1024 / 1024 // MB\r\n };\r\n }\r\n }\r\n return {};\r\n }\r\n\r\n /**\r\n * Log performance metrics to console\r\n */\r\n logPerformanceMetrics(): void {\r\n const stats = this.getPerformanceStats();\r\n const memory = this.profileMemory();\r\n\r\n console.group('[Performance Metrics]');\r\n console.log('Total Renders:', stats.totalRenders);\r\n console.log('Visible Panels:', stats.visiblePanelCount);\r\n if (stats.memoryUsage) {\r\n console.log('Memory Usage:', stats.memoryUsage.toFixed(2), 'MB');\r\n }\r\n if (memory.usedJSHeapSize) {\r\n console.log('Heap Used:', memory.usedJSHeapSize.toFixed(2), 'MB');\r\n console.log('Heap Total:', memory.totalJSHeapSize?.toFixed(2), 'MB');\r\n console.log('Heap Limit:', memory.jsHeapSizeLimit?.toFixed(2), 'MB');\r\n }\r\n console.groupEnd();\r\n }\r\n}\r\n","<div \r\n class=\"viewport-container\"\r\n [class]=\"getViewModeClass()\"\r\n [class.reduced-motion]=\"reducedMotion\"\r\n [class.interactive]=\"interactive\"\r\n role=\"region\"\r\n [attr.aria-label]=\"viewMode === 'page' ? 'Page viewport' : 'Panel viewport'\"\r\n tabindex=\"0\"\r\n (click)=\"onViewportClick($event)\"\r\n (keydown.enter)=\"onKeyboardActivate($event)\"\r\n (keydown.space)=\"onKeyboardActivate($event)\"\r\n (mousemove)=\"onViewportMouseMove($event)\"\r\n (mouseleave)=\"onViewportMouseLeave()\">\r\n \r\n <!-- Panel View -->\r\n @if (viewMode === 'panel') {\r\n <div\r\n class=\"viewport-content\"\r\n [style.transform]=\"getTransformStyle()\"\r\n [style.transition]=\"reducedMotion ? 'none' : 'transform 0.3s ease'\"\r\n [style.--pw-t-duration]=\"transitionDuration\"\r\n [style.--pw-t-easing]=\"transitionEasing\">\r\n\r\n <!-- Outgoing panel during a manifest edge transition -->\r\n @if (leavingPanel) {\r\n <div [class]=\"'t-frame-leave ' + leaveAnimationClass\" aria-hidden=\"true\">\r\n <div class=\"panel-container\">\r\n @for (layer of leavingPanel.layers; track layer.id) {\r\n <pw-layer-renderer\r\n [layer]=\"layer\"\r\n [locale]=\"locale\"\r\n [viewMode]=\"viewMode\"\r\n [viewActive]=\"false\"\r\n [reducedMotion]=\"reducedMotion\"\r\n [targetWidth]=\"targetWidthFor(leavingPanelId)\"\r\n [panelId]=\"leavingPanelId\">\r\n </pw-layer-renderer>\r\n }\r\n\r\n @if (speechEnabled && leavingPanel.speechBubbles && leavingPanel.speechBubbles.length > 0) {\r\n <pw-speech-bubbles\r\n [bubbles]=\"leavingPanel.speechBubbles\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"getContainerWidth()\"\r\n [containerHeight]=\"getContainerHeight()\"\r\n [readingScale]=\"getReadingScale()\"\r\n [workBalloonConfig]=\"workBalloonConfig\"\r\n [characters]=\"characters\">\r\n </pw-speech-bubbles>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <div [class]=\"'t-frame ' + enterAnimationClass\">\r\n @if (panel) {\r\n <div class=\"panel-container\" tabindex=\"0\" (click)=\"onPanelContainerClick($event, currentPanelId)\" (keydown.enter)=\"onPanelContainerClick($any($event), currentPanelId)\">\r\n <!-- Render layers using LayerRenderer -->\r\n @for (layer of panel.layers; track layer.id) {\r\n <pw-layer-renderer\r\n [layer]=\"layer\"\r\n [locale]=\"locale\"\r\n [viewMode]=\"viewMode\"\r\n [viewActive]=\"true\"\r\n [reducedMotion]=\"reducedMotion\"\r\n [targetWidth]=\"targetWidthFor(currentPanelId)\"\r\n [panelId]=\"currentPanelId || ''\"\r\n (layerClick)=\"layerClick.emit($event)\">\r\n </pw-layer-renderer>\r\n }\r\n\r\n <!-- Interactive hotspots overlay (below speech bubbles) -->\r\n @if (interactive && panel.hotspots && panel.hotspots.length > 0) {\r\n <pw-hotspots-overlay\r\n [hotspots]=\"panel.hotspots\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"getContainerWidth()\"\r\n [containerHeight]=\"getContainerHeight()\"\r\n [context]=\"variableContext\"\r\n (hotspotActivate)=\"onHotspotActivate($event, currentPanelId)\">\r\n </pw-hotspots-overlay>\r\n }\r\n\r\n <!-- Speech bubbles overlay for panel view -->\r\n @if (speechEnabled && panel.speechBubbles && panel.speechBubbles.length > 0) {\r\n <pw-speech-bubbles\r\n [bubbles]=\"panel.speechBubbles\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"getContainerWidth()\"\r\n [containerHeight]=\"getContainerHeight()\"\r\n [readingScale]=\"getReadingScale()\"\r\n [workBalloonConfig]=\"workBalloonConfig\"\r\n [characters]=\"characters\">\r\n </pw-speech-bubbles>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"no-panel\">\r\n <p>No panel to display</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n \r\n <!-- Page View -->\r\n @if (viewMode === 'page' && page) {\r\n <div class=\"viewport-page\">\r\n <div class=\"page-stage\">\r\n <!-- Outgoing page during a Page.transitions in/out change -->\r\n @if (leavingPage) {\r\n <div\r\n [class]=\"'pt-frame-leave ' + pageLeaveClass + (pageLeaveAbove ? ' pt-frame-leave--above' : '')\"\r\n [style.--pw-t-duration]=\"pageLeaveDuration\"\r\n [style.--pw-t-easing]=\"pageLeaveEasing\"\r\n aria-hidden=\"true\">\r\n <div class=\"page-canvas\">\r\n @for (placement of getLeavingPagePlacements(); track placement.panelId) {\r\n <div\r\n class=\"panel-container\"\r\n [style.left.%]=\"toPercent(placement.x)\"\r\n [style.top.%]=\"toPercent(placement.y)\"\r\n [style.width.%]=\"toPercent(placement.w)\"\r\n [style.height.%]=\"toPercent(placement.h)\"\r\n [style.z-index]=\"placement.z || 0\"\r\n [style.transform]=\"getPanelTransform(placement)\"\r\n [style.transform-origin]=\"getTransformOrigin(placement)\">\r\n\r\n @if (getLeavingPanel(placement.panelId); as panelData) {\r\n <div class=\"panel-content\"\r\n [style.clip-path]=\"getPanelContentClipPath(placement)\"\r\n [style.transform]=\"getPanelContentTransform(placement)\">\r\n @for (layer of panelData.layers; track layer.id) {\r\n <pw-layer-renderer\r\n [layer]=\"layer\"\r\n [locale]=\"locale\"\r\n [viewMode]=\"viewMode\"\r\n [viewActive]=\"false\"\r\n [reducedMotion]=\"reducedMotion\"\r\n [targetWidth]=\"targetWidthFor(placement.panelId)\"\r\n [panelId]=\"placement.panelId\"\r\n [placementId]=\"placement.panelId\">\r\n </pw-layer-renderer>\r\n }\r\n\r\n @if (speechEnabled && panelData.speechBubbles && panelData.speechBubbles.length > 0) {\r\n <pw-speech-bubbles\r\n [bubbles]=\"panelData.speechBubbles\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"getPagePanelWidth(placement)\"\r\n [containerHeight]=\"getPagePanelHeight(placement)\"\r\n [readingScale]=\"getReadingScale()\"\r\n [workBalloonConfig]=\"workBalloonConfig\"\r\n [characters]=\"characters\">\r\n </pw-speech-bubbles>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <div\r\n [class]=\"'pt-frame ' + pageEnterClass\"\r\n [style.--pw-t-duration]=\"pageEnterDuration\"\r\n [style.--pw-t-easing]=\"pageEnterEasing\">\r\n <div\r\n class=\"page-canvas\"\r\n [attr.tabindex]=\"-1\"\r\n (click)=\"onPanelClickWithFocus($event)\"\r\n (keydown.enter)=\"onCanvasKeyboardActivate($event)\"\r\n (keydown.space)=\"onCanvasKeyboardActivate($event)\">\r\n \r\n @for (placement of getSortedPanels(); track placement.panelId) {\r\n @if (isPanelVisible(placement)) {\r\n <div \r\n class=\"panel-container\"\r\n [class.panel-focused]=\"isPanelFocused(placement.panelId)\"\r\n [style.left.%]=\"toPercent(placement.x)\"\r\n [style.top.%]=\"toPercent(placement.y)\"\r\n [style.width.%]=\"toPercent(placement.w)\"\r\n [style.height.%]=\"toPercent(placement.h)\"\r\n [style.z-index]=\"placement.z || 0\"\r\n [style.transform]=\"getPanelTransform(placement)\"\r\n [style.transform-origin]=\"getTransformOrigin(placement)\"\r\n [attr.data-panel-id]=\"placement.panelId\"\r\n [attr.tabindex]=\"panelHasHotspots(placement.panelId) ? null : 0\"\r\n [attr.role]=\"panelHasHotspots(placement.panelId) ? null : 'button'\"\r\n [attr.aria-label]=\"panelHasHotspots(placement.panelId) ? null : 'Panel ' + placement.panelId\"\r\n [attr.loading]=\"getImageLoadingStrategy()\"\r\n (click)=\"onPanelClick($event, placement.panelId)\"\r\n (keydown.enter)=\"onPanelKeyboardActivate($event, placement.panelId)\"\r\n (keydown.space)=\"onPanelKeyboardActivate($event, placement.panelId)\">\r\n \r\n @if (getPanel(placement.panelId); as panelData) {\r\n <div class=\"panel-content\"\r\n [style.clip-path]=\"getPanelContentClipPath(placement)\"\r\n [style.transform]=\"getPanelContentTransform(placement)\"\r\n tabindex=\"0\"\r\n (click)=\"onPanelContainerClick($event, placement.panelId)\"\r\n (keydown.enter)=\"onPanelContainerClick($any($event), placement.panelId)\">\r\n <!-- Render panel layers -->\r\n @for (layer of panelData.layers; track layer.id) {\r\n <pw-layer-renderer\r\n [layer]=\"layer\"\r\n [locale]=\"locale\"\r\n [altText]=\"getAltText(layer)\"\r\n [viewMode]=\"viewMode\"\r\n [reducedMotion]=\"reducedMotion\"\r\n [targetWidth]=\"targetWidthFor(placement.panelId)\"\r\n [panelId]=\"placement.panelId\"\r\n [placementId]=\"placement.panelId\"\r\n [readingOrderIndex]=\"readingOrderIndexOf(placement.panelId)\"\r\n [placementZ]=\"placement.z || 0\"\r\n [placementY]=\"placement.y\"\r\n [placementX]=\"placement.x\"\r\n (layerClick)=\"layerClick.emit($event)\">\r\n </pw-layer-renderer>\r\n }\r\n\r\n <!-- Interactive hotspots overlay for page view panels -->\r\n @if (interactive && panelData.hotspots && panelData.hotspots.length > 0) {\r\n <pw-hotspots-overlay\r\n [hotspots]=\"panelData.hotspots\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"getPagePanelWidth(placement)\"\r\n [containerHeight]=\"getPagePanelHeight(placement)\"\r\n [context]=\"variableContext\"\r\n (hotspotActivate)=\"onHotspotActivate($event, placement.panelId)\">\r\n </pw-hotspots-overlay>\r\n }\r\n\r\n <!-- Speech bubbles overlay for page view panels -->\r\n @if (speechEnabled && panelData.speechBubbles && panelData.speechBubbles.length > 0) {\r\n <pw-speech-bubbles\r\n [bubbles]=\"panelData.speechBubbles\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"getPagePanelWidth(placement)\"\r\n [containerHeight]=\"getPagePanelHeight(placement)\"\r\n [readingScale]=\"getReadingScale()\"\r\n [workBalloonConfig]=\"workBalloonConfig\"\r\n [characters]=\"characters\">\r\n </pw-speech-bubbles>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Focus indicator for rotated panels -->\r\n @if (isPanelFocused(placement.panelId)) {\r\n <div class=\"focus-rect\" aria-hidden=\"true\"></div>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (viewMode === 'page' && !page) {\r\n <div class=\"no-panel\">\r\n <p>No page to display</p>\r\n </div>\r\n }\r\n\r\n <!-- Overflow navigation arrows -->\r\n @if (showOverflowArrows && panel) {\r\n @if (hasOverflowLeft) {\r\n <button \r\n class=\"overflow-arrow overflow-left\"\r\n type=\"button\"\r\n aria-label=\"Navigate left\"\r\n (click)=\"navigateLeft()\">\r\n <pw-icon name=\"lucideChevronLeft\" />\r\n </button>\r\n }\r\n\r\n @if (hasOverflowRight) {\r\n <button \r\n class=\"overflow-arrow overflow-right\"\r\n type=\"button\"\r\n aria-label=\"Navigate right\"\r\n (click)=\"navigateRight()\">\r\n <pw-icon name=\"lucideChevronRight\" />\r\n </button>\r\n }\r\n\r\n @if (hasOverflowTop) {\r\n <button \r\n class=\"overflow-arrow overflow-top\"\r\n type=\"button\"\r\n aria-label=\"Navigate up\"\r\n (click)=\"navigateUp()\">\r\n <pw-icon name=\"lucideChevronUp\" />\r\n </button>\r\n }\r\n\r\n @if (hasOverflowBottom) {\r\n <button \r\n class=\"overflow-arrow overflow-bottom\"\r\n type=\"button\"\r\n aria-label=\"Navigate down\"\r\n (click)=\"navigateDown()\">\r\n <pw-icon name=\"lucideChevronDown\" />\r\n </button>\r\n }\r\n }\r\n\r\n <!-- Navigation arrows (hover zones) -->\r\n @if (viewMode === 'panel') {\r\n @if (showLeftArrow) {\r\n <button \r\n class=\"nav-arrow nav-arrow-left\"\r\n type=\"button\"\r\n aria-label=\"Previous panel\"\r\n (click)=\"onNavigatePrevious(); $event.stopPropagation()\">\r\n <span class=\"arrow-icon\"><pw-icon name=\"lucideChevronLeft\" /></span>\r\n </button>\r\n }\r\n\r\n @if (showRightArrow) {\r\n <button \r\n class=\"nav-arrow nav-arrow-right\"\r\n type=\"button\"\r\n aria-label=\"Next panel\"\r\n (click)=\"onNavigateNext(); $event.stopPropagation()\">\r\n <span class=\"arrow-icon\"><pw-icon name=\"lucideChevronRight\" /></span>\r\n </button>\r\n }\r\n }\r\n</div>\r\n","/**\r\n * Canvas Camera Service\r\n *\r\n * Owns the persistent world-space camera for canvas view: framing math,\r\n * animated fly-to moves along graph edges (schema 1.4 CameraMove), free-roam\r\n * pan/zoom with bounds clamping, and the overview zoom. World units:\r\n * 1 unit = 1 CSS pixel at zoom 1.0.\r\n */\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\nimport type {\r\n CameraMove,\r\n CanvasCameraPolicy,\r\n CanvasFitMode,\r\n CanvasLayout,\r\n CanvasPlacement,\r\n WorldPoint,\r\n WorldRect,\r\n} from '../types';\r\n\r\n/**\r\n * Camera state: world coordinates of the viewport center plus zoom factor\r\n * (world-to-screen scale).\r\n */\r\nexport interface CameraState {\r\n x: number;\r\n y: number;\r\n zoom: number;\r\n}\r\n\r\n/** Hard readability/asset ceiling for zooming in (not authorable). */\r\nconst MAX_ZOOM = 4;\r\n\r\n/** Default lowest overview zoom when the policy does not specify one. */\r\nconst DEFAULT_MAX_ZOOM_OUT = 0.05;\r\n\r\n/** Built-in camera move when neither edge nor preset defines one. */\r\nconst DEFAULT_MOVE: Required<Pick<CameraMove, 'path' | 'zoomProfile' | 'durationMs' | 'easing'>> = {\r\n path: 'direct',\r\n zoomProfile: 'hold',\r\n durationMs: 800,\r\n easing: 'ease-in-out',\r\n};\r\n\r\n/**\r\n * Maximum camera travel speed in viewport-heights per second at the current\r\n * zoom — long hops get their duration stretched instead of racing across the\r\n * plane (motion-safety cap, see the integration spec §7).\r\n */\r\nconst MAX_SPEED_VIEWPORTS_PER_SEC = 6;\r\n\r\n/** Margin (in world units, pre-zoom) added around auto bounds. */\r\nconst AUTO_BOUNDS_MARGIN = 256;\r\n\r\ntype EasingFn = (t: number) => number;\r\n\r\nconst EASINGS: Record<string, EasingFn> = {\r\n linear: (t) => t,\r\n ease: (t) => cubicBezier(0.25, 0.1, 0.25, 1, t),\r\n 'ease-in': (t) => t * t,\r\n 'ease-out': (t) => 1 - (1 - t) * (1 - t),\r\n 'ease-in-out': (t) => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2),\r\n};\r\n\r\n/** Approximate CSS cubic-bezier easing by sampling the bezier's y for x=t. */\r\nfunction cubicBezier(x1: number, y1: number, x2: number, y2: number, t: number): number {\r\n // Sufficient approximation for camera easing: solve x(u)=t by bisection.\r\n let lo = 0;\r\n let hi = 1;\r\n for (let i = 0; i < 20; i++) {\r\n const mid = (lo + hi) / 2;\r\n const x = bezierAxis(x1, x2, mid);\r\n if (x < t) lo = mid;\r\n else hi = mid;\r\n }\r\n const u = (lo + hi) / 2;\r\n return bezierAxis(y1, y2, u);\r\n}\r\n\r\nfunction bezierAxis(p1: number, p2: number, u: number): number {\r\n const v = 1 - u;\r\n return 3 * v * v * u * p1 + 3 * v * u * u * p2 + u * u * u;\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class CanvasCameraService {\r\n private readonly stateSubject = new BehaviorSubject<CameraState>({ x: 0, y: 0, zoom: 1 });\r\n\r\n /** Camera state stream (fires once per animation frame during moves). */\r\n readonly state$: Observable<CameraState> = this.stateSubject.asObservable();\r\n\r\n private viewportWidth = 1;\r\n private viewportHeight = 1;\r\n\r\n private policy: CanvasCameraPolicy = {};\r\n private bounds: WorldRect | null = null;\r\n\r\n private animationFrame: number | null = null;\r\n private animationResolve: (() => void) | null = null;\r\n\r\n /** Camera state saved when entering overview, restored on exit. */\r\n private preOverviewState: CameraState | null = null;\r\n\r\n get state(): CameraState {\r\n return this.stateSubject.value;\r\n }\r\n\r\n get isAnimating(): boolean {\r\n return this.animationFrame !== null;\r\n }\r\n\r\n get isOverview(): boolean {\r\n return this.preOverviewState !== null;\r\n }\r\n\r\n // --------------------------------------------------------------------------\r\n // Configuration\r\n // --------------------------------------------------------------------------\r\n\r\n /** Configure the camera for a chapter's canvas. Resets overview state. */\r\n configure(layout: CanvasLayout, viewportWidth: number, viewportHeight: number): void {\r\n this.policy = layout.camera ?? {};\r\n this.setViewportSize(viewportWidth, viewportHeight);\r\n this.bounds =\r\n this.policy.bounds && this.policy.bounds !== 'auto'\r\n ? this.policy.bounds\r\n : this.computeAutoBounds(Object.values(layout.placements ?? {}));\r\n this.preOverviewState = null;\r\n this.cancel();\r\n }\r\n\r\n setViewportSize(width: number, height: number): void {\r\n this.viewportWidth = Math.max(1, width);\r\n this.viewportHeight = Math.max(1, height);\r\n }\r\n\r\n /** The configured viewport size (screen pixels). */\r\n get viewportSize(): { width: number; height: number } {\r\n return { width: this.viewportWidth, height: this.viewportHeight };\r\n }\r\n\r\n /** Convert a viewport-relative screen point to world coordinates. */\r\n screenToWorld(screenX: number, screenY: number): WorldPoint {\r\n const s = this.state;\r\n return {\r\n x: s.x + (screenX - this.viewportWidth / 2) / s.zoom,\r\n y: s.y + (screenY - this.viewportHeight / 2) / s.zoom,\r\n };\r\n }\r\n\r\n /** Union of placement bounding boxes (rotation-expanded) plus a margin. */\r\n computeAutoBounds(placements: CanvasPlacement[]): WorldRect | null {\r\n if (placements.length === 0) {\r\n return null;\r\n }\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n for (const placement of placements) {\r\n const box = this.placementBoundingBox(placement);\r\n minX = Math.min(minX, box.x);\r\n minY = Math.min(minY, box.y);\r\n maxX = Math.max(maxX, box.x + box.w);\r\n maxY = Math.max(maxY, box.y + box.h);\r\n }\r\n return {\r\n x: minX - AUTO_BOUNDS_MARGIN,\r\n y: minY - AUTO_BOUNDS_MARGIN,\r\n w: maxX - minX + 2 * AUTO_BOUNDS_MARGIN,\r\n h: maxY - minY + 2 * AUTO_BOUNDS_MARGIN,\r\n };\r\n }\r\n\r\n /** Axis-aligned bounding box of a (possibly rotated) placement. */\r\n placementBoundingBox(placement: CanvasPlacement): WorldRect {\r\n const r = placement.r ?? 0;\r\n if (r === 0) {\r\n return { x: placement.x, y: placement.y, w: placement.w, h: placement.h };\r\n }\r\n const rad = (r * Math.PI) / 180;\r\n const cos = Math.abs(Math.cos(rad));\r\n const sin = Math.abs(Math.sin(rad));\r\n const w = placement.w * cos + placement.h * sin;\r\n const h = placement.w * sin + placement.h * cos;\r\n const ox = placement.origin?.x ?? 0.5;\r\n const oy = placement.origin?.y ?? 0.5;\r\n // The rotation origin stays fixed; the expanded box is centered on the\r\n // rotated rect's center, which only moves when the origin is off-center.\r\n const cx = placement.x + placement.w * ox + (placement.w / 2 - placement.w * ox) * Math.cos(rad) - (placement.h / 2 - placement.h * oy) * Math.sin(rad);\r\n const cy = placement.y + placement.h * oy + (placement.w / 2 - placement.w * ox) * Math.sin(rad) + (placement.h / 2 - placement.h * oy) * Math.cos(rad);\r\n return { x: cx - w / 2, y: cy - h / 2, w, h };\r\n }\r\n\r\n // --------------------------------------------------------------------------\r\n // Framing math\r\n // --------------------------------------------------------------------------\r\n\r\n /**\r\n * Camera state that frames a placement (respecting its `enterFraming`\r\n * panel-relative rect) according to the policy's fit mode.\r\n */\r\n frameForPlacement(placement: CanvasPlacement): CameraState {\r\n const framing = placement.enterFraming;\r\n let rect: WorldRect;\r\n if (framing) {\r\n rect = {\r\n x: placement.x + framing.x * placement.w,\r\n y: placement.y + framing.y * placement.h,\r\n w: Math.max(1, framing.w * placement.w),\r\n h: Math.max(1, framing.h * placement.h),\r\n };\r\n } else {\r\n rect = this.placementBoundingBox(placement);\r\n }\r\n return this.frameForRect(rect, this.policy.fitMode ?? 'contain');\r\n }\r\n\r\n /** Camera state that frames an arbitrary world rect. */\r\n frameForRect(rect: WorldRect, fitMode: CanvasFitMode = 'contain'): CameraState {\r\n const zoomX = this.viewportWidth / rect.w;\r\n const zoomY = this.viewportHeight / rect.h;\r\n let zoom: number;\r\n switch (fitMode) {\r\n case 'cover':\r\n zoom = Math.max(zoomX, zoomY);\r\n break;\r\n case 'width':\r\n zoom = zoomX;\r\n break;\r\n case 'height':\r\n zoom = zoomY;\r\n break;\r\n case 'contain':\r\n default:\r\n zoom = Math.min(zoomX, zoomY);\r\n break;\r\n }\r\n return this.clampState({\r\n x: rect.x + rect.w / 2,\r\n y: rect.y + rect.h / 2,\r\n zoom: this.clampZoom(zoom),\r\n });\r\n }\r\n\r\n /** The world rect currently visible for a given camera state. */\r\n visibleWorldRect(state: CameraState = this.state): WorldRect {\r\n const w = this.viewportWidth / state.zoom;\r\n const h = this.viewportHeight / state.zoom;\r\n return { x: state.x - w / 2, y: state.y - h / 2, w, h };\r\n }\r\n\r\n // --------------------------------------------------------------------------\r\n // Animated moves\r\n // --------------------------------------------------------------------------\r\n\r\n /** Jump instantly (initial placement, reduced motion). */\r\n jumpTo(target: CameraState): void {\r\n this.cancel();\r\n this.preOverviewState = null;\r\n this.stateSubject.next(this.clampState(target));\r\n }\r\n\r\n /**\r\n * Animate the camera to `target` along a CameraMove. Resolves when the\r\n * move settles or is cancelled/superseded. Reduced motion is handled by\r\n * the caller (jumpTo + CSS fallback) — this method always glides.\r\n */\r\n flyTo(target: CameraState, move?: CameraMove): Promise<void> {\r\n this.cancel();\r\n this.preOverviewState = null;\r\n\r\n const from = this.state;\r\n const to = this.clampState(target);\r\n const path = move?.path ?? DEFAULT_MOVE.path;\r\n const zoomProfile = move?.zoomProfile ?? DEFAULT_MOVE.zoomProfile;\r\n const easing = EASINGS[move?.easing ?? DEFAULT_MOVE.easing] ?? EASINGS['ease-in-out'];\r\n const durationMs = this.cappedDuration(\r\n from,\r\n to,\r\n move?.durationMs ?? DEFAULT_MOVE.durationMs\r\n );\r\n\r\n const positions = this.buildPathPoints(from, to, path, move?.waypoints);\r\n const apexZoom = this.pullBackApexZoom(from, to);\r\n\r\n if (\r\n durationMs <= 0 ||\r\n typeof requestAnimationFrame === 'undefined' ||\r\n typeof performance === 'undefined'\r\n ) {\r\n this.stateSubject.next(to);\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise<void>((resolve) => {\r\n this.animationResolve = resolve;\r\n const start = performance.now();\r\n\r\n const step = (now: number): void => {\r\n const rawT = Math.min(1, (now - start) / durationMs);\r\n const t = easing(rawT);\r\n\r\n const position = this.samplePath(positions, t);\r\n const zoom = this.sampleZoom(from.zoom, to.zoom, zoomProfile, apexZoom, t);\r\n this.stateSubject.next(this.clampState({ x: position.x, y: position.y, zoom }));\r\n\r\n if (rawT >= 1) {\r\n this.stateSubject.next(to);\r\n this.animationFrame = null;\r\n this.animationResolve = null;\r\n resolve();\r\n return;\r\n }\r\n this.animationFrame = requestAnimationFrame(step);\r\n };\r\n this.animationFrame = requestAnimationFrame(step);\r\n });\r\n }\r\n\r\n /**\r\n * Cancel a running fly-to (reader grabbed the camera). The pending promise\r\n * resolves — navigation state is already final; only the glide stops.\r\n */\r\n cancel(): void {\r\n if (this.animationFrame !== null && typeof cancelAnimationFrame !== 'undefined') {\r\n cancelAnimationFrame(this.animationFrame);\r\n }\r\n this.animationFrame = null;\r\n if (this.animationResolve) {\r\n const resolve = this.animationResolve;\r\n this.animationResolve = null;\r\n resolve();\r\n }\r\n }\r\n\r\n // --------------------------------------------------------------------------\r\n // Free roam & overview\r\n // --------------------------------------------------------------------------\r\n\r\n /** Pan by a screen-space delta (pixels). */\r\n panBy(screenDx: number, screenDy: number): void {\r\n this.cancel();\r\n const s = this.state;\r\n this.stateSubject.next(\r\n this.clampState({ x: s.x - screenDx / s.zoom, y: s.y - screenDy / s.zoom, zoom: s.zoom })\r\n );\r\n }\r\n\r\n /**\r\n * Zoom by a factor keeping the given screen point (relative to the\r\n * viewport's top-left) stationary — standard map-style zoom-at-cursor.\r\n */\r\n zoomAt(factor: number, screenX: number, screenY: number): void {\r\n this.cancel();\r\n this.preOverviewState = null;\r\n const s = this.state;\r\n const zoom = this.clampZoom(s.zoom * factor);\r\n if (zoom === s.zoom) {\r\n return;\r\n }\r\n // World point under the cursor before the zoom...\r\n const worldX = s.x + (screenX - this.viewportWidth / 2) / s.zoom;\r\n const worldY = s.y + (screenY - this.viewportHeight / 2) / s.zoom;\r\n // ...stays under the cursor after.\r\n this.stateSubject.next(\r\n this.clampState({\r\n x: worldX - (screenX - this.viewportWidth / 2) / zoom,\r\n y: worldY - (screenY - this.viewportHeight / 2) / zoom,\r\n zoom,\r\n })\r\n );\r\n }\r\n\r\n /** Zoom by a factor anchored at the viewport center (keyboard zoom). */\r\n zoomAtCenter(factor: number): void {\r\n this.zoomAt(factor, this.viewportWidth / 2, this.viewportHeight / 2);\r\n }\r\n\r\n /**\r\n * Toggle the overview: zoom out to the full canvas bounds, or return to\r\n * the framing the camera had before entering it.\r\n */\r\n toggleOverview(animate = true): Promise<void> {\r\n if (this.policy.overview?.enabled === false) {\r\n return Promise.resolve();\r\n }\r\n if (this.preOverviewState) {\r\n const restore = this.preOverviewState;\r\n this.preOverviewState = null;\r\n return animate ? this.flyTo(restore, { zoomProfile: 'hold', durationMs: 500 }) : (this.jumpTo(restore), Promise.resolve());\r\n }\r\n if (!this.bounds) {\r\n return Promise.resolve();\r\n }\r\n const saved = this.state;\r\n const overview = this.frameForRect(this.bounds, 'contain');\r\n const promise = animate\r\n ? this.flyTo(overview, { zoomProfile: 'hold', durationMs: 500 })\r\n : (this.jumpTo(overview), Promise.resolve());\r\n // flyTo/jumpTo clear preOverviewState — set it after starting the move.\r\n this.preOverviewState = saved;\r\n return promise;\r\n }\r\n\r\n // --------------------------------------------------------------------------\r\n // Internals\r\n // --------------------------------------------------------------------------\r\n\r\n private clampZoom(zoom: number): number {\r\n const minZoom = this.overviewMinZoom();\r\n return Math.min(MAX_ZOOM, Math.max(minZoom, zoom));\r\n }\r\n\r\n /**\r\n * The lowest permitted zoom: the smaller of the policy's maxZoomOut and\r\n * whatever it takes to see the full bounds (so the overview always fits).\r\n */\r\n private overviewMinZoom(): number {\r\n let min = this.policy.overview?.maxZoomOut ?? DEFAULT_MAX_ZOOM_OUT;\r\n if (this.bounds) {\r\n const fit = Math.min(this.viewportWidth / this.bounds.w, this.viewportHeight / this.bounds.h);\r\n min = Math.min(min, fit);\r\n }\r\n return Math.max(1e-4, min);\r\n }\r\n\r\n /** Keep the visible rect inside the bounds (when bounds are known). */\r\n private clampState(state: CameraState): CameraState {\r\n const zoom = this.clampZoom(state.zoom);\r\n if (!this.bounds) {\r\n return { x: state.x, y: state.y, zoom };\r\n }\r\n const half = { w: this.viewportWidth / zoom / 2, h: this.viewportHeight / zoom / 2 };\r\n let { x, y } = state;\r\n // When the view is wider than the bounds, center on them instead.\r\n if (half.w * 2 >= this.bounds.w) {\r\n x = this.bounds.x + this.bounds.w / 2;\r\n } else {\r\n x = Math.min(this.bounds.x + this.bounds.w - half.w, Math.max(this.bounds.x + half.w, x));\r\n }\r\n if (half.h * 2 >= this.bounds.h) {\r\n y = this.bounds.y + this.bounds.h / 2;\r\n } else {\r\n y = Math.min(this.bounds.y + this.bounds.h - half.h, Math.max(this.bounds.y + half.h, y));\r\n }\r\n return { x, y, zoom };\r\n }\r\n\r\n /**\r\n * Stretch too-short durations so the camera never exceeds the speed cap\r\n * (viewport-heights per second, measured at the destination zoom).\r\n */\r\n private cappedDuration(from: CameraState, to: CameraState, durationMs: number): number {\r\n const distance = Math.hypot(to.x - from.x, to.y - from.y);\r\n const viewportHeightWorld = this.viewportHeight / Math.max(to.zoom, 1e-4);\r\n if (viewportHeightWorld <= 0) {\r\n return durationMs;\r\n }\r\n const minMs = (distance / viewportHeightWorld / MAX_SPEED_VIEWPORTS_PER_SEC) * 1000;\r\n return Math.max(durationMs, Math.ceil(minMs));\r\n }\r\n\r\n /**\r\n * Path polyline for the move: direct = [from, to]; waypoints = through the\r\n * authored points; arc = a single perpendicular-offset midpoint.\r\n */\r\n private buildPathPoints(\r\n from: CameraState,\r\n to: CameraState,\r\n path: string,\r\n waypoints?: WorldPoint[]\r\n ): WorldPoint[] {\r\n const start = { x: from.x, y: from.y };\r\n const end = { x: to.x, y: to.y };\r\n if (path === 'waypoints' && waypoints && waypoints.length > 0) {\r\n return [start, ...waypoints, end];\r\n }\r\n if (path === 'arc') {\r\n const mx = (start.x + end.x) / 2;\r\n const my = (start.y + end.y) / 2;\r\n const dx = end.x - start.x;\r\n const dy = end.y - start.y;\r\n const len = Math.hypot(dx, dy) || 1;\r\n // Perpendicular offset of 20% of the travel distance.\r\n return [start, { x: mx - (dy / len) * len * 0.2, y: my + (dx / len) * len * 0.2 }, end];\r\n }\r\n return [start, end];\r\n }\r\n\r\n /** Sample a polyline by arc length at t in [0,1]. */\r\n private samplePath(points: WorldPoint[], t: number): WorldPoint {\r\n if (points.length === 1) {\r\n return points[0];\r\n }\r\n const lengths: number[] = [];\r\n let total = 0;\r\n for (let i = 1; i < points.length; i++) {\r\n const len = Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y);\r\n lengths.push(len);\r\n total += len;\r\n }\r\n if (total === 0) {\r\n return points[points.length - 1];\r\n }\r\n let remaining = t * total;\r\n for (let i = 0; i < lengths.length; i++) {\r\n if (remaining <= lengths[i] || i === lengths.length - 1) {\r\n const segT = lengths[i] === 0 ? 1 : Math.min(1, remaining / lengths[i]);\r\n return {\r\n x: points[i].x + (points[i + 1].x - points[i].x) * segT,\r\n y: points[i].y + (points[i + 1].y - points[i].y) * segT,\r\n };\r\n }\r\n remaining -= lengths[i];\r\n }\r\n return points[points.length - 1];\r\n }\r\n\r\n /**\r\n * Zoom over the course of the move:\r\n * - hold: lerp start → end zoom\r\n * - pull-back: quadratic dip through the apex (out at the middle, back in)\r\n * - dive: ease-in lerp (accelerating zoom into the target)\r\n */\r\n private sampleZoom(\r\n fromZoom: number,\r\n toZoom: number,\r\n profile: string,\r\n apexZoom: number,\r\n t: number\r\n ): number {\r\n // Interpolate zoom logarithmically — perceptually linear scaling.\r\n const lerpLog = (a: number, b: number, u: number): number =>\r\n Math.exp(Math.log(a) + (Math.log(b) - Math.log(a)) * u);\r\n\r\n switch (profile) {\r\n case 'pull-back': {\r\n if (t < 0.5) {\r\n return lerpLog(fromZoom, apexZoom, t * 2);\r\n }\r\n return lerpLog(apexZoom, toZoom, (t - 0.5) * 2);\r\n }\r\n case 'dive':\r\n return lerpLog(fromZoom, toZoom, t * t);\r\n case 'hold':\r\n default:\r\n return lerpLog(fromZoom, toZoom, t);\r\n }\r\n }\r\n\r\n /**\r\n * Pull-back apex: zoomed out far enough that both the source and target\r\n * viewports fit on screen together (with 20% breathing room), never closer\r\n * than either endpoint.\r\n */\r\n private pullBackApexZoom(from: CameraState, to: CameraState): number {\r\n const fromRect = this.visibleWorldRect(from);\r\n const toRect = this.visibleWorldRect(to);\r\n const minX = Math.min(fromRect.x, toRect.x);\r\n const minY = Math.min(fromRect.y, toRect.y);\r\n const maxX = Math.max(fromRect.x + fromRect.w, toRect.x + toRect.w);\r\n const maxY = Math.max(fromRect.y + fromRect.h, toRect.y + toRect.h);\r\n const fit = Math.min(\r\n this.viewportWidth / (maxX - minX),\r\n this.viewportHeight / (maxY - minY)\r\n ) / 1.2;\r\n return Math.max(this.overviewMinZoom(), Math.min(fit, from.zoom, to.zoom));\r\n }\r\n}\r\n","/**\n * Canvas Stage Component\n *\n * Renders a chapter's infinite-canvas layout (schema 1.4): all placed panels\n * share one continuous world-space plane; a single composited transform on\n * `.canvas-world` is the camera. Panels outside the (inflated) viewport are\n * virtualized out of the DOM entirely.\n *\n * World units: 1 unit = 1 CSS pixel at zoom 1.0 — placed panels render at\n * their placement size and layers keep their pixel coordinates unchanged.\n */\n\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnChanges,\n OnDestroy,\n OnInit,\n Output,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\n\nimport type {\n CanvasDecoration,\n CanvasLayout,\n CanvasPlacement,\n Graph,\n LocaleCode,\n Panel,\n PreloadSettings,\n WorldRect,\n} from '../../types';\nimport type { BalloonConfig } from '../../types';\nimport type { Character } from '../../types';\nimport type { VariableContext } from '../../types';\nimport type { Hotspot } from '../../types';\n\nimport { CanvasCameraService, CameraState } from '../../services/canvas-camera.service';\nimport { ManifestService } from '../../services/manifest.service';\nimport { PreloadService } from '../../services/preload.service';\nimport { quantizeTargetWidth, selectImageVariantForWidth } from '../../utils/image-variant-utils';\nimport { LayerRendererComponent } from '../layer-renderer/layer-renderer.component';\nimport { SpeechBubblesComponent } from '../overlays/speech-bubbles/speech-bubbles.component';\nimport { HotspotsOverlayComponent } from '../overlays/hotspots-overlay/hotspots-overlay.component';\n\n/** A placement prepared for rendering. */\nexport interface StagePlacement {\n panelId: string;\n panel: Panel;\n placement: CanvasPlacement;\n revealed: boolean;\n}\n\n/** Maximum panels mounted in the DOM at once, regardless of chapter size. */\nexport const CANVAS_PANEL_BUDGET = 12;\n\n/** Movement (px) below which a pointer press counts as a tap. */\nconst TAP_SLOP_PX = 8;\n\n/** Press duration (ms) below which a pointer press counts as a tap. */\nconst TAP_MAX_MS = 350;\n\n/** Width fraction of the edge zones that trigger prev/next on tap. */\nconst EDGE_ZONE_FRACTION = 0.15;\n\n/** Throttle interval for cameraChange emissions. */\nconst CAMERA_EMIT_INTERVAL_MS = 100;\n\n@Component({\n selector: 'pw-canvas-stage',\n imports: [LayerRendererComponent, SpeechBubblesComponent, HotspotsOverlayComponent],\n templateUrl: './canvas-stage.component.html',\n styleUrls: ['./canvas-stage.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CanvasStageComponent implements OnInit, OnChanges, OnDestroy {\n /** The chapter's canvas layout. */\n @Input() canvas: CanvasLayout | null = null;\n\n /** The chapter's panels by id. */\n @Input() panels: Record<string, Panel> = {};\n\n /** The chapter's graph (tap-to-advance uses its out-edges). */\n @Input() graph: Graph | null = null;\n\n /** Id of the current (trail) panel. */\n @Input() currentPanelId: string | null = null;\n\n /** Panels the trail has visited (drives `revealMode: \"on-visit\"`). */\n @Input() visitedPanelIds: string[] = [];\n\n @Input() locale: LocaleCode = 'en-US';\n @Input() variableContext: VariableContext | null = null;\n @Input() speechEnabled = true;\n @Input() workBalloonConfig: BalloonConfig | null = null;\n @Input() characters: Character[] = [];\n @Input() reducedMotion = false;\n @Input() interactive = true;\n\n /** Manifest preload settings (settings.preload); null = defaults. */\n @Input() preload: PreloadSettings | null = null;\n\n /** Tap on a placed panel (shell decides whether it is an edge target). */\n @Output() panelTap = new EventEmitter<string>();\n\n /** Tap in the right/left edge zone (same semantics as panel view). */\n @Output() navigateNext = new EventEmitter<void>();\n @Output() navigatePrevious = new EventEmitter<void>();\n\n /** Tap on empty plane (hosts typically toggle the toolbar). */\n @Output() viewportClick = new EventEmitter<void>();\n\n /**\n * A hotspot on the current panel was activated (click, tap or keyboard).\n * Same payload as the panel view's overlay, plus the panel id.\n */\n @Output() hotspotActivate = new EventEmitter<{ hotspot: Hotspot; x: number; y: number; panelId: string }>();\n\n /** Throttled camera state (position/zoom) for hosts and analytics. */\n @Output() cameraChange = new EventEmitter<CameraState>();\n\n readonly camera = inject(CanvasCameraService);\n private readonly manifestService = inject(ManifestService);\n private readonly preloadService = inject(PreloadService);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly cdr = inject(ChangeDetectorRef);\n\n private readonly destroy$ = new Subject<void>();\n\n /** Current world transform CSS for `.canvas-world`. */\n worldTransform = '';\n\n /** Placements currently mounted (virtualized working set). */\n stagePlacements: StagePlacement[] = [];\n\n /** Decorations currently mounted. */\n visibleDecorations: CanvasDecoration[] = [];\n\n private resizeObserver?: ResizeObserver;\n private lastCameraEmit = 0;\n\n /**\n * Required display width per mounted panel (physical px, quantized) for\n * image variant selection. Upgrade-only while mounted so an already-loaded\n * high-res variant is never swapped back to a thumbnail (no flicker).\n */\n private readonly variantWidths = new Map<string, number>();\n private settleTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** `on-approach` panels that have been revealed this session. */\n private readonly approached = new Set<string>();\n\n // Pointer/gesture state\n private readonly activePointers = new Map<number, { x: number; y: number }>();\n private pressStart: { x: number; y: number; time: number } | null = null;\n private isPanning = false;\n private lastPinchDistance = 0;\n\n ngOnInit(): void {\n this.camera.state$.pipe(takeUntil(this.destroy$)).subscribe((state) => {\n this.onCameraState(state);\n });\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.onHostResize());\n this.resizeObserver.observe(this.elementRef.nativeElement);\n }\n this.onHostResize();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['canvas'] && this.canvas) {\n const host = this.elementRef.nativeElement;\n this.camera.configure(this.canvas, host.clientWidth || 1, host.clientHeight || 1);\n // Land on the current panel without animation (initial placement).\n const placement = this.currentPlacement();\n if (placement) {\n this.camera.jumpTo(this.camera.frameForPlacement(placement));\n }\n this.approached.clear();\n this.variantWidths.clear();\n }\n\n // Reduced motion: the shell reframes with jumpTo instead of gliding —\n // soften the hard cut with a short cross-fade (CameraMove's\n // reducedMotionFallback contract; no gliding, ever).\n if (\n changes['currentPanelId'] &&\n !changes['currentPanelId'].firstChange &&\n this.reducedMotion &&\n typeof this.elementRef.nativeElement.animate === 'function'\n ) {\n this.elementRef.nativeElement.animate(\n [{ opacity: 0.15 }, { opacity: 1 }],\n { duration: 220, easing: 'ease-out' }\n );\n }\n\n this.refreshStage();\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n if (this.settleTimer) {\n clearTimeout(this.settleTimer);\n }\n this.camera.cancel();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --------------------------------------------------------------------------\n // Camera plumbing\n // --------------------------------------------------------------------------\n\n private onCameraState(state: CameraState): void {\n const host = this.elementRef.nativeElement;\n const vw = host.clientWidth || 1;\n const vh = host.clientHeight || 1;\n this.worldTransform =\n `translate(${vw / 2}px, ${vh / 2}px) ` +\n `scale(${state.zoom}) ` +\n `translate(${-state.x}px, ${-state.y}px)`;\n this.refreshStage();\n this.cdr.markForCheck();\n\n // Variant/preload work runs on camera settle, never per frame.\n if (this.settleTimer) {\n clearTimeout(this.settleTimer);\n }\n this.settleTimer = setTimeout(() => {\n this.settleTimer = null;\n this.onCameraSettled();\n }, 180);\n\n const now = Date.now();\n if (now - this.lastCameraEmit >= CAMERA_EMIT_INTERVAL_MS) {\n this.lastCameraEmit = now;\n this.cameraChange.emit(state);\n }\n }\n\n /** Zoom settled: re-resolve image variants and warm neighbor assets. */\n private onCameraSettled(): void {\n this.updateVariantWidths();\n this.preloadNeighbors();\n this.cdr.markForCheck();\n }\n\n /**\n * Required display width per mounted panel at the settled zoom\n * (placement width × zoom × devicePixelRatio, quantized). Upgrade-only.\n */\n private updateVariantWidths(): void {\n const zoom = this.camera.state.zoom;\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n for (const entry of this.stagePlacements) {\n const needed = quantizeTargetWidth(entry.placement.w * zoom * dpr);\n const current = this.variantWidths.get(entry.panelId) ?? 0;\n if (needed > current) {\n this.variantWidths.set(entry.panelId, needed);\n }\n }\n }\n\n /** Variant-selection width for a mounted panel (0 = legacy first variant). */\n targetWidthFor(panelId: string): number {\n return this.variantWidths.get(panelId) ?? 0;\n }\n\n /**\n * Warm the assets the reader is likely to see next (integration spec §5):\n * out-edge targets of the current panel first, then the spatially nearest\n * placements. Honors settings.preload (strategy, panelsAhead,\n * maxConcurrent); each candidate preloads the variant it would render at.\n */\n private preloadNeighbors(): void {\n if (!this.canvas || this.preload?.strategy === 'none') {\n return;\n }\n if (this.preload?.maxConcurrent) {\n this.preloadService.setMaxConcurrent(this.preload.maxConcurrent);\n }\n const panelsAhead = this.preload?.panelsAhead ?? 2;\n\n const currentId = this.currentPanelId;\n const edgeTargets = (this.graph?.edges ?? [])\n .filter((edge) => edge.from === currentId)\n .map((edge) => edge.to)\n .slice(0, Math.max(panelsAhead, 1));\n\n const state = this.camera.state;\n const spatial = Object.entries(this.canvas.placements)\n .filter(([panelId]) => panelId !== currentId && !edgeTargets.includes(panelId))\n .map(([panelId, placement]) => ({\n panelId,\n placement,\n distance: Math.hypot(\n placement.x + placement.w / 2 - state.x,\n placement.y + placement.h / 2 - state.y\n ),\n }))\n .sort((a, b) => a.distance - b.distance)\n .slice(0, 4)\n .map((entry) => entry.panelId);\n\n const zoom = state.zoom;\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n const queue: { panelId: string; priority: 'high' | 'medium' }[] = [\n ...edgeTargets.map((panelId) => ({ panelId, priority: 'high' as const })),\n ...spatial.map((panelId) => ({ panelId, priority: 'medium' as const })),\n ];\n\n for (const candidate of queue) {\n const panel = this.panels[candidate.panelId];\n const placement = this.canvas.placements[candidate.panelId];\n if (!panel || !placement) {\n continue;\n }\n const width = quantizeTargetWidth(placement.w * zoom * dpr);\n for (const layer of panel.layers ?? []) {\n if (layer.kind !== 'image' || typeof layer.assetId !== 'string') {\n continue;\n }\n const asset = this.manifestService.getAsset(layer.assetId);\n const variant = selectImageVariantForWidth(asset?.variants as never, width);\n if (variant?.src) {\n this.preloadService.add({\n id: variant.src,\n type: 'image',\n url: variant.src,\n priority: candidate.priority,\n panelId: candidate.panelId,\n });\n }\n }\n }\n }\n\n private onHostResize(): void {\n const host = this.elementRef.nativeElement;\n this.camera.setViewportSize(host.clientWidth || 1, host.clientHeight || 1);\n this.onCameraState(this.camera.state);\n }\n\n private currentPlacement(): CanvasPlacement | null {\n if (!this.canvas || !this.currentPanelId) {\n return null;\n }\n return this.canvas.placements[this.currentPanelId] ?? null;\n }\n\n // --------------------------------------------------------------------------\n // Virtualization\n // --------------------------------------------------------------------------\n\n /**\n * Recompute the mounted working set: placements whose bounding box\n * intersects the camera rect inflated by one viewport in every direction,\n * nearest-first, capped at {@link CANVAS_PANEL_BUDGET} — the current panel\n * is always included.\n */\n private refreshStage(): void {\n if (!this.canvas) {\n this.stagePlacements = [];\n this.visibleDecorations = [];\n return;\n }\n\n const view = this.camera.visibleWorldRect();\n const inflated: WorldRect = {\n x: view.x - view.w,\n y: view.y - view.h,\n w: view.w * 3,\n h: view.h * 3,\n };\n\n const candidates: (StagePlacement & { distance: number })[] = [];\n for (const [panelId, placement] of Object.entries(this.canvas.placements)) {\n const panel = this.panels[panelId];\n if (!panel) {\n continue;\n }\n const box = this.camera.placementBoundingBox(placement);\n const isCurrent = panelId === this.currentPanelId;\n if (!isCurrent && !rectsIntersect(box, inflated)) {\n continue;\n }\n const cx = box.x + box.w / 2 - this.camera.state.x;\n const cy = box.y + box.h / 2 - this.camera.state.y;\n candidates.push({\n panelId,\n panel,\n placement,\n revealed: this.isRevealed(panelId, placement, view),\n distance: isCurrent ? -1 : Math.hypot(cx, cy),\n });\n }\n candidates.sort((a, b) => a.distance - b.distance);\n this.stagePlacements = candidates\n .slice(0, CANVAS_PANEL_BUDGET)\n .map((candidate) => ({\n panelId: candidate.panelId,\n panel: candidate.panel,\n placement: candidate.placement,\n revealed: candidate.revealed,\n }));\n\n this.visibleDecorations = (this.canvas.decorations ?? []).filter((decoration) =>\n rectsIntersect(\n { x: decoration.x, y: decoration.y, w: decoration.w, h: decoration.h },\n inflated\n )\n );\n }\n\n /**\n * Reveal state per placement:\n * - `always` (default): revealed.\n * - `on-visit`: revealed once the trail reached it.\n * - `on-approach`: revealed once the camera rect (x1.5) touches it, then\n * stays revealed for the session.\n */\n private isRevealed(panelId: string, placement: CanvasPlacement, view: WorldRect): boolean {\n const mode = placement.revealMode ?? 'always';\n if (mode === 'always') {\n return true;\n }\n if (this.currentPanelId === panelId || this.visitedPanelIds.includes(panelId)) {\n return true;\n }\n if (mode === 'on-visit') {\n return false;\n }\n // on-approach\n if (this.approached.has(panelId)) {\n return true;\n }\n const near: WorldRect = {\n x: view.x - view.w * 0.25,\n y: view.y - view.h * 0.25,\n w: view.w * 1.5,\n h: view.h * 1.5,\n };\n if (rectsIntersect(this.camera.placementBoundingBox(placement), near)) {\n this.approached.add(panelId);\n return true;\n }\n return false;\n }\n\n // --------------------------------------------------------------------------\n // Template helpers\n // --------------------------------------------------------------------------\n\n placementStyle(entry: StagePlacement): Record<string, string> {\n const p = entry.placement;\n const styles: Record<string, string> = {\n left: `${p.x}px`,\n top: `${p.y}px`,\n width: `${p.w}px`,\n height: `${p.h}px`,\n 'z-index': `${p.z ?? 0}`,\n };\n if (p.r) {\n styles['transform'] = `rotate(${p.r}deg)`;\n styles['transform-origin'] = `${(p.origin?.x ?? 0.5) * 100}% ${(p.origin?.y ?? 0.5) * 100}%`;\n }\n return styles;\n }\n\n decorationStyle(decoration: CanvasDecoration): Record<string, string> {\n const styles: Record<string, string> = {\n left: `${decoration.x}px`,\n top: `${decoration.y}px`,\n width: `${decoration.w}px`,\n height: `${decoration.h}px`,\n 'z-index': `${decoration.z ?? 0}`,\n };\n if (decoration.r) {\n styles['transform'] = `rotate(${decoration.r}deg)`;\n }\n const depth = decoration.parallaxDepth ?? 0;\n if (depth !== 0) {\n const s = this.camera.state;\n const rotate = decoration.r ? ` rotate(${decoration.r}deg)` : '';\n styles['transform'] = `translate(${s.x * depth}px, ${s.y * depth}px)${rotate}`;\n }\n if (decoration.opacity !== undefined) {\n styles['opacity'] = `${decoration.opacity}`;\n }\n return styles;\n }\n\n assetUrl(assetId: string | undefined): string {\n if (!assetId) {\n return '';\n }\n const asset = this.manifestService.getAsset(assetId);\n return asset?.variants?.[0]?.src ?? '';\n }\n\n backgroundStyle(): Record<string, string> {\n const bg = this.canvas?.background;\n const styles: Record<string, string> = {};\n if (bg?.color) {\n styles['background-color'] = bg.color;\n }\n const url = this.assetUrl(bg?.assetId);\n if (url && bg?.repeat === 'fixed') {\n styles['background-image'] = `url(\"${url}\")`;\n styles['background-size'] = 'cover';\n }\n return styles;\n }\n\n /** Tiled/stretched backdrop rect covering the canvas bounds (world space). */\n worldBackgroundStyle(): Record<string, string> | null {\n const bg = this.canvas?.background;\n const url = this.assetUrl(bg?.assetId);\n if (!url || bg?.repeat === 'fixed' || !this.canvas) {\n return null;\n }\n const bounds = this.camera.computeAutoBounds(Object.values(this.canvas.placements));\n if (!bounds) {\n return null;\n }\n return {\n left: `${bounds.x}px`,\n top: `${bounds.y}px`,\n width: `${bounds.w}px`,\n height: `${bounds.h}px`,\n 'background-image': `url(\"${url}\")`,\n 'background-repeat': bg?.repeat === 'stretch' ? 'no-repeat' : 'repeat',\n 'background-size': bg?.repeat === 'stretch' ? '100% 100%' : 'auto',\n };\n }\n\n /** Balloon lettering scale (same DIN-A4 reference as the panel viewport). */\n getReadingScale(): number {\n const h = this.elementRef.nativeElement.clientHeight || 0;\n return h > 0 ? h / 1123 : 1;\n }\n\n isCurrent(panelId: string): boolean {\n return panelId === this.currentPanelId;\n }\n\n trackPlacement(_index: number, entry: StagePlacement): string {\n return entry.panelId;\n }\n\n // --------------------------------------------------------------------------\n // Input handling\n // --------------------------------------------------------------------------\n\n private freeRoamAllowed(): boolean {\n const mode = this.canvas?.camera?.freeRoam ?? 'between-moves';\n if (mode === 'off') {\n return false;\n }\n if (mode === 'between-moves') {\n return !this.camera.isAnimating;\n }\n return true;\n }\n\n onPointerDown(event: PointerEvent): void {\n if (!this.interactive) {\n return;\n }\n // A press that starts on an interactive hotspot belongs to the hotspot:\n // capturing the pointer here would swallow its click (and a tap would\n // turn into panel/edge navigation).\n if (this.isInteractiveHotspotTarget(event.target)) {\n return;\n }\n this.elementRef.nativeElement.setPointerCapture?.(event.pointerId);\n this.activePointers.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (this.activePointers.size === 1) {\n this.pressStart = { x: event.clientX, y: event.clientY, time: Date.now() };\n this.isPanning = false;\n } else if (this.activePointers.size === 2) {\n this.pressStart = null;\n this.lastPinchDistance = this.pinchDistance();\n }\n }\n\n onPointerMove(event: PointerEvent): void {\n if (!this.interactive || !this.activePointers.has(event.pointerId)) {\n return;\n }\n const prev = this.activePointers.get(event.pointerId)!;\n this.activePointers.set(event.pointerId, { x: event.clientX, y: event.clientY });\n\n if (this.activePointers.size === 2) {\n // Pinch zoom at the midpoint (always allowed — it is the overview gesture).\n const distance = this.pinchDistance();\n if (this.lastPinchDistance > 0 && distance > 0) {\n const rect = this.elementRef.nativeElement.getBoundingClientRect();\n const points = [...this.activePointers.values()];\n const midX = (points[0].x + points[1].x) / 2 - rect.left;\n const midY = (points[0].y + points[1].y) / 2 - rect.top;\n this.camera.zoomAt(distance / this.lastPinchDistance, midX, midY);\n }\n this.lastPinchDistance = distance;\n return;\n }\n\n const dx = event.clientX - prev.x;\n const dy = event.clientY - prev.y;\n if (!this.isPanning && this.pressStart) {\n const total = Math.hypot(\n event.clientX - this.pressStart.x,\n event.clientY - this.pressStart.y\n );\n if (total > TAP_SLOP_PX) {\n this.isPanning = true;\n }\n }\n if (this.isPanning && this.freeRoamAllowed()) {\n this.camera.panBy(dx, dy);\n }\n }\n\n onPointerUp(event: PointerEvent): void {\n if (!this.activePointers.has(event.pointerId)) {\n return;\n }\n this.activePointers.delete(event.pointerId);\n if (this.activePointers.size > 0) {\n this.pressStart = null;\n return;\n }\n\n const press = this.pressStart;\n this.pressStart = null;\n if (!press || this.isPanning) {\n this.isPanning = false;\n return;\n }\n if (Date.now() - press.time > TAP_MAX_MS) {\n return;\n }\n this.handleTap(event);\n }\n\n /** Whether an event target sits on a clickable hotspot shape. */\n private isInteractiveHotspotTarget(target: EventTarget | null): boolean {\n const el = target as Element | null;\n if (!el || typeof el.closest !== 'function') {\n return false;\n }\n const shape = el.closest('.hotspot-shape');\n return !!shape && !shape.closest('.hotspots-svg.non-interactive, [data-interactive=\"false\"]') && shape.getAttribute('tabindex') !== '-1';\n }\n\n onWheel(event: WheelEvent): void {\n if (!this.interactive) {\n return;\n }\n event.preventDefault();\n const rect = this.elementRef.nativeElement.getBoundingClientRect();\n if (event.ctrlKey || event.metaKey) {\n const factor = Math.exp(-event.deltaY * 0.002);\n this.camera.zoomAt(factor, event.clientX - rect.left, event.clientY - rect.top);\n } else if (this.freeRoamAllowed()) {\n this.camera.panBy(-event.deltaX, -event.deltaY);\n }\n }\n\n private handleTap(event: PointerEvent): void {\n const rect = this.elementRef.nativeElement.getBoundingClientRect();\n const screenX = event.clientX - rect.left;\n const screenY = event.clientY - rect.top;\n\n const hit = this.panelAtScreenPoint(screenX, screenY);\n if (hit && hit !== this.currentPanelId) {\n this.panelTap.emit(hit);\n return;\n }\n if (screenX <= rect.width * EDGE_ZONE_FRACTION) {\n this.navigatePrevious.emit();\n return;\n }\n if (screenX >= rect.width * (1 - EDGE_ZONE_FRACTION)) {\n this.navigateNext.emit();\n return;\n }\n this.viewportClick.emit();\n }\n\n /** Topmost mounted placement containing the screen point (rotation-aware). */\n panelAtScreenPoint(screenX: number, screenY: number): string | null {\n const { x: worldX, y: worldY } = this.camera.screenToWorld(screenX, screenY);\n\n const sorted = [...this.stagePlacements].sort(\n (a, b) => (b.placement.z ?? 0) - (a.placement.z ?? 0)\n );\n for (const entry of sorted) {\n if (this.pointInPlacement(worldX, worldY, entry.placement)) {\n return entry.panelId;\n }\n }\n return null;\n }\n\n private pointInPlacement(x: number, y: number, placement: CanvasPlacement): boolean {\n let px = x;\n let py = y;\n const r = placement.r ?? 0;\n if (r !== 0) {\n const originX = placement.x + placement.w * (placement.origin?.x ?? 0.5);\n const originY = placement.y + placement.h * (placement.origin?.y ?? 0.5);\n const rad = (-r * Math.PI) / 180;\n const dx = x - originX;\n const dy = y - originY;\n px = originX + dx * Math.cos(rad) - dy * Math.sin(rad);\n py = originY + dx * Math.sin(rad) + dy * Math.cos(rad);\n }\n return (\n px >= placement.x &&\n px <= placement.x + placement.w &&\n py >= placement.y &&\n py <= placement.y + placement.h\n );\n }\n\n private pinchDistance(): number {\n const points = [...this.activePointers.values()];\n if (points.length < 2) {\n return 0;\n }\n return Math.hypot(points[1].x - points[0].x, points[1].y - points[0].y);\n }\n}\n\nfunction rectsIntersect(a: WorldRect, b: WorldRect): boolean {\n return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;\n}\n","<div\r\n class=\"canvas-viewport\"\r\n [class.reduced-motion]=\"reducedMotion\"\r\n [style]=\"backgroundStyle()\"\r\n role=\"region\"\r\n aria-label=\"Canvas viewport\"\r\n tabindex=\"0\"\r\n (pointerdown)=\"onPointerDown($event)\"\r\n (pointermove)=\"onPointerMove($event)\"\r\n (pointerup)=\"onPointerUp($event)\"\r\n (pointercancel)=\"onPointerUp($event)\"\r\n (wheel)=\"onWheel($event)\">\r\n\r\n <div class=\"canvas-world\" [style.transform]=\"worldTransform\">\r\n\r\n <!-- Tiled/stretched backdrop covering the canvas bounds -->\r\n @if (worldBackgroundStyle(); as bgStyle) {\r\n <div class=\"canvas-backdrop\" [style]=\"bgStyle\" aria-hidden=\"true\"></div>\r\n }\r\n\r\n <!-- Non-panel set dressing -->\r\n @for (decoration of visibleDecorations; track decoration.assetId + decoration.x + decoration.y) {\r\n <img\r\n class=\"canvas-decoration\"\r\n [src]=\"assetUrl(decoration.assetId)\"\r\n [style]=\"decorationStyle(decoration)\"\r\n alt=\"\"\r\n aria-hidden=\"true\"\r\n loading=\"lazy\" />\r\n }\r\n\r\n <!-- Placed panels (virtualized) -->\r\n @for (entry of stagePlacements; track trackPlacement($index, entry)) {\r\n <div\r\n class=\"canvas-panel\"\r\n [class.current]=\"isCurrent(entry.panelId)\"\r\n [class.unrevealed]=\"!entry.revealed\"\r\n [style]=\"placementStyle(entry)\"\r\n [attr.data-panel-id]=\"entry.panelId\"\r\n [attr.aria-hidden]=\"isCurrent(entry.panelId) ? null : true\"\r\n [attr.inert]=\"isCurrent(entry.panelId) ? null : ''\">\r\n\r\n @if (entry.revealed) {\r\n @for (layer of entry.panel.layers; track layer.id) {\r\n <pw-layer-renderer\r\n [layer]=\"layer\"\r\n [locale]=\"locale\"\r\n viewMode=\"panel\"\r\n [viewActive]=\"isCurrent(entry.panelId)\"\r\n [reducedMotion]=\"reducedMotion\"\r\n [targetWidth]=\"targetWidthFor(entry.panelId)\"\r\n [panelId]=\"entry.panelId\">\r\n </pw-layer-renderer>\r\n }\r\n\r\n <!-- Hotspots are interactive on the CURRENT panel (the one the\r\n camera frames); other panels show them render-only, and a\r\n tap there keeps its panel-navigation meaning. -->\r\n @if (entry.panel.hotspots && entry.panel.hotspots.length > 0) {\r\n <pw-hotspots-overlay\r\n [hotspots]=\"entry.panel.hotspots\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"entry.placement.w\"\r\n [containerHeight]=\"entry.placement.h\"\r\n [context]=\"variableContext\"\r\n [interactive]=\"interactive && isCurrent(entry.panelId)\"\r\n (hotspotActivate)=\"hotspotActivate.emit({ hotspot: $event.hotspot, x: $event.x, y: $event.y, panelId: entry.panelId })\">\r\n </pw-hotspots-overlay>\r\n }\r\n\r\n @if (speechEnabled && entry.panel.speechBubbles && entry.panel.speechBubbles.length > 0) {\r\n <pw-speech-bubbles\r\n [bubbles]=\"entry.panel.speechBubbles\"\r\n [locale]=\"locale\"\r\n [containerWidth]=\"entry.placement.w\"\r\n [containerHeight]=\"entry.placement.h\"\r\n [readingScale]=\"getReadingScale()\"\r\n [workBalloonConfig]=\"workBalloonConfig\"\r\n [characters]=\"characters\">\r\n </pw-speech-bubbles>\r\n }\r\n } @else {\r\n <!-- Unrevealed panel: dark veil, no content (spoiler protection) -->\r\n <div class=\"canvas-panel-veil\" aria-hidden=\"true\"></div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n","/**\r\n * Toolbar Component\r\n * Bottom toolbar with all player controls\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n} from '@angular/core';\r\n\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport type { LocaleCode } from '../../types';\r\nimport { PwIconComponent } from '../icon/pw-icon.component';\r\n\r\n/**\r\n * Toolbar Component\r\n * Provides all player controls in a bottom toolbar\r\n */\r\n@Component({\r\n selector: 'pw-toolbar',\r\n imports: [TranslateModule, PwIconComponent],\r\n templateUrl: './toolbar.component.html',\r\n styleUrls: ['./toolbar.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class ToolbarComponent {\r\n /**\r\n * Current locale\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Available locales\r\n */\r\n @Input() availableLocales: LocaleCode[] = ['en-US'];\r\n\r\n /**\r\n * Current view mode\r\n */\r\n @Input() viewMode: 'page' | 'panel' | 'canvas' = 'panel';\r\n\r\n /**\r\n * Page view available\r\n */\r\n @Input() pageViewAvailable = false;\r\n\r\n /**\r\n * Speech bubbles enabled\r\n */\r\n @Input() speechEnabled = true;\r\n\r\n /**\r\n * Audio enabled\r\n */\r\n @Input() audioEnabled = true;\r\n\r\n /**\r\n * SFX enabled\r\n */\r\n @Input() sfxEnabled = true;\r\n\r\n /**\r\n * Autoplay enabled\r\n */\r\n @Input() autoplayEnabled = false;\r\n\r\n /**\r\n * Seconds per panel (autoplay)\r\n */\r\n @Input() secondsPerPanel = 5;\r\n\r\n /**\r\n * Autoplay progress (0-100)\r\n */\r\n @Input() autoplayProgress = 0;\r\n\r\n /**\r\n * Thumbnails visible\r\n */\r\n @Input() thumbnailsVisible = false;\r\n\r\n /**\r\n * Has alternatives for current panel\r\n */\r\n @Input() hasAlternatives = false;\r\n\r\n /**\r\n * Has branch choices ahead\r\n */\r\n @Input() hasBranches = false;\r\n\r\n /**\r\n * Reader has liked this work (renders the Like button pressed)\r\n */\r\n @Input() liked = false;\r\n\r\n /**\r\n * Current panel is the reader's bookmark (renders the Bookmark button pressed)\r\n */\r\n @Input() bookmarked = false;\r\n\r\n /**\r\n * Show social controls\r\n */\r\n @Input() showSocial = true;\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Toggle page/panel view\r\n */\r\n @Output() toggleView = new EventEmitter<void>();\r\n\r\n /**\r\n * Locale changed\r\n */\r\n @Output() localeChange = new EventEmitter<LocaleCode>();\r\n\r\n /**\r\n * Toggle speech bubbles\r\n */\r\n @Output() toggleSpeech = new EventEmitter<void>();\r\n\r\n /**\r\n * Toggle audio\r\n */\r\n @Output() toggleAudio = new EventEmitter<void>();\r\n\r\n /**\r\n * Toggle SFX\r\n */\r\n @Output() toggleSfx = new EventEmitter<void>();\r\n\r\n /**\r\n * Toggle autoplay\r\n */\r\n @Output() toggleAutoplay = new EventEmitter<void>();\r\n\r\n /**\r\n * Seconds per panel changed\r\n */\r\n @Output() secondsPerPanelChange = new EventEmitter<number>();\r\n\r\n /**\r\n * Toggle thumbnails\r\n */\r\n @Output() toggleThumbnails = new EventEmitter<void>();\r\n\r\n /**\r\n * Open table of contents\r\n */\r\n @Output() openToc = new EventEmitter<void>();\r\n\r\n /**\r\n * Open settings\r\n */\r\n @Output() openSettings = new EventEmitter<void>();\r\n\r\n /**\r\n * Open characters\r\n */\r\n @Output() openCharacters = new EventEmitter<void>();\r\n\r\n /**\r\n * Cycle alternatives\r\n */\r\n @Output() cycleAlternative = new EventEmitter<void>();\r\n\r\n /**\r\n * Show branch choices\r\n */\r\n @Output() showBranches = new EventEmitter<void>();\r\n\r\n /**\r\n * Open extras\r\n */\r\n @Output() openExtras = new EventEmitter<void>();\r\n\r\n /**\r\n * Like action\r\n */\r\n @Output() like = new EventEmitter<void>();\r\n\r\n /**\r\n * Bookmark action\r\n */\r\n @Output() bookmark = new EventEmitter<void>();\r\n\r\n /**\r\n * Share action\r\n */\r\n @Output() share = new EventEmitter<void>();\r\n\r\n /**\r\n * Open comments\r\n */\r\n @Output() openComments = new EventEmitter<void>();\r\n\r\n /**\r\n * Close toolbar\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Open language modal\r\n */\r\n @Output() openLanguage = new EventEmitter<void>();\r\n\r\n /**\r\n * Handle view toggle\r\n */\r\n onToggleView(): void {\r\n if (this.pageViewAvailable) {\r\n this.toggleView.emit();\r\n }\r\n }\r\n\r\n /**\r\n * Adjust seconds per panel\r\n */\r\n adjustSecondsPerPanel(delta: number): void {\r\n const newValue = Math.max(0.5, Math.min(120, this.secondsPerPanel + delta));\r\n this.secondsPerPanelChange.emit(newValue);\r\n }\r\n\r\n /**\r\n * Handle speech toggle\r\n */\r\n onToggleSpeech(): void {\r\n this.toggleSpeech.emit();\r\n }\r\n\r\n /**\r\n * Handle audio toggle\r\n */\r\n onToggleAudio(): void {\r\n this.toggleAudio.emit();\r\n }\r\n\r\n /**\r\n * Handle SFX toggle\r\n */\r\n onToggleSfx(): void {\r\n this.toggleSfx.emit();\r\n }\r\n\r\n /**\r\n * Handle autoplay toggle\r\n */\r\n onToggleAutoplay(): void {\r\n this.toggleAutoplay.emit();\r\n }\r\n\r\n /**\r\n * Handle thumbnails toggle\r\n */\r\n onToggleThumbnails(): void {\r\n this.toggleThumbnails.emit();\r\n }\r\n\r\n /**\r\n * Handle ToC open\r\n */\r\n onOpenToc(): void {\r\n this.openToc.emit();\r\n }\r\n\r\n /**\r\n * Handle settings open\r\n */\r\n onOpenSettings(): void {\r\n this.openSettings.emit();\r\n }\r\n\r\n /**\r\n * Handle characters open\r\n */\r\n onOpenCharacters(): void {\r\n this.openCharacters.emit();\r\n }\r\n\r\n /**\r\n * Handle alternative cycle\r\n */\r\n onCycleAlternative(): void {\r\n this.cycleAlternative.emit();\r\n }\r\n\r\n /**\r\n * Handle branches display\r\n */\r\n onShowBranches(): void {\r\n this.showBranches.emit();\r\n }\r\n\r\n /**\r\n * Handle extras open\r\n */\r\n onOpenExtras(): void {\r\n this.openExtras.emit();\r\n }\r\n\r\n /**\r\n * Handle like\r\n */\r\n onLike(): void {\r\n this.like.emit();\r\n }\r\n\r\n /**\r\n * Handle bookmark\r\n */\r\n onBookmark(): void {\r\n this.bookmark.emit();\r\n }\r\n\r\n /**\r\n * Handle share\r\n */\r\n onShare(): void {\r\n this.share.emit();\r\n }\r\n\r\n /**\r\n * Handle comments\r\n */\r\n onOpenComments(): void {\r\n this.openComments.emit();\r\n }\r\n\r\n /**\r\n * Handle close\r\n */\r\n onClose(): void {\r\n this.close.emit();\r\n }\r\n}\r\n","<div class=\"toolbar-container\" [class.visible]=\"visible\">\r\n <div class=\"toolbar\">\r\n <!-- Left section: View and navigation controls -->\r\n <div class=\"toolbar-section toolbar-left\">\r\n <!-- View toggle (page/panel) -->\r\n <button\r\n class=\"toolbar-btn\"\r\n [class.disabled]=\"!pageViewAvailable\"\r\n [disabled]=\"!pageViewAvailable\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.view_toggle' | translate\"\r\n [attr.title]=\"'toolbar.view_toggle' | translate\"\r\n (click)=\"onToggleView()\">\r\n <span class=\"btn-icon\"><pw-icon [name]=\"viewMode === 'page' ? 'lucideLayoutGrid' : viewMode === 'canvas' ? 'lucideGlobe' : 'lucideSquare'\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.view' | translate }}</span>\r\n </button>\r\n\r\n <!-- Language selector -->\r\n @if (availableLocales.length > 1) {\r\n <button\r\n class=\"toolbar-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.select_language' | translate\"\r\n (click)=\"openLanguage.emit()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideGlobe\" /></span>\r\n <span class=\"btn-label\">{{ locale }}</span>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Center section: Content controls -->\r\n <div class=\"toolbar-section toolbar-center\">\r\n <!-- Speech bubbles toggle -->\r\n <button\r\n class=\"toolbar-btn toggle-btn\"\r\n [class.active]=\"speechEnabled\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.speech_toggle' | translate\"\r\n [attr.aria-pressed]=\"speechEnabled\"\r\n [attr.title]=\"'toolbar.speech_toggle' | translate\"\r\n (click)=\"onToggleSpeech()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideMessageSquare\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.speech' | translate }}</span>\r\n </button>\r\n\r\n <!-- Audio toggle -->\r\n <button\r\n class=\"toolbar-btn toggle-btn\"\r\n [class.active]=\"audioEnabled\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.audio_toggle' | translate\"\r\n [attr.aria-pressed]=\"audioEnabled\"\r\n [attr.title]=\"'toolbar.audio_toggle' | translate\"\r\n (click)=\"onToggleAudio()\">\r\n <span class=\"btn-icon\"><pw-icon [name]=\"audioEnabled ? 'lucideVolume2' : 'lucideVolumeX'\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.audio' | translate }}</span>\r\n </button>\r\n\r\n <!-- SFX toggle -->\r\n <button\r\n class=\"toolbar-btn toggle-btn\"\r\n [class.active]=\"sfxEnabled\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.sfx_toggle' | translate\"\r\n [attr.aria-pressed]=\"sfxEnabled\"\r\n [attr.title]=\"'toolbar.sfx_toggle' | translate\"\r\n (click)=\"onToggleSfx()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideMusic\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.sfx' | translate }}</span>\r\n </button>\r\n\r\n <!-- Autoplay control -->\r\n <div class=\"toolbar-dropdown\">\r\n <button\r\n class=\"toolbar-btn toggle-btn autoplay-btn\"\r\n [class.active]=\"autoplayEnabled\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.autoplay_toggle' | translate\"\r\n [attr.aria-pressed]=\"autoplayEnabled\"\r\n [attr.title]=\"'toolbar.autoplay_toggle' | translate\"\r\n (click)=\"onToggleAutoplay()\">\r\n <span class=\"btn-icon\"><pw-icon [name]=\"autoplayEnabled ? 'lucidePause' : 'lucidePlay'\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.autoplay' | translate }}</span>\r\n @if (autoplayEnabled) {\r\n <div class=\"autoplay-progress-bar\">\r\n <div class=\"autoplay-progress-fill\" [style.width.%]=\"autoplayProgress\"></div>\r\n </div>\r\n }\r\n </button>\r\n\r\n @if (autoplayEnabled) {\r\n <div class=\"autoplay-controls\">\r\n <button\r\n class=\"control-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.decrease_speed' | translate\"\r\n (click)=\"adjustSecondsPerPanel(-1)\">\r\n -\r\n </button>\r\n <span class=\"control-value\">{{ 'toolbar.seconds' | translate: {value: secondsPerPanel} }}</span>\r\n <button\r\n class=\"control-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.increase_speed' | translate\"\r\n (click)=\"adjustSecondsPerPanel(1)\">\r\n +\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Thumbnails toggle -->\r\n <button\r\n class=\"toolbar-btn toggle-btn\"\r\n [class.active]=\"thumbnailsVisible\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.thumbs_toggle' | translate\"\r\n [attr.aria-pressed]=\"thumbnailsVisible\"\r\n [attr.title]=\"'toolbar.thumbs_toggle' | translate\"\r\n (click)=\"onToggleThumbnails()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideImages\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.thumbs' | translate }}</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Right section: Navigation and info controls -->\r\n <div class=\"toolbar-section toolbar-right\">\r\n <!-- Table of Contents -->\r\n <button\r\n class=\"toolbar-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.toc_open' | translate\"\r\n [attr.title]=\"'toolbar.toc_open' | translate\"\r\n (click)=\"onOpenToc()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideList\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.toc' | translate }}</span>\r\n </button>\r\n\r\n <!-- Settings -->\r\n <button\r\n class=\"toolbar-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.settings_open' | translate\"\r\n [attr.title]=\"'toolbar.settings_open' | translate\"\r\n (click)=\"onOpenSettings()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideSettings\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.settings' | translate }}</span>\r\n </button>\r\n\r\n <!-- Characters -->\r\n <button\r\n class=\"toolbar-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.characters_open' | translate\"\r\n [attr.title]=\"'toolbar.characters_open' | translate\"\r\n (click)=\"onOpenCharacters()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideUsers\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.characters' | translate }}</span>\r\n </button>\r\n\r\n <!-- Alternatives (if available) -->\r\n @if (hasAlternatives) {\r\n <button\r\n class=\"toolbar-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.alt_label' | translate\"\r\n [attr.title]=\"'toolbar.alt_cycle' | translate\"\r\n (click)=\"onCycleAlternative()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideRefreshCw\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.alt' | translate }}</span>\r\n </button>\r\n }\r\n\r\n <!-- Branch indicator (if choices ahead) -->\r\n @if (hasBranches) {\r\n <button\r\n class=\"toolbar-btn branch-indicator\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.choices_label' | translate\"\r\n [attr.title]=\"'toolbar.choices_view' | translate\"\r\n (click)=\"onShowBranches()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideSplit\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.choices' | translate }}</span>\r\n </button>\r\n }\r\n\r\n <!-- Extras -->\r\n <button\r\n class=\"toolbar-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.extras' | translate\"\r\n [attr.title]=\"'toolbar.extras_open' | translate\"\r\n (click)=\"onOpenExtras()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideSparkles\" /></span>\r\n <span class=\"btn-label\">{{ 'toolbar.extras' | translate }}</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Social cluster (rightmost) -->\r\n @if (showSocial) {\r\n <div class=\"toolbar-section toolbar-social\">\r\n <button\r\n class=\"toolbar-btn icon-only\"\r\n type=\"button\"\r\n [class.active]=\"liked\"\r\n [attr.aria-pressed]=\"liked\"\r\n [attr.aria-label]=\"'toolbar.like' | translate\"\r\n [attr.title]=\"(liked ? 'toolbar.like_remove' : 'toolbar.like_work') | translate\"\r\n (click)=\"onLike()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideHeart\" /></span>\r\n </button>\r\n\r\n <button\r\n class=\"toolbar-btn icon-only\"\r\n type=\"button\"\r\n [class.active]=\"bookmarked\"\r\n [attr.aria-pressed]=\"bookmarked\"\r\n [attr.aria-label]=\"'toolbar.bookmark' | translate\"\r\n [attr.title]=\"(bookmarked ? 'toolbar.bookmark_remove' : 'toolbar.bookmark_panel') | translate\"\r\n (click)=\"onBookmark()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideBookmark\" /></span>\r\n </button>\r\n\r\n <button\r\n class=\"toolbar-btn icon-only\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.share' | translate\"\r\n [attr.title]=\"'toolbar.share_panel' | translate\"\r\n (click)=\"onShare()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideShare2\" /></span>\r\n </button>\r\n\r\n <button\r\n class=\"toolbar-btn icon-only\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.comments' | translate\"\r\n [attr.title]=\"'toolbar.comments_view' | translate\"\r\n (click)=\"onOpenComments()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideMessageCircle\" /></span>\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- Close button -->\r\n <button\r\n class=\"toolbar-btn close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toolbar.close' | translate\"\r\n [attr.title]=\"'toolbar.close' | translate\"\r\n (click)=\"onClose()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideX\" /></span>\r\n </button>\r\n </div>\r\n</div>\r\n","/**\r\n * Language Selection Modal Component\r\n */\r\n\r\nimport { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';\r\n\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\nimport type { LocaleCode } from '../../../types';\r\n\r\n/**\r\n * Language Selection Modal\r\n * Allows users to select the interface language\r\n */\r\n@Component({\r\n selector: 'pw-language-modal',\r\n imports: [TranslateModule, PwIconComponent],\r\n templateUrl: './language-modal.component.html',\r\n styleUrls: ['./language-modal.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class LanguageModalComponent {\r\n /**\r\n * Modal visibility\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Current locale\r\n */\r\n @Input() currentLocale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Available locales\r\n */\r\n @Input() availableLocales: LocaleCode[] = [];\r\n\r\n /**\r\n * Close modal\r\n */\r\n @Output() closeModal = new EventEmitter<void>();\r\n\r\n /**\r\n * Locale selected\r\n */\r\n @Output() localeSelected = new EventEmitter<LocaleCode>();\r\n\r\n /**\r\n * Handle locale selection\r\n */\r\n onSelectLocale(locale: LocaleCode): void {\r\n this.localeSelected.emit(locale);\r\n this.closeModal.emit();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n this.closeModal.emit();\r\n }\r\n }\r\n\r\n /**\r\n * Handle escape key\r\n */\r\n onBackdropKeydown(event: KeyboardEvent): void {\r\n if (event.key === 'Escape') {\r\n this.closeModal.emit();\r\n }\r\n }\r\n}\r\n","@if (visible) {\r\n <div \r\n class=\"language-overlay\" \r\n (click)=\"onBackdropClick($event)\"\r\n (keydown)=\"onBackdropKeydown($event)\"\r\n tabindex=\"-1\">\r\n <div class=\"language-container\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"language-title\">\r\n <!-- Header -->\r\n <div class=\"language-header\">\r\n <h2 id=\"language-title\" class=\"language-title\">\r\n {{ 'toolbar.select_language' | translate }}\r\n </h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'settings.close' | translate\"\r\n (click)=\"closeModal.emit()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Language list -->\r\n <div class=\"language-content\">\r\n <div class=\"language-list\">\r\n @for (locale of availableLocales; track locale) {\r\n <button\r\n class=\"language-item\"\r\n [class.active]=\"locale === currentLocale\"\r\n type=\"button\"\r\n (click)=\"onSelectLocale(locale)\">\r\n <span class=\"language-icon\"><pw-icon name=\"lucideGlobe\" /></span>\r\n <span class=\"language-name\">{{ locale }}</span>\r\n @if (locale === currentLocale) {\r\n <span class=\"language-check\"><pw-icon name=\"lucideCheck\" /></span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n","/**\r\n * Thumbnail Strip Component\r\n * Displays panel thumbnails for navigation\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n OnChanges,\r\n SimpleChanges,\r\n ChangeDetectionStrategy,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n HostListener,\r\n Injector,\r\n afterNextRender,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport type { Chapter, Panel } from '../../../types';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\n\r\n/**\r\n * Thumbnail navigation target\r\n */\r\nexport interface ThumbnailNavigationTarget {\r\n chapterId: string;\r\n panelId: string;\r\n}\r\n\r\n/**\r\n * Thumbnail item with metadata\r\n */\r\ninterface ThumbnailItem {\r\n chapterId: string;\r\n panelId: string;\r\n thumbnail?: string;\r\n isLocked: boolean;\r\n isCurrentChapter: boolean;\r\n isCurrentPanel: boolean;\r\n chapterStart: boolean;\r\n chapterTitle?: string;\r\n index: number;\r\n}\r\n\r\n/**\r\n * Thumbnail Strip Component\r\n * Horizontal strip of panel thumbnails for quick navigation\r\n */\r\n@Component({\r\n selector: 'pw-thumbnail-strip',\r\n imports: [PwIconComponent],\r\n templateUrl: './thumbnail-strip.component.html',\r\n styleUrls: ['./thumbnail-strip.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class ThumbnailStripComponent implements OnChanges, AfterViewInit {\r\n private readonly injector = inject(Injector);\r\n\r\n /**\r\n * Whether a post-render scroll to the current panel is already queued\r\n */\r\n private scrollQueued = false;\r\n\r\n /**\r\n * Chapters with panels\r\n */\r\n @Input() chapters: Chapter[] = [];\r\n\r\n /**\r\n * Current chapter ID\r\n */\r\n @Input() currentChapterId?: string;\r\n\r\n /**\r\n * Current panel ID\r\n */\r\n @Input() currentPanelId?: string;\r\n\r\n /**\r\n * Base URL for thumbnails\r\n */\r\n @Input() baseUrl = '';\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Locked panel IDs (for paywall)\r\n */\r\n @Input() lockedPanels: string[] = [];\r\n\r\n /**\r\n * Navigate to panel\r\n */\r\n @Output() navigate = new EventEmitter<ThumbnailNavigationTarget>();\r\n\r\n /**\r\n * Close strip\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Scroll container reference\r\n */\r\n @ViewChild('scrollContainer', { static: false }) scrollContainer?: ElementRef<HTMLDivElement>;\r\n\r\n /**\r\n * Flattened thumbnail items\r\n */\r\n thumbnailItems: ThumbnailItem[] = [];\r\n\r\n /**\r\n * Virtual scroll viewport\r\n */\r\n viewportStart = 0;\r\n viewportEnd = 50; // Show 50 items at a time\r\n itemWidth = 120; // Width of each thumbnail\r\n itemGap = 8; // Gap between items\r\n\r\n /**\r\n * Drag scrolling state\r\n */\r\n private isDragging = false;\r\n private startX = 0;\r\n private dragScrollLeft = 0;\r\n\r\n /**\r\n * Handle changes\r\n */\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['chapters'] || changes['currentChapterId'] || changes['currentPanelId'] || changes['lockedPanels']) {\r\n this.buildThumbnailItems();\r\n }\r\n\r\n // The scroll container only exists inside @if (visible): when the strip\r\n // is shown later, or the current panel/chapters change, scroll once the\r\n // view has rendered. The initial render is covered by ngAfterViewInit.\r\n const scrollTriggers = ['visible', 'currentPanelId', 'chapters'];\r\n const needsScroll = scrollTriggers.some((key) => changes[key] && !changes[key].firstChange);\r\n if (needsScroll && this.visible) {\r\n this.queueScrollToCurrentPanel();\r\n }\r\n }\r\n\r\n /**\r\n * Scroll to the current panel after the next render\r\n */\r\n private queueScrollToCurrentPanel(): void {\r\n if (this.scrollQueued) return;\r\n this.scrollQueued = true;\r\n afterNextRender(\r\n () => {\r\n this.scrollQueued = false;\r\n this.scrollToCurrentPanel();\r\n },\r\n { injector: this.injector },\r\n );\r\n }\r\n\r\n /**\r\n * After view init\r\n */\r\n ngAfterViewInit(): void {\r\n this.scrollToCurrentPanel();\r\n }\r\n\r\n /**\r\n * Build flattened thumbnail items\r\n */\r\n private buildThumbnailItems(): void {\r\n const items: ThumbnailItem[] = [];\r\n let globalIndex = 0;\r\n\r\n this.chapters.forEach((chapter) => {\r\n const panels = this.getPanels(chapter);\r\n \r\n panels.forEach((panel, panelIndex) => {\r\n items.push({\r\n chapterId: chapter.id,\r\n panelId: panel.id,\r\n thumbnail: panel.thumbnail,\r\n isLocked: this.isPanelLocked(panel.id),\r\n isCurrentChapter: chapter.id === this.currentChapterId,\r\n isCurrentPanel: panel.id === this.currentPanelId,\r\n chapterStart: panelIndex === 0,\r\n chapterTitle: panelIndex === 0 ? this.getChapterTitle(chapter) : undefined,\r\n index: globalIndex++,\r\n });\r\n });\r\n });\r\n\r\n this.thumbnailItems = items;\r\n }\r\n\r\n /**\r\n * Get panels from chapter with their IDs\r\n */\r\n private getPanels(chapter: Chapter): (Panel & { id: string; thumbnail?: string })[] {\r\n if (!chapter.panels) return [];\r\n return Object.entries(chapter.panels).map(([id, panel]) => ({\r\n ...panel,\r\n id,\r\n thumbnail: undefined, // Thumbnails should be generated/cached separately\r\n }));\r\n }\r\n\r\n /**\r\n * Get chapter title\r\n */\r\n private getChapterTitle(chapter: Chapter): string {\r\n // Simplified - should use localization\r\n if (chapter.title && typeof chapter.title === 'object') {\r\n const keys = Object.keys(chapter.title);\r\n return keys.length > 0 ? (chapter.title as Record<string, string>)[keys[0]] : chapter.id;\r\n }\r\n return chapter.id;\r\n }\r\n\r\n /**\r\n * Check if panel is locked\r\n */\r\n private isPanelLocked(panelId: string): boolean {\r\n return this.lockedPanels.includes(panelId);\r\n }\r\n\r\n /**\r\n * Get thumbnail URL\r\n */\r\n getThumbnailUrl(item: ThumbnailItem): string {\r\n if (!item.thumbnail) {\r\n return '';\r\n }\r\n\r\n // Absolute URL\r\n if (\r\n item.thumbnail.startsWith('http://') ||\r\n item.thumbnail.startsWith('https://') ||\r\n item.thumbnail.startsWith('data:')\r\n ) {\r\n return item.thumbnail;\r\n }\r\n\r\n // Relative URL\r\n return this.baseUrl + item.thumbnail;\r\n }\r\n\r\n /**\r\n * Navigate to panel\r\n */\r\n onNavigate(item: ThumbnailItem): void {\r\n if (!item.isLocked) {\r\n this.navigate.emit({\r\n chapterId: item.chapterId,\r\n panelId: item.panelId,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Close strip\r\n */\r\n onClose(): void {\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Scroll to current panel\r\n */\r\n scrollToCurrentPanel(): void {\r\n if (!this.scrollContainer) return;\r\n\r\n const currentIndex = this.thumbnailItems.findIndex((item) => item.isCurrentPanel);\r\n if (currentIndex >= 0) {\r\n const scrollPosition = currentIndex * (this.itemWidth + this.itemGap);\r\n const containerWidth = this.scrollContainer.nativeElement.offsetWidth;\r\n const centeredPosition = scrollPosition - containerWidth / 2 + this.itemWidth / 2;\r\n\r\n this.scrollContainer.nativeElement.scrollTo({\r\n left: Math.max(0, centeredPosition),\r\n behavior: 'smooth',\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Handle scroll for virtual scrolling\r\n */\r\n onScroll(event: Event): void {\r\n const target = event.target as HTMLElement;\r\n const scrollLeft = target.scrollLeft;\r\n const containerWidth = target.offsetWidth;\r\n\r\n // Calculate visible range with buffer\r\n const buffer = 10;\r\n this.viewportStart = Math.max(0, Math.floor(scrollLeft / (this.itemWidth + this.itemGap)) - buffer);\r\n this.viewportEnd = Math.ceil((scrollLeft + containerWidth) / (this.itemWidth + this.itemGap)) + buffer;\r\n }\r\n\r\n /**\r\n * Check if item is in viewport\r\n */\r\n isInViewport(item: ThumbnailItem): boolean {\r\n return item.index >= this.viewportStart && item.index <= this.viewportEnd;\r\n }\r\n\r\n /**\r\n * Get total scroll width\r\n */\r\n getTotalWidth(): number {\r\n return this.thumbnailItems.length * (this.itemWidth + this.itemGap);\r\n }\r\n\r\n /**\r\n * Get visible items (for virtual scrolling)\r\n */\r\n getVisibleItems(): ThumbnailItem[] {\r\n return this.thumbnailItems.filter((item) => this.isInViewport(item));\r\n }\r\n\r\n /**\r\n * Scroll left by one viewport width\r\n */\r\n scrollLeft(): void {\r\n if (!this.scrollContainer) return;\r\n \r\n const container = this.scrollContainer.nativeElement;\r\n const scrollAmount = container.offsetWidth * 0.8; // Scroll 80% of viewport\r\n \r\n container.scrollTo({\r\n left: Math.max(0, container.scrollLeft - scrollAmount),\r\n behavior: 'smooth',\r\n });\r\n }\r\n\r\n /**\r\n * Scroll right by one viewport width\r\n */\r\n scrollRight(): void {\r\n if (!this.scrollContainer) return;\r\n \r\n const container = this.scrollContainer.nativeElement;\r\n const scrollAmount = container.offsetWidth * 0.8; // Scroll 80% of viewport\r\n const maxScroll = container.scrollWidth - container.offsetWidth;\r\n \r\n container.scrollTo({\r\n left: Math.min(maxScroll, container.scrollLeft + scrollAmount),\r\n behavior: 'smooth',\r\n });\r\n }\r\n\r\n /**\r\n * Check if can scroll left\r\n */\r\n canScrollLeft(): boolean {\r\n if (!this.scrollContainer) return false;\r\n return this.scrollContainer.nativeElement.scrollLeft > 0;\r\n }\r\n\r\n /**\r\n * Check if can scroll right\r\n */\r\n canScrollRight(): boolean {\r\n if (!this.scrollContainer) return false;\r\n const container = this.scrollContainer.nativeElement;\r\n return container.scrollLeft < container.scrollWidth - container.offsetWidth - 1;\r\n }\r\n\r\n /**\r\n * Handle keyboard navigation\r\n */\r\n @HostListener('window:keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent): void {\r\n if (!this.visible) return;\r\n\r\n switch (event.key) {\r\n case 'ArrowLeft':\r\n event.preventDefault();\r\n this.scrollLeft();\r\n break;\r\n case 'ArrowRight':\r\n event.preventDefault();\r\n this.scrollRight();\r\n break;\r\n case 'Escape':\r\n event.preventDefault();\r\n this.onClose();\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Start drag scrolling\r\n */\r\n onMouseDown(event: MouseEvent): void {\r\n if (!this.scrollContainer) return;\r\n \r\n this.isDragging = true;\r\n this.startX = event.pageX - this.scrollContainer.nativeElement.offsetLeft;\r\n this.dragScrollLeft = this.scrollContainer.nativeElement.scrollLeft;\r\n this.scrollContainer.nativeElement.style.cursor = 'grabbing';\r\n }\r\n\r\n /**\r\n * Handle drag scrolling\r\n */\r\n onMouseMove(event: MouseEvent): void {\r\n if (!this.isDragging || !this.scrollContainer) return;\r\n \r\n event.preventDefault();\r\n const x = event.pageX - this.scrollContainer.nativeElement.offsetLeft;\r\n const walk = (x - this.startX) * 2; // Multiply for faster scrolling\r\n this.scrollContainer.nativeElement.scrollLeft = this.dragScrollLeft - walk;\r\n }\r\n\r\n /**\r\n * End drag scrolling\r\n */\r\n onMouseUp(): void {\r\n if (!this.scrollContainer) return;\r\n \r\n this.isDragging = false;\r\n this.scrollContainer.nativeElement.style.cursor = 'grab';\r\n }\r\n\r\n /**\r\n * Handle mouse leave\r\n */\r\n onMouseLeave(): void {\r\n if (this.isDragging) {\r\n this.onMouseUp();\r\n }\r\n }\r\n}\r\n","@if (visible) {\r\n <div class=\"thumbnail-strip\">\r\n <!-- Close button -->\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n aria-label=\"Close thumbnail strip\"\r\n (click)=\"onClose()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n\r\n <!-- Left arrow navigation -->\r\n <button\r\n class=\"nav-arrow nav-arrow-left\"\r\n type=\"button\"\r\n aria-label=\"Scroll left\"\r\n [disabled]=\"!canScrollLeft()\"\r\n [class.disabled]=\"!canScrollLeft()\"\r\n (click)=\"scrollLeft()\">\r\n <pw-icon name=\"lucideChevronLeft\" />\r\n </button>\r\n\r\n <!-- Right arrow navigation -->\r\n <button\r\n class=\"nav-arrow nav-arrow-right\"\r\n type=\"button\"\r\n aria-label=\"Scroll right\"\r\n [disabled]=\"!canScrollRight()\"\r\n [class.disabled]=\"!canScrollRight()\"\r\n (click)=\"scrollRight()\">\r\n <pw-icon name=\"lucideChevronRight\" />\r\n </button>\r\n\r\n <!-- Scroll container -->\r\n <div\r\n class=\"strip-scroll-container\"\r\n #scrollContainer\r\n (scroll)=\"onScroll($event)\"\r\n (mousedown)=\"onMouseDown($event)\"\r\n (mousemove)=\"onMouseMove($event)\"\r\n (mouseup)=\"onMouseUp()\"\r\n (mouseleave)=\"onMouseLeave()\">\r\n \r\n <!-- Content wrapper for virtual scrolling -->\r\n <div\r\n class=\"strip-content\"\r\n [style.width.px]=\"getTotalWidth()\">\r\n \r\n @for (item of getVisibleItems(); track item.panelId) {\r\n <div\r\n class=\"thumbnail-wrapper\"\r\n [style.left.px]=\"item.index * (itemWidth + itemGap)\"\r\n [class.chapter-start]=\"item.chapterStart\">\r\n \r\n <!-- Chapter separator -->\r\n @if (item.chapterStart && item.chapterTitle) {\r\n <div class=\"chapter-separator\">\r\n <span class=\"separator-title\">{{ item.chapterTitle }}</span>\r\n </div>\r\n }\r\n\r\n <!-- Thumbnail -->\r\n <button\r\n class=\"thumbnail-item\"\r\n [class.current]=\"item.isCurrentPanel\"\r\n [class.current-chapter]=\"item.isCurrentChapter\"\r\n [class.locked]=\"item.isLocked\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Panel ' + item.panelId\"\r\n [attr.aria-current]=\"item.isCurrentPanel ? 'true' : null\"\r\n (click)=\"onNavigate(item)\">\r\n \r\n @if (getThumbnailUrl(item)) {\r\n <img\r\n [src]=\"getThumbnailUrl(item)\"\r\n [alt]=\"'Panel ' + item.panelId\"\r\n class=\"thumbnail-image\"\r\n loading=\"lazy\" />\r\n } @else {\r\n <div class=\"thumbnail-placeholder\">\r\n <span class=\"placeholder-text\">{{ item.panelId }}</span>\r\n </div>\r\n }\r\n\r\n <!-- Lock overlay -->\r\n @if (item.isLocked) {\r\n <div class=\"lock-overlay\">\r\n <span class=\"lock-icon\"><pw-icon name=\"lucideLock\" /></span>\r\n </div>\r\n }\r\n\r\n <!-- Current indicator -->\r\n @if (item.isCurrentPanel) {\r\n <div class=\"current-indicator\"></div>\r\n }\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Navigation hints -->\r\n <div class=\"strip-hints\">\r\n <kbd>←</kbd> <kbd>→</kbd> Navigate\r\n <span class=\"separator\">•</span>\r\n <kbd>Esc</kbd> Close\r\n </div>\r\n </div>\r\n}\r\n","/**\r\n * Table of Contents Overlay Component\r\n * Displays chapter and panel navigation\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n OnInit,\r\n OnChanges,\r\n SimpleChanges,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n} from '@angular/core';\r\n\r\nimport { FormsModule } from '@angular/forms';\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\nimport type { Chapter, Panel, Page, LocaleCode, LocalizedString, PanelWaveManifest } from '../../../types';\r\n\r\n/**\r\n * ToC navigation target\r\n */\r\nexport interface TocNavigationTarget {\r\n chapterId: string;\r\n panelId?: string;\r\n}\r\n\r\n/**\r\n * Table of Contents Overlay Component\r\n * Modal overlay for chapter/panel navigation\r\n */\r\n@Component({\r\n selector: 'pw-toc-overlay',\r\n imports: [FormsModule, TranslateModule, PwIconComponent],\r\n templateUrl: './toc-overlay.component.html',\r\n styleUrls: ['./toc-overlay.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class TocOverlayComponent implements OnInit, OnChanges {\r\n /**\r\n * Manifest (optional, will extract chapters)\r\n */\r\n @Input() manifest?: PanelWaveManifest;\r\n\r\n /**\r\n * List of chapters (alternative to manifest)\r\n */\r\n @Input() chapters: Chapter[] = [];\r\n\r\n /**\r\n * Current chapter ID\r\n */\r\n @Input() currentChapterId?: string;\r\n\r\n /**\r\n * Current panel ID\r\n */\r\n @Input() currentPanelId?: string;\r\n\r\n /**\r\n * Current locale\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Base URL for thumbnails\r\n */\r\n @Input() baseUrl = '';\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Navigate to chapter/panel\r\n */\r\n @Output() navigate = new EventEmitter<TocNavigationTarget>();\r\n\r\n /**\r\n * Close overlay\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Search query\r\n */\r\n searchQuery = '';\r\n\r\n /**\r\n * Selected chapter index\r\n */\r\n selectedChapterIndex = 0;\r\n\r\n /**\r\n * Filtered chapters\r\n */\r\n filteredChapters: Chapter[] = [];\r\n\r\n /**\r\n * Initialize component\r\n */\r\n ngOnInit(): void {\r\n this.syncChapters();\r\n this.filterChapters();\r\n this.selectCurrentChapter();\r\n }\r\n\r\n /**\r\n * React to manifest / chapter / current-chapter changes after init\r\n */\r\n ngOnChanges(changes: SimpleChanges): void {\r\n const chaptersChanged = !!(changes['manifest'] || changes['chapters']);\r\n if (chaptersChanged) {\r\n this.syncChapters();\r\n this.filterChapters();\r\n if (this.selectedChapterIndex >= this.filteredChapters.length) {\r\n this.selectedChapterIndex = Math.max(this.filteredChapters.length - 1, 0);\r\n }\r\n }\r\n if (chaptersChanged || changes['currentChapterId']) {\r\n this.selectCurrentChapter();\r\n }\r\n }\r\n\r\n /**\r\n * Extract chapters from the manifest when one is provided\r\n */\r\n private syncChapters(): void {\r\n if (this.manifest?.chapters) {\r\n this.chapters = Object.values(this.manifest.chapters);\r\n }\r\n }\r\n\r\n /**\r\n * Filter chapters based on search query\r\n */\r\n filterChapters(): void {\r\n if (!this.searchQuery.trim()) {\r\n this.filteredChapters = [...this.chapters];\r\n return;\r\n }\r\n\r\n const query = this.searchQuery.toLowerCase();\r\n this.filteredChapters = this.chapters.filter((chapter) => {\r\n const title = this.getLocalizedString(chapter.title);\r\n return title.toLowerCase().includes(query);\r\n });\r\n }\r\n\r\n /**\r\n * Select current chapter\r\n */\r\n selectCurrentChapter(): void {\r\n if (!this.currentChapterId) return;\r\n\r\n const index = this.filteredChapters.findIndex(\r\n (ch) => ch.id === this.currentChapterId\r\n );\r\n if (index >= 0) {\r\n this.selectedChapterIndex = index;\r\n }\r\n }\r\n\r\n /**\r\n * Handle search input\r\n */\r\n onSearchChange(): void {\r\n this.filterChapters();\r\n this.selectedChapterIndex = 0;\r\n }\r\n\r\n /**\r\n * Get localized string\r\n */\r\n getLocalizedString(text?: LocalizedString): string {\r\n if (!text || typeof text !== 'object') {\r\n return '';\r\n }\r\n\r\n // Try exact locale\r\n if (text[this.locale]) {\r\n return text[this.locale];\r\n }\r\n\r\n // Try base language\r\n const baseLocale = this.locale.split('-')[0];\r\n const baseMatch = Object.keys(text).find((key) => key.startsWith(baseLocale));\r\n if (baseMatch && text[baseMatch]) {\r\n return text[baseMatch];\r\n }\r\n\r\n // Return first available\r\n const firstKey = Object.keys(text)[0];\r\n return firstKey ? text[firstKey] : '';\r\n }\r\n\r\n /**\r\n * Get chapter title\r\n */\r\n getChapterTitle(chapter: Chapter): string {\r\n return this.getLocalizedString(chapter.title) || chapter.id;\r\n }\r\n\r\n /**\r\n * Get panels for chapter with IDs\r\n */\r\n getPanels(chapter: Chapter): { id: string; panel: Panel }[] {\r\n if (!chapter.panels) return [];\r\n return Object.entries(chapter.panels).map(([id, panel]) => ({ id, panel }));\r\n }\r\n\r\n /**\r\n * Get pages for chapter\r\n */\r\n getPages(chapter: Chapter): Page[] {\r\n return chapter.pages || [];\r\n }\r\n\r\n /**\r\n * Check if chapter has pages\r\n */\r\n hasPages(chapter: Chapter): boolean {\r\n return !!(chapter.pages && chapter.pages.length > 0);\r\n }\r\n\r\n /**\r\n * Get panels for a specific page\r\n */\r\n getPanelsForPage(chapter: Chapter, page: Page): { id: string; panel: Panel }[] {\r\n if (!chapter.panels || !page.readingOrder) return [];\r\n \r\n return page.readingOrder\r\n .filter(panelId => chapter.panels[panelId])\r\n .map(panelId => ({\r\n id: panelId,\r\n panel: chapter.panels[panelId]\r\n }));\r\n }\r\n\r\n /**\r\n * Get page title\r\n */\r\n getPageTitle(page: Page): string {\r\n return this.getLocalizedString(page.title) || `Page ${page.id}`;\r\n }\r\n\r\n /**\r\n * Get panel title\r\n */\r\n getPanelTitle(panel: Panel, panelId: string): string {\r\n return this.getLocalizedString(panel.title) || panelId;\r\n }\r\n\r\n /**\r\n * Get thumbnail URL for panel\r\n */\r\n getThumbnailUrl(panel: Panel): string {\r\n const thumbnail = (panel as Panel & { thumbnail?: string }).thumbnail;\r\n if (!thumbnail) {\r\n return '';\r\n }\r\n\r\n // Absolute URL\r\n if (\r\n thumbnail.startsWith('http://') ||\r\n thumbnail.startsWith('https://') ||\r\n thumbnail.startsWith('data:')\r\n ) {\r\n return thumbnail;\r\n }\r\n\r\n // Relative URL\r\n return this.baseUrl + thumbnail;\r\n }\r\n\r\n /**\r\n * Navigate to chapter\r\n */\r\n navigateToChapter(chapter: Chapter): void {\r\n this.navigate.emit({ chapterId: chapter.id });\r\n }\r\n\r\n /**\r\n * Navigate to panel\r\n */\r\n navigateToPanel(chapter: Chapter, panelId: string): void {\r\n this.navigate.emit({\r\n chapterId: chapter.id,\r\n panelId: panelId,\r\n });\r\n }\r\n\r\n /**\r\n * Check if chapter is current\r\n */\r\n isCurrentChapter(chapter: Chapter): boolean {\r\n return chapter.id === this.currentChapterId;\r\n }\r\n\r\n /**\r\n * Check if panel is current\r\n */\r\n isCurrentPanel(panelId: string): boolean {\r\n return panelId === this.currentPanelId;\r\n }\r\n\r\n /**\r\n * Select chapter\r\n */\r\n selectChapter(index: number): void {\r\n this.selectedChapterIndex = index;\r\n }\r\n\r\n /**\r\n * Close overlay\r\n */\r\n onClose(): void {\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n // Close if clicking directly on backdrop\r\n if (event.target === event.currentTarget) {\r\n this.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Handle keyboard events\r\n */\r\n @HostListener('window:keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent): void {\r\n if (!this.visible) return;\r\n\r\n switch (event.key) {\r\n case 'Escape':\r\n event.preventDefault();\r\n this.onClose();\r\n break;\r\n\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this.selectChapter(\r\n Math.min(this.selectedChapterIndex + 1, this.filteredChapters.length - 1)\r\n );\r\n break;\r\n\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this.selectChapter(Math.max(this.selectedChapterIndex - 1, 0));\r\n break;\r\n\r\n case 'Enter':\r\n // Focused interactive elements (chapter headers/items, panel cards,\r\n // buttons) handle Enter themselves; acting here too would emit twice.\r\n if (this.isOwnEnterTarget(event.target)) return;\r\n event.preventDefault();\r\n if (this.filteredChapters[this.selectedChapterIndex]) {\r\n this.navigateToChapter(this.filteredChapters[this.selectedChapterIndex]);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Whether a keyboard event target is an interactive element with its own\r\n * Enter handling (the search input is deliberately not one of them).\r\n */\r\n private isOwnEnterTarget(target: EventTarget | null): boolean {\r\n if (!(target instanceof Element)) return false;\r\n return !!target.closest('button, a[href], select, textarea, [tabindex]:not([tabindex=\"-1\"])');\r\n }\r\n\r\n /**\r\n * Get selected chapter\r\n */\r\n getSelectedChapter(): Chapter | undefined {\r\n return this.filteredChapters[this.selectedChapterIndex];\r\n }\r\n}\r\n","@if (visible) {\r\n <div class=\"toc-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"$event.stopPropagation(); onClose()\">\r\n <div class=\"toc-container\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Table of Contents\">\r\n <!-- Header -->\r\n <div class=\"toc-header\">\r\n <h2 class=\"toc-title\">{{ 'toc.title' | translate }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'toc.close' | translate\"\r\n (click)=\"onClose()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"toc-search\">\r\n <input\r\n type=\"text\"\r\n class=\"search-input\"\r\n [placeholder]=\"'toc.search_chapters' | translate\"\r\n [attr.aria-label]=\"'toc.search_label' | translate\"\r\n [(ngModel)]=\"searchQuery\"\r\n (ngModelChange)=\"onSearchChange()\" />\r\n <span class=\"search-icon\"><pw-icon name=\"lucideSearch\" /></span>\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"toc-content\">\r\n <!-- Chapter list -->\r\n <div class=\"chapter-list\" role=\"list\">\r\n @for (chapter of filteredChapters; track chapter.id; let i = $index) {\r\n <div\r\n class=\"chapter-item\"\r\n [class.selected]=\"i === selectedChapterIndex\"\r\n [class.current]=\"isCurrentChapter(chapter)\"\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"selectChapter(i)\"\r\n (keydown.enter)=\"selectChapter(i)\">\r\n \r\n <!-- Chapter header -->\r\n <div class=\"chapter-header\" tabindex=\"0\" (click)=\"navigateToChapter(chapter)\" (keydown.enter)=\"navigateToChapter(chapter)\">\r\n <span class=\"chapter-number\">{{ i + 1 }}</span>\r\n <h3 class=\"chapter-title\">{{ getChapterTitle(chapter) }}</h3>\r\n @if (isCurrentChapter(chapter)) {\r\n <span class=\"current-badge\">{{ 'toc.current' | translate }}</span>\r\n }\r\n </div>\r\n\r\n <!-- Panel list (if chapter selected) -->\r\n @if (i === selectedChapterIndex) {\r\n <div class=\"panel-list\">\r\n <!-- If chapter has pages, group by pages -->\r\n @if (hasPages(chapter)) {\r\n @for (page of getPages(chapter); track page.id) {\r\n <div class=\"page-group\">\r\n <div class=\"page-header\">\r\n <span class=\"page-title\">{{ getPageTitle(page) }}</span>\r\n </div>\r\n <div class=\"panels-grid\">\r\n @for (panelItem of getPanelsForPage(chapter, page); track panelItem.id) {\r\n <button\r\n class=\"panel-card\"\r\n [class.current]=\"isCurrentPanel(panelItem.id)\"\r\n type=\"button\"\r\n (click)=\"navigateToPanel(chapter, panelItem.id)\">\r\n \r\n @if (getThumbnailUrl(panelItem.panel)) {\r\n <div class=\"panel-thumbnail\">\r\n <img \r\n [src]=\"getThumbnailUrl(panelItem.panel)\" \r\n [alt]=\"getPanelTitle(panelItem.panel, panelItem.id)\"\r\n loading=\"lazy\" />\r\n @if (isCurrentPanel(panelItem.id)) {\r\n <div class=\"current-overlay\">\r\n <span class=\"current-icon\"><pw-icon name=\"lucidePlay\" /></span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"panel-thumbnail placeholder\">\r\n <span class=\"placeholder-icon\"><pw-icon name=\"lucideImage\" /></span>\r\n </div>\r\n }\r\n \r\n <div class=\"panel-info\">\r\n <span class=\"panel-title\">{{ getPanelTitle(panelItem.panel, panelItem.id) }}</span>\r\n </div>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n } @else {\r\n <!-- No pages, show all panels directly -->\r\n <div class=\"panels-grid\">\r\n @for (panelItem of getPanels(chapter); track panelItem.id) {\r\n <button\r\n class=\"panel-card\"\r\n [class.current]=\"isCurrentPanel(panelItem.id)\"\r\n type=\"button\"\r\n (click)=\"navigateToPanel(chapter, panelItem.id)\">\r\n \r\n @if (getThumbnailUrl(panelItem.panel)) {\r\n <div class=\"panel-thumbnail\">\r\n <img \r\n [src]=\"getThumbnailUrl(panelItem.panel)\" \r\n [alt]=\"getPanelTitle(panelItem.panel, panelItem.id)\"\r\n loading=\"lazy\" />\r\n @if (isCurrentPanel(panelItem.id)) {\r\n <div class=\"current-overlay\">\r\n <span class=\"current-icon\"><pw-icon name=\"lucidePlay\" /></span>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"panel-thumbnail placeholder\">\r\n <span class=\"placeholder-icon\"><pw-icon name=\"lucideImage\" /></span>\r\n </div>\r\n }\r\n \r\n <div class=\"panel-info\">\r\n <span class=\"panel-title\">{{ getPanelTitle(panelItem.panel, panelItem.id) }}</span>\r\n </div>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n @if (filteredChapters.length === 0) {\r\n <div class=\"empty-state\">\r\n <p>{{ 'toc.no_results' | translate: {query: searchQuery} }}</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"toc-footer\">\r\n <p class=\"footer-hint\">\r\n <kbd>↑</kbd> <kbd>↓</kbd> {{ 'toc.keyboard_hint_nav' | translate }}\r\n <kbd>Enter</kbd> {{ 'toc.keyboard_hint_select' | translate }}\r\n <kbd>{{ 'common.esc' | translate }}</kbd> {{ 'toc.keyboard_hint_close' | translate }}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n","/**\r\n * Paywall Overlay Component\r\n * Displays paywall gate UI with purchase options\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport { TranslateService } from '@ngx-translate/core';\r\n\r\nimport type { PaywallGate, PurchaseInfo } from '../../../types/entitlement.types';\r\nimport type { LocaleCode, LocalizedString } from '../../../types';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\n\r\n/**\r\n * Built-in English UI strings, used when no TranslateService is provided or a\r\n * key is not loaded. Must match the \"paywall\" section of assets/i18n/en.json.\r\n */\r\nconst PAYWALL_TEXT_EN: Record<string, string> = {\r\n 'paywall.title_work': 'Unlock This Comic',\r\n 'paywall.title_chapter': 'Unlock This Chapter',\r\n 'paywall.title_panel': 'Unlock Premium Content',\r\n 'paywall.title_default': 'Premium Content',\r\n 'paywall.message_default': 'This content requires a subscription or purchase to access.',\r\n 'paywall.close': 'Close',\r\n 'paywall.preview_panels': 'Preview {{count}} panels free',\r\n 'paywall.preview_mode': 'Preview mode: {{mode}}',\r\n 'paywall.choose_option': 'Choose an option:',\r\n 'paywall.type_one_time': 'Buy Once',\r\n 'paywall.type_subscription': 'Subscribe',\r\n 'paywall.type_token': 'Use Token',\r\n 'paywall.type_default': 'Purchase',\r\n 'paywall.sign_in': 'Sign In to Continue',\r\n 'paywall.go_back': 'Go Back',\r\n 'paywall.maybe_later': 'Maybe Later',\r\n 'paywall.secure_payment': 'Secure payment processing',\r\n};\r\n\r\n/**\r\n * Paywall action\r\n */\r\nexport type PaywallAction = 'purchase' | 'subscribe' | 'login' | 'dismiss';\r\n\r\n/**\r\n * Paywall Overlay Component\r\n * Modal overlay for gated content\r\n */\r\n@Component({\r\n selector: 'pw-paywall-overlay',\r\n imports: [PwIconComponent],\r\n templateUrl: './paywall-overlay.component.html',\r\n styleUrls: ['./paywall-overlay.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class PaywallOverlayComponent {\r\n /**\r\n * Optional: the overlay is a public library component and must keep working\r\n * (in English) when a host embeds it without ngx-translate.\r\n */\r\n private readonly translate = inject(TranslateService, { optional: true });\r\n\r\n /**\r\n * Visibility state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Paywall gate information\r\n */\r\n @Input() gate?: PaywallGate;\r\n\r\n /**\r\n * Available purchase options\r\n */\r\n @Input() purchaseOptions: PurchaseInfo[] = [];\r\n\r\n /**\r\n * Current locale\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Custom title\r\n */\r\n @Input() title?: LocalizedString;\r\n\r\n /**\r\n * Custom message\r\n */\r\n @Input() message?: LocalizedString;\r\n\r\n /**\r\n * Show preview button\r\n */\r\n @Input() allowPreview = false;\r\n\r\n /**\r\n * Show login option\r\n */\r\n @Input() showLogin = true;\r\n\r\n /**\r\n * Action taken\r\n */\r\n @Output() action = new EventEmitter<PaywallAction>();\r\n\r\n /**\r\n * Purchase selected\r\n */\r\n @Output() purchase = new EventEmitter<string>();\r\n\r\n /**\r\n * Close overlay\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Handle escape key\r\n */\r\n @HostListener('document:keydown.escape')\r\n onEscape(): void {\r\n if (this.visible) {\r\n this.onDismiss();\r\n }\r\n }\r\n\r\n /**\r\n * Get localized title\r\n */\r\n getTitle(): string {\r\n if (this.title) {\r\n return this.getLocalizedString(this.title);\r\n }\r\n\r\n switch (this.gate?.scope) {\r\n case 'work':\r\n return this.t('paywall.title_work');\r\n case 'chapter':\r\n return this.t('paywall.title_chapter');\r\n case 'panel':\r\n return this.t('paywall.title_panel');\r\n default:\r\n return this.t('paywall.title_default');\r\n }\r\n }\r\n\r\n /**\r\n * Get localized message\r\n */\r\n getMessage(): string {\r\n if (this.message) {\r\n return this.getLocalizedString(this.message);\r\n }\r\n\r\n if (this.gate?.reason) {\r\n return this.gate.reason;\r\n }\r\n\r\n return this.t('paywall.message_default');\r\n }\r\n\r\n /**\r\n * Handle purchase option selection\r\n */\r\n onPurchaseOption(productId: string): void {\r\n this.purchase.emit(productId);\r\n this.action.emit('purchase');\r\n }\r\n\r\n /**\r\n * Handle login action\r\n */\r\n onLogin(): void {\r\n this.action.emit('login');\r\n }\r\n\r\n /**\r\n * Handle dismiss\r\n */\r\n onDismiss(): void {\r\n this.action.emit('dismiss');\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n this.onDismiss();\r\n }\r\n }\r\n\r\n /**\r\n * Format price\r\n */\r\n formatPrice(amount: number, currency: string): string {\r\n return new Intl.NumberFormat(this.locale, {\r\n style: 'currency',\r\n currency: currency,\r\n }).format(amount);\r\n }\r\n\r\n /**\r\n * Get localized string\r\n */\r\n private getLocalizedString(str: LocalizedString): string {\r\n if (typeof str === 'string') {\r\n return str;\r\n }\r\n return str[this.locale] || str['en-US'] || Object.values(str)[0] || '';\r\n }\r\n\r\n /**\r\n * Get purchase type label\r\n */\r\n getPurchaseTypeLabel(type: string): string {\r\n switch (type) {\r\n case 'one-time':\r\n return this.t('paywall.type_one_time');\r\n case 'subscription':\r\n return this.t('paywall.type_subscription');\r\n case 'token':\r\n return this.t('paywall.type_token');\r\n default:\r\n return this.t('paywall.type_default');\r\n }\r\n }\r\n\r\n /**\r\n * Translate a built-in UI string. Falls back to the built-in English text\r\n * (with {{param}} interpolation) when no TranslateService is available or the\r\n * key is not loaded, so the output never degrades to the raw key.\r\n * Manifest-provided texts (title/message/gate.reason) bypass this.\r\n */\r\n t(key: string, params?: Record<string, string | number | undefined>): string {\r\n const value = this.translate?.instant(key, params) as unknown;\r\n if (typeof value === 'string' && value !== key) {\r\n return value;\r\n }\r\n return (PAYWALL_TEXT_EN[key] ?? key).replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (_m, name: string) => String(params?.[name] ?? ''));\r\n }\r\n}\r\n","<!-- Paywall Overlay -->\r\n<div class=\"paywall-overlay\" [class.visible]=\"visible\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"$event.stopPropagation(); onDismiss()\">\r\n <div class=\"paywall-modal\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"getTitle()\">\r\n <!-- Header -->\r\n <div class=\"paywall-header\">\r\n <h2 class=\"paywall-title\">{{ getTitle() }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"t('paywall.close')\"\r\n (click)=\"onDismiss()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"paywall-content\">\r\n <!-- Icon -->\r\n <div class=\"paywall-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z\"/>\r\n </svg>\r\n </div>\r\n\r\n <!-- Message -->\r\n <p class=\"paywall-message\">{{ getMessage() }}</p>\r\n\r\n <!-- Preview Info -->\r\n @if (gate?.preview && allowPreview) {\r\n <div class=\"preview-info\">\r\n @if (gate?.preview?.previewPanels) {\r\n <p class=\"preview-text\">\r\n <pw-icon name=\"lucideCheck\" /> {{ t('paywall.preview_panels', { count: gate?.preview?.previewPanels }) }}\r\n </p>\r\n }\r\n @if (gate?.preview?.mode) {\r\n <p class=\"preview-mode\">\r\n {{ t('paywall.preview_mode', { mode: gate?.preview?.mode }) }}\r\n </p>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Purchase Options -->\r\n @if (purchaseOptions.length > 0) {\r\n <div class=\"purchase-options\">\r\n <h3 class=\"options-title\">{{ t('paywall.choose_option') }}</h3>\r\n @for (option of purchaseOptions; track option.productId) {\r\n <button\r\n class=\"purchase-option\"\r\n type=\"button\"\r\n (click)=\"onPurchaseOption(option.productId)\">\r\n <div class=\"option-header\">\r\n <span class=\"option-name\">{{ option.name }}</span>\r\n <span class=\"option-price\">{{ formatPrice(option.price.amount, option.price.currency) }}</span>\r\n </div>\r\n @if (option.description) {\r\n <p class=\"option-description\">{{ option.description }}</p>\r\n }\r\n <span class=\"option-type\">{{ getPurchaseTypeLabel(option.type) }}</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Login Option -->\r\n @if (showLogin && !purchaseOptions.length) {\r\n <button\r\n class=\"login-btn\"\r\n type=\"button\"\r\n (click)=\"onLogin()\">\r\n {{ t('paywall.sign_in') }}\r\n </button>\r\n }\r\n\r\n <!-- Actions -->\r\n <div class=\"paywall-actions\">\r\n @if (purchaseOptions.length === 0 && !showLogin) {\r\n <button\r\n class=\"action-btn primary\"\r\n type=\"button\"\r\n (click)=\"onDismiss()\">\r\n {{ t('paywall.go_back') }}\r\n </button>\r\n }\r\n @if (purchaseOptions.length > 0 || showLogin) {\r\n <button\r\n class=\"action-btn secondary\"\r\n type=\"button\"\r\n (click)=\"onDismiss()\">\r\n {{ t('paywall.maybe_later') }}\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Footer Info -->\r\n <div class=\"paywall-footer\">\r\n <p class=\"footer-text\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z\"/>\r\n </svg>\r\n {{ t('paywall.secure_payment') }}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","/**\r\n * Settings Modal Component\r\n * Manages user preferences and variables\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n OnInit,\r\n OnChanges,\r\n SimpleChanges,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n} from '@angular/core';\r\n\r\nimport { FormsModule } from '@angular/forms';\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\nimport type { LocaleCode, VariableDefinition } from '../../../types';\r\n\r\n/**\r\n * Preferences interface\r\n */\r\nexport interface Preferences {\r\n speech: boolean;\r\n audio: boolean;\r\n sfx: boolean;\r\n autoplay: boolean;\r\n secondsPerPanel: number;\r\n mangaMode: boolean;\r\n reducedMotion: boolean;\r\n highContrast: boolean;\r\n}\r\n\r\n/**\r\n * Variable value change\r\n */\r\nexport interface VariableChange {\r\n key: string;\r\n value: unknown;\r\n}\r\n\r\n/**\r\n * Settings Modal Component\r\n * Modal for editing preferences and variables\r\n */\r\n@Component({\r\n selector: 'pw-settings-modal',\r\n imports: [FormsModule, TranslateModule, PwIconComponent],\r\n templateUrl: './settings-modal.component.html',\r\n styleUrls: ['./settings-modal.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class SettingsModalComponent implements OnInit, OnChanges {\r\n /**\r\n * Current preferences\r\n */\r\n @Input() preferences: Preferences = {\r\n speech: true,\r\n audio: true,\r\n sfx: true,\r\n autoplay: false,\r\n secondsPerPanel: 5,\r\n mangaMode: false,\r\n reducedMotion: false,\r\n highContrast: false,\r\n };\r\n\r\n /**\r\n * Available locales\r\n */\r\n @Input() availableLocales: LocaleCode[] = ['en-US'];\r\n\r\n /**\r\n * Current locale\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Variable definitions\r\n */\r\n @Input() variables: VariableDefinition[] = [];\r\n\r\n /**\r\n * Current variable values\r\n */\r\n @Input() variableValues: Record<string, unknown> = {};\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Preferences changed\r\n */\r\n @Output() preferencesChange = new EventEmitter<Preferences>();\r\n\r\n /**\r\n * Locale changed\r\n */\r\n @Output() localeChange = new EventEmitter<LocaleCode>();\r\n\r\n /**\r\n * Variable changed\r\n */\r\n @Output() variableChange = new EventEmitter<VariableChange>();\r\n\r\n /**\r\n * Close modal\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Active tab\r\n */\r\n activeTab: 'preferences' | 'variables' = 'preferences';\r\n\r\n /**\r\n * Local copy of preferences (for cancel)\r\n */\r\n private originalPreferences: Preferences = { ...this.preferences };\r\n\r\n /**\r\n * Local copy of locale (for cancel)\r\n */\r\n private originalLocale: LocaleCode = this.locale;\r\n\r\n /**\r\n * Local copy of variable values (for cancel)\r\n */\r\n private originalVariableValues: Record<string, unknown> = { ...this.variableValues };\r\n\r\n /**\r\n * Initialize component\r\n */\r\n ngOnInit(): void {\r\n this.detachWorkingCopies();\r\n this.saveOriginalValues();\r\n }\r\n\r\n /**\r\n * Keep the cancel baseline in sync with the inputs. New preferences /\r\n * locale / variable values from the parent become the new baseline; when\r\n * the modal (re)opens, any edits left over from a previous session that\r\n * was closed without Save are discarded.\r\n */\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['preferences']) {\r\n this.preferences = { ...this.preferences };\r\n this.originalPreferences = { ...this.preferences };\r\n }\r\n if (changes['locale']) {\r\n this.originalLocale = this.locale;\r\n }\r\n if (changes['variableValues']) {\r\n this.variableValues = { ...this.variableValues };\r\n this.originalVariableValues = { ...this.variableValues };\r\n }\r\n const visible = changes['visible'];\r\n if (visible && visible.currentValue && !visible.previousValue && !visible.firstChange) {\r\n this.restoreOriginalValues();\r\n }\r\n }\r\n\r\n /**\r\n * Replace the input objects with component-local copies so edits never\r\n * mutate the parent's objects before Save emits.\r\n */\r\n private detachWorkingCopies(): void {\r\n this.preferences = { ...this.preferences };\r\n this.variableValues = { ...this.variableValues };\r\n }\r\n\r\n /**\r\n * Restore the working values from the cancel baseline\r\n */\r\n private restoreOriginalValues(): void {\r\n this.preferences = { ...this.originalPreferences };\r\n this.locale = this.originalLocale;\r\n this.variableValues = { ...this.originalVariableValues };\r\n }\r\n\r\n /**\r\n * Save original values for cancel\r\n */\r\n private saveOriginalValues(): void {\r\n this.originalPreferences = { ...this.preferences };\r\n this.originalLocale = this.locale;\r\n this.originalVariableValues = { ...this.variableValues };\r\n }\r\n\r\n /**\r\n * Switch tab\r\n */\r\n switchTab(tab: 'preferences' | 'variables'): void {\r\n this.activeTab = tab;\r\n }\r\n\r\n /**\r\n * Update preference\r\n */\r\n updatePreference<K extends keyof Preferences>(\r\n key: K,\r\n value: Preferences[K]\r\n ): void {\r\n this.preferences = { ...this.preferences, [key]: value };\r\n }\r\n\r\n /**\r\n * Update locale\r\n */\r\n updateLocale(locale: LocaleCode): void {\r\n this.locale = locale;\r\n }\r\n\r\n /**\r\n * Update variable\r\n */\r\n updateVariable(key: string, value: unknown): void {\r\n this.variableValues = { ...this.variableValues, [key]: value };\r\n }\r\n\r\n /**\r\n * Get variable value\r\n */\r\n getVariableValue(variable: VariableDefinition): unknown {\r\n return this.variableValues[variable.id] ?? variable.default;\r\n }\r\n\r\n /**\r\n * Get the reader-editable variables: public visibility (the default\r\n * when the manifest omits it) and not read-only.\r\n */\r\n getPublicVariables(): VariableDefinition[] {\r\n return this.variables.filter((v) => v.visibility !== 'private' && !v.readOnly);\r\n }\r\n\r\n /**\r\n * Save changes\r\n */\r\n save(): void {\r\n // Emit all changes\r\n this.preferencesChange.emit(this.preferences);\r\n this.localeChange.emit(this.locale);\r\n\r\n // Emit variable changes\r\n Object.keys(this.variableValues).forEach((key) => {\r\n if (this.variableValues[key] !== this.originalVariableValues[key]) {\r\n this.variableChange.emit({ key, value: this.variableValues[key] });\r\n }\r\n });\r\n\r\n this.saveOriginalValues();\r\n this.onClose();\r\n }\r\n\r\n /**\r\n * Cancel changes\r\n */\r\n cancel(): void {\r\n this.restoreOriginalValues();\r\n this.onClose();\r\n }\r\n\r\n /**\r\n * Reset preferences to defaults\r\n */\r\n resetPreferences(): void {\r\n this.preferences = {\r\n speech: true,\r\n audio: true,\r\n sfx: true,\r\n autoplay: false,\r\n secondsPerPanel: 5,\r\n mangaMode: false,\r\n reducedMotion: false,\r\n highContrast: false,\r\n };\r\n }\r\n\r\n /**\r\n * Reset variable to default\r\n */\r\n resetVariable(variable: VariableDefinition): void {\r\n this.updateVariable(variable.id, variable.default);\r\n }\r\n\r\n /**\r\n * Reset all variables to defaults\r\n */\r\n resetAllVariables(): void {\r\n const publicVars = this.getPublicVariables();\r\n publicVars.forEach((variable) => {\r\n this.updateVariable(variable.id, variable.default);\r\n });\r\n }\r\n\r\n /**\r\n * Close modal\r\n */\r\n onClose(): void {\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n this.cancel();\r\n }\r\n }\r\n\r\n /**\r\n * Handle keyboard events\r\n */\r\n @HostListener('window:keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent): void {\r\n if (!this.visible) return;\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n this.cancel();\r\n }\r\n }\r\n\r\n /**\r\n * Get variable editor type\r\n */\r\n getVariableType(variable: VariableDefinition): string {\r\n return variable.type || 'string';\r\n }\r\n\r\n /**\r\n * Check if variable is boolean\r\n */\r\n isBoolean(variable: VariableDefinition): boolean {\r\n return this.getVariableType(variable) === 'boolean';\r\n }\r\n\r\n /**\r\n * Check if variable is number\r\n */\r\n isNumber(variable: VariableDefinition): boolean {\r\n const type = this.getVariableType(variable);\r\n return type === 'number' || type === 'integer';\r\n }\r\n\r\n /**\r\n * Check if variable is enum\r\n */\r\n isEnum(variable: VariableDefinition): boolean {\r\n return !!(variable as VariableDefinition & { enum?: unknown[] }).enum;\r\n }\r\n\r\n /**\r\n * Check if variable is string\r\n */\r\n isString(variable: VariableDefinition): boolean {\r\n return this.getVariableType(variable) === 'string' && !this.isEnum(variable);\r\n }\r\n\r\n /**\r\n * Get enum options\r\n */\r\n getEnumOptions(variable: VariableDefinition): unknown[] {\r\n return (variable as VariableDefinition & { enum?: unknown[] }).enum || [];\r\n }\r\n\r\n /**\r\n * Get variable min value\r\n */\r\n getMin(variable: VariableDefinition): number | undefined {\r\n return (variable as VariableDefinition & { min?: number }).min;\r\n }\r\n\r\n /**\r\n * Get variable max value\r\n */\r\n getMax(variable: VariableDefinition): number | undefined {\r\n return (variable as VariableDefinition & { max?: number }).max;\r\n }\r\n}\r\n","@if (visible) {\n <div class=\"settings-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"$event.stopPropagation(); cancel()\">\n <div class=\"settings-container\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Settings\">\n <!-- Header -->\n <div class=\"settings-header\">\n <h2 class=\"settings-title\">{{ 'settings.title' | translate }}</h2>\n <button\n class=\"close-btn\"\n type=\"button\"\n [attr.aria-label]=\"'settings.close' | translate\"\n (click)=\"cancel()\">\n <pw-icon name=\"lucideX\" />\n </button>\n </div>\n\n <!-- Tabs -->\n <div class=\"settings-tabs\" role=\"tablist\">\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'preferences'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'preferences'\"\n (click)=\"switchTab('preferences')\">\n {{ 'settings.preferences' | translate }}\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"activeTab === 'variables'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'variables'\"\n (click)=\"switchTab('variables')\">\n {{ 'settings.variables' | translate }}\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"settings-content\">\n <!-- Preferences Tab -->\n @if (activeTab === 'preferences') {\n <div class=\"tab-panel\" role=\"tabpanel\">\n <div class=\"settings-section\">\n <h3 class=\"section-title\">{{ 'settings.language' | translate }}</h3>\n <div class=\"setting-item\">\n <label class=\"setting-label\" for=\"locale-select\">{{ 'settings.interface_language' | translate }}</label>\n <select\n id=\"locale-select\"\n class=\"setting-select\"\n [ngModel]=\"locale\"\n (ngModelChange)=\"updateLocale($event)\">\n @for (loc of availableLocales; track loc) {\n <option [value]=\"loc\">{{ loc }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"settings-section\">\n <h3 class=\"section-title\">{{ 'settings.display' | translate }}</h3>\n \n <div class=\"setting-item\">\n <label class=\"setting-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [ngModel]=\"preferences.mangaMode\"\n (ngModelChange)=\"updatePreference('mangaMode', $event)\" />\n <span>{{ 'settings.manga_mode' | translate }}</span>\n </label>\n </div>\n\n <div class=\"setting-item\">\n <label class=\"setting-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [ngModel]=\"preferences.reducedMotion\"\n (ngModelChange)=\"updatePreference('reducedMotion', $event)\" />\n <span>{{ 'settings.reduced_motion' | translate }}</span>\n </label>\n </div>\n\n <div class=\"setting-item\">\n <label class=\"setting-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [ngModel]=\"preferences.highContrast\"\n (ngModelChange)=\"updatePreference('highContrast', $event)\" />\n <span>{{ 'settings.high_contrast' | translate }}</span>\n </label>\n </div>\n </div>\n\n <div class=\"settings-section\">\n <h3 class=\"section-title\">{{ 'settings.content' | translate }}</h3>\n \n <div class=\"setting-item\">\n <label class=\"setting-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [ngModel]=\"preferences.speech\"\n (ngModelChange)=\"updatePreference('speech', $event)\" />\n <span>{{ 'settings.show_speech_bubbles' | translate }}</span>\n </label>\n </div>\n </div>\n\n <div class=\"settings-section\">\n <h3 class=\"section-title\">{{ 'settings.audio' | translate }}</h3>\n \n <div class=\"setting-item\">\n <label class=\"setting-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [ngModel]=\"preferences.audio\"\n (ngModelChange)=\"updatePreference('audio', $event)\" />\n <span>{{ 'settings.enable_audio' | translate }}</span>\n </label>\n </div>\n\n <div class=\"setting-item\">\n <label class=\"setting-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [ngModel]=\"preferences.sfx\"\n (ngModelChange)=\"updatePreference('sfx', $event)\" />\n <span>{{ 'settings.enable_sfx' | translate }}</span>\n </label>\n </div>\n </div>\n\n <div class=\"settings-section\">\n <h3 class=\"section-title\">{{ 'settings.autoplay' | translate }}</h3>\n \n <div class=\"setting-item\">\n <label class=\"setting-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [ngModel]=\"preferences.autoplay\"\n (ngModelChange)=\"updatePreference('autoplay', $event)\" />\n <span>{{ 'settings.enable_autoplay' | translate }}</span>\n </label>\n </div>\n\n <div class=\"setting-item\">\n <label class=\"setting-label\" for=\"seconds-input\">{{ 'settings.seconds_per_panel' | translate }}</label>\n <div class=\"number-input\">\n <input\n id=\"seconds-input\"\n type=\"number\"\n class=\"setting-number\"\n min=\"0.5\"\n max=\"120\"\n step=\"0.5\"\n [ngModel]=\"preferences.secondsPerPanel\"\n (ngModelChange)=\"updatePreference('secondsPerPanel', $event)\" />\n <span class=\"input-unit\">{{ 'settings.seconds_unit' | translate }}</span>\n </div>\n </div>\n </div>\n\n <div class=\"settings-actions\">\n <button\n class=\"action-btn secondary\"\n type=\"button\"\n (click)=\"resetPreferences()\">\n {{ 'settings.reset_defaults' | translate }}\n </button>\n </div>\n </div>\n }\n\n <!-- Variables Tab -->\n @if (activeTab === 'variables') {\n <div class=\"tab-panel\" role=\"tabpanel\">\n @if (getPublicVariables().length > 0) {\n <div class=\"settings-section\">\n <h3 class=\"section-title\">{{ 'settings.public_variables' | translate }}</h3>\n \n @for (variable of getPublicVariables(); track variable.id) {\n <div class=\"setting-item variable-item\">\n <span class=\"setting-label\">{{ variable.id }}</span>\n \n <!-- Boolean Variable -->\n @if (isBoolean(variable)) {\n <label class=\"toggle-label\">\n <input\n type=\"checkbox\"\n class=\"setting-checkbox\"\n [checked]=\"getVariableValue(variable)\"\n (change)=\"updateVariable(variable.id, $any($event.target).checked)\" />\n <span>{{ getVariableValue(variable) ? ('settings.enabled' | translate) : ('settings.disabled' | translate) }}</span>\n </label>\n }\n\n <!-- Number Variable -->\n @if (isNumber(variable)) {\n <div class=\"number-input\">\n <input\n type=\"number\"\n class=\"setting-number\"\n [min]=\"getMin(variable)\"\n [max]=\"getMax(variable)\"\n [value]=\"getVariableValue(variable)\"\n (input)=\"updateVariable(variable.id, $any($event.target).valueAsNumber)\" />\n <button\n class=\"reset-btn-small\"\n type=\"button\"\n [attr.title]=\"'settings.reset_to_default' | translate\"\n (click)=\"resetVariable(variable)\">\n <pw-icon name=\"lucideRotateCcw\" />\n </button>\n </div>\n }\n\n <!-- Enum Variable -->\n @if (isEnum(variable)) {\n <select\n class=\"setting-select\"\n [value]=\"getVariableValue(variable)\"\n (change)=\"updateVariable(variable.id, $any($event.target).value)\">\n @for (option of getEnumOptions(variable); track option) {\n <option [value]=\"option\">{{ option }}</option>\n }\n </select>\n }\n\n <!-- String Variable -->\n @if (isString(variable)) {\n <input\n type=\"text\"\n class=\"setting-text\"\n [value]=\"getVariableValue(variable)\"\n (input)=\"updateVariable(variable.id, $any($event.target).value)\" />\n }\n </div>\n }\n </div>\n\n <div class=\"settings-actions\">\n <button\n class=\"action-btn secondary\"\n type=\"button\"\n (click)=\"resetAllVariables()\">\n {{ 'settings.reset_all_variables' | translate }}\n </button>\n </div>\n } @else {\n <div class=\"empty-state\">\n <p>{{ 'settings.no_variables' | translate }}</p>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"settings-footer\">\n <button\n class=\"action-btn secondary\"\n type=\"button\"\n (click)=\"cancel()\">\n {{ 'settings.cancel' | translate }}\n </button>\n <button\n class=\"action-btn primary\"\n type=\"button\"\n (click)=\"save()\">\n {{ 'settings.save_changes' | translate }}\n </button>\n </div>\n </div>\n </div>\n}\n","/**\r\n * Character Roster Component\r\n * Displays character grid with filtering\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n OnInit,\r\n OnChanges,\r\n OnDestroy,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n HostListener,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport { FormsModule } from '@angular/forms';\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\nimport type { LocaleCode, LocalizedString } from '../../../types';\r\n\r\n/**\r\n * Character definition\r\n */\r\nexport interface Character {\r\n id: string;\r\n name: LocalizedString;\r\n avatar?: string;\r\n bio?: LocalizedString;\r\n voiceSample?: string;\r\n role?: string;\r\n}\r\n\r\n/**\r\n * Character Roster Component\r\n * Modal for displaying and filtering characters\r\n */\r\n@Component({\r\n selector: 'pw-character-roster',\r\n imports: [FormsModule, TranslateModule, PwIconComponent],\r\n templateUrl: './character-roster.component.html',\r\n styleUrls: ['./character-roster.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class CharacterRosterComponent implements OnInit, OnChanges, OnDestroy {\r\n private readonly cdr = inject(ChangeDetectorRef);\r\n\r\n /**\r\n * Listeners attached to the current audio element (removed on stop)\r\n */\r\n private audioListeners: { ended: () => void; error: () => void } | null = null;\r\n\r\n /**\r\n * List of characters\r\n */\r\n @Input() characters: Character[] = [];\r\n\r\n /**\r\n * Current locale\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Base URL for assets\r\n */\r\n @Input() baseUrl = '';\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Character selected (kept for backward compatibility but not used internally)\r\n */\r\n @Output() characterSelect = new EventEmitter<Character>();\r\n\r\n /**\r\n * Close overlay\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Search query\r\n */\r\n searchQuery = '';\r\n\r\n /**\r\n * Current view: 'list' or 'detail'\r\n */\r\n currentView: 'list' | 'detail' = 'list';\r\n\r\n /**\r\n * Selected character for detail view\r\n */\r\n selectedCharacter: Character | null = null;\r\n\r\n /**\r\n * Audio element for voice samples\r\n */\r\n private audioElement: HTMLAudioElement | null = null;\r\n\r\n /**\r\n * Is voice sample playing\r\n */\r\n isPlaying = false;\r\n\r\n /**\r\n * Filtered characters\r\n */\r\n filteredCharacters: Character[] = [];\r\n\r\n /**\r\n * Initialize component\r\n */\r\n ngOnInit(): void {\r\n this.filterCharacters();\r\n }\r\n\r\n /**\r\n * Handle input changes\r\n */\r\n ngOnChanges(): void {\r\n this.filterCharacters();\r\n }\r\n\r\n /**\r\n * Filter characters based on search query\r\n */\r\n filterCharacters(): void {\r\n if (!this.searchQuery.trim()) {\r\n this.filteredCharacters = [...this.characters];\r\n return;\r\n }\r\n\r\n const query = this.searchQuery.toLowerCase();\r\n this.filteredCharacters = this.characters.filter((character) => {\r\n const name = this.getLocalizedString(character.name);\r\n const role = character.role || '';\r\n return (\r\n name.toLowerCase().includes(query) ||\r\n role.toLowerCase().includes(query)\r\n );\r\n });\r\n }\r\n\r\n /**\r\n * Handle search input\r\n */\r\n onSearchChange(): void {\r\n this.filterCharacters();\r\n }\r\n\r\n /**\r\n * Get localized string\r\n */\r\n getLocalizedString(text?: LocalizedString): string {\r\n if (!text || typeof text !== 'object') {\r\n return '';\r\n }\r\n\r\n // Try exact locale\r\n if (text[this.locale]) {\r\n return text[this.locale];\r\n }\r\n\r\n // Try base language\r\n const baseLocale = this.locale.split('-')[0];\r\n const baseMatch = Object.keys(text).find((key) => key.startsWith(baseLocale));\r\n if (baseMatch && text[baseMatch]) {\r\n return text[baseMatch];\r\n }\r\n\r\n // Return first available\r\n const firstKey = Object.keys(text)[0];\r\n return firstKey ? text[firstKey] : '';\r\n }\r\n\r\n /**\r\n * Get character name\r\n */\r\n getCharacterName(character: Character): string {\r\n return this.getLocalizedString(character.name) || character.id;\r\n }\r\n\r\n /**\r\n * Get character bio\r\n */\r\n getCharacterBio(character: Character): string {\r\n return this.getLocalizedString(character.bio) || '';\r\n }\r\n\r\n /**\r\n * Get avatar URL\r\n */\r\n getAvatarUrl(character: Character): string {\r\n if (!character.avatar) {\r\n return '';\r\n }\r\n\r\n // Absolute URL\r\n if (\r\n character.avatar.startsWith('http://') ||\r\n character.avatar.startsWith('https://') ||\r\n character.avatar.startsWith('data:')\r\n ) {\r\n return character.avatar;\r\n }\r\n\r\n // Relative URL\r\n return this.baseUrl + character.avatar;\r\n }\r\n\r\n /**\r\n * Select character - shows detail view\r\n */\r\n selectCharacter(character: Character): void {\r\n this.selectedCharacter = character;\r\n this.currentView = 'detail';\r\n this.searchQuery = ''; // Clear search when viewing detail\r\n }\r\n\r\n /**\r\n * Go back to character list\r\n */\r\n backToList(): void {\r\n this.currentView = 'list';\r\n this.selectedCharacter = null;\r\n this.stopVoiceSample();\r\n }\r\n\r\n /**\r\n * Close roster\r\n */\r\n onClose(): void {\r\n this.backToList(); // Reset view when closing\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Get character initials for placeholder\r\n */\r\n getInitials(character: Character): string {\r\n const name = this.getCharacterName(character);\r\n const words = name.split(' ').filter(w => w.length > 0);\r\n if (words.length === 0) return '?';\r\n if (words.length === 1) return words[0].substring(0, 2).toUpperCase();\r\n return (words[0][0] + words[words.length - 1][0]).toUpperCase();\r\n }\r\n\r\n /**\r\n * Check if character has voice sample\r\n */\r\n hasVoiceSample(character: Character): boolean {\r\n return !!character.voiceSample;\r\n }\r\n\r\n /**\r\n * Play or stop voice sample\r\n */\r\n playVoiceSample(character: Character): void {\r\n if (!character.voiceSample) return;\r\n\r\n if (this.isPlaying && this.audioElement) {\r\n this.stopVoiceSample();\r\n } else {\r\n this.startVoiceSample(character.voiceSample);\r\n }\r\n }\r\n\r\n /**\r\n * Start playing voice sample\r\n */\r\n private startVoiceSample(url: string): void {\r\n this.stopVoiceSample(); // Stop any existing audio\r\n\r\n const audioUrl = url.startsWith('http://') || url.startsWith('https://') || url.startsWith('data:')\r\n ? url\r\n : this.baseUrl + url;\r\n\r\n const audio = new Audio(audioUrl);\r\n this.audioElement = audio;\r\n // All state changes below happen outside Angular's template events, so the\r\n // OnPush view must be marked for check explicitly.\r\n const listeners = {\r\n ended: () => this.setPlaying(false),\r\n error: () => {\r\n this.setPlaying(false);\r\n console.error('Failed to load voice sample');\r\n },\r\n };\r\n this.audioListeners = listeners;\r\n audio.addEventListener('ended', listeners.ended);\r\n audio.addEventListener('error', listeners.error);\r\n\r\n audio.play().then(() => {\r\n // Ignore a late resolution for an element that was already stopped/replaced\r\n if (this.audioElement === audio) {\r\n this.setPlaying(true);\r\n }\r\n }).catch((error) => {\r\n console.error('Failed to play voice sample:', error);\r\n if (this.audioElement === audio) {\r\n this.setPlaying(false);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Update the playing flag and schedule an OnPush re-render\r\n */\r\n private setPlaying(playing: boolean): void {\r\n this.isPlaying = playing;\r\n this.cdr.markForCheck();\r\n }\r\n\r\n /**\r\n * Stop playing voice sample\r\n */\r\n private stopVoiceSample(): void {\r\n if (this.audioElement) {\r\n if (this.audioListeners) {\r\n this.audioElement.removeEventListener('ended', this.audioListeners.ended);\r\n this.audioElement.removeEventListener('error', this.audioListeners.error);\r\n }\r\n this.audioElement.pause();\r\n this.audioElement.currentTime = 0;\r\n this.audioElement = null;\r\n }\r\n this.audioListeners = null;\r\n this.isPlaying = false;\r\n }\r\n\r\n /**\r\n * Stop any playing voice sample when the component is destroyed\r\n */\r\n ngOnDestroy(): void {\r\n this.stopVoiceSample();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n this.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Handle backdrop keyboard interaction\r\n */\r\n onBackdropKeydown(event: KeyboardEvent): void {\r\n // Only handle Enter/Space on the backdrop itself\r\n if (event.target === event.currentTarget && \r\n (event.key === 'Enter' || event.key === ' ')) {\r\n event.preventDefault();\r\n this.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Handle keyboard events\r\n */\r\n @HostListener('window:keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent): void {\r\n if (!this.visible) return;\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n this.onClose();\r\n }\r\n }\r\n\r\n}\r\n","@if (visible) {\r\n <div class=\"roster-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown)=\"onBackdropKeydown($event)\">\r\n <div class=\"roster-container\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"currentView === 'list' ? 'Character Roster' : 'Character Details'\">\r\n \r\n <!-- LIST VIEW -->\r\n @if (currentView === 'list') {\r\n <!-- Header -->\r\n <div class=\"roster-header\">\r\n <h2 class=\"roster-title\">{{ 'character_roster.title' | translate }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'character_roster.close' | translate\"\r\n (click)=\"onClose()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Search -->\r\n <div class=\"roster-search\">\r\n <input\r\n type=\"text\"\r\n class=\"search-input\"\r\n [placeholder]=\"'character_roster.search' | translate\"\r\n [attr.aria-label]=\"'character_roster.search_label' | translate\"\r\n [(ngModel)]=\"searchQuery\"\r\n (ngModelChange)=\"onSearchChange()\" />\r\n <span class=\"search-icon\"><pw-icon name=\"lucideSearch\" /></span>\r\n </div>\r\n\r\n <!-- Character grid -->\r\n <div class=\"roster-content\">\r\n @if (filteredCharacters.length > 0) {\r\n <div class=\"character-grid\" role=\"list\">\r\n @for (character of filteredCharacters; track character.id) {\r\n <button\r\n class=\"character-card\"\r\n type=\"button\"\r\n role=\"listitem\"\r\n (click)=\"selectCharacter(character)\">\r\n \r\n <!-- Avatar -->\r\n <div class=\"character-avatar\">\r\n @if (getAvatarUrl(character)) {\r\n <img\r\n [src]=\"getAvatarUrl(character)\"\r\n [alt]=\"getCharacterName(character)\"\r\n class=\"avatar-image\" />\r\n } @else {\r\n <div class=\"avatar-placeholder\">\r\n {{ getInitials(character) }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Info -->\r\n <div class=\"character-info\">\r\n <h3 class=\"character-name\">{{ getCharacterName(character) }}</h3>\r\n @if (character['role']) {\r\n <p class=\"character-role\">{{ character['role'] }}</p>\r\n }\r\n </div>\r\n </button>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"empty-state\">\r\n <p>{{ 'character_roster.no_results' | translate: {query: searchQuery} }}</p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"roster-footer\">\r\n <p class=\"footer-hint\">\r\n <kbd>{{ 'common.esc' | translate }}</kbd> {{ 'character_roster.keyboard_hint' | translate }}\r\n </p>\r\n </div>\r\n }\r\n\r\n <!-- DETAIL VIEW -->\r\n @if (currentView === 'detail' && selectedCharacter) {\r\n <!-- Header with back button -->\r\n <div class=\"roster-header\">\r\n <button\r\n class=\"back-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'character_roster.back_to_list' | translate\"\r\n (click)=\"backToList()\">\r\n {{ 'character_roster.back_to_list' | translate }}\r\n </button>\r\n <h2 class=\"roster-title\">{{ getCharacterName(selectedCharacter) }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'character_sheet.close' | translate\"\r\n (click)=\"onClose()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"sheet-content\">\r\n <!-- Portrait -->\r\n <div class=\"portrait-section\">\r\n <div class=\"portrait-container\">\r\n @if (getAvatarUrl(selectedCharacter)) {\r\n <img\r\n [src]=\"getAvatarUrl(selectedCharacter)\"\r\n [alt]=\"getCharacterName(selectedCharacter)\"\r\n class=\"portrait-image\" />\r\n } @else {\r\n <div class=\"portrait-placeholder\">\r\n {{ getInitials(selectedCharacter) }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Role badge -->\r\n @if (selectedCharacter['role']) {\r\n <div class=\"role-badge\">\r\n {{ selectedCharacter['role'] }}\r\n </div>\r\n }\r\n\r\n <!-- Voice sample button -->\r\n @if (hasVoiceSample(selectedCharacter)) {\r\n <button\r\n class=\"voice-btn\"\r\n [class.playing]=\"isPlaying\"\r\n type=\"button\"\r\n [attr.aria-label]=\"(isPlaying ? 'character_sheet.stop_voice' : 'character_sheet.play_voice') | translate\"\r\n (click)=\"playVoiceSample(selectedCharacter)\">\r\n <span class=\"voice-icon\"><pw-icon [name]=\"isPlaying ? 'lucidePause' : 'lucideVolume2'\" /></span>\r\n <span class=\"voice-label\">{{ (isPlaying ? 'character_sheet.stop_voice' : 'character_sheet.play_voice') | translate }}</span>\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Bio -->\r\n <div class=\"bio-section\">\r\n <h3 class=\"bio-title\">Biography</h3>\r\n @if (getCharacterBio(selectedCharacter)) {\r\n <div class=\"bio-content\">\r\n {{ getCharacterBio(selectedCharacter) }}\r\n </div>\r\n } @else {\r\n <p class=\"bio-empty\">No biography available.</p>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"sheet-footer\">\r\n <p class=\"footer-hint\">\r\n <kbd>{{ 'common.esc' | translate }}</kbd> {{ 'character_sheet.keyboard_hint' | translate }}\r\n </p>\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n}\r\n","/**\r\n * Extras Viewer Component\r\n * Displays bonus content gallery\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n OnChanges,\r\n SimpleChanges,\r\n} from '@angular/core';\r\n\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\nimport type { LocaleCode, LocalizedString } from '../../../types';\r\n\r\n/**\r\n * Extra item type\r\n */\r\nexport type ExtraType = 'cover' | 'art' | 'bts' | 'interview' | 'other';\r\n\r\n/**\r\n * Extra item definition\r\n */\r\nexport interface Extra {\r\n id: string;\r\n type: ExtraType;\r\n title: LocalizedString;\r\n description?: LocalizedString;\r\n thumbnail?: string;\r\n asset?: string;\r\n mediaType?: 'image' | 'video' | 'audio' | 'document';\r\n gated?: boolean;\r\n tags?: string[];\r\n}\r\n\r\n/**\r\n * Extras Viewer Component\r\n * Modal for displaying and browsing extras\r\n */\r\n@Component({\r\n selector: 'pw-extras-viewer',\r\n imports: [TranslateModule, PwIconComponent],\r\n templateUrl: './extras-viewer.component.html',\r\n styleUrls: ['./extras-viewer.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class ExtrasViewerComponent implements OnChanges {\r\n /**\r\n * List of extras\r\n */\r\n @Input() extras: Extra[] = [];\r\n\r\n /**\r\n * Extra item to open when the viewer becomes visible (hotspot openExtras)\r\n */\r\n @Input() initialExtraId?: string;\r\n\r\n /**\r\n * Current locale\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Base URL for assets\r\n */\r\n @Input() baseUrl = '';\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * User has premium access\r\n */\r\n @Input() hasPremiumAccess = false;\r\n\r\n /**\r\n * Purchase triggered\r\n */\r\n @Output() purchase = new EventEmitter<void>();\r\n\r\n /**\r\n * Close viewer\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Selected extra for detail view\r\n */\r\n selectedExtra?: Extra;\r\n\r\n /**\r\n * Current filter type\r\n */\r\n filterType: ExtraType | 'all' = 'all';\r\n\r\n /**\r\n * Get filtered extras\r\n */\r\n getFilteredExtras(): Extra[] {\r\n if (this.filterType === 'all') {\r\n return this.extras;\r\n }\r\n return this.extras.filter((extra) => extra.type === this.filterType);\r\n }\r\n\r\n /**\r\n * Get extras by type for filter counts\r\n */\r\n getExtrasByType(type: ExtraType): number {\r\n return this.extras.filter((extra) => extra.type === type).length;\r\n }\r\n\r\n /**\r\n * Check if any extras are gated\r\n */\r\n hasGatedExtras(): boolean {\r\n return this.extras.some((extra) => extra.gated);\r\n }\r\n\r\n /**\r\n * Set filter type\r\n */\r\n setFilter(type: ExtraType | 'all'): void {\r\n this.filterType = type;\r\n }\r\n\r\n /**\r\n * Get localized string\r\n */\r\n getLocalizedString(text?: LocalizedString): string {\r\n if (!text || typeof text !== 'object') {\r\n return '';\r\n }\r\n\r\n // Try exact locale\r\n if (text[this.locale]) {\r\n return text[this.locale];\r\n }\r\n\r\n // Try base language\r\n const baseLocale = this.locale.split('-')[0];\r\n const baseMatch = Object.keys(text).find((key) => key.startsWith(baseLocale));\r\n if (baseMatch && text[baseMatch]) {\r\n return text[baseMatch];\r\n }\r\n\r\n // Return first available\r\n const firstKey = Object.keys(text)[0];\r\n return firstKey ? text[firstKey] : '';\r\n }\r\n\r\n /**\r\n * Get extra title\r\n */\r\n getExtraTitle(extra: Extra): string {\r\n return this.getLocalizedString(extra.title) || extra.id;\r\n }\r\n\r\n /**\r\n * Get extra description\r\n */\r\n getExtraDescription(extra: Extra): string {\r\n return this.getLocalizedString(extra.description) || '';\r\n }\r\n\r\n /**\r\n * Get thumbnail URL\r\n */\r\n getThumbnailUrl(extra: Extra): string {\r\n if (!extra.thumbnail) {\r\n return '';\r\n }\r\n\r\n // Absolute URL\r\n if (\r\n extra.thumbnail.startsWith('http://') ||\r\n extra.thumbnail.startsWith('https://') ||\r\n extra.thumbnail.startsWith('data:')\r\n ) {\r\n return extra.thumbnail;\r\n }\r\n\r\n // Relative URL\r\n return this.baseUrl + extra.thumbnail;\r\n }\r\n\r\n /**\r\n * Get asset URL\r\n */\r\n getAssetUrl(extra: Extra): string {\r\n if (!extra.asset) {\r\n return '';\r\n }\r\n\r\n // Absolute URL\r\n if (\r\n extra.asset.startsWith('http://') ||\r\n extra.asset.startsWith('https://') ||\r\n extra.asset.startsWith('data:')\r\n ) {\r\n return extra.asset;\r\n }\r\n\r\n // Relative URL\r\n return this.baseUrl + extra.asset;\r\n }\r\n\r\n /**\r\n * Check if extra is accessible\r\n */\r\n isAccessible(extra: Extra): boolean {\r\n return !extra.gated || this.hasPremiumAccess;\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['visible'] && this.visible && this.initialExtraId) {\r\n const match = this.extras.find((e) => e.id === this.initialExtraId);\r\n if (match) {\r\n this.openExtra(match);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Open extra detail\r\n */\r\n openExtra(extra: Extra): void {\r\n if (!this.isAccessible(extra)) {\r\n return;\r\n }\r\n this.selectedExtra = extra;\r\n }\r\n\r\n /**\r\n * Close detail view\r\n */\r\n closeDetail(): void {\r\n this.selectedExtra = undefined;\r\n }\r\n\r\n /**\r\n * Trigger purchase\r\n */\r\n onPurchase(): void {\r\n this.purchase.emit();\r\n }\r\n\r\n /**\r\n * Close viewer\r\n */\r\n onClose(): void {\r\n this.closeDetail();\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n if (this.selectedExtra) {\r\n this.closeDetail();\r\n } else {\r\n this.onClose();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle backdrop keyboard interaction\r\n */\r\n onBackdropKeydown(event: KeyboardEvent): void {\r\n if (event.target === event.currentTarget && \r\n (event.key === 'Enter' || event.key === ' ')) {\r\n event.preventDefault();\r\n if (this.selectedExtra) {\r\n this.closeDetail();\r\n } else {\r\n this.onClose();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle keyboard events\r\n */\r\n @HostListener('window:keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent): void {\r\n if (!this.visible) return;\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n if (this.selectedExtra) {\r\n this.closeDetail();\r\n } else {\r\n this.onClose();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get type display name\r\n */\r\n getTypeName(type: ExtraType): string {\r\n const names: Record<ExtraType, string> = {\r\n cover: 'Covers',\r\n art: 'Artwork',\r\n bts: 'Behind the Scenes',\r\n interview: 'Interviews',\r\n other: 'Other',\r\n };\r\n return names[type] || type;\r\n }\r\n\r\n /**\r\n * Get media type icon (Lucide icon name for {@link PwIconComponent})\r\n */\r\n getMediaIcon(extra: Extra): string {\r\n switch (extra.mediaType) {\r\n case 'image': return 'lucideImage';\r\n case 'video': return 'lucideClapperboard';\r\n case 'audio': return 'lucideMusic';\r\n case 'document': return 'lucideFileText';\r\n default: return 'lucidePaperclip';\r\n }\r\n }\r\n}\r\n","@if (visible) {\r\n <div class=\"extras-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown)=\"onBackdropKeydown($event)\">\r\n <div class=\"extras-container\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Extras Viewer\">\r\n <!-- Header -->\r\n <div class=\"extras-header\">\r\n <h2 class=\"extras-title\">{{ 'extras.title' | translate }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'extras.close' | translate\"\r\n (click)=\"onClose()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Filters -->\r\n <div class=\"extras-filters\">\r\n <button\r\n class=\"filter-btn\"\r\n [class.active]=\"filterType === 'all'\"\r\n type=\"button\"\r\n (click)=\"setFilter('all')\">\r\n {{ 'extras.all' | translate }} ({{ extras.length }})\r\n </button>\r\n @if (getExtrasByType('cover') > 0) {\r\n <button\r\n class=\"filter-btn\"\r\n [class.active]=\"filterType === 'cover'\"\r\n type=\"button\"\r\n (click)=\"setFilter('cover')\">\r\n {{ getTypeName('cover') }} ({{ getExtrasByType('cover') }})\r\n </button>\r\n }\r\n @if (getExtrasByType('art') > 0) {\r\n <button\r\n class=\"filter-btn\"\r\n [class.active]=\"filterType === 'art'\"\r\n type=\"button\"\r\n (click)=\"setFilter('art')\">\r\n {{ getTypeName('art') }} ({{ getExtrasByType('art') }})\r\n </button>\r\n }\r\n @if (getExtrasByType('bts') > 0) {\r\n <button\r\n class=\"filter-btn\"\r\n [class.active]=\"filterType === 'bts'\"\r\n type=\"button\"\r\n (click)=\"setFilter('bts')\">\r\n {{ getTypeName('bts') }} ({{ getExtrasByType('bts') }})\r\n </button>\r\n }\r\n @if (getExtrasByType('interview') > 0) {\r\n <button\r\n class=\"filter-btn\"\r\n [class.active]=\"filterType === 'interview'\"\r\n type=\"button\"\r\n (click)=\"setFilter('interview')\">\r\n {{ getTypeName('interview') }} ({{ getExtrasByType('interview') }})\r\n </button>\r\n }\r\n @if (getExtrasByType('other') > 0) {\r\n <button\r\n class=\"filter-btn\"\r\n [class.active]=\"filterType === 'other'\"\r\n type=\"button\"\r\n (click)=\"setFilter('other')\">\r\n {{ getTypeName('other') }} ({{ getExtrasByType('other') }})\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Gallery Grid -->\r\n <div class=\"extras-content\">\r\n @if (getFilteredExtras().length > 0) {\r\n <div class=\"extras-grid\" role=\"list\">\r\n @for (extra of getFilteredExtras(); track extra.id) {\r\n <div class=\"extra-card\" role=\"listitem\">\r\n <button\r\n class=\"extra-thumbnail\"\r\n [class.locked]=\"!isAccessible(extra)\"\r\n type=\"button\"\r\n (click)=\"openExtra(extra)\">\r\n \r\n @if (getThumbnailUrl(extra)) {\r\n <img\r\n [src]=\"getThumbnailUrl(extra)\"\r\n [alt]=\"getExtraTitle(extra)\"\r\n class=\"thumbnail-image\" />\r\n } @else {\r\n <div class=\"thumbnail-placeholder\">\r\n <pw-icon [name]=\"getMediaIcon(extra)\" />\r\n </div>\r\n }\r\n\r\n <!-- Lock overlay for gated content -->\r\n @if (!isAccessible(extra)) {\r\n <div class=\"lock-overlay\">\r\n <span class=\"lock-icon\"><pw-icon name=\"lucideLock\" /></span>\r\n <span class=\"lock-text\">{{ 'extras.locked_premium' | translate }}</span>\r\n </div>\r\n }\r\n\r\n <!-- Media type badge -->\r\n <div class=\"media-badge\">\r\n <pw-icon [name]=\"getMediaIcon(extra)\" />\r\n </div>\r\n </button>\r\n\r\n <div class=\"extra-info\">\r\n <h3 class=\"extra-title\">{{ getExtraTitle(extra) }}</h3>\r\n @if (getExtraDescription(extra)) {\r\n <p class=\"extra-description\">{{ getExtraDescription(extra) }}</p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"empty-state\">\r\n <p>{{ 'extras.no_extras' | translate }}</p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Detail View -->\r\n @if (selectedExtra) {\r\n <div class=\"detail-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"$event.stopPropagation(); closeDetail()\">\r\n <div class=\"detail-container\">\r\n <!-- Detail Header -->\r\n <div class=\"detail-header\">\r\n <h3 class=\"detail-title\">{{ getExtraTitle(selectedExtra) }}</h3>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'extras.close_detail' | translate\"\r\n (click)=\"closeDetail()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Detail Content -->\r\n <div class=\"detail-content\">\r\n @if ((selectedExtra.mediaType === 'image' || !selectedExtra.mediaType) && getAssetUrl(selectedExtra)) {\r\n <img\r\n [src]=\"getAssetUrl(selectedExtra)\"\r\n [alt]=\"getExtraTitle(selectedExtra)\"\r\n class=\"detail-image\" />\r\n }\r\n\r\n @if (selectedExtra.mediaType === 'video') {\r\n <video\r\n [src]=\"getAssetUrl(selectedExtra)\"\r\n controls\r\n class=\"detail-video\">\r\n {{ 'extras.video_not_supported' | translate }}\r\n </video>\r\n }\r\n\r\n @if (selectedExtra.mediaType === 'audio') {\r\n <audio\r\n [src]=\"getAssetUrl(selectedExtra)\"\r\n controls\r\n class=\"detail-audio\">\r\n {{ 'extras.audio_not_supported' | translate }}\r\n </audio>\r\n }\r\n\r\n @if (selectedExtra.mediaType === 'document' && getAssetUrl(selectedExtra)) {\r\n <a\r\n class=\"action-btn detail-document-link\"\r\n [href]=\"getAssetUrl(selectedExtra)\"\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\">\r\n {{ 'extras.open_document' | translate }}\r\n </a>\r\n }\r\n\r\n @if (getExtraDescription(selectedExtra)) {\r\n <div class=\"detail-description\">\r\n {{ getExtraDescription(selectedExtra) }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Detail Footer -->\r\n <div class=\"detail-footer\">\r\n <button\r\n class=\"action-btn\"\r\n type=\"button\"\r\n (click)=\"closeDetail()\">\r\n {{ 'extras.close_button' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Paywall Notice (for gated content without access) -->\r\n @if (!hasPremiumAccess && hasGatedExtras()) {\r\n <div class=\"paywall-notice\">\r\n <p class=\"notice-text\">\r\n <span class=\"notice-icon\"><pw-icon name=\"lucideLock\" /></span>\r\n {{ 'extras.premium_notice' | translate }}\r\n </p>\r\n <button\r\n class=\"upgrade-btn\"\r\n type=\"button\"\r\n (click)=\"onPurchase()\">\r\n {{ 'extras.upgrade_now' | translate }}\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n}\r\n","/**\r\n * Action Modal Component\r\n * Simple localized title + content dialog opened by a hotspot's openModal\r\n * action. Follows the shell's modal contract: visible input + close output.\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n} from '@angular/core';\r\n\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\nimport type { LocalizedString } from '../../../types';\r\nimport { resolveLocalizedString } from '../../../utils';\r\n\r\n@Component({\r\n selector: 'pw-action-modal',\r\n imports: [PwIconComponent],\r\n templateUrl: './action-modal.component.html',\r\n styleUrls: ['./action-modal.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class ActionModalComponent {\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Current locale for text resolution\r\n */\r\n @Input() locale = 'en-US';\r\n\r\n /**\r\n * Localized modal title\r\n */\r\n @Input() title: LocalizedString | null = null;\r\n\r\n /**\r\n * Localized modal body text\r\n */\r\n @Input() content: LocalizedString | null = null;\r\n\r\n /**\r\n * Close requested\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n @HostListener('document:keydown.escape')\r\n onEscape(): void {\r\n if (this.visible) {\r\n this.close.emit();\r\n }\r\n }\r\n\r\n resolved(ls: LocalizedString | null): string {\r\n return ls ? resolveLocalizedString(ls, this.locale, 'en-US') : '';\r\n }\r\n\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n this.close.emit();\r\n }\r\n }\r\n}\r\n","@if (visible) {\r\n <div class=\"action-modal-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"$event.stopPropagation(); close.emit()\">\r\n <div class=\"action-modal-container\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"resolved(title)\">\r\n <div class=\"action-modal-header\">\r\n <h2 class=\"action-modal-title\">{{ resolved(title) }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n aria-label=\"Close\"\r\n (click)=\"close.emit()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n <!-- Plain text only: manifest content is untrusted, never innerHTML -->\r\n <div class=\"action-modal-content\">{{ resolved(content) }}</div>\r\n </div>\r\n </div>\r\n}\r\n","/**\r\n * Age Gate Component\r\n * Displays age verification UI for restricted content\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n} from '@angular/core';\r\n\r\nimport { FormsModule } from '@angular/forms';\r\nimport type { LocaleCode } from '../../../types';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\n\r\n/**\r\n * Age verification result\r\n */\r\nexport interface AgeVerificationResult {\r\n verified: boolean;\r\n age?: number;\r\n birthDate?: Date;\r\n}\r\n\r\n/**\r\n * Age Gate Component\r\n * Modal overlay for age verification\r\n */\r\n@Component({\r\n selector: 'pw-age-gate',\r\n imports: [FormsModule, PwIconComponent],\r\n templateUrl: './age-gate.component.html',\r\n styleUrls: ['./age-gate.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class AgeGateComponent {\r\n /**\r\n * Visibility state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Minimum required age\r\n */\r\n @Input() minimumAge = 18;\r\n\r\n /**\r\n * Current locale\r\n */\r\n @Input() locale: LocaleCode = 'en-US';\r\n\r\n /**\r\n * Custom warning message\r\n */\r\n @Input() warningMessage?: string;\r\n\r\n /**\r\n * Allow dismiss\r\n */\r\n @Input() allowDismiss = true;\r\n\r\n /**\r\n * Verification completed\r\n */\r\n @Output() verify = new EventEmitter<AgeVerificationResult>();\r\n\r\n /**\r\n * Close overlay\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Birth date inputs\r\n */\r\n birthMonth = '';\r\n birthDay = '';\r\n birthYear = '';\r\n\r\n /**\r\n * Error message\r\n */\r\n errorMessage = '';\r\n\r\n /**\r\n * Handle escape key\r\n */\r\n @HostListener('document:keydown.escape')\r\n onEscape(): void {\r\n if (this.visible && this.allowDismiss) {\r\n this.onDismiss();\r\n }\r\n }\r\n\r\n /**\r\n * Get warning message\r\n */\r\n getWarningMessage(): string {\r\n if (this.warningMessage) {\r\n return this.warningMessage;\r\n }\r\n return `This content is restricted to users ${this.minimumAge} years of age or older.`;\r\n }\r\n\r\n /**\r\n * Handle verification submit\r\n */\r\n onSubmit(): void {\r\n this.errorMessage = '';\r\n\r\n // Validate inputs\r\n if (!this.birthMonth || !this.birthDay || !this.birthYear) {\r\n this.errorMessage = 'Please enter your complete birth date.';\r\n return;\r\n }\r\n\r\n const month = parseInt(this.birthMonth, 10);\r\n const day = parseInt(this.birthDay, 10);\r\n const year = parseInt(this.birthYear, 10);\r\n\r\n // Validate ranges\r\n if (month < 1 || month > 12) {\r\n this.errorMessage = 'Please enter a valid month (1-12).';\r\n return;\r\n }\r\n\r\n if (day < 1 || day > 31) {\r\n this.errorMessage = 'Please enter a valid day (1-31).';\r\n return;\r\n }\r\n\r\n const currentYear = new Date().getFullYear();\r\n if (year < 1900 || year > currentYear) {\r\n this.errorMessage = `Please enter a valid year (1900-${currentYear}).`;\r\n return;\r\n }\r\n\r\n // Reject calendar-impossible dates (31 Apr, 30 Feb, 29 Feb in non-leap\r\n // years): new Date() would silently roll them over into the next month.\r\n const daysInMonth = new Date(year, month, 0).getDate();\r\n if (day > daysInMonth) {\r\n this.errorMessage = `Please enter a valid day (1-${daysInMonth}).`;\r\n return;\r\n }\r\n\r\n // Calculate age\r\n const birthDate = new Date(year, month - 1, day);\r\n const age = this.calculateAge(birthDate);\r\n\r\n if (age < this.minimumAge) {\r\n this.errorMessage = `You must be at least ${this.minimumAge} years old to access this content.`;\r\n this.verify.emit({\r\n verified: false,\r\n age,\r\n birthDate,\r\n });\r\n return;\r\n }\r\n\r\n // Success\r\n this.verify.emit({\r\n verified: true,\r\n age,\r\n birthDate,\r\n });\r\n }\r\n\r\n /**\r\n * Handle dismiss\r\n */\r\n onDismiss(): void {\r\n if (this.allowDismiss) {\r\n this.verify.emit({ verified: false });\r\n this.close.emit();\r\n }\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget && this.allowDismiss) {\r\n this.onDismiss();\r\n }\r\n }\r\n\r\n /**\r\n * Calculate age from birth date\r\n */\r\n private calculateAge(birthDate: Date): number {\r\n const today = new Date();\r\n let age = today.getFullYear() - birthDate.getFullYear();\r\n const monthDiff = today.getMonth() - birthDate.getMonth();\r\n \r\n if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {\r\n age--;\r\n }\r\n \r\n return age;\r\n }\r\n\r\n /**\r\n * Get month options\r\n */\r\n getMonthOptions(): { value: string; label: string }[] {\r\n const months = [\r\n 'January', 'February', 'March', 'April', 'May', 'June',\r\n 'July', 'August', 'September', 'October', 'November', 'December'\r\n ];\r\n \r\n return months.map((month, index) => ({\r\n value: String(index + 1),\r\n label: month,\r\n }));\r\n }\r\n\r\n /**\r\n * Get day options\r\n */\r\n getDayOptions(): number[] {\r\n return Array.from({ length: 31 }, (_, i) => i + 1);\r\n }\r\n\r\n /**\r\n * Get year options\r\n */\r\n getYearOptions(): number[] {\r\n const currentYear = new Date().getFullYear();\r\n const years: number[] = [];\r\n for (let year = currentYear; year >= 1900; year--) {\r\n years.push(year);\r\n }\r\n return years;\r\n }\r\n}\r\n","<!-- Age Gate Overlay -->\r\n<div class=\"age-gate-overlay\" [class.visible]=\"visible\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"$event.stopPropagation(); onDismiss()\">\r\n <div class=\"age-gate-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Age Verification\">\r\n <!-- Header -->\r\n <div class=\"age-gate-header\">\r\n <div class=\"warning-icon\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/>\r\n </svg>\r\n </div>\r\n <h2 class=\"age-gate-title\">Age Verification Required</h2>\r\n @if (allowDismiss) {\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n aria-label=\"Close\"\r\n (click)=\"onDismiss()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"age-gate-content\">\r\n <!-- Warning Message -->\r\n <p class=\"warning-message\">{{ getWarningMessage() }}</p>\r\n\r\n <!-- Birth Date Form -->\r\n <form class=\"birth-date-form\" (ngSubmit)=\"onSubmit()\">\r\n <div class=\"form-label\">Please enter your birth date:</div>\r\n\r\n <div class=\"date-inputs\">\r\n <!-- Month -->\r\n <div class=\"input-group\">\r\n <label for=\"birth-month\" class=\"input-label\">Month</label>\r\n <select\r\n id=\"birth-month\"\r\n class=\"date-input\"\r\n [(ngModel)]=\"birthMonth\"\r\n name=\"birthMonth\"\r\n required>\r\n <option value=\"\">--</option>\r\n @for (month of getMonthOptions(); track month.value) {\r\n <option [value]=\"month.value\">{{ month.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <!-- Day -->\r\n <div class=\"input-group\">\r\n <label for=\"birth-day\" class=\"input-label\">Day</label>\r\n <select\r\n id=\"birth-day\"\r\n class=\"date-input\"\r\n [(ngModel)]=\"birthDay\"\r\n name=\"birthDay\"\r\n required>\r\n <option value=\"\">--</option>\r\n @for (day of getDayOptions(); track day) {\r\n <option [value]=\"day\">{{ day }}</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n <!-- Year -->\r\n <div class=\"input-group\">\r\n <label for=\"birth-year\" class=\"input-label\">Year</label>\r\n <select\r\n id=\"birth-year\"\r\n class=\"date-input\"\r\n [(ngModel)]=\"birthYear\"\r\n name=\"birthYear\"\r\n required>\r\n <option value=\"\">----</option>\r\n @for (year of getYearOptions(); track year) {\r\n <option [value]=\"year\">{{ year }}</option>\r\n }\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <!-- Error Message -->\r\n @if (errorMessage) {\r\n <div class=\"error-message\" role=\"alert\">\r\n {{ errorMessage }}\r\n </div>\r\n }\r\n\r\n <!-- Submit Button -->\r\n <button\r\n type=\"submit\"\r\n class=\"verify-btn\">\r\n Verify Age\r\n </button>\r\n </form>\r\n\r\n <!-- Privacy Notice -->\r\n <div class=\"privacy-notice\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2z\"/>\r\n </svg>\r\n <span>Your information is private and will not be stored.</span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","/**\n * Branch Chooser Component\n * Lists the outgoing edges of the current panel whose conditions currently\n * pass, so a reader can pick a path explicitly instead of relying on edge\n * priority. Opened from the toolbar's \"Choices\" button; follows the shell's\n * modal contract (visible input + close output).\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectionStrategy,\n HostListener,\n} from '@angular/core';\n\nimport { PwIconComponent } from '../../icon/pw-icon.component';\nimport type { Edge } from '../../../types';\n\n/** One selectable path out of the current panel. */\nexport interface BranchChoice {\n /** The graph edge this choice traverses. */\n edge: Edge;\n /** Reader-facing label (edge label → target panel title → \"Option N\"). */\n label: string;\n /** Position in the offered list (0-based), stable for tracking. */\n index: number;\n}\n\n@Component({\n selector: 'pw-branch-chooser',\n imports: [PwIconComponent],\n templateUrl: './branch-chooser.component.html',\n styleUrls: ['./branch-chooser.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class BranchChooserComponent {\n /** Visible state */\n @Input() visible = false;\n\n /** Current locale (labels are already resolved by the shell). */\n @Input() locale = 'en-US';\n\n /** Paths on offer, in graph order. */\n @Input() choices: BranchChoice[] = [];\n\n /** Reader picked a path. */\n @Output() choose = new EventEmitter<BranchChoice>();\n\n /** Close requested without choosing. */\n @Output() close = new EventEmitter<void>();\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.visible) {\n this.close.emit();\n }\n }\n\n onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) {\n this.close.emit();\n }\n }\n\n trackChoice(_index: number, choice: BranchChoice): number {\n return choice.index;\n }\n}\n","@if (visible) {\n <div\n class=\"branch-chooser-overlay\"\n tabindex=\"-1\"\n (click)=\"onBackdropClick($event)\"\n (keydown.escape)=\"close.emit()\">\n <div\n class=\"branch-chooser-container\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"pw-branch-chooser-title\">\n <div class=\"branch-chooser-header\">\n <h2 id=\"pw-branch-chooser-title\" class=\"branch-chooser-title\">Choose your path</h2>\n <button\n class=\"close-btn\"\n type=\"button\"\n aria-label=\"Close\"\n (click)=\"close.emit()\">\n <pw-icon name=\"lucideX\" />\n </button>\n </div>\n\n <ul class=\"branch-chooser-list\">\n @for (choice of choices; track choice.index) {\n <li>\n <button\n class=\"branch-chooser-option\"\n type=\"button\"\n (click)=\"choose.emit(choice)\">\n <span class=\"branch-chooser-index\" aria-hidden=\"true\">{{ choice.index + 1 }}</span>\n <span class=\"branch-chooser-label\">{{ choice.label }}</span>\n <span class=\"branch-chooser-arrow\" aria-hidden=\"true\"><pw-icon name=\"lucideChevronRight\" /></span>\n </button>\n </li>\n }\n </ul>\n </div>\n </div>\n}\n","/**\r\n * Hotspot Action Service\r\n * Executes a hotspot's action. Pure side effects (variable mutations, plugin\r\n * events) happen here; UI side effects (navigation, modals) are returned as\r\n * an effect for the shell to apply — keeps this fully unit-testable.\r\n */\r\n\r\nimport { Injectable, inject } from '@angular/core';\r\n\r\nimport type { HotspotAction, LocalizedString, Transition } from '../types';\r\nimport { VariableStoreService } from './variable-store.service';\r\nimport { PluginHostService } from './plugin-host.service';\r\n\r\n/**\r\n * UI side effect the shell must apply after executing a hotspot action\r\n */\r\nexport type HotspotUiEffect =\r\n | { kind: 'navigate'; to: string; transition?: Transition }\r\n | { kind: 'openExtras'; extrasId: string }\r\n | { kind: 'openModal'; title: LocalizedString; content: LocalizedString }\r\n | { kind: 'none' };\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class HotspotActionService {\r\n private readonly variableStore = inject(VariableStoreService);\r\n private readonly pluginHost = inject(PluginHostService);\r\n\r\n /**\r\n * Execute a hotspot action\r\n * @param action - The hotspot's action (manifest shape)\r\n * @param ids - Scope identifiers for chapter/page-scoped mutations\r\n * @returns The UI effect for the caller to apply\r\n */\r\n execute(action: HotspotAction, ids: { chapterId?: string; pageId?: string }): HotspotUiEffect {\r\n switch (action.type) {\r\n case 'goTo':\r\n if (action.mutations?.length) {\r\n this.variableStore.applyMutations(action.mutations, {\r\n chapterId: ids.chapterId,\r\n pageId: ids.pageId,\r\n });\r\n }\r\n return { kind: 'navigate', to: action.to, transition: action.transition };\r\n\r\n case 'setVariables':\r\n this.variableStore.applyMutations(action.mutations, {\r\n chapterId: ids.chapterId,\r\n pageId: ids.pageId,\r\n });\r\n return { kind: 'none' };\r\n\r\n case 'openExtras':\r\n return { kind: 'openExtras', extrasId: action.extrasId };\r\n\r\n case 'openModal':\r\n return { kind: 'openModal', title: action.title, content: action.content };\r\n\r\n case 'pluginEvent':\r\n this.pluginHost.emitEventToPlugins(action.event, {\r\n pluginId: action.pluginId,\r\n payload: action.payload,\r\n });\r\n return { kind: 'none' };\r\n\r\n default:\r\n return { kind: 'none' };\r\n }\r\n }\r\n}\r\n","/**\r\n * Share Modal Component\r\n * Provides sharing options for panels\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n ChangeDetectorRef,\r\n OnDestroy,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\n\r\n/**\r\n * Share platform\r\n */\r\nexport type SharePlatform = 'twitter' | 'facebook' | 'reddit' | 'email' | 'copy' | 'qr' | 'native';\r\n\r\n/**\r\n * Share Modal Component\r\n * Modal for sharing content via various platforms\r\n */\r\n@Component({\r\n selector: 'pw-share-modal',\r\n imports: [TranslateModule, PwIconComponent],\r\n templateUrl: './share-modal.component.html',\r\n styleUrls: ['./share-modal.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class ShareModalComponent implements OnDestroy {\r\n private readonly cdr = inject(ChangeDetectorRef);\r\n\r\n /** Pending timer that clears the copy-success state */\r\n private copyResetTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n /**\r\n * URL to share\r\n */\r\n @Input() shareUrl = '';\r\n\r\n /**\r\n * Title to share\r\n */\r\n @Input() shareTitle = '';\r\n\r\n /**\r\n * Description to share\r\n */\r\n @Input() shareDescription = '';\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Panel is shareable\r\n */\r\n @Input() shareable = true;\r\n\r\n /**\r\n * Close modal\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * Share action triggered\r\n */\r\n @Output() share = new EventEmitter<SharePlatform>();\r\n\r\n /**\r\n * Copy status\r\n */\r\n copySuccess = false;\r\n\r\n /**\r\n * Show QR code\r\n */\r\n showQrCode = false;\r\n\r\n /**\r\n * QR code data URL\r\n */\r\n qrCodeDataUrl = '';\r\n\r\n /**\r\n * Copy link to clipboard\r\n */\r\n async copyLink(): Promise<void> {\r\n try {\r\n if (navigator.clipboard && navigator.clipboard.writeText) {\r\n await navigator.clipboard.writeText(this.shareUrl);\r\n this.markCopySuccess();\r\n } else {\r\n // Fallback for older browsers\r\n this.fallbackCopyTextToClipboard(this.shareUrl);\r\n }\r\n } catch (err) {\r\n console.error('Failed to copy:', err);\r\n }\r\n }\r\n\r\n /**\r\n * Show the copy-success state, emit 'copy', and reset it after 2 seconds.\r\n * The component is OnPush and both transitions happen outside an input/\r\n * template event, so each one must mark the view for check.\r\n */\r\n private markCopySuccess(): void {\r\n this.copySuccess = true;\r\n this.share.emit('copy');\r\n this.cdr.markForCheck();\r\n\r\n this.clearCopyResetTimer();\r\n this.copyResetTimer = setTimeout(() => {\r\n this.copyResetTimer = null;\r\n this.copySuccess = false;\r\n this.cdr.markForCheck();\r\n }, 2000);\r\n }\r\n\r\n private clearCopyResetTimer(): void {\r\n if (this.copyResetTimer !== null) {\r\n clearTimeout(this.copyResetTimer);\r\n this.copyResetTimer = null;\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.clearCopyResetTimer();\r\n }\r\n\r\n /**\r\n * Fallback copy method for older browsers\r\n */\r\n private fallbackCopyTextToClipboard(text: string): void {\r\n const textArea = document.createElement('textarea');\r\n textArea.value = text;\r\n textArea.style.position = 'fixed';\r\n textArea.style.top = '0';\r\n textArea.style.left = '0';\r\n textArea.style.opacity = '0';\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n\r\n try {\r\n const successful = document.execCommand('copy');\r\n if (successful) {\r\n this.markCopySuccess();\r\n }\r\n } catch (err) {\r\n console.error('Fallback copy failed:', err);\r\n }\r\n\r\n document.body.removeChild(textArea);\r\n }\r\n\r\n /**\r\n * Share on Twitter\r\n */\r\n shareOnTwitter(): void {\r\n const text = encodeURIComponent(this.shareTitle || this.shareDescription);\r\n const url = encodeURIComponent(this.shareUrl);\r\n const twitterUrl = `https://twitter.com/intent/tweet?text=${text}&url=${url}`;\r\n window.open(twitterUrl, '_blank', 'width=550,height=420');\r\n this.share.emit('twitter');\r\n }\r\n\r\n /**\r\n * Share on Facebook\r\n */\r\n shareOnFacebook(): void {\r\n const url = encodeURIComponent(this.shareUrl);\r\n const facebookUrl = `https://www.facebook.com/sharer/sharer.php?u=${url}`;\r\n window.open(facebookUrl, '_blank', 'width=550,height=420');\r\n this.share.emit('facebook');\r\n }\r\n\r\n /**\r\n * Share on Reddit\r\n */\r\n shareOnReddit(): void {\r\n const title = encodeURIComponent(this.shareTitle);\r\n const url = encodeURIComponent(this.shareUrl);\r\n const redditUrl = `https://www.reddit.com/submit?title=${title}&url=${url}`;\r\n window.open(redditUrl, '_blank', 'width=550,height=500');\r\n this.share.emit('reddit');\r\n }\r\n\r\n /**\r\n * Share via Email\r\n */\r\n shareViaEmail(): void {\r\n const subject = encodeURIComponent(this.shareTitle);\r\n const body = encodeURIComponent(\r\n `${this.shareDescription}\\n\\n${this.shareUrl}`\r\n );\r\n const mailtoUrl = `mailto:?subject=${subject}&body=${body}`;\r\n window.location.href = mailtoUrl;\r\n this.share.emit('email');\r\n }\r\n\r\n /**\r\n * Toggle QR code display\r\n */\r\n toggleQrCode(): void {\r\n this.showQrCode = !this.showQrCode;\r\n \r\n if (this.showQrCode && !this.qrCodeDataUrl) {\r\n this.generateQrCode();\r\n }\r\n \r\n if (this.showQrCode) {\r\n this.share.emit('qr');\r\n }\r\n }\r\n\r\n /**\r\n * Generate QR code\r\n * Uses a simple QR code API service\r\n */\r\n private generateQrCode(): void {\r\n // Using a public QR code API\r\n const size = 256;\r\n const url = encodeURIComponent(this.shareUrl);\r\n this.qrCodeDataUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${url}`;\r\n }\r\n\r\n /**\r\n * Use native share API if available\r\n */\r\n async useNativeShare(): Promise<void> {\r\n if (navigator.share) {\r\n try {\r\n await navigator.share({\r\n title: this.shareTitle,\r\n text: this.shareDescription,\r\n url: this.shareUrl,\r\n });\r\n this.share.emit('native');\r\n } catch (err) {\r\n // User cancelled or share failed\r\n console.log('Share cancelled:', err);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Check if native share is supported\r\n */\r\n get isNativeShareSupported(): boolean {\r\n return !!(navigator.share);\r\n }\r\n\r\n /**\r\n * Close modal\r\n */\r\n onClose(): void {\r\n this.showQrCode = false;\r\n this.copySuccess = false;\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n this.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Handle backdrop keyboard interaction\r\n */\r\n onBackdropKeydown(event: KeyboardEvent): void {\r\n if (event.target === event.currentTarget && \r\n (event.key === 'Enter' || event.key === ' ')) {\r\n event.preventDefault();\r\n this.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Handle keyboard events\r\n */\r\n @HostListener('window:keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent): void {\r\n if (!this.visible) return;\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n this.onClose();\r\n }\r\n }\r\n}\r\n","@if (visible) {\r\n <div class=\"share-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown)=\"onBackdropKeydown($event)\">\r\n <div class=\"share-container\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Share\">\r\n <!-- Header -->\r\n <div class=\"share-header\">\r\n <h2 class=\"share-title\">{{ 'share.title' | translate }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'share.close' | translate\"\r\n (click)=\"onClose()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"share-content\">\r\n @if (!shareable) {\r\n <!-- Not shareable message -->\r\n <div class=\"not-shareable\">\r\n <span class=\"warning-icon\"><pw-icon name=\"lucideTriangleAlert\" /></span>\r\n <p>{{ 'share.not_shareable' | translate }}</p>\r\n </div>\r\n } @else {\r\n <!-- Copy Link -->\r\n <div class=\"share-section\">\r\n <h3 class=\"section-title\">{{ 'share.copy_link' | translate }}</h3>\r\n <div class=\"link-container\">\r\n <input\r\n type=\"text\"\r\n class=\"link-input\"\r\n [value]=\"shareUrl\"\r\n readonly\r\n [attr.aria-label]=\"'share.share_url' | translate\" />\r\n <button\r\n class=\"copy-btn\"\r\n [class.success]=\"copySuccess\"\r\n type=\"button\"\r\n (click)=\"copyLink()\">\r\n <pw-icon [name]=\"copySuccess ? 'lucideCheck' : 'lucideClipboard'\" />\r\n {{ copySuccess ? ('share.copied' | translate) : ('share.copy' | translate) }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Native Share (if supported) -->\r\n @if (isNativeShareSupported) {\r\n <div class=\"share-section\">\r\n <button\r\n class=\"native-share-btn\"\r\n type=\"button\"\r\n (click)=\"useNativeShare()\">\r\n <span class=\"btn-icon\"><pw-icon name=\"lucideShare2\" /></span>\r\n <span class=\"btn-label\">{{ 'share.share_via' | translate }}</span>\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- Social Share Buttons -->\r\n <div class=\"share-section\">\r\n <h3 class=\"section-title\">{{ 'share.social_media' | translate }}</h3>\r\n <div class=\"social-buttons\">\r\n <button\r\n class=\"social-btn twitter\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Share on ' + ('share.twitter' | translate)\"\r\n (click)=\"shareOnTwitter()\">\r\n <span class=\"social-icon\">𝕏</span>\r\n <span class=\"social-label\">{{ 'share.twitter' | translate }}</span>\r\n </button>\r\n\r\n <button\r\n class=\"social-btn facebook\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Share on ' + ('share.facebook' | translate)\"\r\n (click)=\"shareOnFacebook()\">\r\n <span class=\"social-icon\">f</span>\r\n <span class=\"social-label\">{{ 'share.facebook' | translate }}</span>\r\n </button>\r\n\r\n <button\r\n class=\"social-btn reddit\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Share on ' + ('share.reddit' | translate)\"\r\n (click)=\"shareOnReddit()\">\r\n <span class=\"social-icon\">▲</span>\r\n <span class=\"social-label\">{{ 'share.reddit' | translate }}</span>\r\n </button>\r\n\r\n <button\r\n class=\"social-btn email\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Share via ' + ('share.email' | translate)\"\r\n (click)=\"shareViaEmail()\">\r\n <span class=\"social-icon\"><pw-icon name=\"lucideMail\" /></span>\r\n <span class=\"social-label\">{{ 'share.email' | translate }}</span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- QR Code -->\r\n <div class=\"share-section\">\r\n <button\r\n class=\"qr-toggle-btn\"\r\n type=\"button\"\r\n (click)=\"toggleQrCode()\">\r\n <span class=\"btn-icon\"><pw-icon [name]=\"showQrCode ? 'lucideChevronDown' : 'lucideChevronRight'\" /></span>\r\n <span class=\"btn-label\">{{ showQrCode ? ('share.hide_qr' | translate) : ('share.show_qr' | translate) }}</span>\r\n </button>\r\n\r\n @if (showQrCode) {\r\n <div class=\"qr-code-container\">\r\n @if (qrCodeDataUrl) {\r\n <img\r\n [src]=\"qrCodeDataUrl\"\r\n [alt]=\"'share.qr_code' | translate\"\r\n class=\"qr-code-image\" />\r\n <p class=\"qr-hint\">{{ 'share.scan_mobile' | translate }}</p>\r\n } @else {\r\n <div class=\"qr-loading\">{{ 'share.generating_qr' | translate }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Share Info -->\r\n <div class=\"share-info\">\r\n <p class=\"info-text\">\r\n <pw-icon name=\"lucideInfo\" /> {{ 'share.share_info' | translate }}\r\n </p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n","/**\r\n * Comments Drawer Component\r\n * Side drawer for viewing and posting comments\r\n */\r\n\r\nimport {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectionStrategy,\r\n HostListener,\r\n inject,\r\n} from '@angular/core';\r\n\r\nimport { TranslateModule, TranslateService } from '@ngx-translate/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { PwIconComponent } from '../../icon/pw-icon.component';\r\n\r\n/**\r\n * Comment interface\r\n */\r\nexport interface Comment {\r\n id: string;\r\n author: string;\r\n authorAvatar?: string;\r\n content: string;\r\n timestamp: Date;\r\n likes?: number;\r\n isLiked?: boolean;\r\n replies?: Comment[];\r\n}\r\n\r\n/**\r\n * Comment post event\r\n */\r\nexport interface CommentPost {\r\n content: string;\r\n replyTo?: string;\r\n}\r\n\r\n/**\r\n * Comments Drawer Component\r\n * Side drawer for comment interaction\r\n */\r\n@Component({\r\n selector: 'pw-comments-drawer',\r\n imports: [FormsModule, TranslateModule, PwIconComponent],\r\n templateUrl: './comments-drawer.component.html',\r\n styleUrls: ['./comments-drawer.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class CommentsDrawerComponent {\r\n private readonly translate = inject(TranslateService);\r\n\r\n /**\r\n * List of comments\r\n */\r\n @Input() comments: Comment[] = [];\r\n\r\n /**\r\n * Visible state\r\n */\r\n @Input() visible = false;\r\n\r\n /**\r\n * Loading state\r\n */\r\n @Input() loading = false;\r\n\r\n /**\r\n * Current page\r\n */\r\n @Input() currentPage = 1;\r\n\r\n /**\r\n * Total pages\r\n */\r\n @Input() totalPages = 1;\r\n\r\n /**\r\n * Has more comments\r\n */\r\n @Input() hasMore = false;\r\n\r\n /**\r\n * User is authenticated\r\n */\r\n @Input() isAuthenticated = false;\r\n\r\n /**\r\n * Post comment\r\n */\r\n @Output() postComment = new EventEmitter<CommentPost>();\r\n\r\n /**\r\n * Load more comments\r\n */\r\n @Output() loadMore = new EventEmitter<number>();\r\n\r\n /**\r\n * Like comment\r\n */\r\n @Output() likeComment = new EventEmitter<string>();\r\n\r\n /**\r\n * Close drawer\r\n */\r\n @Output() close = new EventEmitter<void>();\r\n\r\n /**\r\n * New comment content\r\n */\r\n newCommentContent = '';\r\n\r\n /**\r\n * Reply target\r\n */\r\n replyTarget?: Comment;\r\n\r\n /**\r\n * Show reply composer\r\n */\r\n showReplyComposer = false;\r\n\r\n /**\r\n * Reply content\r\n */\r\n replyContent = '';\r\n\r\n /**\r\n * Post new comment\r\n */\r\n submitComment(): void {\r\n const content = this.newCommentContent.trim();\r\n if (!content || !this.isAuthenticated) {\r\n return;\r\n }\r\n\r\n this.postComment.emit({ content });\r\n this.newCommentContent = '';\r\n }\r\n\r\n /**\r\n * Start reply to comment\r\n */\r\n startReply(comment: Comment): void {\r\n this.replyTarget = comment;\r\n this.showReplyComposer = true;\r\n this.replyContent = '';\r\n }\r\n\r\n /**\r\n * Cancel reply\r\n */\r\n cancelReply(): void {\r\n this.replyTarget = undefined;\r\n this.showReplyComposer = false;\r\n this.replyContent = '';\r\n }\r\n\r\n /**\r\n * Submit reply\r\n */\r\n submitReply(): void {\r\n const content = this.replyContent.trim();\r\n if (!content || !this.replyTarget || !this.isAuthenticated) {\r\n return;\r\n }\r\n\r\n this.postComment.emit({\r\n content,\r\n replyTo: this.replyTarget.id,\r\n });\r\n\r\n this.cancelReply();\r\n }\r\n\r\n /**\r\n * Like a comment\r\n */\r\n onLikeComment(comment: Comment): void {\r\n if (!this.isAuthenticated) {\r\n return;\r\n }\r\n this.likeComment.emit(comment.id);\r\n }\r\n\r\n /**\r\n * Load next page\r\n */\r\n onLoadMore(): void {\r\n if (this.hasMore && !this.loading) {\r\n this.loadMore.emit(this.currentPage + 1);\r\n }\r\n }\r\n\r\n /**\r\n * Format timestamp\r\n */\r\n formatTimestamp(date: Date): string {\r\n const now = new Date();\r\n const diff = now.getTime() - date.getTime();\r\n const seconds = Math.floor(diff / 1000);\r\n const minutes = Math.floor(seconds / 60);\r\n const hours = Math.floor(minutes / 60);\r\n const days = Math.floor(hours / 24);\r\n\r\n if (seconds < 60) {\r\n return this.t('comments.just_now', 'Just now');\r\n } else if (minutes < 60) {\r\n return this.t('comments.minutes_ago', '{{count}}m ago', minutes);\r\n } else if (hours < 24) {\r\n return this.t('comments.hours_ago', '{{count}}h ago', hours);\r\n } else if (days < 7) {\r\n return this.t('comments.days_ago', '{{count}}d ago', days);\r\n } else {\r\n return date.toLocaleDateString();\r\n }\r\n }\r\n\r\n /**\r\n * Translate a relative-time key; falls back to the English template when the\r\n * key is not (yet) loaded so the output never degrades to the raw key.\r\n */\r\n private t(key: string, fallback: string, count?: number): string {\r\n const params = count === undefined ? undefined : { count };\r\n const value = this.translate.instant(key, params) as unknown;\r\n if (typeof value === 'string' && value !== key) {\r\n return value;\r\n }\r\n return fallback.replace('{{count}}', String(count));\r\n }\r\n\r\n /**\r\n * Get author initials\r\n */\r\n getAuthorInitials(author: string): string {\r\n const words = (author ?? '').split(/\\s+/).filter((word) => word.length > 0);\r\n if (words.length === 0) {\r\n return '?';\r\n }\r\n if (words.length >= 2) {\r\n return (words[0][0] + words[1][0]).toUpperCase();\r\n }\r\n return words[0].substring(0, 2).toUpperCase();\r\n }\r\n\r\n /**\r\n * Close drawer\r\n */\r\n onClose(): void {\r\n this.cancelReply();\r\n this.close.emit();\r\n }\r\n\r\n /**\r\n * Handle backdrop click\r\n */\r\n onBackdropClick(event: MouseEvent): void {\r\n if (event.target === event.currentTarget) {\r\n this.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Handle backdrop keyboard interaction\r\n */\r\n onBackdropKeydown(event: KeyboardEvent): void {\r\n if (event.target === event.currentTarget && \r\n (event.key === 'Enter' || event.key === ' ')) {\r\n event.preventDefault();\r\n this.onClose();\r\n }\r\n }\r\n\r\n /**\r\n * Handle keyboard events\r\n */\r\n @HostListener('window:keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent): void {\r\n if (!this.visible) return;\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n if (this.showReplyComposer) {\r\n this.cancelReply();\r\n } else {\r\n this.onClose();\r\n }\r\n }\r\n }\r\n}\r\n","@if (visible) {\r\n <div class=\"drawer-overlay\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown)=\"onBackdropKeydown($event)\">\r\n <div class=\"drawer-container\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Comments\">\r\n <!-- Header -->\r\n <div class=\"drawer-header\">\r\n <h2 class=\"drawer-title\">{{ 'comments.title' | translate }}</h2>\r\n <button\r\n class=\"close-btn\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'comments.close' | translate\"\r\n (click)=\"onClose()\">\r\n <pw-icon name=\"lucideX\" />\r\n </button>\r\n </div>\r\n\r\n <!-- Comment Composer (Top) -->\r\n @if (isAuthenticated) {\r\n <div class=\"comment-composer\">\r\n <textarea\r\n class=\"composer-input\"\r\n [placeholder]=\"'comments.write_comment' | translate\"\r\n rows=\"3\"\r\n [(ngModel)]=\"newCommentContent\"\r\n [attr.aria-label]=\"'comments.new_comment_label' | translate\"></textarea>\r\n <div class=\"composer-actions\">\r\n <button\r\n class=\"post-btn\"\r\n type=\"button\"\r\n [disabled]=\"!newCommentContent.trim()\"\r\n (click)=\"submitComment()\">\r\n {{ 'comments.post_comment' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"auth-notice\">\r\n <p>{{ 'comments.sign_in' | translate }}</p>\r\n </div>\r\n }\r\n\r\n <!-- Comments List -->\r\n <div class=\"comments-content\">\r\n @if (loading && comments.length === 0) {\r\n <div class=\"loading-state\">\r\n <div class=\"loading-spinner\"></div>\r\n <p>{{ 'comments.loading' | translate }}</p>\r\n </div>\r\n } @else if (comments.length === 0) {\r\n <div class=\"empty-state\">\r\n <span class=\"empty-icon\"><pw-icon name=\"lucideMessageCircle\" /></span>\r\n <p>{{ 'comments.no_comments' | translate }}</p>\r\n </div>\r\n } @else {\r\n <div class=\"comments-list\">\r\n @for (comment of comments; track comment.id) {\r\n <div class=\"comment-item\">\r\n <!-- Avatar -->\r\n <div class=\"comment-avatar\">\r\n @if (comment.authorAvatar) {\r\n <img\r\n [src]=\"comment.authorAvatar\"\r\n [alt]=\"comment.author\"\r\n class=\"avatar-image\" />\r\n } @else {\r\n <div class=\"avatar-placeholder\">\r\n {{ getAuthorInitials(comment.author) }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"comment-content\">\r\n <div class=\"comment-header\">\r\n <span class=\"comment-author\">{{ comment.author }}</span>\r\n <span class=\"comment-timestamp\">{{ formatTimestamp(comment.timestamp) }}</span>\r\n </div>\r\n\r\n <p class=\"comment-text\">{{ comment.content }}</p>\r\n\r\n <!-- Actions -->\r\n <div class=\"comment-actions\">\r\n @if (isAuthenticated) {\r\n <button\r\n class=\"action-btn\"\r\n [class.active]=\"comment.isLiked\"\r\n type=\"button\"\r\n (click)=\"onLikeComment(comment)\">\r\n <pw-icon name=\"lucideHeart\" />\r\n @if (comment.likes && comment.likes > 0) {\r\n <span>{{ comment.likes }}</span>\r\n }\r\n </button>\r\n\r\n <button\r\n class=\"action-btn\"\r\n type=\"button\"\r\n (click)=\"startReply(comment)\">\r\n {{ 'comments.reply' | translate }}\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Replies -->\r\n @if (comment.replies && comment.replies.length > 0) {\r\n <div class=\"comment-replies\">\r\n @for (reply of comment.replies; track reply.id) {\r\n <div class=\"reply-item\">\r\n <div class=\"comment-avatar small\">\r\n @if (reply.authorAvatar) {\r\n <img\r\n [src]=\"reply.authorAvatar\"\r\n [alt]=\"reply.author\"\r\n class=\"avatar-image\" />\r\n } @else {\r\n <div class=\"avatar-placeholder\">\r\n {{ getAuthorInitials(reply.author) }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"comment-content\">\r\n <div class=\"comment-header\">\r\n <span class=\"comment-author\">{{ reply.author }}</span>\r\n <span class=\"comment-timestamp\">{{ formatTimestamp(reply.timestamp) }}</span>\r\n </div>\r\n <p class=\"comment-text\">{{ reply.content }}</p>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Reply Composer -->\r\n @if (showReplyComposer && replyTarget?.id === comment.id) {\r\n <div class=\"reply-composer\">\r\n <textarea\r\n class=\"composer-input\"\r\n [placeholder]=\"'comments.write_reply' | translate\"\r\n rows=\"2\"\r\n [(ngModel)]=\"replyContent\"\r\n [attr.aria-label]=\"'comments.reply_label' | translate\"></textarea>\r\n <div class=\"composer-actions\">\r\n <button\r\n class=\"cancel-btn\"\r\n type=\"button\"\r\n (click)=\"cancelReply()\">\r\n {{ 'comments.cancel' | translate }}\r\n </button>\r\n <button\r\n class=\"post-btn\"\r\n type=\"button\"\r\n [disabled]=\"!replyContent.trim()\"\r\n (click)=\"submitReply()\">\r\n {{ 'comments.reply' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Load More -->\r\n @if (hasMore) {\r\n <div class=\"load-more\">\r\n @if (loading) {\r\n <div class=\"loading-spinner small\"></div>\r\n } @else {\r\n <button\r\n class=\"load-more-btn\"\r\n type=\"button\"\r\n (click)=\"onLoadMore()\">\r\n {{ 'comments.load_more' | translate }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Footer Info -->\r\n <div class=\"drawer-footer\">\r\n <p class=\"footer-text\">\r\n {{ comments.length }} {{ comments.length === 1 ? ('comments.comment_count_singular' | translate) : ('comments.comment_count_plural' | translate) }}\r\n @if (totalPages > 1) {\r\n <span> • {{ 'comments.page_of' | translate: {current: currentPage, total: totalPages} }}</span>\r\n }\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n","/**\n * Player Shell Component\n * Main container component that orchestrates the entire PanelWave player\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n HostListener,\n inject,\n} from '@angular/core';\n\nimport { HttpClient } from '@angular/common/http';\nimport { Subject, takeUntil } from 'rxjs';\nimport { TranslateModule, TranslateLoader } from '@ngx-translate/core';\nimport { CustomTranslateLoader } from '../../utils/translation-loader';\n\nimport { PlayerEvent } from '../../types';\nimport type {\n PanelWaveManifest,\n Panel,\n Page,\n Chapter,\n LocaleCode,\n Character as ManifestCharacter,\n Transition,\n VideoLayer,\n VideoTrackingPayload,\n CameraMove,\n ViewMode,\n BalloonConfig,\n Hotspot,\n VariableContext,\n VariableDefinition,\n LocalizedString,\n} from '../../types';\nimport type { Character as RosterCharacter } from '../modals/character-roster/character-roster.component';\n\nimport { PlayerStateService } from '../../services/player-state.service';\nimport { ManifestService } from '../../services/manifest.service';\nimport { VariableStoreService } from '../../services/variable-store.service';\nimport { FlowEngineService } from '../../services/flow-engine.service';\nimport { TranslationService } from '../../services/translation.service';\nimport { TrackingService } from '../../services/tracking.service';\nimport { VideoControllerService } from '../../services/video-controller.service';\nimport { VideoSequencerService } from '../../services/video-sequencer.service';\nimport { resolveStartMode } from '../../utils/video-config-utils';\nimport { shouldReduceMotion } from '../../utils/animation-utils';\nimport { evaluateJsonLogic } from '../../utils/json-logic-utils';\nimport { resolvePanelVariant, resolvePanels } from '../../utils/variant-utils';\nimport { extrasFromManifest, type CatalogLike } from '../../utils/extras-utils';\n\nimport { ViewportComponent } from '../viewport/viewport.component';\nimport { CanvasStageComponent } from '../canvas-stage/canvas-stage.component';\nimport { CanvasCameraService, CameraState } from '../../services/canvas-camera.service';\nimport { ToolbarComponent } from '../toolbar/toolbar.component';\nimport { LanguageModalComponent } from '../modals/language-modal/language-modal.component';\nimport { ThumbnailStripComponent } from '../overlays/thumbnail-strip/thumbnail-strip.component';\nimport { TocOverlayComponent } from '../modals/toc-overlay/toc-overlay.component';\nimport {\n PaywallOverlayComponent,\n type PaywallAction,\n} from '../overlays/paywall-overlay/paywall-overlay.component';\nimport { PaywallService } from '../../services/paywall.service';\nimport { HttpEntitlementAdapter } from '../../entitlement/http-entitlement.adapter';\nimport type { EntitlementSnapshot } from '../../entitlement/paywall-evaluator';\nimport type { PaywallGate } from '../../types/entitlement.types';\nimport { SettingsModalComponent, type Preferences } from '../modals/settings-modal/settings-modal.component';\nimport { AudioEngineService } from '../../services/audio-engine.service';\nimport { PanelAudioService } from '../../services/panel-audio.service';\nimport { CharacterRosterComponent } from '../modals/character-roster/character-roster.component';\nimport { ExtrasViewerComponent, type Extra } from '../modals/extras-viewer/extras-viewer.component';\nimport { ActionModalComponent } from '../modals/action-modal/action-modal.component';\nimport { AgeGateComponent, type AgeVerificationResult } from '../overlays/age-gate/age-gate.component';\nimport { BranchChooserComponent, type BranchChoice } from '../modals/branch-chooser/branch-chooser.component';\nimport { HotspotActionService, type HotspotUiEffect } from '../../services/hotspot-action.service';\nimport { ShareModalComponent } from '../modals/share-modal/share-modal.component';\nimport { CommentsDrawerComponent } from '../modals/comments-drawer/comments-drawer.component';\nimport { PwIconComponent } from '../icon/pw-icon.component';\n\n/**\n * Factory function for TranslateLoader\n */\nexport function createTranslateLoader(http: HttpClient): TranslateLoader {\n // Use CustomTranslateLoader to load JSON translation files\n return new CustomTranslateLoader(http);\n}\n\n/**\n * Entitlement adapter interface\n * Provides entitlement and paywall functionality\n */\nexport interface EntitlementAdapter {\n /**\n * Check if user has access to a specific panel\n */\n hasAccess(panelId: string): Promise<boolean>;\n\n /**\n * Get entitlement context\n */\n getContext(): Promise<Record<string, unknown>>;\n\n /**\n * Handle purchase flow\n */\n purchase?(productId: string): Promise<boolean>;\n}\n\n/**\n * Player Shell Component\n * Main orchestrator for the PanelWave player\n */\n@Component({\n selector: 'pw-player-shell',\n providers: [CanvasCameraService],\n imports: [\n TranslateModule,\n ViewportComponent,\n CanvasStageComponent,\n ToolbarComponent,\n ThumbnailStripComponent,\n TocOverlayComponent,\n PaywallOverlayComponent,\n SettingsModalComponent,\n LanguageModalComponent,\n CharacterRosterComponent,\n ExtrasViewerComponent,\n ActionModalComponent,\n AgeGateComponent,\n BranchChooserComponent,\n ShareModalComponent,\n CommentsDrawerComponent,\n PwIconComponent\n],\n templateUrl: './player-shell.component.html',\n styleUrls: ['./player-shell.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class PlayerShellComponent implements OnInit, OnDestroy {\n /**\n * Manifest to load\n */\n @Input() manifest?: PanelWaveManifest;\n\n /**\n * Manifest URL (alternative to providing manifest directly)\n */\n @Input() manifestUrl?: string;\n\n /**\n * Entitlement adapter for paywall integration\n */\n @Input() entitlementAdapter?: EntitlementAdapter;\n\n /**\n * What the reader owns. Supplying this switches the manifest's\n * `paywall.rules` on: gated panels stop navigation and raise the paywall\n * overlay instead of erroring out.\n *\n * Omit it and an anonymous snapshot is used, which is the correct default —\n * a reader who has bought nothing sees the free preview and the gate. A\n * work with no paywall rules is unaffected either way.\n */\n @Input() entitlementSnapshot?: EntitlementSnapshot;\n\n /**\n * Endpoint that returns the reader's entitlement snapshot, with `{workId}`\n * substituted. When set, the shell fetches the snapshot itself instead of\n * the host passing `entitlementSnapshot`.\n */\n @Input() entitlementEndpoint?: string;\n\n /** Bearer token identifying the reader to `entitlementEndpoint`. */\n @Input() readerToken?: string;\n\n /**\n * Emitted when a reader acts on the paywall overlay. The host owns\n * checkout — the player never talks to a payment provider itself.\n */\n @Output() paywallAction = new EventEmitter<{ action: PaywallAction; gate: PaywallGate }>();\n\n /**\n * Emitted after the reader answers an `age_gate` rule's overlay (verified or\n * not). The result is also persisted on the device so returning readers are\n * not asked again.\n */\n @Output() ageVerified = new EventEmitter<AgeVerificationResult>();\n\n /**\n * Emitted when the reader likes / unlikes the work. The like is persisted\n * locally (per work); a host with accounts may mirror it server-side.\n */\n @Output() likeChange = new EventEmitter<{ workId: string; liked: boolean }>();\n\n /**\n * Emitted when the reader sets / clears the bookmark. The bookmark is\n * persisted locally (per work) and resumed on the next load when the host\n * gives no explicit initial position.\n */\n @Output() bookmarkChange = new EventEmitter<{\n workId: string;\n chapterId: string;\n panelId: string;\n bookmarked: boolean;\n }>();\n\n /**\n * Host-supplied initial variable values, keyed by variable id and\n * applied once at initialization through a privileged path: unlike\n * runtime mutations, these MAY seed variables the manifest declares\n * `readOnly` — the intended channel for externally-sourced facts\n * (e.g. a verified `user.age` from the host's account system) that\n * in-story content and the settings UI must not be able to change.\n * Values land in each definition's declared scope (global for\n * undeclared ids); the entitlement adapter's context is applied after\n * and wins on collisions.\n */\n @Input() initialVariables?: Record<string, unknown>;\n\n /**\n * Initial locale\n */\n @Input() locale: LocaleCode = 'en-US';\n\n /**\n * Initial chapter ID\n */\n @Input() initialChapterId?: string;\n\n /**\n * Initial panel ID\n */\n @Input() initialPanelId?: string;\n\n /**\n * Enable autoplay\n */\n @Input() autoplay = false;\n\n /**\n * Seconds per panel in autoplay mode\n */\n @Input() secondsPerPanel = 5;\n\n /**\n * Force reduced motion (host override). Reduced motion is also on when the\n * reader enabled it in Settings or the OS asks for it — see `motionReduced`.\n */\n @Input() reducedMotion = false;\n\n /** The reader's in-player \"Reduced motion\" preference (Settings). */\n private prefReducedMotion = false;\n /** Live `prefers-reduced-motion: reduce` media query. */\n private osReducedMotion = shouldReduceMotion();\n private reducedMotionQuery?: MediaQueryList;\n private readonly onReducedMotionQueryChange = (e: MediaQueryListEvent): void => {\n this.osReducedMotion = e.matches;\n this.cdr.markForCheck();\n };\n\n /**\n * Effective reduced-motion state for every transition the shell drives\n * (panel/page transitions in the viewport, canvas camera glides): the host\n * input, the reader's setting, or the OS preference.\n */\n get motionReduced(): boolean {\n return this.reducedMotion || this.prefReducedMotion || this.osReducedMotion;\n }\n\n /**\n * Show toolbar by default\n */\n @Input() showToolbar = false;\n\n /**\n * View-mode override for hosts (e.g. the CMS preview harness):\n * 'auto' (default) keeps the manifest-driven behavior (canvas chapters\n * auto-enter canvas view); 'panel' forces classic panel view; 'canvas'\n * enters canvas view whenever the chapter allows it.\n */\n @Input() viewModeOverride: 'auto' | 'panel' | 'canvas' = 'auto';\n\n /**\n * Player ready\n */\n @Output() ready = new EventEmitter<void>();\n\n /**\n * Panel changed\n */\n @Output() panelChange = new EventEmitter<{ panel: Panel; chapter: Chapter }>();\n\n /**\n * Chapter changed\n */\n @Output() chapterChange = new EventEmitter<Chapter>();\n\n /**\n * Error occurred\n */\n @Output() error = new EventEmitter<Error>();\n\n /**\n * Locale changed\n */\n @Output() localeChange = new EventEmitter<LocaleCode>();\n\n /**\n * Variable changed\n */\n @Output() variableChange = new EventEmitter<{ key: string; value: unknown }>();\n\n /**\n * Navigation attempted\n */\n @Output() navigationAttempt = new EventEmitter<{ direction: 'next' | 'previous' | 'panel'; target?: string }>();\n\n /**\n * Camera moved in canvas view (throttled).\n */\n @Output() cameraChange = new EventEmitter<CameraState>();\n\n /**\n * Destroy subject\n */\n private destroy$ = new Subject<void>();\n\n /**\n * Loading state\n */\n loading = true;\n\n /**\n * Error state\n */\n hasError = false;\n\n /**\n * Error message\n */\n errorMessage = '';\n\n /**\n * Current panel\n */\n currentPanel?: Panel;\n\n /**\n * Transition for the current panel change, passed to the viewport\n * (resolved edge transition on next, reversed edge transition on\n * previous, null for jumps).\n */\n viewportTransition: Transition | null = null;\n\n /**\n * Current page (for page view)\n */\n currentPage?: Page;\n\n /**\n * Current chapter\n */\n currentChapter?: Chapter;\n\n /**\n * Toolbar visibility\n */\n toolbarVisible = false;\n\n /**\n * Modal visibility states\n */\n tocVisible = false;\n\n /**\n * Gate blocking the panel the reader tried to open, or null.\n *\n * Held locally rather than in PlayerStateService: the library contains TWO\n * classes of that name — `services/player-state.service.ts` (the one this\n * shell injects and public-api exports) and `state/player-state.service.ts`\n * (which has paywallGate state and showPaywallGate/hidePaywallGate, but is\n * exported nowhere and used by nothing). Reconciling them is a separate\n * change; wiring the paywall through the dead one would be worse than\n * keeping this local.\n */\n paywallGate: PaywallGate | null = null;\n paywallVisible = false;\n /** Adapter built from `entitlementEndpoint`, when the host supplied one. */\n private httpEntitlement?: HttpEntitlementAdapter;\n\n /**\n * Age gate raised by an `age_gate` paywall rule. The navigation it\n * interrupted is remembered and resumed once the reader passes.\n */\n ageGateVisible = false;\n ageGateMinimumAge = 18;\n private pendingAgeGatedNavigation: {\n chapterId: string;\n panelId: string;\n transition?: Transition;\n cameraMove?: CameraMove;\n } | null = null;\n\n /** Reader's like / bookmark for this work (persisted per work on the device). */\n liked = false;\n bookmarked = false;\n\n /** Branch chooser (\"Choices\" toolbar button). */\n branchChooserVisible = false;\n branchChoices: BranchChoice[] = [];\n settingsVisible = false;\n languageModalVisible = false;\n charactersVisible = false;\n extrasVisible = false;\n shareVisible = false;\n commentsVisible = false;\n thumbnailsVisible = false;\n\n /**\n * Action modal state (hotspot openModal action)\n */\n actionModalVisible = false;\n actionModalTitle: LocalizedString | null = null;\n actionModalContent: LocalizedString | null = null;\n\n /**\n * Extras flattened from the manifest's keyed blocks, plus the item a\n * hotspot openExtras action wants preselected\n */\n extrasList: Extra[] = [];\n extrasInitialId?: string;\n\n /**\n * Variable context passed to the viewport/canvas for hotspot visibleIf\n * evaluation. Refreshed on navigation and after mutations are applied.\n */\n variableContext: VariableContext | null = null;\n\n /**\n * Variant-resolved view of the current panel: what the viewport\n * renders and what autoplay/video timing read. Equals `currentPanel`\n * (same reference) when no variant applies. `currentPanel` itself\n * stays the raw manifest panel — identity comparisons depend on it.\n */\n effectivePanel?: Panel;\n\n /** Id of the variant applied to the current panel, if any. */\n activeVariantId?: string;\n\n /** Variant-resolved panels of the current chapter (page/canvas views). */\n resolvedPanels: Record<string, Panel> = {};\n\n /**\n * Manual variant selection per panel id (Alt toolbar cycling):\n * a variant id forces that variant, `null` forces the base panel,\n * absence means automatic condition-based selection. Session-scoped.\n */\n private readonly variantOverrides = new Map<string, string | null>();\n\n /**\n * The manifest's variable definitions (registered with the store at\n * init; passed to the settings modal's Variables tab).\n */\n variableDefinitions: VariableDefinition[] = [];\n\n /**\n * Snapshot of current variable values, rebuilt each time the settings\n * modal opens (the modal edits a local copy and emits on save).\n */\n settingsVariableValues: Record<string, unknown> = {};\n\n /**\n * View mode\n */\n viewMode: ViewMode = 'panel';\n\n /**\n * Page view available (has pages defined)\n */\n pageViewAvailable = false;\n\n /**\n * Canvas view available for the current chapter (chapter has a canvas\n * layout AND some output preset enables canvasView — schema 1.4).\n */\n canvasViewAvailable = false;\n\n /**\n * Panels the trail has visited in the current chapter (drives canvas\n * reveal modes and revisit-jumps).\n */\n visitedPanelIds: string[] = [];\n\n /**\n * Autoplay timer\n */\n private autoplayTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Autoplay enabled state\n */\n autoplayEnabled = false;\n\n /**\n * Speech-bubble toggle state. Every bubble is implicitly subject to this\n * (schema 1.3) — per-bubble visibleIf is reserved for story logic.\n * Initialized from the manifest's settings.ui.speechDefault.\n */\n speechEnabled = true;\n\n /**\n * Audio toggle state (master mute: every engine bus and video sound).\n * Reader preference when set, else the manifest's settings.ui.audioDefault.\n */\n audioEnabled = true;\n\n /**\n * SFX toggle state (sfx bus, which also carries `ui` sounds). Reader\n * preference when set, else the manifest's settings.ui.sfxDefault.\n */\n sfxEnabled = true;\n\n /**\n * Snapshot handed to the settings modal's Preferences tab (rebuilt on open).\n */\n settingsPreferences: Preferences = {\n speech: true,\n audio: true,\n sfx: true,\n autoplay: false,\n secondsPerPanel: 5,\n mangaMode: false,\n reducedMotion: false,\n highContrast: false,\n };\n\n /**\n * Autoplay progress (0-100)\n */\n autoplayProgress = 0;\n\n /**\n * Autoplay progress interval\n */\n private autoplayProgressInterval?: ReturnType<typeof setInterval>;\n\n /**\n * Autoplay start time\n */\n private autoplayStartTime = 0;\n\n /**\n * Autoplay duration for current panel\n */\n private autoplayDuration = 0;\n\n /**\n * Video layer ids of the current panel that still owe a pass completion\n * before autoplay may advance (panel view, video panels — §4.5). Empty when\n * the wall-clock timer drives the advance instead.\n */\n private pendingVideoPasses = new Set<string>();\n\n /**\n * Fallback watchdog for panel-view on-view video panels (§4.5): guards\n * against a video that never reports a pass (corrupt/unreachable source\n * stalling forever) by force-advancing after a bounded wait. Canceled\n * when every pending video's pass arrives first, or when autoplay stops.\n */\n private videoWatchdogTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * The panel the currently-armed watchdog belongs to. Any navigation away\n * from it invalidates a late-firing watchdog even if the timer itself\n * hasn't been cleared yet (belt-and-braces against a double advance).\n */\n private videoWatchdogPanel?: Panel;\n\n private readonly trackingService = inject(TrackingService);\n private readonly videoController = inject(VideoControllerService);\n private readonly videoSequencer = inject(VideoSequencerService);\n private readonly hotspotAction = inject(HotspotActionService);\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly audioEngine = inject(AudioEngineService);\n private readonly panelAudio = inject(PanelAudioService);\n\n /**\n * Reading order per panel id (1-based, across chapters), computed once per\n * manifest. Reported as `panelOrder` on panel_view / funnel events and as\n * `totalPanels` on session_start so the backend can compute exact\n * completion and funnel steps.\n */\n private analyticsPanelOrder = new Map<string, number>();\n private analyticsTotalPanels = 0;\n\n /** Analytics session lifecycle guards (one session per shell instance). */\n private analyticsSessionStarted = false;\n private analyticsSessionEnded = false;\n private workCompleteTracked = false;\n private lastTrackedPanelId?: string;\n\n /** Bound pagehide handler so add/removeEventListener match. */\n private readonly onPageHide = (): void => this.endAnalyticsSession();\n\n private readonly playerState = inject(PlayerStateService);\n private readonly manifestService = inject(ManifestService);\n private readonly variableStore = inject(VariableStoreService);\n private readonly flowEngine = inject(FlowEngineService);\n private readonly translationService = inject(TranslationService);\n private readonly canvasCamera = inject(CanvasCameraService);\n private readonly paywallService = inject(PaywallService);\n\n /**\n * Initialize component\n */\n ngOnInit(): void {\n this.toolbarVisible = this.showToolbar;\n this.watchReducedMotion();\n this.subscribeToVideoSignals();\n this.initializePlayer();\n // pagehide fires for both tab close and navigation (incl. bfcache) —\n // the last chance to flush the analytics queue.\n if (typeof window !== 'undefined') {\n window.addEventListener('pagehide', this.onPageHide);\n }\n }\n\n /**\n * Cleanup on destroy\n */\n ngOnDestroy(): void {\n if (typeof window !== 'undefined') {\n window.removeEventListener('pagehide', this.onPageHide);\n }\n this.reducedMotionQuery?.removeEventListener('change', this.onReducedMotionQueryChange);\n this.endAnalyticsSession();\n this.stopAutoplay();\n this.stopAutoplayProgress();\n this.videoSequencer.reset();\n this.panelAudio.stopAll();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Follow both reduced-motion sources that can change at runtime: the OS\n * media query and the reader's Settings preference.\n */\n private watchReducedMotion(): void {\n if (typeof window !== 'undefined' && window.matchMedia) {\n this.reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n this.osReducedMotion = this.reducedMotionQuery.matches;\n this.reducedMotionQuery.addEventListener('change', this.onReducedMotionQueryChange);\n }\n this.playerState.preferences$?.pipe(takeUntil(this.destroy$)).subscribe((prefs) => {\n const next = !!prefs.reducedMotion;\n if (next !== this.prefReducedMotion) {\n this.prefReducedMotion = next;\n this.cdr.markForCheck();\n }\n });\n }\n\n /**\n * Subscribe to the media-driven auto-advance signals:\n * - `VideoControllerService.passComplete$` drives panel-view advance for\n * video panels (precise, media-event based — §4.5);\n * - `VideoSequencerService.queueComplete` drives page-view advance once the\n * last visible on-view video finished one pass (§4.3 step 6).\n * Both only navigate while autoplay is enabled.\n */\n private subscribeToVideoSignals(): void {\n this.videoController.passComplete$\n .pipe(takeUntil(this.destroy$))\n .subscribe((videoId) => this.onVideoPassComplete(videoId));\n\n this.videoSequencer.queueComplete\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => this.onVideoQueueComplete());\n }\n\n /** Panel-view auto-advance for video panels (§4.5). */\n private onVideoPassComplete(videoId: string): void {\n if (\n !this.autoplayEnabled ||\n this.viewMode !== 'panel' ||\n this.pendingVideoPasses.size === 0 ||\n !this.pendingVideoPasses.has(videoId)\n ) {\n return;\n }\n this.pendingVideoPasses.delete(videoId);\n // Multiple video layers in one panel: advance when the longest pass\n // (i.e. the last outstanding video) completes.\n if (this.pendingVideoPasses.size > 0) {\n return;\n }\n // Media-driven advance won the race — the stall watchdog is now moot.\n this.clearVideoWatchdog();\n void this.navigateNext().then(() => {\n if (this.autoplayEnabled) {\n this.startAutoplay();\n }\n });\n }\n\n /** Page-view auto-advance when the video queue finishes (§4.3 step 6). */\n private onVideoQueueComplete(): void {\n if (!this.autoplayEnabled || this.viewMode !== 'page') {\n return;\n }\n this.navigateToNextPage();\n }\n\n /**\n * Initialize player\n */\n private async initializePlayer(): Promise<void> {\n try {\n this.loading = true;\n\n // Load manifest\n if (this.manifestUrl) {\n await this.loadManifestFromUrl(this.manifestUrl);\n } else if (this.manifest) {\n await this.manifestService.loadManifestFromObject(this.manifest).toPromise();\n } else {\n throw new Error('No manifest or manifestUrl provided');\n }\n\n // Register the manifest's variable definitions: initializes defaults\n // and arms type validation + the read-only guard for every later\n // set()/mutation.\n this.variableDefinitions = this.extractVariableDefinitions();\n this.variableStore.setDefinitions(this.variableDefinitions);\n\n // Host-supplied initial values (privileged: may seed read-only vars).\n if (this.initialVariables) {\n this.variableStore.seed(this.initialVariables);\n }\n\n // Arm the paywall: rules come from the manifest, the snapshot from the\n // host (or from entitlementEndpoint). A work with no paywall.rules is\n // unaffected — PaywallService reports every panel accessible.\n await this.configurePaywall();\n\n // Initialize entitlement context. Seeded (not set()) so entitlement\n // facts can populate read-only variables; applied after\n // initialVariables so the adapter's values win on collisions.\n if (this.entitlementAdapter) {\n const context = await this.entitlementAdapter.getContext();\n this.variableStore.seed(context);\n }\n\n // Set initial locale and configure translations\n this.playerState.setLocale(this.locale);\n this.translationService.setLanguage(this.locale);\n\n // Check if page view is available\n const loadedManifest = this.manifestService.getManifest();\n if (loadedManifest?.chapters) {\n const chapters = Object.values(loadedManifest.chapters);\n this.pageViewAvailable = chapters.some(chapter =>\n chapter.pages && chapter.pages.length > 0\n );\n }\n\n // Initial speech / audio / SFX toggle state: the reader's stored\n // preference wins, else the work's settings.ui.*Default (default: on).\n this.initializeAudioPreferences(loadedManifest ?? null);\n\n // Configure tracking (consent requirements + event whitelist) from the\n // manifest so video events flow through the consent/whitelist pipeline.\n this.configureTracking(loadedManifest);\n\n // Flatten the manifest's keyed extras blocks for the extras viewer\n // (also the target of hotspot openExtras actions).\n this.buildExtrasList(loadedManifest ?? null);\n\n // Like / bookmark state for this work, from the device.\n this.restoreSocialState();\n\n // Navigate to initial position. Without an explicit host position, a\n // bookmark the reader left in this work is resumed.\n const bookmark = !this.initialChapterId && !this.initialPanelId ? this.readBookmark() : null;\n if (this.initialChapterId && this.initialPanelId) {\n await this.navigateToPanel(this.initialChapterId, this.initialPanelId);\n } else if (this.initialChapterId) {\n await this.navigateToChapter(this.initialChapterId);\n } else if (bookmark && this.manifestService.getChapter(bookmark.chapterId)?.panels?.[bookmark.panelId]) {\n await this.navigateToPanel(bookmark.chapterId, bookmark.panelId);\n } else {\n await this.navigateToStart();\n }\n\n // Subscribe to state changes\n this.subscribeToStateChanges();\n\n this.loading = false;\n this.ready.emit();\n } catch (err) {\n this.handleError(err as Error);\n }\n }\n\n /**\n * Configure the TrackingService from the manifest's `tracking` section:\n * consent requirement, event whitelist and endpoint. Consent itself follows\n * the manifest's `defaultOptIn` (until an explicit consent UI overrides it\n * via `PlayerStateService.setTrackingConsent`).\n */\n private configureTracking(manifest: PanelWaveManifest | null): void {\n const tracking = manifest?.tracking;\n if (!tracking) {\n return;\n }\n this.trackingService.configure({\n consentRequired: tracking.consent?.required ?? true,\n eventWhitelist: tracking.eventWhitelist,\n endpoint: tracking.endpoint,\n });\n if (tracking.consent?.defaultOptIn) {\n this.trackingService.setConsent(true);\n }\n\n // TrackingService's UUID is the single analytics session ID (embedding\n // hosts can override it via TrackingService.setSessionId before init).\n this.startAnalyticsSession(manifest!);\n }\n\n /**\n * Open the analytics session: compute the reading order across chapters\n * (graph traversal from each chapter's entry) and emit `session_start`\n * with device/locale/work-size context. Runs before the initial\n * navigation, so session_start precedes the first panel_view.\n */\n private startAnalyticsSession(manifest: PanelWaveManifest): void {\n if (this.analyticsSessionStarted) {\n return;\n }\n this.analyticsSessionStarted = true;\n\n this.analyticsPanelOrder.clear();\n let order = 0;\n for (const chapter of manifest.chapters ?? []) {\n for (const panelId of this.readingOrderForChapter(chapter)) {\n if (!this.analyticsPanelOrder.has(panelId)) {\n this.analyticsPanelOrder.set(panelId, ++order);\n }\n }\n }\n this.analyticsTotalPanels = order;\n\n this.trackingService.track('session_start', {\n deviceType: this.detectDeviceType(),\n locale: this.locale,\n totalPanels: this.analyticsTotalPanels,\n });\n }\n\n /**\n * Deterministic reading order for a chapter: breadth-first over the graph\n * from the entry panel(s), then any unreachable panels in declaration\n * order (branching narratives have no single true order — BFS approximates\n * \"distance from start\", which is what the funnel needs).\n */\n private readingOrderForChapter(chapter: Chapter): string[] {\n const orderedIds: string[] = [];\n const seen = new Set<string>();\n const graph = chapter.graph;\n\n const entry = graph ? this.flowEngine.getEntry(graph) : undefined;\n const queue: string[] = entry === undefined ? [] : typeof entry === 'string' ? [entry] : [...entry];\n\n while (queue.length > 0) {\n const panelId = queue.shift()!;\n if (seen.has(panelId)) {\n continue;\n }\n seen.add(panelId);\n orderedIds.push(panelId);\n for (const edge of graph?.edges ?? []) {\n if (edge.from === panelId && !seen.has(edge.to)) {\n queue.push(edge.to);\n }\n }\n }\n\n for (const panelId of Object.keys(chapter.panels ?? {})) {\n if (!seen.has(panelId)) {\n orderedIds.push(panelId);\n }\n }\n return orderedIds;\n }\n\n /**\n * Coarse device class for analytics breakdowns (matches the dashboard's\n * device segments): touch + narrow = phone, touch + wide = tablet,\n * everything else desktop.\n */\n private detectDeviceType(): string {\n if (typeof window === 'undefined') {\n return 'desktop';\n }\n const coarsePointer = window.matchMedia?.('(pointer: coarse)')?.matches ?? false;\n if (coarsePointer) {\n return window.innerWidth < 768 ? 'phone' : 'tablet';\n }\n return 'desktop';\n }\n\n /**\n * Track a panel view (deduplicated against immediate re-emissions of the\n * same panel) and, on reaching an end panel of the last chapter, the\n * one-time `work_complete` signal.\n */\n private trackPanelView(panel: Panel, chapter: Chapter): void {\n // Panels don't carry their own id — resolve it from the chapter's map\n // (same identity lookup as getCurrentPanelId).\n const panelId = Object.entries(chapter.panels ?? {}).find(([, p]) => p === panel)?.[0];\n if (!panelId || panelId === this.lastTrackedPanelId) {\n return;\n }\n this.lastTrackedPanelId = panelId;\n\n this.trackingService.track('panel_view', {\n panelId,\n chapterId: chapter.id,\n panelOrder: this.analyticsPanelOrder.get(panelId) ?? 0,\n });\n\n if (!this.workCompleteTracked && this.isEndOfWork(panelId, chapter)) {\n this.workCompleteTracked = true;\n this.trackingService.track('work_complete', {\n panelId,\n chapterId: chapter.id,\n });\n }\n }\n\n /** An end panel (no outgoing edges) of the manifest's last chapter. */\n private isEndOfWork(panelId: string, chapter: Chapter): boolean {\n const chapters = this.manifestService.getManifest()?.chapters ?? [];\n if (chapters.length > 0 && chapters[chapters.length - 1]?.id !== chapter.id) {\n return false;\n }\n return !(chapter.graph?.edges ?? []).some((edge) => edge.from === panelId);\n }\n\n /**\n * Close the analytics session exactly once: emit `session_end` and flush\n * the queue via sendBeacon (survives tab close / navigation).\n */\n private endAnalyticsSession(): void {\n if (!this.analyticsSessionStarted || this.analyticsSessionEnded) {\n return;\n }\n this.analyticsSessionEnded = true;\n this.trackingService.track('session_end', {});\n this.trackingService.flushSync();\n }\n\n /**\n * Load manifest from URL\n */\n private async loadManifestFromUrl(url: string): Promise<void> {\n await this.manifestService.loadManifestFromUrl(url).toPromise();\n }\n\n /**\n * Subscribe to state changes\n */\n private subscribeToStateChanges(): void {\n // Listen to panel changes\n this.playerState.currentPanel$\n .pipe(takeUntil(this.destroy$))\n .subscribe((panel) => {\n if (panel && this.currentChapter) {\n this.currentPanel = panel;\n // Resolve variants before emitting so consumers (and the\n // tracked event) see the effective panel state.\n this.refreshResolvedPanels();\n this.panelChange.emit({ panel, chapter: this.currentChapter });\n this.trackPanelView(panel, this.currentChapter);\n }\n });\n\n // Listen to locale changes\n this.playerState.locale$\n .pipe(takeUntil(this.destroy$))\n .subscribe((locale) => {\n this.localeChange.emit(locale);\n });\n }\n\n /**\n * Navigate to start\n */\n private async navigateToStart(): Promise<void> {\n const manifest = this.manifestService.getManifest();\n if (!manifest) {\n throw new Error('No manifest loaded');\n }\n\n // Get first chapter\n const firstChapter = manifest.chapters[0];\n if (!firstChapter) {\n throw new Error('No chapters in manifest');\n }\n\n await this.navigateToChapter(firstChapter.id);\n }\n\n /**\n * Navigate to chapter\n */\n async navigateToChapter(chapterId: string): Promise<void> {\n try {\n const chapter = this.manifestService.getChapter(chapterId);\n if (!chapter) {\n throw new Error(`Chapter not found: ${chapterId}`);\n }\n\n this.currentChapter = chapter;\n this.chapterChange.emit(chapter);\n this.visitedPanelIds = [];\n this.updateCanvasAvailability();\n\n // Get first panel in chapter from graph entry\n const entry = this.flowEngine.getEntry(chapter.graph);\n const firstPanelId = typeof entry === 'string' ? entry : entry[0];\n if (firstPanelId) {\n const panelData = this.manifestService.getPanel(firstPanelId);\n if (panelData) {\n this.playerState.setCurrentPanel(panelData.panel);\n this.currentPanel = panelData.panel;\n this.refreshVariableContext();\n }\n }\n } catch (err) {\n this.handleError(err as Error);\n }\n }\n\n /**\n * Navigate to panel\n * @param transition - Optional transition to render for this panel change\n * (already resolved against the outputPresets default). Omitted for\n * non-adjacent jumps (TOC, initial load), which swap instantly.\n */\n async navigateToPanel(\n chapterId: string,\n panelId: string,\n transition?: Transition,\n cameraMove?: CameraMove\n ): Promise<void> {\n try {\n this.viewportTransition = transition ?? null;\n // Check entitlement. A host-supplied adapter still wins — it is the\n // documented override — but a refusal now raises the paywall instead of\n // throwing a navigation error at the reader.\n if (this.entitlementAdapter) {\n const hasAccess = await this.entitlementAdapter.hasAccess(panelId);\n if (!hasAccess) {\n this.openPaywall(this.paywallService.gateFor(panelId) ?? {\n scope: 'panel',\n refId: panelId,\n reason: 'This content requires an entitlement to access.',\n });\n return;\n }\n } else if (!this.paywallService.canAccess(panelId)) {\n // Manifest paywall rules (schema `paywall.rules`) evaluated against\n // what the reader owns. Navigation stops here: the reader stays on\n // the last panel they were entitled to see.\n if (this.paywallService.evaluate(panelId).reason === 'age_verification_required') {\n // An age gate is answered in-player (birth date), not by checkout.\n this.openAgeGate(chapterId, panelId, transition, cameraMove);\n return;\n }\n const gate = this.paywallService.gateFor(panelId);\n if (gate) {\n this.openPaywall(gate);\n return;\n }\n }\n\n const chapter = this.manifestService.getChapter(chapterId);\n if (!chapter) {\n throw new Error(`Chapter not found: ${chapterId}`);\n }\n\n const panelData = this.manifestService.getPanel(panelId);\n if (!panelData) {\n throw new Error(`Panel not found: ${panelId}`);\n }\n\n const chapterChanged = this.currentChapter !== chapter;\n const leavingPanelId = this.getCurrentPanelId();\n this.currentChapter = chapter;\n this.currentPanel = panelData.panel;\n this.playerState.setCurrentPanel(panelData.panel);\n this.refreshVariableContext();\n\n if (chapterChanged) {\n this.visitedPanelIds = [];\n this.updateCanvasAvailability();\n }\n if (leavingPanelId && !chapterChanged && !this.visitedPanelIds.includes(leavingPanelId)) {\n this.visitedPanelIds = [...this.visitedPanelIds, leavingPanelId];\n }\n if (!this.visitedPanelIds.includes(panelId)) {\n this.visitedPanelIds = [...this.visitedPanelIds, panelId];\n }\n\n // Canvas view: glide the camera to the target panel's framing.\n if (this.viewMode === 'canvas') {\n this.flyCameraToPanel(chapter, panelId, cameraMove);\n }\n // No panelChange.emit here: setCurrentPanel() above already emitted it\n // through the currentPanel$ subscription (with variants resolved) —\n // emitting again handed every host each panel change twice.\n } catch (err) {\n this.handleError(err as Error);\n }\n }\n\n /**\n * Rebuild the flat variable context handed to the viewport/canvas for\n * hotspot visibleIf evaluation. New object identity per call so OnPush\n * children re-evaluate.\n */\n private refreshVariableContext(): void {\n this.variableContext = this.variableStore.createContext(this.currentChapter?.id);\n this.refreshResolvedPanels();\n }\n\n /**\n * Re-resolve panel variants against the current variable context.\n * Called whenever variables change or the current panel/chapter moves,\n * so variant-driven content reacts immediately (spec: \"Re-evaluate\n * variants\" after every mutation).\n */\n private refreshResolvedPanels(): void {\n const panels = this.currentChapter?.panels ?? {};\n this.resolvedPanels = resolvePanels(panels, this.variableContext);\n\n if (!this.currentPanel) {\n this.effectivePanel = undefined;\n this.activeVariantId = undefined;\n this.syncPanelAudio();\n return;\n }\n\n const panelId = this.getCurrentPanelId();\n const forced = panelId !== undefined ? this.variantOverrides.get(panelId) : undefined;\n const resolved = resolvePanelVariant(this.currentPanel, this.variableContext, forced);\n this.effectivePanel = resolved.panel;\n this.activeVariantId = resolved.variantId;\n\n // A manual override on the current panel must also win in the\n // page/canvas panel record.\n if (panelId && this.resolvedPanels[panelId] !== resolved.panel) {\n this.resolvedPanels = { ...this.resolvedPanels, [panelId]: resolved.panel };\n }\n\n this.syncPanelAudio();\n }\n\n /**\n * Keep the audio engine's playing set in step with the effective panel\n * (variant-resolved, so a variant's `audio` override wins) and the\n * variable context its tracks' `visibleIf` conditions read.\n */\n private syncPanelAudio(): void {\n this.panelAudio.syncPanel(\n this.getCurrentPanelId(),\n this.effectivePanel ?? this.currentPanel,\n this.variableContext\n );\n }\n\n /**\n * Hotspot activated in the viewport (click or keyboard): execute its\n * action, apply the returned UI effect, refresh the variable context so\n * visibleIf-dependent hotspots/variants update.\n */\n onHotspotActivate(evt: { hotspot: Hotspot; x: number; y: number; panelId: string | null }): void {\n this.trackHotspotClick(evt.panelId, evt.x, evt.y, evt.hotspot.id);\n const effect = this.hotspotAction.execute(evt.hotspot.action, {\n chapterId: this.currentChapter?.id,\n });\n this.applyHotspotEffect(effect);\n this.refreshVariableContext();\n }\n\n private applyHotspotEffect(effect: HotspotUiEffect): void {\n switch (effect.kind) {\n case 'navigate':\n if (this.currentChapter) {\n void this.navigateToPanel(this.currentChapter.id, effect.to, effect.transition);\n }\n break;\n case 'openExtras':\n this.extrasInitialId = effect.extrasId;\n this.extrasVisible = true;\n break;\n case 'openModal':\n this.actionModalTitle = effect.title;\n this.actionModalContent = effect.content;\n this.actionModalVisible = true;\n break;\n case 'none':\n break;\n }\n }\n\n /**\n * Click on panel content that hit no hotspot\n */\n onDeadClick(evt: { x: number; y: number; panelId: string | null }): void {\n this.trackHotspotClick(evt.panelId, evt.x, evt.y);\n }\n\n /**\n * Track a hotspot_click event. Dead clicks (no hotspotId) reuse the same\n * event type with hit=false — the payload contract the CMS heatmap\n * endpoint queries: { panelId, chapterId, hotspotId?, x, y, hit }.\n */\n private trackHotspotClick(panelId: string | null, x: number, y: number, hotspotId?: string): void {\n this.trackingService.track('hotspot_click', {\n panelId: panelId ?? this.getCurrentPanelId() ?? undefined,\n chapterId: this.currentChapter?.id,\n hotspotId,\n x: Math.round(x * 10000) / 10000,\n y: Math.round(y * 10000) / 10000,\n hit: !!hotspotId,\n });\n }\n\n /**\n * Flatten the manifest's keyed Extras structure (cover/bonus_art/...) into\n * the viewer's flat list. Asset/thumbnail resolution is a pre-existing\n * viewer gap and stays out of scope here.\n */\n private buildExtrasList(manifest: PanelWaveManifest | null): void {\n // Media (images / video / audio / thumbnails) resolve through the asset\n // catalog; see utils/extras-utils.ts for the ExtraBlock mapping.\n this.extrasList = extrasFromManifest(\n manifest?.extras as Record<string, unknown> | undefined,\n (assetId) => this.manifestService.getAsset(assetId) as CatalogLike | null\n );\n }\n\n /**\n * Canvas view is available when the current chapter has a canvas layout\n * and at least one output preset enables `canvasView` (the player does not\n * track an active output format — same pragmatic rule as\n * `FlowEngineService.getDefaultTransition`). Entering a canvas chapter\n * auto-switches to canvas view; leaving one falls back to panel view.\n */\n private updateCanvasAvailability(): void {\n const presets = this.manifestService.getManifest()?.settings?.outputPresets ?? {};\n const enabled = Object.values(presets).some((preset) => preset?.canvasView === true);\n this.canvasViewAvailable = enabled && !!this.currentChapter?.canvas;\n\n if (this.viewModeOverride === 'panel') {\n if (this.viewMode === 'canvas') {\n this.viewMode = 'panel';\n }\n return;\n }\n if (this.canvasViewAvailable && this.viewMode === 'panel') {\n this.viewMode = 'canvas';\n } else if (!this.canvasViewAvailable && this.viewMode === 'canvas') {\n this.viewMode = 'panel';\n }\n }\n\n /**\n * Fly (or, under reduced motion, jump) the canvas camera to a panel's\n * authored framing. The camera service caps travel speed; user input\n * during the glide cancels it (the reader owns the camera).\n */\n private flyCameraToPanel(chapter: Chapter, panelId: string, cameraMove?: CameraMove): void {\n const placement = chapter.canvas?.placements?.[panelId];\n if (!placement) {\n return;\n }\n const target = this.canvasCamera.frameForPlacement(placement);\n if (this.motionReduced) {\n // Reduced motion: no gliding, ever. (CameraMove.reducedMotionFallback\n // degrades to an instant reframe; a cross-fade is a future refinement.)\n this.canvasCamera.jumpTo(target);\n return;\n }\n void this.canvasCamera.flyTo(\n target,\n cameraMove ?? this.flowEngine.getDefaultCameraMove(this.manifestService.getManifest()?.settings)\n );\n }\n\n /**\n * Navigate to next panel\n */\n async navigateNext(): Promise<void> {\n if (!this.currentChapter || !this.currentPanel) {\n return;\n }\n\n this.navigationAttempt.emit({ direction: 'next' });\n\n try {\n const context = this.variableStore.createContext(this.currentChapter.id);\n const currentPanelId = this.getCurrentPanelId();\n if (!currentPanelId) return;\n\n const result = this.flowEngine.getNextPanel(\n this.currentChapter.graph,\n currentPanelId,\n context,\n this.flowEngine.getDefaultTransition(this.manifestService.getManifest()?.settings),\n this.flowEngine.getDefaultCameraMove(this.manifestService.getManifest()?.settings)\n );\n\n if (result.nextPanelId) {\n // Edge `action` mutations (schema: \"applied when traversing this\n // edge\") were returned by the flow engine but never applied here.\n if (result.action?.length) {\n this.variableStore.applyMutations(result.action, { chapterId: this.currentChapter.id });\n }\n await this.navigateToPanel(\n this.currentChapter.id,\n result.nextPanelId,\n result.transition,\n result.cameraMove\n );\n }\n } catch (err) {\n this.handleError(err as Error);\n }\n }\n\n /**\n * Navigate to previous panel\n */\n async navigatePrevious(): Promise<void> {\n if (!this.currentChapter || !this.currentPanel) {\n return;\n }\n\n this.navigationAttempt.emit({ direction: 'previous' });\n\n try {\n const currentPanelId = this.getCurrentPanelId();\n if (!currentPanelId) return;\n\n const previousPanels = this.flowEngine.getPreviousPanels(\n this.currentChapter.graph,\n currentPanelId\n );\n\n if (previousPanels.length > 0) {\n // Navigate to the first previous panel, replaying the traversed\n // edge's transition in reverse (slide left becomes slide right).\n const transition = this.flowEngine.getReturnTransition(\n this.currentChapter.graph,\n previousPanels[0],\n currentPanelId,\n this.flowEngine.getDefaultTransition(this.manifestService.getManifest()?.settings)\n );\n const cameraMove = this.flowEngine.getReturnCameraMove(\n this.currentChapter.graph,\n previousPanels[0],\n currentPanelId,\n this.flowEngine.getDefaultCameraMove(this.manifestService.getManifest()?.settings)\n );\n await this.navigateToPanel(this.currentChapter.id, previousPanels[0], transition, cameraMove);\n }\n } catch (err) {\n this.handleError(err as Error);\n }\n }\n\n /**\n * Toggle toolbar visibility\n */\n toggleToolbar(): void {\n this.toolbarVisible = !this.toolbarVisible;\n }\n\n /**\n * Show toolbar\n */\n showToolbarTemporarily(): void {\n this.toolbarVisible = true;\n \n // Auto-hide after 5 seconds. The timeout runs outside any template\n // event, so OnPush needs an explicit markForCheck to repaint.\n setTimeout(() => {\n if (this.toolbarVisible) {\n this.toolbarVisible = false;\n this.cdr.markForCheck();\n }\n }, 5000);\n }\n\n /**\n * Change locale\n */\n changeLocale(locale: LocaleCode): void {\n this.playerState.setLocale(locale);\n }\n\n /**\n * Set variable\n */\n setVariable(key: string, value: unknown, scope: 'global' | 'chapter' | 'page' | 'session' | 'persistent' = 'session'): void {\n this.variableStore.set(key, value, scope);\n // Conditional content (visibleIf, variants) reacts immediately.\n this.refreshVariableContext();\n this.variableChange.emit({ key, value });\n }\n\n /**\n * Get variable\n */\n getVariable(key: string, scope: 'global' | 'chapter' | 'page' | 'session' | 'persistent' = 'session', scopeId?: string): unknown {\n return this.variableStore.get(key, scope, scopeId);\n }\n\n /**\n * Get current panel ID\n */\n getCurrentPanelId(): string | undefined {\n if (!this.currentPanel || !this.currentChapter) return undefined;\n \n // Find the panel ID by searching in the chapter's panels\n for (const [panelId, panel] of Object.entries(this.currentChapter.panels)) {\n if (panel === this.currentPanel) {\n return panelId;\n }\n }\n \n return undefined;\n }\n\n /**\n * Handle error\n */\n private handleError(err: Error): void {\n console.error('Player error:', err);\n this.hasError = true;\n this.errorMessage = err.message;\n this.loading = false;\n this.error.emit(err);\n }\n\n /**\n * Toolbar event handlers\n */\n onToggleView(): void {\n // Cycle through the modes available for the current chapter:\n // panel -> page (if pages exist) -> canvas (if canvas exists) -> panel.\n // Page view keeps its historical behavior of being attempted whenever a\n // page contains the current panel, even without the manifest-level flag.\n const modes: ViewMode[] = ['panel'];\n if (this.pageViewAvailable || this.findPageContainingPanel()) {\n modes.push('page');\n }\n if (this.canvasViewAvailable) {\n modes.push('canvas');\n }\n const newMode = modes[(modes.indexOf(this.viewMode) + 1) % modes.length];\n\n if (newMode === 'page') {\n // Switch to page view - find page containing current panel\n this.currentPage = this.findPageContainingPanel();\n if (this.currentPage) {\n this.viewMode = 'page';\n // Start the page-view video sequence; video components register as\n // they render and visibility drives the queue.\n this.videoSequencer.start();\n } else {\n console.warn('No page found for current panel');\n }\n } else if (newMode === 'canvas') {\n this.viewMode = 'canvas';\n this.videoSequencer.reset();\n // Land the camera on the current panel when entering canvas view.\n if (this.currentChapter) {\n const panelId = this.getCurrentPanelId();\n if (panelId) {\n const placement = this.currentChapter.canvas?.placements?.[panelId];\n if (placement) {\n this.canvasCamera.jumpTo(this.canvasCamera.frameForPlacement(placement));\n }\n }\n }\n } else {\n // Switch to panel view\n this.viewMode = 'panel';\n this.videoSequencer.reset();\n }\n\n // Re-arm autoplay for the new view mode (video panels vs wall clock).\n if (this.autoplayEnabled) {\n this.startAutoplay();\n }\n\n console.log('View mode:', this.viewMode);\n }\n\n /**\n * Tap on a placed panel in canvas view. Traverses the matching out-edge of\n * the current panel when its condition passes (the graph still gates\n * movement); otherwise allows a revisit-jump to already-visited panels.\n * Taps on unrelated panels are ignored — free roaming never mutates story\n * state.\n */\n onCanvasPanelTap(panelId: string): void {\n if (!this.currentChapter) {\n return;\n }\n const currentPanelId = this.getCurrentPanelId();\n if (!currentPanelId || panelId === currentPanelId) {\n return;\n }\n const context = this.variableStore.createContext(this.currentChapter.id);\n const edge = this.currentChapter.graph.edges.find(\n (candidate) =>\n candidate.from === currentPanelId &&\n candidate.to === panelId &&\n (!candidate.condition || evaluateJsonLogic(candidate.condition, context))\n );\n if (edge) {\n this.navigationAttempt.emit({ direction: 'panel', target: panelId });\n void this.navigateToPanel(\n this.currentChapter.id,\n panelId,\n edge.transition,\n edge.cameraMove ??\n this.flowEngine.getDefaultCameraMove(this.manifestService.getManifest()?.settings)\n );\n return;\n }\n if (this.visitedPanelIds.includes(panelId)) {\n this.navigationAttempt.emit({ direction: 'panel', target: panelId });\n void this.navigateToPanel(this.currentChapter.id, panelId);\n }\n }\n\n /** Balloon defaults for the canvas stage (same source as the viewport). */\n get manifestBalloonConfig(): BalloonConfig | null {\n return this.manifestService.getManifest()?.settings?.typography?.balloon_config ?? null;\n }\n\n /** Manifest characters for speech-bubble styling in canvas view. */\n get manifestCharacters(): ManifestCharacter[] {\n return this.manifestService.getManifest()?.meta?.characters ?? [];\n }\n\n /** Manifest preload settings for the canvas stage's neighbor warming. */\n get manifestPreloadSettings() {\n return this.manifestService.getManifest()?.settings?.preload ?? null;\n }\n\n onLocaleChange(locale: LocaleCode): void {\n // Update content locale\n this.locale = locale;\n this.playerState.setLocale(locale);\n \n // Update GUI language (sync with content locale)\n this.translationService.setLanguage(locale);\n \n console.log('Locale changed to:', locale);\n }\n\n onToggleSpeech(): void {\n this.setSpeechEnabled(!this.speechEnabled);\n }\n\n onToggleAudio(): void {\n this.setAudioEnabled(!this.audioEnabled);\n }\n\n onToggleSfx(): void {\n this.setSfxEnabled(!this.sfxEnabled);\n }\n\n /**\n * Speech bubbles on/off. Also gates the voiceover bus: spoken lines belong\n * to the bubbles they voice (schema audio roles).\n */\n setSpeechEnabled(enabled: boolean): void {\n if (this.speechEnabled === enabled) {\n return;\n }\n this.speechEnabled = enabled;\n this.playerState.updatePreference('speech', enabled);\n this.applyAudioPreferences();\n this.trackingService.track('speech_toggle', { enabled });\n }\n\n /**\n * Master audio on/off: every engine bus and video sound.\n */\n setAudioEnabled(enabled: boolean): void {\n if (this.audioEnabled === enabled) {\n return;\n }\n this.audioEnabled = enabled;\n this.playerState.updatePreference('audio', enabled);\n this.applyAudioPreferences();\n this.trackingService.track('audio_toggle', { enabled });\n }\n\n /**\n * Sound effects on/off (sfx bus incl. `ui` sounds).\n */\n setSfxEnabled(enabled: boolean): void {\n if (this.sfxEnabled === enabled) {\n return;\n }\n this.sfxEnabled = enabled;\n this.playerState.updatePreference('sfx', enabled);\n this.applyAudioPreferences();\n this.trackingService.track('sfx_toggle', { enabled });\n }\n\n /**\n * Seed the toggle states once the manifest is loaded: a preference the\n * reader set explicitly (this or an earlier session) wins over the work's\n * `settings.ui.speechDefault` / `audioDefault` / `sfxDefault`.\n */\n private initializeAudioPreferences(manifest: PanelWaveManifest | null): void {\n const ui = manifest?.settings?.ui;\n const prefs = this.playerState.getPreferences();\n const pick = (key: 'speech' | 'audio' | 'sfx', workDefault: boolean | undefined): boolean =>\n this.playerState.hasPersistedPreference(key) ? prefs[key] : workDefault !== false;\n\n this.speechEnabled = pick('speech', ui?.speechDefault);\n this.audioEnabled = pick('audio', ui?.audioDefault);\n this.sfxEnabled = pick('sfx', ui?.sfxDefault);\n this.applyAudioPreferences();\n }\n\n /**\n * Push the toggle states and stored volumes into the mixer. Mutes and\n * volumes are independent in the engine, so toggling never loses a level.\n */\n private applyAudioPreferences(): void {\n const prefs = this.playerState.getPreferences();\n this.audioEngine.setMasterVolume(prefs.masterVolume ?? 1);\n this.audioEngine.setRoleVolume('sfx', prefs.sfxVolume ?? 1);\n this.audioEngine.setMasterMuted(!this.audioEnabled);\n this.audioEngine.setRoleMuted('sfx', !this.sfxEnabled);\n this.audioEngine.setRoleMuted('voiceover', !this.speechEnabled);\n }\n\n /**\n * Settings modal \"Save\" (Preferences tab). Toggle-backed preferences go\n * through the same setters as the toolbar; the rest are persisted for the\n * host/state to read (manga mode, reduced motion and high contrast have\n * no shell behaviour yet).\n */\n onPreferencesChange(prefs: Preferences): void {\n this.setSpeechEnabled(prefs.speech);\n this.setAudioEnabled(prefs.audio);\n this.setSfxEnabled(prefs.sfx);\n\n const seconds = Number(prefs.secondsPerPanel);\n if (Number.isFinite(seconds) && seconds > 0 && seconds !== this.secondsPerPanel) {\n this.onSecondsPerPanelChange(seconds);\n }\n if (prefs.autoplay !== this.autoplayEnabled) {\n this.onToggleAutoplay();\n }\n\n this.playerState.updatePreferences({\n autoplay: prefs.autoplay,\n secondsPerPanel: this.secondsPerPanel,\n mangaMode: prefs.mangaMode,\n reducedMotion: prefs.reducedMotion,\n highContrast: prefs.highContrast,\n });\n }\n\n onToggleAutoplay(): void {\n this.autoplayEnabled = !this.autoplayEnabled;\n \n if (this.autoplayEnabled) {\n this.startAutoplay();\n } else {\n this.stopAutoplay();\n }\n }\n\n onSecondsPerPanelChange(seconds: number): void {\n this.secondsPerPanel = seconds;\n \n // Restart autoplay if active to apply new timing\n if (this.autoplayEnabled) {\n this.stopAutoplay();\n this.startAutoplay();\n }\n }\n\n onToggleThumbnails(): void {\n this.thumbnailsVisible = !this.thumbnailsVisible;\n }\n\n onOpenToc(): void {\n this.tocVisible = true;\n }\n\n onOpenSettings(): void {\n // Fresh snapshot of the current values for the modal's local copy.\n const values: Record<string, unknown> = {};\n for (const def of this.variableDefinitions) {\n values[def.id] = this.variableStore.get(def.id, def.scope, this.scopeIdFor(def));\n }\n this.settingsVariableValues = values;\n\n // Preferences tab: toggle-backed values from the shell, the rest from\n // the persisted state.\n const prefs = this.playerState.getPreferences();\n this.settingsPreferences = {\n speech: this.speechEnabled,\n audio: this.audioEnabled,\n sfx: this.sfxEnabled,\n autoplay: this.autoplayEnabled,\n secondsPerPanel: this.secondsPerPanel,\n mangaMode: prefs.mangaMode,\n reducedMotion: prefs.reducedMotion,\n highContrast: prefs.highContrast,\n };\n this.settingsVisible = true;\n }\n\n /**\n * A settings-modal variable edit (emitted per changed key on save).\n * Routed through set(), so read-only definitions stay untouchable and\n * types are validated; conditional content re-resolves immediately.\n */\n onSettingsVariableChange(change: { key: string; value: unknown }): void {\n const def = this.variableDefinitions.find((d) => d.id === change.key);\n this.variableStore.set(\n change.key,\n change.value,\n def?.scope ?? 'session',\n def ? this.scopeIdFor(def) : undefined\n );\n this.refreshVariableContext();\n this.variableChange.emit({ key: change.key, value: change.value });\n }\n\n /** Scope id for chapter-/page-scoped variable definitions. */\n private scopeIdFor(def: VariableDefinition): string | undefined {\n if (def.scope === 'chapter') return this.currentChapter?.id;\n if (def.scope === 'page') return this.currentPage?.id;\n return undefined;\n }\n\n /**\n * Normalize the manifest's `variables` block into a definitions array.\n * The schema shape is { definitions: VariableDefinition[] }; a legacy\n * map keyed by variable id is tolerated as well.\n */\n private extractVariableDefinitions(): VariableDefinition[] {\n const variables = this.manifestService.getManifest()?.variables as\n | { definitions?: VariableDefinition[] }\n | Record<string, VariableDefinition>\n | undefined;\n if (!variables || typeof variables !== 'object') {\n return [];\n }\n const definitions = (variables as { definitions?: VariableDefinition[] }).definitions;\n if (Array.isArray(definitions)) {\n return definitions.filter((d) => !!d && typeof d.id === 'string');\n }\n // Legacy map form: { \"<id>\": definition }\n return Object.values(variables).filter(\n (d): d is VariableDefinition => !!d && typeof d === 'object' && typeof d.id === 'string'\n );\n }\n\n onOpenCharacters(): void {\n this.charactersVisible = true;\n }\n\n /**\n * Cycle the manual variant selection of the current panel:\n * automatic (conditions) → each variant in order → base panel →\n * back to automatic. The selection is a session-scoped shadow\n * override; navigation keeps it per panel.\n */\n onCycleAlternative(): void {\n const panelId = this.getCurrentPanelId();\n const variants = this.currentPanel?.variants;\n if (!panelId || !variants?.length) {\n return;\n }\n\n const current = this.variantOverrides.has(panelId)\n ? this.variantOverrides.get(panelId)\n : undefined;\n\n let next: string | null | undefined;\n if (current === undefined) {\n next = variants[0].id;\n } else if (current === null) {\n next = undefined; // base → back to automatic\n } else {\n const index = variants.findIndex((v) => v.id === current);\n next = index >= 0 && index < variants.length - 1 ? variants[index + 1].id : null;\n }\n\n if (next === undefined) {\n this.variantOverrides.delete(panelId);\n } else {\n this.variantOverrides.set(panelId, next);\n }\n this.refreshResolvedPanels();\n }\n\n /** Open the branch chooser with the paths currently open from this panel. */\n onShowBranches(): void {\n this.branchChoices = this.computeBranchChoices();\n if (this.branchChoices.length === 0) {\n return;\n }\n this.branchChooserVisible = true;\n this.cdr.markForCheck();\n }\n\n onOpenExtras(): void {\n this.extrasVisible = true;\n }\n\n /** Toggle the reader's like for this work (persisted on the device). */\n onLike(): void {\n this.liked = !this.liked;\n const store = this.readSocialStore();\n const entry = store[this.workKey()] ?? {};\n entry.liked = this.liked;\n store[this.workKey()] = entry;\n this.writeSocialStore(store);\n\n this.trackingService.track('like', { workId: this.workKey(), liked: this.liked });\n this.likeChange.emit({ workId: this.workKey(), liked: this.liked });\n this.cdr.markForCheck();\n }\n\n /**\n * Toggle the bookmark on the current panel: set it here, or clear it when\n * this panel already is the bookmark. Resumed on the next load when the\n * host passes no initial position.\n */\n onBookmark(): void {\n const chapterId = this.currentChapter?.id;\n const panelId = this.getCurrentPanelId();\n if (!chapterId || !panelId) {\n return;\n }\n\n const store = this.readSocialStore();\n const entry = store[this.workKey()] ?? {};\n const isSamePanel = entry.bookmark?.chapterId === chapterId && entry.bookmark?.panelId === panelId;\n if (isSamePanel) {\n delete entry.bookmark;\n this.bookmarked = false;\n } else {\n entry.bookmark = { chapterId, panelId, savedAt: Date.now() };\n this.bookmarked = true;\n }\n store[this.workKey()] = entry;\n this.writeSocialStore(store);\n\n this.trackingService.track('bookmark', { workId: this.workKey(), chapterId, panelId, bookmarked: this.bookmarked });\n this.bookmarkChange.emit({ workId: this.workKey(), chapterId, panelId, bookmarked: this.bookmarked });\n this.cdr.markForCheck();\n }\n\n onShare(): void {\n this.shareVisible = true;\n }\n\n onOpenComments(): void {\n this.commentsVisible = true;\n }\n\n /**\n * Modal close handlers\n */\n onTocClose(): void {\n this.tocVisible = false;\n }\n\n onSettingsClose(): void {\n this.settingsVisible = false;\n }\n\n onCharactersClose(): void {\n this.charactersVisible = false;\n }\n\n onExtrasClose(): void {\n this.extrasVisible = false;\n }\n\n onShareClose(): void {\n this.shareVisible = false;\n }\n\n onCommentsClose(): void {\n this.commentsVisible = false;\n }\n\n onThumbnailsClose(): void {\n this.thumbnailsVisible = false;\n }\n\n /**\n * Handle ToC navigation\n */\n onTocNavigate(target: { chapterId: string; panelId?: string }): void {\n this.tocVisible = false;\n if (target.panelId) {\n this.navigateToPanel(target.chapterId, target.panelId);\n } else {\n this.navigateToChapter(target.chapterId);\n }\n }\n\n /**\n * Handle thumbnail navigation\n */\n onThumbnailNavigate(target: { chapterId: string; panelId: string }): void {\n this.navigateToPanel(target.chapterId, target.panelId);\n }\n\n /**\n * Keyboard shortcut handler\n */\n @HostListener('window:keydown', ['$event'])\n handleKeyboard(event: KeyboardEvent): void {\n // Don't handle if user is typing in an input\n if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {\n return;\n }\n\n // While a dialog is open the story behind it must not react: Escape\n // closes the dialog (not the toolbar), every other shortcut is ignored.\n if (this.closableDialogOpen()) {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.closeTopDialog();\n }\n return;\n }\n // A dialog that handled Escape itself has already closed by now; the\n // key press was meant for it, not for hiding the toolbar.\n if (event.key === 'Escape' && this.cameFromDialog(event)) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n if (this.viewMode === 'page') {\n this.navigateToNextPage();\n } else {\n this.navigateNext();\n }\n break;\n\n case 'ArrowLeft':\n event.preventDefault();\n if (this.viewMode === 'page') {\n this.navigateToPreviousPage();\n } else {\n this.navigatePrevious();\n }\n break;\n\n case 't':\n case 'T':\n event.preventDefault();\n this.toggleToolbar();\n break;\n\n case 'o':\n case 'O':\n // Canvas overview: see the whole shape of the story.\n if (this.viewMode === 'canvas') {\n event.preventDefault();\n void this.canvasCamera.toggleOverview(!(this.motionReduced));\n }\n break;\n\n case '+':\n case '=':\n if (this.viewMode === 'canvas') {\n event.preventDefault();\n this.canvasZoomAtCenter(1.25);\n }\n break;\n\n case '-':\n case '_':\n if (this.viewMode === 'canvas') {\n event.preventDefault();\n this.canvasZoomAtCenter(0.8);\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n if (this.toolbarVisible) {\n this.toolbarVisible = false;\n }\n break;\n }\n }\n\n /** Dialogs the reader can dismiss with Escape (paywall/age gate excluded). */\n private closableDialogOpen(): boolean {\n return this.actionModalVisible || this.branchChooserVisible || this.shareVisible\n || this.commentsVisible || this.extrasVisible || this.charactersVisible\n || this.languageModalVisible || this.settingsVisible || this.tocVisible;\n }\n\n /** Close the most recently layered dialog (nested ones first). */\n private closeTopDialog(): void {\n if (this.actionModalVisible) { this.actionModalVisible = false; return; }\n if (this.branchChooserVisible) { this.branchChooserVisible = false; return; }\n if (this.shareVisible) { this.shareVisible = false; return; }\n if (this.commentsVisible) { this.commentsVisible = false; return; }\n if (this.extrasVisible) { this.extrasVisible = false; return; }\n if (this.charactersVisible) { this.charactersVisible = false; return; }\n if (this.languageModalVisible) { this.languageModalVisible = false; return; }\n if (this.settingsVisible) { this.settingsVisible = false; return; }\n if (this.tocVisible) { this.tocVisible = false; }\n }\n\n private static readonly DIALOG_HOSTS = new Set([\n 'PW-ACTION-MODAL', 'PW-BRANCH-CHOOSER', 'PW-CHARACTER-ROSTER', 'PW-COMMENTS-DRAWER',\n 'PW-EXTRAS-VIEWER', 'PW-LANGUAGE-MODAL', 'PW-SETTINGS-MODAL', 'PW-SHARE-MODAL',\n 'PW-TOC-OVERLAY', 'PW-AGE-GATE', 'PW-PAYWALL-OVERLAY', 'PW-CONTENT-WARNING-OVERLAY',\n ]);\n\n private cameFromDialog(event: KeyboardEvent): boolean {\n return event.composedPath().some(\n (node) => node instanceof Element && PlayerShellComponent.DIALOG_HOSTS.has(node.tagName)\n );\n }\n\n /**\n * Handle viewport click\n */\n onViewportClick(): void {\n this.showToolbarTemporarily();\n }\n\n /** Keyboard zoom for canvas view (viewport-center anchored). */\n private canvasZoomAtCenter(factor: number): void {\n this.canvasCamera.zoomAtCenter(factor);\n }\n\n /**\n * Handle swipe gesture\n */\n onSwipe(direction: 'left' | 'right' | 'up' | 'down'): void {\n if (direction === 'left') {\n // Swipe left = navigate forward\n if (this.viewMode === 'page') {\n this.navigateToNextPage();\n } else {\n this.navigateNext();\n }\n } else if (direction === 'right') {\n // Swipe right = navigate backward\n if (this.viewMode === 'page') {\n this.navigateToPreviousPage();\n } else {\n this.navigatePrevious();\n }\n }\n }\n\n /**\n * Start autoplay.\n *\n * Video-aware (§4.5): in panel view, when the current panel contains\n * `on-view` video layers, the advance is driven by their media events\n * (one full pass each, signalled via `VideoControllerService.passComplete$`)\n * instead of a wall-clock timer — buffering or a user pause can never\n * desync the dwell time. A watchdog ({@link armVideoWatchdog}) covers the\n * case where the media event never arrives at all (corrupt/unreachable\n * source stalling forever). In page view, pages with visible `on-view`\n * videos advance when the sequencer queue completes (§4.3 step 6). All\n * other panels/pages keep the wall-clock `durationMs`/`secondsPerPanel`\n * timer.\n */\n private startAutoplay(): void {\n this.stopAutoplay(); // Clear any existing timer / pending media waits\n\n if (this.viewMode === 'panel') {\n const videoIds = this.onViewVideoLayerIds(this.effectivePanel ?? this.currentPanel);\n if (videoIds.length > 0) {\n // Media-event driven: wait for every on-view video's pass (the\n // longest pass wins). Progress display uses durationMs as estimate.\n this.pendingVideoPasses = new Set(videoIds);\n this.autoplayDuration =\n (this.effectivePanel ?? this.currentPanel)?.durationMs ?? this.secondsPerPanel * 1000;\n this.autoplayProgress = 0;\n this.autoplayStartTime = Date.now();\n this.startAutoplayProgress();\n this.armVideoWatchdog();\n return;\n }\n } else if (this.viewMode === 'page' && this.pageHasOnViewVideos()) {\n // Page view with on-view videos: the sequencer's queueComplete event\n // advances the page — no wall-clock timer.\n return;\n }\n\n // Use panel-specific durationMs if available, otherwise use global setting (in seconds)\n const durationMs = (this.effectivePanel ?? this.currentPanel)?.durationMs ?? (this.secondsPerPanel * 1000);\n\n // Ensure we have a valid duration\n if (!durationMs || durationMs <= 0) {\n console.warn('Invalid autoplay duration, using default 5s');\n this.autoplayDuration = 5000;\n } else {\n this.autoplayDuration = durationMs;\n }\n\n // Reset and start progress tracking\n this.autoplayProgress = 0;\n this.autoplayStartTime = Date.now();\n this.startAutoplayProgress();\n\n this.autoplayTimer = setTimeout(() => {\n // Continue autoplay if still enabled\n if (this.autoplayEnabled) {\n this.navigateNext();\n // Small delay to let panel change complete, then restart\n setTimeout(() => {\n if (this.autoplayEnabled) {\n this.startAutoplay();\n }\n }, 10);\n }\n }, this.autoplayDuration);\n }\n\n /**\n * Stop autoplay\n */\n private stopAutoplay(): void {\n if (this.autoplayTimer) {\n clearTimeout(this.autoplayTimer);\n this.autoplayTimer = undefined;\n }\n this.pendingVideoPasses.clear();\n this.clearVideoWatchdog();\n this.stopAutoplayProgress();\n this.autoplayProgress = 0;\n }\n\n /**\n * Arm the stall-fallback watchdog for the current panel-view video panel.\n * Bound = the panel's effective duration (`durationMs`, falling back to\n * `secondsPerPanel`) plus a grace margin — reusing\n * `VideoSequencerService`'s configurable stall-skip timeout (§7) rather\n * than a hardcoded number, so the page-view and panel-view fallbacks share\n * one knob. If it fires before every pending video reports its pass, the\n * stalled panel is force-advanced exactly like the sequencer's stall-skip.\n */\n private armVideoWatchdog(): void {\n this.clearVideoWatchdog();\n if (typeof setTimeout === 'undefined') {\n return;\n }\n this.videoWatchdogPanel = this.currentPanel;\n const graceMs = this.videoSequencer.getStallTimeout();\n const boundMs = Math.max(0, this.autoplayDuration) + graceMs;\n this.videoWatchdogTimer = setTimeout(() => this.onVideoWatchdogTimeout(), boundMs);\n }\n\n /** Cancel the video watchdog, if armed, without touching anything else. */\n private clearVideoWatchdog(): void {\n if (this.videoWatchdogTimer) {\n clearTimeout(this.videoWatchdogTimer);\n this.videoWatchdogTimer = undefined;\n }\n this.videoWatchdogPanel = undefined;\n }\n\n /**\n * The watchdog bound elapsed before every pending video reported a pass.\n * No-ops if autoplay stopped, the view mode changed, the panel navigated\n * away in the meantime (stale timer — belt-and-braces against a double\n * advance), or the media event already won the race. Otherwise: emit the\n * same `VIDEO_ENDED` / `stall-skip` tracking signal the page-view\n * sequencer's stall-skip uses (`VideoLayerComponent.emitStallSkip`) for\n * each still-pending video, then advance.\n */\n private onVideoWatchdogTimeout(): void {\n this.videoWatchdogTimer = undefined;\n if (\n !this.autoplayEnabled ||\n this.viewMode !== 'panel' ||\n this.currentPanel !== this.videoWatchdogPanel ||\n this.pendingVideoPasses.size === 0\n ) {\n return;\n }\n const panelId = this.getCurrentPanelId();\n for (const videoId of this.pendingVideoPasses) {\n this.trackVideoStallSkip(panelId, videoId);\n }\n this.pendingVideoPasses.clear();\n this.videoWatchdogPanel = undefined;\n void this.navigateNext().then(() => {\n if (this.autoplayEnabled) {\n this.startAutoplay();\n }\n });\n }\n\n /**\n * Emit a `VIDEO_ENDED` tracking event with a `stall-skip` reason for a\n * video the panel-view watchdog force-advanced past — the panel-view\n * counterpart of `VideoLayerComponent.emitStallSkip()` (page view).\n */\n private trackVideoStallSkip(panelId: string | undefined, videoId: string): void {\n const layer = (this.effectivePanel ?? this.currentPanel)?.layers?.find((l) => l.id === videoId);\n const assetId = typeof layer?.assetId === 'string' ? layer.assetId : undefined;\n const payload: VideoTrackingPayload = {\n panelId,\n assetId,\n trigger: 'view',\n reason: 'stall-skip',\n };\n this.trackingService.track(\n PlayerEvent.VIDEO_ENDED,\n payload as unknown as Record<string, unknown>\n );\n }\n\n /**\n * Ids of the given panel's video layers whose *effective* start mode is\n * `on-view` (i.e. the ones that will actually autoplay and produce media\n * events). Mirrors `VideoLayerComponent.effectiveStartMode()`: reduced\n * motion degrades `on-view` to `on-click`.\n */\n private onViewVideoLayerIds(panel: Panel | undefined): string[] {\n if (!panel?.layers) {\n return [];\n }\n const ui = this.manifestService.getManifest()?.settings?.ui;\n const reduced = this.motionReduced;\n const ids: string[] = [];\n for (const layer of panel.layers) {\n if (layer.kind !== 'video') {\n continue;\n }\n const startMode = resolveStartMode(layer as Partial<VideoLayer>, ui);\n if (startMode === 'on-view' && !reduced) {\n ids.push(layer.id);\n }\n }\n return ids;\n }\n\n /** Whether the current page contains any panel with on-view video layers. */\n private pageHasOnViewVideos(): boolean {\n if (!this.currentPage || !this.currentChapter) {\n return false;\n }\n for (const placement of this.currentPage.layout?.placements ?? []) {\n const panel = this.currentChapter.panels[placement.panelId];\n if (this.onViewVideoLayerIds(panel).length > 0) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Start autoplay progress tracking\n */\n private startAutoplayProgress(): void {\n this.stopAutoplayProgress();\n \n this.autoplayProgressInterval = setInterval(() => {\n const elapsed = Date.now() - this.autoplayStartTime;\n const progress = Math.min(100, (elapsed / this.autoplayDuration) * 100);\n this.autoplayProgress = progress;\n }, 50); // Update every 50ms for smooth animation\n }\n\n /**\n * Stop autoplay progress tracking\n */\n private stopAutoplayProgress(): void {\n if (this.autoplayProgressInterval) {\n clearInterval(this.autoplayProgressInterval);\n this.autoplayProgressInterval = undefined;\n }\n }\n\n /**\n * Find the page that contains the current panel\n */\n private findPageContainingPanel(): Page | undefined {\n if (!this.currentChapter) return undefined;\n \n const currentPanelId = this.getCurrentPanelId();\n if (!currentPanelId) return undefined;\n \n // Search through pages in the current chapter\n const pages = this.currentChapter.pages || [];\n for (const page of pages) {\n // Check if this page's placements include the current panel\n if (page.layout?.placements?.some(p => p.panelId === currentPanelId)) {\n return page;\n }\n }\n \n return undefined;\n }\n\n /**\n * Navigate to next page (in page view mode)\n */\n navigateToNextPage(): void {\n if (!this.currentChapter?.pages || !this.currentPage) return;\n \n const pages = this.currentChapter.pages;\n const currentIndex = pages.findIndex(p => p.id === this.currentPage!.id);\n \n if (currentIndex === -1 || currentIndex >= pages.length - 1) {\n console.log('Already at last page');\n return;\n }\n \n // Move to next page\n this.currentPage = pages[currentIndex + 1];\n\n // Update current panel to first panel in reading order\n if (this.currentPage.readingOrder && this.currentPage.readingOrder.length > 0) {\n const firstPanelId = this.currentPage.readingOrder[0];\n this.currentPanel = this.currentChapter.panels[firstPanelId];\n this.refreshResolvedPanels();\n }\n\n this.onPageChanged();\n console.log('Navigated to next page:', this.currentPage.id);\n }\n\n /**\n * Restart the page-view video sequence (and autoplay arming) after the\n * current page changed.\n */\n private onPageChanged(): void {\n if (this.viewMode === 'page') {\n this.videoSequencer.start();\n }\n if (this.autoplayEnabled) {\n this.startAutoplay();\n }\n }\n\n /**\n * Navigate to previous page (in page view mode)\n */\n navigateToPreviousPage(): void {\n if (!this.currentChapter?.pages || !this.currentPage) return;\n \n const pages = this.currentChapter.pages;\n const currentIndex = pages.findIndex(p => p.id === this.currentPage!.id);\n \n if (currentIndex <= 0) {\n console.log('Already at first page');\n return;\n }\n \n // Move to previous page\n this.currentPage = pages[currentIndex - 1];\n\n // Update current panel to first panel in reading order\n if (this.currentPage.readingOrder && this.currentPage.readingOrder.length > 0) {\n const firstPanelId = this.currentPage.readingOrder[0];\n this.currentPanel = this.currentChapter.panels[firstPanelId];\n this.refreshResolvedPanels();\n }\n\n this.onPageChanged();\n console.log('Navigated to previous page:', this.currentPage.id);\n }\n\n // ============================================================================\n // Character helpers\n // ============================================================================\n\n /**\n * Get available locales from manifest\n */\n get availableLocales(): LocaleCode[] {\n const manifest = this.manifestService.getManifest();\n if (!manifest?.meta?.locales) {\n return ['en-US'];\n }\n return manifest.meta.locales;\n }\n\n /**\n * Get characters from manifest mapped to roster format\n */\n get characters(): RosterCharacter[] {\n const manifest = this.manifestService.getManifest();\n if (!manifest?.meta?.characters) {\n return [];\n }\n return this.mapCharacters(manifest.meta.characters);\n }\n\n /**\n * Map manifest characters to roster character format\n */\n private mapCharacters(characters: ManifestCharacter[]): RosterCharacter[] {\n return characters.map(char => ({\n id: char.id,\n name: char.name,\n avatar: char.images?.['portrait'],\n bio: char.description,\n voiceSample: undefined, // Could be added later if needed\n role: undefined, // Could be extracted from description or added to schema\n }));\n }\n\n // ── Paywall ───────────────────────────────────────────────────────────────\n\n /**\n * Load the manifest's paywall rules and the reader's entitlement snapshot.\n *\n * Precedence: an explicit `entitlementSnapshot` wins over\n * `entitlementEndpoint`, so a host that already knows what the reader owns\n * never pays for a round-trip.\n */\n private async configurePaywall(): Promise<void> {\n try {\n await this.loadEntitlementSnapshot();\n } finally {\n // A verification the reader already passed on this device tops up\n // whatever snapshot the host provided.\n this.restoreAgeVerification();\n }\n }\n\n private async loadEntitlementSnapshot(): Promise<void> {\n const manifest = this.manifestService.getManifest();\n this.paywallService.setManifest(manifest);\n\n if (this.entitlementSnapshot) {\n this.paywallService.setSnapshot(this.entitlementSnapshot);\n return;\n }\n\n if (this.entitlementEndpoint && manifest) {\n this.httpEntitlement = new HttpEntitlementAdapter({\n endpoint: this.entitlementEndpoint,\n readerToken: this.readerToken,\n });\n this.httpEntitlement.setManifest(manifest);\n try {\n // resolveEntitlement() populates the cached snapshot as a side effect;\n // the work-level call is the cheapest way to prime it.\n await this.httpEntitlement.resolveEntitlement({ workId: manifest.meta?.id ?? '' });\n this.paywallService.setSnapshot(this.httpEntitlement.getSnapshot());\n } catch {\n // Leave the anonymous snapshot in place: on a backend failure the\n // reader sees the free preview and the gate, never the paid content.\n }\n }\n }\n\n /** Raise the paywall overlay for a gate. */\n private openPaywall(gate: PaywallGate): void {\n this.paywallGate = gate;\n this.paywallVisible = true;\n }\n\n /** Dismiss the overlay without changing entitlement. */\n closePaywall(): void {\n this.paywallVisible = false;\n this.paywallGate = null;\n }\n\n /**\n * A reader acted on the overlay. Checkout belongs to the host — the player\n * never talks to a payment provider — so the action is emitted and the\n * overlay closes for anything other than a dismiss.\n */\n onPaywallAction(action: PaywallAction): void {\n const gate = this.paywallGate;\n if (gate) {\n this.paywallAction.emit({ action, gate });\n }\n this.closePaywall();\n }\n\n /**\n * Re-check entitlements after the host reports a completed purchase, then\n * drop the overlay if the reader is now through the gate.\n */\n async refreshEntitlements(snapshot?: EntitlementSnapshot): Promise<void> {\n if (snapshot) {\n this.paywallService.setSnapshot(snapshot);\n } else if (this.httpEntitlement) {\n this.httpEntitlement.invalidate();\n const manifest = this.manifestService.getManifest();\n await this.httpEntitlement.resolveEntitlement({ workId: manifest?.meta?.id ?? '' });\n this.paywallService.setSnapshot(this.httpEntitlement.getSnapshot());\n }\n\n const gatedPanelId = this.paywallGate?.refId ?? this.getCurrentPanelId();\n if (gatedPanelId && this.paywallService.canAccess(gatedPanelId)) {\n this.closePaywall();\n }\n }\n\n // ── Age gate ──────────────────────────────────────────────────────────────\n\n private static readonly AGE_VERIFIED_STORAGE_KEY = 'pw-age-verified';\n\n /** Raise the age gate for a panel and remember where the reader was going. */\n private openAgeGate(chapterId: string, panelId: string, transition?: Transition, cameraMove?: CameraMove): void {\n this.ageGateMinimumAge = this.paywallService.ruleFor(panelId)?.minimumAge ?? 18;\n this.pendingAgeGatedNavigation = { chapterId, panelId, transition, cameraMove };\n this.ageGateVisible = true;\n this.cdr.markForCheck();\n }\n\n /** Dismissed without verifying: the reader stays where they were. */\n closeAgeGate(): void {\n this.ageGateVisible = false;\n this.pendingAgeGatedNavigation = null;\n this.cdr.markForCheck();\n }\n\n /**\n * The reader answered the gate. A pass is persisted on the device and\n * folded into the entitlement snapshot, then the interrupted navigation\n * resumes; a fail keeps the overlay (it shows its own message).\n */\n async onAgeGateVerify(result: AgeVerificationResult): Promise<void> {\n this.ageVerified.emit(result);\n if (!result.verified || result.age === undefined) {\n return;\n }\n\n this.persistAgeVerification(result.age);\n this.paywallService.setSnapshot({\n ...this.paywallService.getSnapshot(),\n ageVerified: true,\n age: result.age,\n });\n\n const pending = this.pendingAgeGatedNavigation;\n this.ageGateVisible = false;\n this.pendingAgeGatedNavigation = null;\n this.cdr.markForCheck();\n\n if (pending && this.paywallService.canAccess(pending.panelId)) {\n await this.navigateToPanel(pending.chapterId, pending.panelId, pending.transition, pending.cameraMove);\n }\n }\n\n private persistAgeVerification(age: number): void {\n try {\n localStorage.setItem(\n PlayerShellComponent.AGE_VERIFIED_STORAGE_KEY,\n JSON.stringify({ age, verifiedAt: Date.now() })\n );\n } catch {\n // Storage unavailable (private mode, quota): the gate simply asks again next time.\n }\n }\n\n private restoreAgeVerification(): void {\n if (this.paywallService.getSnapshot().ageVerified) {\n return;\n }\n try {\n const raw = localStorage.getItem(PlayerShellComponent.AGE_VERIFIED_STORAGE_KEY);\n if (!raw) {\n return;\n }\n const stored = JSON.parse(raw) as { age?: number };\n if (typeof stored.age !== 'number') {\n return;\n }\n this.paywallService.setSnapshot({\n ...this.paywallService.getSnapshot(),\n ageVerified: true,\n age: stored.age,\n });\n } catch {\n // Unreadable storage: treat as not verified.\n }\n }\n\n // ── Like / bookmark (device-local social state) ──────────────────────────\n\n private static readonly SOCIAL_STORAGE_KEY = 'pw-social';\n\n /** Key that identifies this work in device storage. */\n private workKey(): string {\n return this.manifestService.getManifest()?.meta?.id ?? this.manifestUrl ?? 'work';\n }\n\n private readSocialStore(): Record<string, SocialEntry> {\n try {\n const raw = localStorage.getItem(PlayerShellComponent.SOCIAL_STORAGE_KEY);\n const parsed = raw ? (JSON.parse(raw) as unknown) : null;\n return parsed && typeof parsed === 'object' ? (parsed as Record<string, SocialEntry>) : {};\n } catch {\n return {};\n }\n }\n\n private writeSocialStore(store: Record<string, SocialEntry>): void {\n try {\n localStorage.setItem(PlayerShellComponent.SOCIAL_STORAGE_KEY, JSON.stringify(store));\n } catch {\n // Storage unavailable: the toggle still works for this session.\n }\n }\n\n private readBookmark(): SocialEntry['bookmark'] | null {\n return this.readSocialStore()[this.workKey()]?.bookmark ?? null;\n }\n\n /** Load the like flag; the bookmark flag follows the current panel. */\n private restoreSocialState(): void {\n const entry = this.readSocialStore()[this.workKey()];\n this.liked = entry?.liked === true;\n this.syncBookmarkFlag();\n }\n\n /** `bookmarked` is true only while the reader is ON the bookmarked panel. */\n private syncBookmarkFlag(): void {\n const bookmark = this.readBookmark();\n this.bookmarked =\n !!bookmark &&\n bookmark.chapterId === this.currentChapter?.id &&\n bookmark.panelId === this.getCurrentPanelId();\n }\n\n // ── Branch choices ────────────────────────────────────────────────────────\n\n /** More than one edge leaves the current panel — the toolbar shows \"Choices\". */\n get hasBranchesAhead(): boolean {\n const panelId = this.getCurrentPanelId();\n const edges = this.currentChapter?.graph?.edges;\n if (!panelId || !edges) {\n return false;\n }\n let count = 0;\n for (const edge of edges) {\n if (edge.from === panelId && ++count > 1) {\n return true;\n }\n }\n return false;\n }\n\n /** Outgoing edges whose conditions pass right now, with reader-facing labels. */\n private computeBranchChoices(): BranchChoice[] {\n const chapter = this.currentChapter;\n const panelId = this.getCurrentPanelId();\n if (!chapter?.graph || !panelId) {\n return [];\n }\n const context = this.variableStore.createContext(chapter.id);\n return chapter.graph.edges\n .filter((edge) => edge.from === panelId)\n .filter((edge) => !edge.condition || evaluateJsonLogic(edge.condition, context))\n .map((edge, index) => ({ edge, index, label: this.branchLabel(edge, chapter, index) }));\n }\n\n private branchLabel(edge: { label?: Record<string, string>; to: string }, chapter: Chapter, index: number): string {\n const fromEdge = this.localizedText(edge.label);\n if (fromEdge) {\n return fromEdge;\n }\n const fromTarget = this.localizedText(chapter.panels?.[edge.to]?.title);\n return fromTarget || `Option ${index + 1}`;\n }\n\n private localizedText(value: LocalizedString | Record<string, string> | undefined): string {\n if (!value) {\n return '';\n }\n if (typeof value === 'string') {\n return value;\n }\n return value[this.locale] ?? value['en-US'] ?? Object.values(value)[0] ?? '';\n }\n\n /** Traverse the chosen edge (its transition / camera move / mutations apply). */\n async onBranchChosen(choice: BranchChoice): Promise<void> {\n this.branchChooserVisible = false;\n const chapter = this.currentChapter;\n if (!chapter) {\n return;\n }\n const settings = this.manifestService.getManifest()?.settings;\n this.trackingService.track('branch_choice', {\n chapterId: chapter.id,\n from: choice.edge.from,\n to: choice.edge.to,\n index: choice.index,\n });\n if (choice.edge.action?.length) {\n this.variableStore.applyMutations(choice.edge.action, { chapterId: chapter.id });\n }\n await this.navigateToPanel(\n chapter.id,\n choice.edge.to,\n choice.edge.transition ?? this.flowEngine.getDefaultTransition(settings),\n choice.edge.cameraMove ?? this.flowEngine.getDefaultCameraMove(settings)\n );\n }\n}\n\n/** Per-work like / bookmark record kept in device storage. */\ninterface SocialEntry {\n liked?: boolean;\n bookmark?: { chapterId: string; panelId: string; savedAt: number };\n}\n","<div class=\"player-shell\" [class.has-error]=\"hasError\">\n <!-- Loading state -->\n @if (loading) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\"></div>\n <p class=\"loading-text\">{{ 'loading.text' | translate }}</p>\n </div>\n }\n\n <!-- Error state -->\n @if (hasError && !loading) {\n <div class=\"error-container\">\n <div class=\"error-icon\"><pw-icon name=\"lucideTriangleAlert\" /></div>\n <h2 class=\"error-title\">{{ 'error.title' | translate }}</h2>\n <p class=\"error-message\">{{ errorMessage }}</p>\n <button class=\"retry-button\" type=\"button\" (click)=\"ngOnInit()\">\n {{ 'error.retry' | translate }}\n </button>\n </div>\n }\n\n <!-- Main player -->\n @if (!loading && !hasError && currentPanel) {\n <div class=\"player-content\">\n <!-- Viewport (panel / page view) -->\n @if (viewMode !== 'canvas') {\n <pw-viewport\n [transition]=\"viewportTransition\"\n [panel]=\"effectivePanel || currentPanel\"\n [page]=\"currentPage || null\"\n [panels]=\"resolvedPanels\"\n [graph]=\"currentChapter?.graph || null\"\n [currentPanelId]=\"getCurrentPanelId() || null\"\n [viewMode]=\"viewMode\"\n [reducedMotion]=\"motionReduced\"\n [locale]=\"locale\"\n [interactive]=\"true\"\n [showOverflowArrows]=\"true\"\n [speechEnabled]=\"speechEnabled\"\n [preload]=\"manifestPreloadSettings\"\n [variableContext]=\"variableContext\"\n (viewportClick)=\"onViewportClick()\"\n (swipe)=\"onSwipe($event)\"\n (navigatePrevious)=\"navigatePrevious()\"\n (navigateNext)=\"navigateNext()\"\n (hotspotActivate)=\"onHotspotActivate($event)\"\n (deadClick)=\"onDeadClick($event)\">\n </pw-viewport>\n }\n\n <!-- Canvas stage (infinite-canvas view, schema 1.4) -->\n @if (viewMode === 'canvas') {\n <pw-canvas-stage\n [canvas]=\"currentChapter?.canvas || null\"\n [panels]=\"resolvedPanels\"\n [graph]=\"currentChapter?.graph || null\"\n [currentPanelId]=\"getCurrentPanelId() || null\"\n [visitedPanelIds]=\"visitedPanelIds\"\n [locale]=\"locale\"\n [variableContext]=\"variableContext\"\n [speechEnabled]=\"speechEnabled\"\n [workBalloonConfig]=\"manifestBalloonConfig\"\n [characters]=\"manifestCharacters\"\n [reducedMotion]=\"motionReduced\"\n [interactive]=\"true\"\n [preload]=\"manifestPreloadSettings\"\n (panelTap)=\"onCanvasPanelTap($event)\"\n (navigateNext)=\"navigateNext()\"\n (navigatePrevious)=\"navigatePrevious()\"\n (viewportClick)=\"onViewportClick()\"\n (hotspotActivate)=\"onHotspotActivate($event)\"\n (cameraChange)=\"cameraChange.emit($event)\">\n </pw-canvas-stage>\n }\n\n <!-- Full Toolbar -->\n <pw-toolbar\n [visible]=\"toolbarVisible\"\n [locale]=\"locale\"\n [availableLocales]=\"availableLocales\"\n [viewMode]=\"viewMode\"\n [pageViewAvailable]=\"pageViewAvailable\"\n [speechEnabled]=\"speechEnabled\"\n [audioEnabled]=\"audioEnabled\"\n [sfxEnabled]=\"sfxEnabled\"\n [autoplayEnabled]=\"autoplayEnabled\"\n [autoplayProgress]=\"autoplayProgress\"\n [secondsPerPanel]=\"secondsPerPanel\"\n [thumbnailsVisible]=\"thumbnailsVisible\"\n [hasAlternatives]=\"!!(currentPanel && currentPanel.variants && currentPanel.variants.length)\"\n [hasBranches]=\"hasBranchesAhead\"\n [showSocial]=\"true\"\n [liked]=\"liked\"\n [bookmarked]=\"bookmarked\"\n (toggleView)=\"onToggleView()\"\n (localeChange)=\"onLocaleChange($event)\"\n (toggleSpeech)=\"onToggleSpeech()\"\n (toggleAudio)=\"onToggleAudio()\"\n (toggleSfx)=\"onToggleSfx()\"\n (toggleAutoplay)=\"onToggleAutoplay()\"\n (secondsPerPanelChange)=\"onSecondsPerPanelChange($event)\"\n (toggleThumbnails)=\"onToggleThumbnails()\"\n (openToc)=\"onOpenToc()\"\n (openSettings)=\"onOpenSettings()\"\n (openLanguage)=\"languageModalVisible = true\"\n (openCharacters)=\"onOpenCharacters()\"\n (cycleAlternative)=\"onCycleAlternative()\"\n (showBranches)=\"onShowBranches()\"\n (openExtras)=\"onOpenExtras()\"\n (like)=\"onLike()\"\n (bookmark)=\"onBookmark()\"\n (share)=\"onShare()\"\n (openComments)=\"onOpenComments()\"\n (close)=\"toggleToolbar()\">\n </pw-toolbar>\n\n <!-- Thumbnail Strip -->\n <pw-thumbnail-strip\n [visible]=\"thumbnailsVisible\"\n [chapters]=\"manifest?.chapters || []\"\n [currentChapterId]=\"currentChapter?.id\"\n [currentPanelId]=\"getCurrentPanelId()\"\n [baseUrl]=\"''\"\n [lockedPanels]=\"[]\"\n (navigate)=\"onThumbnailNavigate($event)\"\n (close)=\"onThumbnailsClose()\">\n </pw-thumbnail-strip>\n\n <!-- Active variant indicator -->\n @if (activeVariantId) {\n <div class=\"variant-active\" role=\"status\" aria-live=\"polite\"\n [attr.aria-label]=\"'Active panel variant: ' + activeVariantId\">\n {{ activeVariantId }}\n </div>\n }\n\n <!-- PanelWave floating icon -->\n @if (!toolbarVisible) {\n <button \n class=\"floating-icon\"\n type=\"button\"\n aria-label=\"Show toolbar\"\n (click)=\"toggleToolbar()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z\"/>\n </svg>\n </button>\n }\n\n <!-- Modals -->\n @if (paywallVisible && paywallGate) {\n <pw-paywall-overlay\n [visible]=\"paywallVisible\"\n [gate]=\"paywallGate\"\n [locale]=\"locale\"\n (action)=\"onPaywallAction($event)\"\n (close)=\"closePaywall()\">\n </pw-paywall-overlay>\n }\n\n @if (ageGateVisible) {\n <pw-age-gate\n [visible]=\"ageGateVisible\"\n [minimumAge]=\"ageGateMinimumAge\"\n [locale]=\"locale\"\n [allowDismiss]=\"true\"\n (verify)=\"onAgeGateVerify($event)\"\n (close)=\"closeAgeGate()\">\n </pw-age-gate>\n }\n\n @if (branchChooserVisible) {\n <pw-branch-chooser\n [visible]=\"branchChooserVisible\"\n [locale]=\"locale\"\n [choices]=\"branchChoices\"\n (choose)=\"onBranchChosen($event)\"\n (close)=\"branchChooserVisible = false\">\n </pw-branch-chooser>\n }\n\n @if (tocVisible) {\n <pw-toc-overlay\n [visible]=\"tocVisible\"\n [manifest]=\"manifest\"\n [currentChapterId]=\"currentChapter?.id\"\n [currentPanelId]=\"getCurrentPanelId()\"\n [locale]=\"locale\"\n [baseUrl]=\"''\"\n (navigate)=\"onTocNavigate($event)\"\n (close)=\"tocVisible = false\">\n </pw-toc-overlay>\n }\n\n @if (settingsVisible) {\n <pw-settings-modal\n [visible]=\"settingsVisible\"\n [variables]=\"variableDefinitions\"\n [variableValues]=\"settingsVariableValues\"\n [availableLocales]=\"availableLocales\"\n [locale]=\"locale\"\n [preferences]=\"settingsPreferences\"\n (preferencesChange)=\"onPreferencesChange($event)\"\n (variableChange)=\"onSettingsVariableChange($event)\"\n (close)=\"settingsVisible = false\">\n </pw-settings-modal>\n }\n\n @if (languageModalVisible) {\n <pw-language-modal\n [visible]=\"languageModalVisible\"\n [currentLocale]=\"locale\"\n [availableLocales]=\"availableLocales\"\n (localeSelected)=\"onLocaleChange($event)\"\n (closeModal)=\"languageModalVisible = false\">\n </pw-language-modal>\n }\n\n @if (charactersVisible) {\n <pw-character-roster\n [visible]=\"charactersVisible\"\n [characters]=\"characters\"\n [locale]=\"locale\"\n [baseUrl]=\"''\"\n (close)=\"charactersVisible = false\">\n </pw-character-roster>\n }\n\n @if (extrasVisible) {\n <pw-extras-viewer\n [visible]=\"extrasVisible\"\n [extras]=\"extrasList\"\n [initialExtraId]=\"extrasInitialId\"\n [locale]=\"locale\"\n (close)=\"extrasVisible = false; extrasInitialId = undefined\">\n </pw-extras-viewer>\n }\n\n @if (actionModalVisible) {\n <pw-action-modal\n [visible]=\"actionModalVisible\"\n [locale]=\"locale\"\n [title]=\"actionModalTitle\"\n [content]=\"actionModalContent\"\n (close)=\"actionModalVisible = false\">\n </pw-action-modal>\n }\n\n @if (shareVisible) {\n <pw-share-modal\n [visible]=\"shareVisible\"\n [shareable]=\"currentPanel.shareable ?? true\"\n (close)=\"shareVisible = false\">\n </pw-share-modal>\n }\n\n @if (commentsVisible) {\n <pw-comments-drawer\n [visible]=\"commentsVisible\"\n (close)=\"commentsVisible = false\">\n </pw-comments-drawer>\n }\n </div>\n }\n</div>\n","/**\n * Plugin Sandbox Component\n * Provides a secure container for plugin iframes\n */\n\nimport { inject,\n Component,\n Input,\n Output,\n EventEmitter,\n OnInit,\n OnDestroy,\n ElementRef,\n ViewChild,\n ChangeDetectionStrategy,\n} from '@angular/core';\n\nimport { PluginHostService } from '../../services/plugin-host.service';\nimport type { PluginManifest } from '../../types/plugin.types';\n\n@Component({\n selector: 'pw-plugin-sandbox',\n imports: [],\n template: `\n <div class=\"plugin-sandbox\" [class.loading]=\"loading\">\n @if (loading) {\n <div class=\"plugin-loading\">\n <div class=\"spinner\"></div>\n <p>Loading plugin: {{ manifest?.name }}</p>\n </div>\n }\n <div #container class=\"plugin-container\" [class.hidden]=\"loading\"></div>\n @if (error) {\n <div class=\"plugin-error\">\n <p>Failed to load plugin: {{ error }}</p>\n </div>\n }\n </div>\n `,\n styles: [`\n .plugin-sandbox {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n .plugin-container {\n width: 100%;\n height: 100%;\n }\n\n .plugin-container.hidden {\n opacity: 0;\n }\n\n .plugin-loading,\n .plugin-error {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n }\n\n .spinner {\n border: 3px solid rgba(0, 0, 0, 0.1);\n border-top-color: #3498db;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n animation: spin 1s linear infinite;\n margin: 0 auto 16px;\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .plugin-error {\n color: #e74c3c;\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class PluginSandboxComponent implements OnInit, OnDestroy {\n @Input() manifest!: PluginManifest;\n @Output() loaded = new EventEmitter<void>();\n @Output() failed = new EventEmitter<Error>();\n\n @ViewChild('container', { static: true }) container!: ElementRef<HTMLDivElement>;\n\n loading = true;\n error: string | null = null;\n\n private readonly pluginHost = inject(PluginHostService);\n\n async ngOnInit() {\n try {\n await this.pluginHost.loadPlugin(this.manifest);\n await this.pluginHost.mountPlugin(\n this.manifest.id,\n this.container.nativeElement\n );\n this.loading = false;\n this.loaded.emit();\n } catch (err) {\n this.loading = false;\n this.error = (err as Error).message;\n this.failed.emit(err as Error);\n }\n }\n\n async ngOnDestroy() {\n try {\n await this.pluginHost.disposePlugin(this.manifest.id);\n } catch (err) {\n console.error('Failed to dispose plugin:', err);\n }\n }\n}\n","import { Component } from '@angular/core';\r\n\r\n@Component({\n selector: 'pw-player',\n imports: [],\n template: `\r\n <p>\r\n player works!\r\n </p>\r\n `,\n styles: ``\n})\r\nexport class PlayerComponent {\r\n\r\n}\r\n","/*\r\n * Public API Surface of player\r\n */\r\n\r\n// Type definitions\r\nexport * from './lib/types';\r\n\r\n// Services (export only the service classes, not re-exporting types)\r\nexport { PlayerStateService } from './lib/services/player-state.service';\r\nexport { ManifestService } from './lib/services/manifest.service';\r\nexport { VariableStoreService } from './lib/services/variable-store.service';\r\nexport { FlowEngineService } from './lib/services/flow-engine.service';\r\nexport { ImageCacheService } from './lib/services/image-cache.service';\r\nexport { AudioEngineService, type AudioTrack, type AudioRole, type PlaybackState } from './lib/services/audio-engine.service';\r\nexport {\r\n PanelAudioService,\r\n busForRole,\r\n PANEL_AUDIO_LEAVE_FADE_MS,\r\n type ResolvedPanelAudio,\r\n} from './lib/services/panel-audio.service';\r\nexport { VideoControllerService, type VideoState, type VideoEvent, type VideoStatus } from './lib/services/video-controller.service';\r\nexport { UserGestureService } from './lib/services/user-gesture.service';\r\nexport { VisibilityService, VISIBILITY_THRESHOLD, type VisibilityChange } from './lib/services/visibility.service';\r\nexport {\r\n VideoSequencerService,\r\n DEFAULT_STALL_TIMEOUT_MS,\r\n type SequencedVideo,\r\n type SequencedVideoInfo,\r\n} from './lib/services/video-sequencer.service';\r\nexport { PreloadService, type PreloadItem, type PreloadPriority } from './lib/services/preload.service';\r\nexport { TrackingService, type TrackingEvent } from './lib/services/tracking.service';\r\nexport { EntitlementService } from './lib/services/entitlement.service';\r\nexport { PaywallService } from './lib/services/paywall.service';\r\n\r\n// Paywall evaluation (manifest `paywall.rules` -> access decisions).\r\nexport {\r\n ANONYMOUS_READER,\r\n evaluatePanelAccess,\r\n evaluateWorkAccess,\r\n findWorkGateRule,\r\n fromManifestRule,\r\n readingOrderFromManifest,\r\n rulesFromManifest,\r\n satisfiesRule,\r\n toEntitlementStatus,\r\n type AccessDecision,\r\n type EntitlementSnapshot,\r\n type EvaluatorEntitlementType,\r\n type EvaluatorRule,\r\n type EvaluatorScope,\r\n type LockReason,\r\n type PanelRef,\r\n} from './lib/entitlement/paywall-evaluator';\r\nexport {\r\n HttpEntitlementAdapter,\r\n type EntitlementSnapshotResponse,\r\n type HttpEntitlementAdapterConfig,\r\n} from './lib/entitlement/http-entitlement.adapter';\r\nexport { PluginHostService } from './lib/services/plugin-host.service';\r\nexport { ExportService } from './lib/services/export.service';\r\nexport { TranslationService } from './lib/services/translation.service';\r\n\r\n// Legacy\r\nexport * from './lib/player.service';\r\n\r\n// Utilities\r\nexport {\r\n DEFAULT_BALLOON_CONFIG,\r\n mergeBalloonConfig,\r\n balloonConfigToRenderOptions,\r\n balloonConfigToTailOptions,\r\n ComicBalloon,\r\n createBalloon,\r\n type BalloonOptions,\r\n type TailOptions,\r\n type BalloonRenderResult,\r\n DEFAULT_VIDEO_PLAY_MODE,\r\n DEFAULT_VIDEO_START_MODE,\r\n DEFAULT_VIDEO_MUTED,\r\n resolvePlayMode,\r\n resolveStartMode,\r\n resolveMuted,\r\n resolveVideoConfig,\r\n type EffectiveVideoConfig,\r\n selectVariant,\r\n applyVariantOverrides,\r\n resolvePanelVariant,\r\n resolvePanels,\r\n type ResolvedPanel,\r\n type VariantContext,\r\n} from './lib/utils';\r\n\r\n// Components\r\nexport { PwIconComponent } from './lib/components/icon/pw-icon.component';\r\nexport { PlayerShellComponent } from './lib/components/player-shell/player-shell.component';\r\nexport {\r\n CanvasStageComponent,\r\n CANVAS_PANEL_BUDGET,\r\n type StagePlacement,\r\n} from './lib/components/canvas-stage/canvas-stage.component';\r\nexport {\r\n CanvasCameraService,\r\n type CameraState,\r\n} from './lib/services/canvas-camera.service';\r\nexport { SpeechBubblesComponent } from './lib/components/overlays/speech-bubbles/speech-bubbles.component';\r\nexport { HotspotsOverlayComponent } from './lib/components/overlays/hotspots-overlay/hotspots-overlay.component';\r\nexport { ActionModalComponent } from './lib/components/modals/action-modal/action-modal.component';\r\nexport { BranchChooserComponent, type BranchChoice } from './lib/components/modals/branch-chooser/branch-chooser.component';\r\nexport { HotspotActionService, type HotspotUiEffect } from './lib/services/hotspot-action.service';\r\nexport { PaywallOverlayComponent, type PaywallAction } from './lib/components/overlays/paywall-overlay/paywall-overlay.component';\r\nexport { AgeGateComponent, type AgeVerificationResult } from './lib/components/overlays/age-gate/age-gate.component';\r\nexport { PluginSandboxComponent } from './lib/components/plugin-sandbox/plugin-sandbox.component';\r\nexport { VideoLayerComponent, type LayerViewMode } from './lib/components/layers/video-layer/video-layer.component';\r\nexport * from './lib/player.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2"],"mappings":"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"}
|