@phont-ai/subtitles-core 0.1.10 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -45,6 +45,128 @@ interface PhontClientOptions {
45
45
  apiBaseUrl?: string;
46
46
  }
47
47
 
48
+ /**
49
+ * Animation Types
50
+ *
51
+ * Type definitions for animation parameter states, curves, and animation state
52
+ */
53
+ interface CurvePoint {
54
+ time: number;
55
+ value: number | string;
56
+ }
57
+ interface ParameterState {
58
+ points: CurvePoint[];
59
+ currentValue?: number | string;
60
+ }
61
+ interface ParameterStates {
62
+ [key: string]: ParameterState;
63
+ }
64
+ interface AnimationParameterStates {
65
+ parameterStates: ParameterStates;
66
+ duration?: number;
67
+ format?: 'normalized' | 'absolute';
68
+ fontData?: {
69
+ style?: {
70
+ fontFamily?: string;
71
+ [key: string]: unknown;
72
+ };
73
+ config?: unknown;
74
+ fontId?: string | null;
75
+ fontName?: string | null;
76
+ };
77
+ text?: string;
78
+ name?: string;
79
+ }
80
+ interface AnimationState {
81
+ fontSize: number;
82
+ scale: number;
83
+ opacity: number;
84
+ slant: number;
85
+ weight: number;
86
+ width: number;
87
+ textColor: string;
88
+ translateX: number;
89
+ translateY: number;
90
+ stretchY: number;
91
+ rotation?: number;
92
+ skewX?: number;
93
+ fontVariationAxes?: Record<string, number>;
94
+ letterShake?: number;
95
+ shadowColor?: string;
96
+ }
97
+ interface SentenceAnimationState extends AnimationState {
98
+ text: string;
99
+ emotion: string;
100
+ emotionIntensity: number;
101
+ fontFamily: string;
102
+ startTime: number;
103
+ endTime: number;
104
+ duration: number;
105
+ isActive: boolean;
106
+ }
107
+ interface WordAnimationState {
108
+ text: string;
109
+ words: Array<{
110
+ word: string;
111
+ start: number;
112
+ end: number;
113
+ animationEnd: number;
114
+ isActive: boolean;
115
+ emotion: string;
116
+ emotionIntensity: number;
117
+ originalEmotionIntensity?: number;
118
+ fontFamily: string;
119
+ emphasis: number;
120
+ emphasisEffect?: any;
121
+ strongEmphasis?: any;
122
+ animationParameters: AnimationState;
123
+ joyAnimationMode?: 'letter' | 'letter-bulge' | 'word' | null;
124
+ joyProgress?: number | null;
125
+ }>;
126
+ currentWordIndex: number;
127
+ emotion: string;
128
+ emotionIntensity: number;
129
+ fontFamily: string;
130
+ startTime: number;
131
+ endTime: number;
132
+ isActive: boolean;
133
+ }
134
+ interface SubtitleSegment {
135
+ start_time: number;
136
+ end_time: number;
137
+ text?: string;
138
+ subtitle?: string;
139
+ emotion?: string;
140
+ emotion_intensity?: number;
141
+ animation_url?: string;
142
+ /** Per-cue expressiveness (0–1); combined with global GTS slider at playback. */
143
+ gts?: number;
144
+ words?: Array<{
145
+ word: string;
146
+ start: number;
147
+ end: number;
148
+ emphasis?: number;
149
+ emotion?: string;
150
+ emotion_intensity?: number;
151
+ animation_url?: string;
152
+ animations?: Record<string, number>;
153
+ gts?: number;
154
+ }>;
155
+ animations?: Record<string, number>;
156
+ volume?: number;
157
+ speech_rate?: number;
158
+ merged_subtitles?: SubtitleSegment[];
159
+ }
160
+ interface AnimationOptions {
161
+ maxExpression?: number;
162
+ threshold?: number;
163
+ isRTL?: boolean;
164
+ volume?: number;
165
+ speechRate?: number;
166
+ nextSegmentStartTime?: number;
167
+ extendedEndTime?: number;
168
+ }
169
+
48
170
  /**
49
171
  * ============================================
50
172
  * SUBTITLE STATE MANAGER
@@ -164,12 +286,12 @@ declare class SubtitleStateManager {
164
286
  *
165
287
  * STATUS: Phase 2 Complete - All 8 classes extracted, clean architecture, no duplication
166
288
  */
167
- type AnimationMode = "Sentence" | "Word" | string;
289
+ type AnimationMode$1 = "Sentence" | "Word" | string;
168
290
  interface SubtitleState {
169
291
  isVisible: boolean;
170
292
  isKaraokeMode: boolean;
171
293
  isSpeaker: boolean;
172
- animationMode: AnimationMode;
294
+ animationMode: AnimationMode$1;
173
295
  currentSubtitle: string;
174
296
  currentSequence: number | null;
175
297
  subtitles: any[];
@@ -242,7 +364,7 @@ declare class SubtitleManager {
242
364
  toggleSoundbiteAnimations(isVisible: boolean): void;
243
365
  mapEventLabelToAnimation(eventLabel: string): string | null;
244
366
  processSoundbiteAnimations(soundbites: any[]): any[];
245
- setAnimationMode(mode: AnimationMode): void;
367
+ setAnimationMode(mode: AnimationMode$1): void;
246
368
  toggleTransition(enabled: boolean): void;
247
369
  updateSubtitle(text: string): void;
248
370
  updateLiveTime(videoTime?: number | null): number;
@@ -262,7 +384,7 @@ declare class SubtitleManager {
262
384
  getInitialLiveSequenceNumber(): Promise<number>;
263
385
  fetchSubtitles(sequenceNumber: number): Promise<any | null>;
264
386
  loadVodSubtitles(urlOrVodId: string, languageCode?: string | null): Promise<void>;
265
- _processVodData(data: any, url: string, languageCode: string | null): void;
387
+ _processVodData(data: any, url: string, languageCode: string | null, originalSubtitles?: any[]): void;
266
388
  getSubtitleForTime(time: number): any;
267
389
  getLiveSubtitleForTime(): any;
268
390
  getCurrentSubtitleData(): any | null;
@@ -293,106 +415,191 @@ declare class SubtitleManager {
293
415
  declare const subtitleManager: SubtitleManager;
294
416
 
295
417
  /**
296
- * Animation Types
418
+ * URL Decoder for Animation Parameters
297
419
  *
298
- * Type definitions for animation parameter states, curves, and animation state
420
+ * Extracted from app/playground/utils/urlEncoding.js
421
+ * Decodes animation URLs into parameter states
422
+ *
423
+ * Supports both full URLs and query strings:
424
+ * - Full URL: https://stage-dev.phont.ai/playground/shared?name=...&scale=0,1|1,1.2
425
+ * - Query string: ?name=...&scale=0,1|1,1.2
299
426
  */
300
- interface CurvePoint {
301
- time: number;
302
- value: number | string;
303
- }
304
- interface ParameterState {
305
- points: CurvePoint[];
306
- currentValue?: number | string;
307
- }
308
- interface ParameterStates {
309
- [key: string]: ParameterState;
310
- }
311
- interface AnimationParameterStates {
312
- parameterStates: ParameterStates;
313
- duration?: number;
314
- format?: 'normalized' | 'absolute';
315
- }
316
- interface AnimationState {
317
- fontSize: number;
427
+
428
+ /**
429
+ * Decode animation data from URL or query string
430
+ * @param urlOrQuery - Full URL (https://...) or query string (?name=... or name=...)
431
+ * @returns Decoded animation data object with parameterStates
432
+ */
433
+ declare function decodeAnimationUrl(urlOrQuery: string): AnimationParameterStates;
434
+
435
+ /**
436
+ * Animation parameter calculation -- the unified rendering pipeline.
437
+ * TypeScript port of app/utils/animation/animationParameters.js.
438
+ *
439
+ * Samples authored URL curves with linear interpolation, then scales deviations
440
+ * proportionally from a reference point (REFERENCE_INTENSITY × REFERENCE_GTS).
441
+ * At the reference point the authored curve is rendered 1:1.
442
+ */
443
+
444
+ /**
445
+ * Exponential variance curve (hockey stick)
446
+ *
447
+ * Creates an exponential curve that accelerates dramatically after 0.7 intensity.
448
+ * Low intensities (0.0-0.7): Subtle effects (gradual rise)
449
+ * High intensities (0.7-1.0): Dramatic effects (exponential acceleration)
450
+ *
451
+ * @param i - Input intensity (0-1)
452
+ * @returns Transformed intensity (0-1) with exponential variance
453
+ */
454
+ declare function hockeyStickIntensity(i: number): number;
455
+ /**
456
+ * Sample a parameter curve at a given time
457
+ *
458
+ * Interpolates between keyframe points to get the value at a specific time.
459
+ * Supports both normalized (0-1) and absolute time formats.
460
+ * For color parameters, uses RGB interpolation for smooth color transitions.
461
+ *
462
+ * @param points - Array of {time, value} points or [time, value] arrays
463
+ * @param t - Normalized time (0-1)
464
+ * @param duration - Animation duration in seconds
465
+ * @param isNormalized - Whether points are in normalized (0-1) or absolute time
466
+ * @param parameterName - Name of the parameter (e.g., 'color', 'shadowColor', 'outlineColor') for color interpolation
467
+ * @returns Sampled value or null if no points
468
+ */
469
+ declare function sampleParameterCurve(points: Array<{
470
+ time?: number;
471
+ value?: number | string;
472
+ } | [number, number | string]> | undefined | null, t: number, duration: number, isNormalized?: boolean, parameterName?: string | null): number | string | null;
473
+ interface AnimationParameterState {
474
+ rawIntensity: number;
475
+ scaleFactor: number;
318
476
  scale: number;
319
- opacity: number;
320
477
  slant: number;
478
+ stretchY: number;
479
+ translateX: number;
480
+ translateY: number;
321
481
  weight: number;
322
482
  width: number;
483
+ fontFamily: string;
323
484
  textColor: string;
324
- translateX: number;
325
- translateY: number;
326
- stretchY: number;
327
- rotation?: number;
328
- skewX?: number;
329
- fontVariationAxes?: Record<string, number>;
330
- letterShake?: number;
331
- letterSpacingOffsets?: number[];
332
- shadowColor?: string;
333
- }
334
- interface SentenceAnimationState extends AnimationState {
485
+ opacity: number;
486
+ textShadow: string;
487
+ blur: number;
488
+ outlineWidth: number;
489
+ outlineColor: string;
490
+ outline2Width?: number;
491
+ outline2Color?: string;
492
+ outline3Width?: number;
493
+ outline3Color?: string;
494
+ outlineShadowWidth?: number;
495
+ outlineShadowColor?: string;
496
+ outlineShadowBlur?: number;
497
+ glowIntensity?: number;
498
+ glowColor?: string;
499
+ snakeWave?: number;
500
+ karaoke?: number;
501
+ stretchX?: number;
502
+ letterSpacing: string;
503
+ fontVariationAxes: Record<string, number>;
335
504
  text: string;
336
- emotion: string;
337
- emotionIntensity: number;
338
- fontFamily: string;
339
- startTime: number;
340
- endTime: number;
341
- duration: number;
342
- isActive: boolean;
505
+ joy: number;
506
+ fear: number;
507
+ standardEmphasis: number;
508
+ strongEmphasis: number;
509
+ joyWaveProgress: number;
343
510
  }
344
- interface WordAnimationState {
345
- text: string;
346
- words: Array<{
347
- word: string;
348
- start: number;
349
- end: number;
350
- animationEnd: number;
351
- isActive: boolean;
352
- emotion: string;
353
- emotionIntensity: number;
354
- originalEmotionIntensity?: number;
355
- fontFamily: string;
356
- emphasis: number;
357
- emphasisEffect?: any;
358
- strongEmphasis?: any;
359
- animationParameters: AnimationState;
360
- joyAnimationMode?: 'letter' | 'letter-bulge' | 'word' | null;
361
- joyProgress?: number | null;
362
- }>;
363
- currentWordIndex: number;
511
+ declare const REFERENCE_INTENSITY = 0.7;
512
+ declare const REFERENCE_GTS = 0.7;
513
+ /** Play authored URL curves 1:1 — matches main playground preview (no intensity/GTS scaling). */
514
+ /** Playground / converter preview only — bypasses GTS scaling (1:1 at reference). */
515
+ declare const AUTHORED_PLAYBACK_OPTIONS: {
516
+ rawMode: boolean;
517
+ };
518
+ /**
519
+ * Sample all animation parameters at time `t` with proportional intensity scaling.
520
+ *
521
+ * The authored curve represents the animation at REFERENCE_INTENSITY × REFERENCE_GTS.
522
+ * At those values you see exactly what was authored. Other intensity × GTS values
523
+ * scale linearly from there.
524
+ */
525
+ declare function calculateAnimationParameters(animationData: AnimationParameterStates | null, rawIntensity: number, t: number, gts: number, subtitleDuration?: number | null, { rawMode }?: {
526
+ rawMode?: boolean;
527
+ }): AnimationParameterState | null;
528
+
529
+ type AnimationMode = 'sentence' | 'word';
530
+ type AnimationStateOptions = AnimationOptions & {
531
+ transparentUntilSpoken?: boolean;
532
+ };
533
+ declare function calculateAnimationState(segment: SubtitleSegment | null, currentTime: number, modeOrOptions?: AnimationMode | AnimationStateOptions, maybeOptions?: AnimationStateOptions): SentenceAnimationState | WordAnimationState;
534
+
535
+ /**
536
+ * Emotion Animation URLs
537
+ *
538
+ * Config mapping emotion → animation URL
539
+ * Uses full playground URLs from app/gallery/config/animations.js
540
+ *
541
+ * SYNCED FROM: app/gallery/config/emotionMapping.js
542
+ *
543
+ * To update these URLs:
544
+ * 1. Update app/gallery/config/animations.js with new URLs
545
+ * 2. Update app/gallery/config/emotionMapping.js to map emotions to indices
546
+ * 3. Run: node scripts/sync-animation-urls.js
547
+ * OR manually copy the URLs based on the mapping
548
+ *
549
+ * The decodeAnimationUrl() function now supports both full URLs and query strings.
550
+ */
551
+ declare const ANIMATION_URLS: string[];
552
+ /**
553
+ * Emotion to Animation URL mapping
554
+ * Based on app/gallery/config/emotionMapping.js
555
+ *
556
+ * Maps each emotion to an index in ANIMATION_URLS array
557
+ */
558
+ declare const EMOTION_ANIMATION_URLS: Record<string, string>;
559
+ /**
560
+ * Get animation URL for an emotion
561
+ * @param emotion - Emotion name (case-insensitive)
562
+ * @returns Full animation URL or query string fallback
563
+ */
564
+ declare function getAnimationUrlForEmotion(emotion: string): string;
565
+
566
+ /**
567
+ * Published Animation Resolver (framework-agnostic)
568
+ *
569
+ * Fetches the active published animation URL for each emotion from the backend,
570
+ * caches the results, and provides sync/async accessors.
571
+ *
572
+ * Any consumer (app, SDK, extension) creates an instance by supplying a fetcher
573
+ * that returns an array of animation objects for a given stylesheet.
574
+ *
575
+ * USAGE:
576
+ * import { createPublishedAnimationResolver } from '@phont-ai/subtitles-core';
577
+ *
578
+ * const resolver = createPublishedAnimationResolver(
579
+ * async (stylesheet) => fetch(`/animations?stylesheet_name=${stylesheet}&is_active=true`).then(r => r.json())
580
+ * );
581
+ *
582
+ * await resolver.prefetch('default'); // warm the cache
583
+ * const url = resolver.getSync('lust'); // sync (returns null if not cached)
584
+ * const url = await resolver.get('lust'); // async (fetches if needed)
585
+ * resolver.invalidate(); // bust after publishing
586
+ */
587
+ interface AnimationRecord {
364
588
  emotion: string;
365
- emotionIntensity: number;
366
- fontFamily: string;
367
- startTime: number;
368
- endTime: number;
369
- isActive: boolean;
370
- }
371
- interface SubtitleSegment {
372
- start_time: number;
373
- end_time: number;
374
- text?: string;
375
- subtitle?: string;
376
- words?: Array<{
377
- word: string;
378
- start: number;
379
- end: number;
380
- emphasis?: number;
381
- }>;
382
- animations?: Record<string, number>;
383
- volume?: number;
384
- speech_rate?: number;
385
- merged_subtitles?: SubtitleSegment[];
589
+ url: string;
590
+ is_active: boolean;
591
+ [key: string]: unknown;
386
592
  }
387
- interface AnimationOptions {
388
- maxExpression?: number;
389
- threshold?: number;
390
- isRTL?: boolean;
391
- volume?: number;
392
- speechRate?: number;
393
- nextSegmentStartTime?: number;
394
- extendedEndTime?: number;
593
+ type AnimationFetcher = (stylesheetName: string) => Promise<AnimationRecord[]>;
594
+ interface PublishedAnimationResolver {
595
+ prefetch: (stylesheetName?: string) => Promise<Map<string, string>>;
596
+ get: (emotion: string, stylesheetName?: string) => Promise<string | null>;
597
+ getSync: (emotion: string, stylesheetName?: string) => string | null;
598
+ invalidate: () => void;
395
599
  }
600
+ declare function createPublishedAnimationResolver(fetcher: AnimationFetcher, { ttlMs }?: {
601
+ ttlMs?: number;
602
+ }): PublishedAnimationResolver;
396
603
 
397
604
  /**
398
605
  * Emotion Selector
@@ -421,86 +628,24 @@ interface EmotionSelectionResult {
421
628
  declare function selectEmotion(animationsObject: Record<string, number> | null | undefined, threshold?: number): EmotionSelectionResult;
422
629
 
423
630
  /**
424
- * Animation Engine
631
+ * Timing Utilities
425
632
  *
426
- * Pure functions that calculate animation state from emotion curves
427
- * Uses function-based EMOTION_ANIMATIONS (identical to monorepo)
633
+ * Pure functions for calculating subtitle timing
428
634
  */
429
635
 
430
636
  /**
431
- * Calculate sentence animation state
432
- *
433
- * Pure function version of useSentenceAnimation - uses function-based EMOTION_ANIMATIONS (identical to monorepo)
637
+ * Get subtitle timing information
434
638
  */
435
- declare function calculateSentenceAnimation(segment: SubtitleSegment | null, currentTime: number, options?: AnimationOptions): SentenceAnimationState;
639
+ declare function getSubtitleTiming(subtitle: SubtitleSegment | null): {
640
+ startTime: number;
641
+ endTime: number;
642
+ duration: number;
643
+ };
436
644
  /**
437
- * Calculate word animation state
438
- *
439
- * Pure function version of useWordAnimation - uses function-based EMOTION_ANIMATIONS (identical to monorepo)
440
- */
441
- declare function calculateWordAnimation(segment: SubtitleSegment | null, currentTime: number, options?: AnimationOptions): WordAnimationState;
442
- /**
443
- * Main function: Calculate animation state from segment and emotion
444
- *
445
- * This is the main entry point that uses function-based EMOTION_ANIMATIONS (identical to monorepo)
446
- */
447
- declare function calculateAnimationState(segment: SubtitleSegment | null, currentTime: number, mode: 'sentence' | 'word', options?: AnimationOptions): SentenceAnimationState | WordAnimationState;
448
-
449
- /**
450
- * Timing Utilities
451
- *
452
- * Pure functions for calculating subtitle timing
453
- */
454
-
455
- /**
456
- * Get subtitle timing information
457
- */
458
- declare function getSubtitleTiming(subtitle: SubtitleSegment | null): {
459
- startTime: number;
460
- endTime: number;
461
- duration: number;
462
- };
463
- /**
464
- * Get subtitle text content
465
- */
466
- declare function getSubtitleText(subtitle: SubtitleSegment | null): string;
467
- /**
468
- * Calculate normalized time (t: 0→1) through subtitle duration
645
+ * Calculate normalized time (t: 0→1) through subtitle duration
469
646
  */
470
647
  declare function calculateNormalizedTime(currentTime: number, startTime: number, duration: number): number;
471
648
 
472
- /**
473
- * **EMOTION_CURVES_DEFINITION** - Animation DNA
474
- *
475
- * Emotion Curves - Animation Parameter Definitions
476
- *
477
- * These curves define how subtitle text animates over time based on emotion.
478
- * Each emotion has time-based functions that return values for visual parameters.
479
- *
480
- * PARAMETERS:
481
- * - fontSize: Always constant (ANIMATION_STYLING.fontSize) for layout stability
482
- * - scale: Size multiplier applied via CSS transform (prevents text wrapping)
483
- * - slant: Italic/skew effect in degrees (applied as CSS skewX)
484
- * - weight: Font weight (100-900) - overridden by VariableFontContext in practice
485
- * - translateX/Y: Movement in pixels (direct CSS values)
486
- * - textColor: Text color (rgba)
487
- * - stretchY: Vertical stretch multiplier (CSS scaleY)
488
- * - letterShakeIntensity: Per-letter shake amount in pixels (fear)
489
- *
490
- * WHY SCALE INSTEAD OF FONTSIZE:
491
- * Using transform: scale() instead of fontSize changes allows the layout engine
492
- * to calculate word positions ONCE at the base fontSize, preventing words from
493
- * wrapping to new lines mid-animation. Scale is GPU-accelerated and doesn't trigger reflow.
494
- *
495
- * ⚠️ Parameters NOT included (handled elsewhere):
496
- * - opacity: Always 1.0 (fade in/out handled by controllers)
497
- * - shadows: Handled by styling.js ANIMATION_STYLING.shadow (emotion-specific for disgust/angry)
498
- * - font family: Handled by fontSelection.js based on emotion + intensity
499
- * - transitions: Handled by styling.js ANIMATION_STYLING.transition
500
- * - marginRight: Handled by calculateDynamicWordSpacing() based on current scale
501
- */
502
- declare const EMOTION_ANIMATIONS: Record<string, any>;
503
-
504
649
  /**
505
650
  * Animation Defaults - Visual Styling Layer
506
651
  *
@@ -572,6 +717,11 @@ declare const ANIMATION_STYLING: {
572
717
  wordSpacingMultiplier: number;
573
718
  fontSizeOffset: number;
574
719
  };
720
+ 'Bricolage Grotesque': {
721
+ letterSpacing: string;
722
+ wordSpacingMultiplier: number;
723
+ fontSizeOffset: number;
724
+ };
575
725
  Rakkas: {
576
726
  letterSpacing: string;
577
727
  wordSpacingMultiplier: number;
@@ -607,6 +757,9 @@ declare const RENDERING_CONTROL: {
607
757
  breathingRoomDuration: number;
608
758
  breathingRoomMinGap: number;
609
759
  breathingRoomLargeGap: number;
760
+ breathingRoomSafetyBuffer: number;
761
+ breathingRoomNoNextHold: number;
762
+ fadeOutDuration: number;
610
763
  timeRangeTolerance: number;
611
764
  };
612
765
  emotion: {
@@ -703,81 +856,22 @@ declare const RENDERING_CONTROL: {
703
856
  };
704
857
  };
705
858
 
706
- /**
707
- * Shared Animation Parameter Calculation Utility
708
- *
709
- * Calculates animation parameters from emotion curves.
710
- * Shared by calculateWordAnimation and calculateSentenceAnimation to eliminate duplication.
711
- *
712
- * This utility extracts all animation parameters defined in EMOTION_ANIMATIONS
713
- * including variation axes (YOPQ, YTAS) that are separate from voice axes (wght, wdth).
714
- *
715
- * TERMINOLOGY:
716
- * - **Voice Axes**: Font axes driven by audio analysis (volume→wght, speech_rate→wdth)
717
- * - **Variation Axes**: Font axes driven by emotion animations (YOPQ, YTAS from emotion curves)
718
- */
719
- interface VariableFontStyle {
720
- fontWeight?: number;
721
- fontStretch?: string;
722
- }
723
- interface AnimationParameters {
724
- fontSize: number;
725
- scale: number;
726
- opacity: number;
727
- slant: number;
728
- weight: number;
729
- width: number;
730
- textColor: string;
731
- translateX: number;
732
- translateY: number;
733
- stretchY: number;
734
- letterShake?: number;
735
- fontVariationAxes?: Record<string, number>;
736
- shadowColor?: string | ((t: number, intensity: number) => string);
737
- }
738
- interface EmotionCurve {
739
- fontSize?: number | ((t: number, intensity: number) => number);
740
- scale?: number | ((t: number, intensity: number) => number);
741
- opacity?: number | ((t: number, intensity: number) => number);
742
- slant?: number | ((t: number, intensity?: number) => number);
743
- weight?: number | ((t: number, intensity?: number) => number);
744
- translateX?: number | ((t: number, intensity: number) => number);
745
- translateY?: number | ((t: number, intensity: number) => number);
746
- stretchY?: number | ((t: number, intensity: number) => number);
747
- textColor?: string | ((t: number, intensity: number) => string);
748
- shadowColor?: string | ((t: number, intensity: number) => string);
749
- thinStroke?: (t: number, intensity: number, gtsValue: number) => number;
750
- ascenderHeight?: (t: number, intensity: number, gtsValue: number) => number;
751
- letterShake?: (t: number, intensity: number, gtsValue: number) => number;
752
- }
753
- /**
754
- * Calculate animation parameters from emotion curve
755
- *
756
- * @param emotionCurve - Emotion curve from EMOTION_ANIMATIONS
757
- * @param t - Normalized time (0-1) through animation
758
- * @param intensity - Emotion intensity (0-1), capped by GTS (maxExpression)
759
- * @param variableFontStyle - Font style from variable font calculations
760
- * @param gtsValue - GTS maxExpression value (0.2-1.0) for scaling ranges
761
- * @param selectedFontFamily - The selected font family (e.g., 'Cormorant', 'Roboto Flex')
762
- * @returns Complete animation parameters including fontVariationAxes (variation axes, not voice axes)
763
- */
764
- declare function calculateAnimationParameters(emotionCurve: EmotionCurve, t: number, intensity: number, variableFontStyle?: VariableFontStyle | null, gtsValue?: number, selectedFontFamily?: string): AnimationParameters;
765
-
766
859
  /**
767
860
  * Shadow Generator
768
861
  *
769
- * Generates CSS text-shadow strings from shadow colors and emotion-specific styling
862
+ * Generates CSS text-shadow strings from shadow colors
863
+ * All emotion-specific shadows are now controlled by URL animations
770
864
  */
771
865
  /**
772
866
  * Generate CSS text-shadow string from shadow color
773
867
  *
774
868
  * @param shadowColor - Shadow color in hex format (e.g., '#ff3232')
775
- * @param fontFamily - Font family to determine shadow style
776
- * @param emotion - Current emotion to determine shadow style
777
- * @param intensity - Emotion intensity (0-1) to scale glow effects
778
- * @returns CSS text-shadow value
869
+ * @param _fontFamily - Unused (kept for API compatibility)
870
+ * @param _emotion - Unused (kept for API compatibility)
871
+ * @param _intensity - Unused (kept for API compatibility)
872
+ * @returns CSS text-shadow value or empty string if no shadow
779
873
  */
780
- declare function generateTextShadow(shadowColor: string | undefined, fontFamily?: string, emotion?: string, intensity?: number): string;
874
+ declare function generateTextShadow(shadowColor: string | undefined, _fontFamily?: string, _emotion?: string, _intensity?: number): string;
781
875
 
782
876
  /**
783
877
  * Dynamic Word Spacing Calculator
@@ -796,6 +890,27 @@ declare function generateTextShadow(shadowColor: string | undefined, fontFamily?
796
890
  */
797
891
  declare function calculateDynamicWordSpacing(currentScale?: number, fontFamily?: string, gtsIntensity?: number, emotion?: string): string;
798
892
 
893
+ /**
894
+ * Prosody Weight — Natural Voice Intonation for Animations
895
+ *
896
+ * Only ~20% of words get motion animation, mimicking how natural speech
897
+ * stresses only a few key words per phrase. Font styling (color, weight,
898
+ * slant) is unaffected — this only gates movement.
899
+ *
900
+ * Selection criteria:
901
+ * 1. Function words (the, a, is, and…) → always quiet
902
+ * 2. Content words are scored by length + deterministic hash
903
+ * 3. Only the top ~35% of content words animate
904
+ * (since function/short words are ~55% of text,
905
+ * 35% of remaining 45% ≈ 16-20% of all words)
906
+ */
907
+ /**
908
+ * Compute a prosody importance weight for a single word.
909
+ *
910
+ * @returns 0 (no motion) or 1 (full motion).
911
+ */
912
+ declare function computeProsodyWeight(word: any, _emotionIntensity: number, _gts: number): number;
913
+
799
914
  /**
800
915
  * Joy Animation Effects
801
916
  *
@@ -841,11 +956,140 @@ declare function getJoyTransform(joyEffect: JoyEffect | null): string;
841
956
  */
842
957
  declare function getJoyFilter(joyEffect: JoyEffect | null): string;
843
958
 
959
+ /**
960
+ * Word Emphasis Effects
961
+ *
962
+ * Calculates emphasis effects (standard and strong) for words based on confidence levels.
963
+ *
964
+ * USED BY:
965
+ * - calculateWordAnimation: Main word animation orchestrator
966
+ *
967
+ * HOW IT WORKS:
968
+ * 1. Standard Emphasis (50-70%): Quick "pop" effect at word start
969
+ * 2. Strong Emphasis (70%+): Per-letter dramatic effects throughout word
970
+ * 3. Both scale with GTS (expressiveness level) and word confidence
971
+ *
972
+ * KEY FEATURES:
973
+ * - Confidence-based thresholds (50-70% vs 70%+)
974
+ * - GTS-scaled intensity
975
+ * - Emotion slant inheritance
976
+ * - Smooth transitions
977
+ */
978
+ interface Word {
979
+ emphasis?: number;
980
+ start: number;
981
+ end: number;
982
+ animationEnd?: number;
983
+ }
984
+ interface EmphasisEffect {
985
+ scaleMultiplier: number;
986
+ slantAdditive: number;
987
+ weightBoost: number;
988
+ scaleProgress: number;
989
+ gtsMultiplier: number;
990
+ emphasis: number;
991
+ emphasisMultiplier: number;
992
+ elapsed: number;
993
+ scaleActive: boolean;
994
+ }
995
+ interface StrongEmphasisData {
996
+ emphasis: number;
997
+ rawEmphasis: number;
998
+ scale: number;
999
+ rotation: number;
1000
+ translateX: number;
1001
+ translateY: number;
1002
+ skewX: number;
1003
+ stretchY: number;
1004
+ brightness: number;
1005
+ contrast: number;
1006
+ shadowBlur: number;
1007
+ shadowOpacity: number;
1008
+ zIndex: number;
1009
+ weightBoost: number;
1010
+ shadowOffsetX: number;
1011
+ shadowOffsetY: number;
1012
+ gtsMultiplier: number;
1013
+ emphasisMultiplier: number;
1014
+ fadeFactor: number;
1015
+ isInTail: boolean;
1016
+ }
1017
+ /**
1018
+ * Calculate emphasis effects for a word
1019
+ *
1020
+ * @param params - Emphasis calculation parameters
1021
+ * @returns Emphasis effects { emphasisEffect, strongEmphasisData }
1022
+ */
1023
+ declare function calculateWordEmphasisEffects({ word, currentTime, maxExpression, emotionAnimationDuration, wordBaseSlant, isActive, wordEmotion, }: {
1024
+ word: Word;
1025
+ currentTime: number;
1026
+ maxExpression: number;
1027
+ emotionAnimationDuration: number;
1028
+ wordBaseSlant: number;
1029
+ isActive: boolean;
1030
+ wordEmotion?: string;
1031
+ }): {
1032
+ emphasisEffect: EmphasisEffect | null;
1033
+ strongEmphasisData: StrongEmphasisData | null;
1034
+ };
1035
+
1036
+ /**
1037
+ * ============================================
1038
+ * WORD LETTER SPACING
1039
+ * ============================================
1040
+ *
1041
+ * PURPOSE:
1042
+ * Calculates per-letter translateX offsets for GPU-accelerated spacing (no layout reflow).
1043
+ * Extracted from animationEngine for better maintainability.
1044
+ *
1045
+ * USED BY:
1046
+ * - animationEngine: Main word animation orchestrator
1047
+ *
1048
+ * HOW IT WORKS:
1049
+ * 1. Detects active effects (fear shake only - emphasis spacing is disabled)
1050
+ * 2. Calculates per-letter translateX offsets to create spacing between letters
1051
+ * 3. Returns array of translateX values in pixels (one per letter)
1052
+ *
1053
+ * KEY FEATURES:
1054
+ * - Transform-based spacing (GPU-accelerated, no layout reflow)
1055
+ * - Letter spacing disabled for emphasis effects (standard and strong)
1056
+ * - Only fear shake effects get letter spacing (if needed)
1057
+ * - Zero baseline for clean transitions
1058
+ *
1059
+ * PERFORMANCE BENEFITS:
1060
+ * - Uses translateX (compositor property) instead of letter-spacing (layout property)
1061
+ * - Smooth CSS transitions without triggering layout reflow
1062
+ * - All spacing animations run on GPU compositor layer
1063
+ */
1064
+ interface WordLetterSpacingParams {
1065
+ strongEmphasisData?: any;
1066
+ emphasisEffect?: any;
1067
+ wordLetterShakeIntensity: number | null;
1068
+ wordFontFamily: string;
1069
+ currentTime: number;
1070
+ word: any;
1071
+ emotionAnimationDuration: number;
1072
+ wordEmotion?: string;
1073
+ totalLetters: number;
1074
+ fontSize: number;
1075
+ }
1076
+ /**
1077
+ * Calculate per-letter translateX offsets for GPU-accelerated spacing
1078
+ *
1079
+ * @param params - Spacing calculation parameters
1080
+ * @returns Array of translateX offsets in pixels (one per letter)
1081
+ */
1082
+ declare function calculateWordLetterSpacing({ strongEmphasisData, emphasisEffect, wordLetterShakeIntensity, wordFontFamily, currentTime, word, emotionAnimationDuration, wordEmotion, totalLetters, fontSize, }: WordLetterSpacingParams): number[];
1083
+
844
1084
  /**
845
1085
  * GTS (Global Text Style) Calculations
846
1086
  *
847
1087
  * Centralized logic for GTS-derived values and emotion threshold calculations
848
1088
  */
1089
+ /**
1090
+ * Combine global GTS slider with optional per-segment / per-word authored gts.
1091
+ */
1092
+ declare function resolveEffectiveGts(sliderGts: number, segmentGts?: number, wordGts?: number): number;
849
1093
  /**
850
1094
  * Calculate all GTS-derived values from slider position
851
1095
  *
@@ -871,11 +1115,16 @@ declare function calculateGTSValues(gts: number): {
871
1115
  */
872
1116
  declare function meetsEmotionThreshold(intensity: number, threshold: number): boolean;
873
1117
  /**
874
- * Calculate capped emotion intensity based on GTS maxExpression
1118
+ * Calculate scaled emotion intensity based on GTS maxExpression
1119
+ *
1120
+ * GTS acts as a scaling multiplier (final layer) to preserve variance in emotion values
1121
+ * while controlling overall expressiveness.
1122
+ *
1123
+ * When GTS=0.0 (maxExpression=0.2), animations are completely disabled.
875
1124
  *
876
1125
  * @param rawIntensity - Raw emotion intensity from backend (0-1)
877
- * @param maxExpression - GTS-derived max expression cap (0-1)
878
- * @returns Capped emotion intensity (0-1)
1126
+ * @param maxExpression - GTS-derived max expression multiplier (0.2-1.0)
1127
+ * @returns Scaled emotion intensity (0-1), or 0 if GTS=0.0
879
1128
  */
880
1129
  declare function capEmotionIntensity(rawIntensity: number, maxExpression: number): number;
881
1130
  /**
@@ -903,14 +1152,6 @@ declare function isInEmphasisRange(emphasis: number): boolean;
903
1152
  */
904
1153
  declare function isInStrongEmphasisRange(emphasis: number): boolean;
905
1154
 
906
- /**
907
- * Emotion Animation URLs
908
- *
909
- * Config mapping emotion → animation URL
910
- * Replaces hardcoded EMOTION_ANIMATIONS config with URL-based parameters
911
- */
912
- declare const EMOTION_ANIMATION_URLS: Record<string, string>;
913
-
914
1155
  /**
915
1156
  * Font Selection Utilities
916
1157
  *
@@ -985,129 +1226,33 @@ interface Letter {
985
1226
  declare function splitTextIntoLetters(text: string): Letter[];
986
1227
 
987
1228
  /**
988
- * Word Emphasis Effects
989
- *
990
- * Calculates emphasis effects (standard and strong) for words based on confidence levels.
991
- *
992
- * USED BY:
993
- * - calculateWordAnimation: Main word animation orchestrator
994
- *
995
- * HOW IT WORKS:
996
- * 1. Standard Emphasis (50-70%): Quick "pop" effect at word start
997
- * 2. Strong Emphasis (70%+): Per-letter dramatic effects throughout word
998
- * 3. Both scale with GTS (expressiveness level) and word confidence
999
- *
1000
- * KEY FEATURES:
1001
- * - Confidence-based thresholds (50-70% vs 70%+)
1002
- * - GTS-scaled intensity
1003
- * - Emotion slant inheritance
1004
- * - Smooth transitions
1005
- */
1006
- interface Word {
1007
- emphasis?: number;
1008
- start: number;
1009
- end: number;
1010
- animationEnd?: number;
1011
- }
1012
- interface EmphasisEffect {
1013
- scaleMultiplier: number;
1014
- slantAdditive: number;
1015
- weightBoost: number;
1016
- scaleProgress: number;
1017
- gtsMultiplier: number;
1018
- emphasis: number;
1019
- emphasisMultiplier: number;
1020
- elapsed: number;
1021
- scaleActive: boolean;
1022
- }
1023
- interface StrongEmphasisData {
1024
- emphasis: number;
1025
- rawEmphasis: number;
1026
- scale: number;
1027
- rotation: number;
1028
- translateX: number;
1029
- translateY: number;
1030
- skewX: number;
1031
- stretchY: number;
1032
- brightness: number;
1033
- contrast: number;
1034
- shadowBlur: number;
1035
- shadowOpacity: number;
1036
- zIndex: number;
1037
- weightBoost: number;
1038
- shadowOffsetX: number;
1039
- shadowOffsetY: number;
1040
- gtsMultiplier: number;
1041
- emphasisMultiplier: number;
1042
- fadeFactor: number;
1043
- isInTail: boolean;
1044
- }
1045
- /**
1046
- * Calculate emphasis effects for a word
1047
- *
1048
- * @param params - Emphasis calculation parameters
1049
- * @returns Emphasis effects { emphasisEffect, strongEmphasisData }
1229
+ * Motion blur from scale deviation — matches main app WordRenderer during movement.
1230
+ * Authored `blur` from animation curves is separate.
1050
1231
  */
1051
- declare function calculateWordEmphasisEffects({ word, currentTime, maxExpression, emotionAnimationDuration, wordBaseSlant, isActive, wordEmotion, }: {
1052
- word: Word;
1053
- currentTime: number;
1054
- maxExpression: number;
1055
- emotionAnimationDuration: number;
1056
- wordBaseSlant: number;
1057
- isActive: boolean;
1058
- wordEmotion?: string;
1059
- }): {
1060
- emphasisEffect: EmphasisEffect | null;
1061
- strongEmphasisData: StrongEmphasisData | null;
1062
- };
1232
+ declare function getMotionBlurAmount(scale: number, { minDeviation, maxBlur, multiplier }?: {
1233
+ minDeviation?: number | undefined;
1234
+ maxBlur?: number | undefined;
1235
+ multiplier?: number | undefined;
1236
+ }): number;
1237
+ declare function getCombinedBlurAmount(authoredBlur?: number, scale?: number, gts?: number): number;
1063
1238
 
1064
1239
  /**
1065
- * ============================================
1066
- * WORD LETTER SPACING
1067
- * ============================================
1068
- *
1069
- * PURPOSE:
1070
- * Calculates per-letter translateX offsets for GPU-accelerated spacing (no layout reflow).
1071
- * Extracted from animationEngine for better maintainability.
1072
- *
1073
- * USED BY:
1074
- * - animationEngine: Main word animation orchestrator
1075
- *
1076
- * HOW IT WORKS:
1077
- * 1. Detects active effects (fear shake only - emphasis spacing is disabled)
1078
- * 2. Calculates per-letter translateX offsets to create spacing between letters
1079
- * 3. Returns array of translateX values in pixels (one per letter)
1080
- *
1081
- * KEY FEATURES:
1082
- * - Transform-based spacing (GPU-accelerated, no layout reflow)
1083
- * - Letter spacing disabled for emphasis effects (standard and strong)
1084
- * - Only fear shake effects get letter spacing (if needed)
1085
- * - Zero baseline for clean transitions
1240
+ * Emotion Importance Processing
1086
1241
  *
1087
- * PERFORMANCE BENEFITS:
1088
- * - Uses translateX (compositor property) instead of letter-spacing (layout property)
1089
- * - Smooth CSS transitions without triggering layout reflow
1090
- * - All spacing animations run on GPU compositor layer
1242
+ * Core emotions (anger, fear, sadness, joy) are prioritized over secondary emotions
1243
+ * by multiplying their intensity by 1.5 before selection.
1244
+ * Identical to monorepo app/utils/data/emotionImportance.js
1091
1245
  */
1092
- interface WordLetterSpacingParams {
1093
- strongEmphasisData?: any;
1094
- emphasisEffect?: any;
1095
- wordLetterShakeIntensity: number | null;
1096
- wordFontFamily: string;
1097
- currentTime: number;
1098
- word: any;
1099
- emotionAnimationDuration: number;
1100
- wordEmotion?: string;
1101
- totalLetters: number;
1102
- fontSize: number;
1103
- }
1104
1246
  /**
1105
- * Calculate per-letter translateX offsets for GPU-accelerated spacing
1247
+ * Process emotions with importance factors
1106
1248
  *
1107
- * @param params - Spacing calculation parameters
1108
- * @returns Array of translateX offsets in pixels (one per letter)
1249
+ * Core emotions (anger, fear, sadness, joy) get ×1.5 multiplier
1250
+ * Secondary emotions get ×1.0 multiplier
1251
+ *
1252
+ * @param emotions - Array of [emotion, intensity] tuples
1253
+ * @returns Array of [emotion, originalIntensity, adjustedIntensity, importanceFactor, isCore] tuples
1109
1254
  */
1110
- declare function calculateWordLetterSpacing({ strongEmphasisData, emphasisEffect, wordLetterShakeIntensity, wordFontFamily, currentTime, word, emotionAnimationDuration, wordEmotion, totalLetters, fontSize, }: WordLetterSpacingParams): number[];
1255
+ declare function processEmotionsWithImportance(emotions: Array<[string, number]>): Array<[string, number, number, number, boolean]>;
1111
1256
 
1112
1257
  /**
1113
1258
  * Backend Data Accessors
@@ -1117,6 +1262,21 @@ declare function calculateWordLetterSpacing({ strongEmphasisData, emphasisEffect
1117
1262
  * Identical to monorepo app/utils/data/backendDataAccessors.js
1118
1263
  */
1119
1264
 
1265
+ /**
1266
+ * Get word emphasis data
1267
+ */
1268
+ declare function getWordEmphasis(word: any): {
1269
+ confidence: any;
1270
+ emphasis: any;
1271
+ hasEmphasis: boolean;
1272
+ hasStrongEmphasis: boolean;
1273
+ };
1274
+ /**
1275
+ * Get subtitle text content
1276
+ *
1277
+ * Handles both 'subtitle' and 'text' properties
1278
+ */
1279
+ declare function getSubtitleText(subtitle: SubtitleSegment | null): string;
1120
1280
  /**
1121
1281
  * Get subtitle words array
1122
1282
  */
@@ -1140,24 +1300,6 @@ declare function getMergedSubtitles(subtitle: SubtitleSegment | null): SubtitleS
1140
1300
  */
1141
1301
  declare function findSubtitleForWord(subtitles: SubtitleSegment[], word: any): SubtitleSegment | null;
1142
1302
 
1143
- /**
1144
- * Emotion Importance Processing
1145
- *
1146
- * Core emotions (anger, fear, sadness, joy) are prioritized over secondary emotions
1147
- * by multiplying their intensity by 1.5 before selection.
1148
- * Identical to monorepo app/utils/data/emotionImportance.js
1149
- */
1150
- /**
1151
- * Process emotions with importance factors
1152
- *
1153
- * Core emotions (anger, fear, sadness, joy) get ×1.5 multiplier
1154
- * Secondary emotions get ×1.0 multiplier
1155
- *
1156
- * @param emotions - Array of [emotion, intensity] tuples
1157
- * @returns Array of [emotion, originalIntensity, adjustedIntensity, importanceFactor, isCore] tuples
1158
- */
1159
- declare function processEmotionsWithImportance(emotions: Array<[string, number]>): Array<[string, number, number, number, boolean]>;
1160
-
1161
1303
  /**
1162
1304
  * Variable Font Calculations
1163
1305
  *
@@ -1204,34 +1346,8 @@ declare function calculateWeightFromVolume(volume: number | undefined, weightAxi
1204
1346
  */
1205
1347
  declare function calculateWidthFromSpeechRate(speechRate: number | undefined, widthAxis: FontAxisConfig | undefined, baseWidth?: number): number;
1206
1348
 
1207
- /**
1208
- * Subtitle Engine
1209
- *
1210
- * TODO: Extract from app/hooks/subtitle/useSentenceAnimation.js and useWordAnimation.js
1211
- *
1212
- * This module should provide:
1213
- * - createSubtitleEngine(track) - creates engine instance
1214
- * - engine.at(time) - returns SubtitleEngineState for given time
1215
- * - Handle karaoke mode (word-by-word) and sentence mode
1216
- * - Handle edge cases: gaps, overlaps, end-of-video
1217
- */
1218
-
1219
- declare function createSubtitleEngine(track: SubtitleTrack): {
1220
- at(time: number): SubtitleEngineState;
1221
- };
1222
-
1223
- /**
1224
- * Emotion → Style Mapper
1225
- *
1226
- * TODO: Extract from app/config/animation/ directory
1227
- *
1228
- * This module should provide:
1229
- * - getEmotionStyle(emotion, intensity) - maps emotion to CSS styles
1230
- * - Handle all 6 emotions: joy, anger, sadness, fear, disgust, surprise
1231
- * - Support intensity scaling (0-1)
1232
- */
1233
-
1234
- declare function getEmotionStyle(emotion: Emotion, intensity: number): EmotionStyle;
1349
+ declare function ensureFont(fontFamily: string | undefined | null): void;
1350
+ declare function preloadAnimationFonts(): void;
1235
1351
 
1236
1352
  /**
1237
1353
  * PHONT API Client
@@ -1287,7 +1403,11 @@ declare class PhontClient {
1287
1403
  /**
1288
1404
  * Register a new user
1289
1405
  */
1290
- register(username: string, email: string, password: string): Promise<RegisterResponse>;
1406
+ register(username: string, email: string, password: string, profile: {
1407
+ company: string;
1408
+ first_name: string;
1409
+ last_name: string;
1410
+ }): Promise<RegisterResponse>;
1291
1411
  /**
1292
1412
  * Get subtitle track for a VOD
1293
1413
  * Requires: Session token authentication
@@ -1343,4 +1463,4 @@ declare class PhontClient {
1343
1463
  clearCredentials(): void;
1344
1464
  }
1345
1465
 
1346
- export { ANIMATION_STYLING, type AnimationOptions, type AnimationParameterStates, type AnimationParameters, type AnimationState, type CurvePoint, EMOTION_ANIMATIONS, EMOTION_ANIMATION_URLS, type Emotion, type EmotionCurve, type EmotionSelectionResult, type EmotionStyle, type EmphasisEffect, type FontAxisConfig, type FontConfig, type JoyEffect, type Letter, type LoginResponse, type ParameterState, type ParameterStates, PhontClient, type PhontClientOptions, RENDERING_CONTROL, type RegisterResponse, type SentenceAnimationState, type StateCallback, type StrongEmphasisData, type Stylesheet, type SubtitleEngineState, type SubtitleLine, SubtitleManager, type SubtitleSegment, type SubtitleState$1 as SubtitleState, SubtitleStateManager, type SubtitleTrack, type SubtitleWord, type VariableFontStyle, type VodMetadata, type VodState$1 as VodState, type Word, type WordAnimationState, type WordLetterSpacingParams, calculateAnimationParameters, calculateAnimationState, calculateDynamicWordSpacing, calculateEmphasisMultiplier, calculateGTSValues, calculateJoy, calculateJoyBulge, calculateNormalizedTime, calculateSentenceAnimation, calculateWeightFromVolume, calculateWidthFromSpeechRate, calculateWordAnimation, calculateWordEmphasisEffects, calculateWordLetterSpacing, capEmotionIntensity, createSubtitleEngine, findSubtitleForWord, generateTextShadow, getEmotionStyle, getFontFamilyCSS, getJoyAnimationMode, getJoyFilter, getJoyTransform, getMergedSubtitles, getSubtitleAnimations, getSubtitleText, getSubtitleTiming, getSubtitleWords, hasMergedSubtitles, isInEmphasisRange, isInStrongEmphasisRange, meetsEmotionThreshold, processEmotionsWithImportance, selectEmotion, selectFontFamily, shouldUseAngryFont, shouldUseJoyFont, shouldUseSadnessFont, splitTextIntoLetters, subtitleManager };
1466
+ export { ANIMATION_STYLING, ANIMATION_URLS, AUTHORED_PLAYBACK_OPTIONS, type AnimationFetcher, type AnimationOptions, type AnimationParameterState, type AnimationParameterStates, type AnimationRecord, type AnimationState, type CurvePoint, EMOTION_ANIMATION_URLS, type Emotion, type EmotionSelectionResult, type EmotionStyle, type EmphasisEffect, type FontAxisConfig, type FontConfig, type JoyEffect, type Letter, type LoginResponse, type ParameterState, type ParameterStates, PhontClient, type PhontClientOptions, type PublishedAnimationResolver, REFERENCE_GTS, REFERENCE_INTENSITY, RENDERING_CONTROL, type RegisterResponse, type SentenceAnimationState, type StateCallback, type StrongEmphasisData, type Stylesheet, type SubtitleEngineState, type SubtitleLine, SubtitleManager, type SubtitleSegment, type SubtitleState$1 as SubtitleState, SubtitleStateManager, type SubtitleTrack, type SubtitleWord, type VodMetadata, type VodState$1 as VodState, type Word, type WordAnimationState, type WordLetterSpacingParams, calculateAnimationParameters, calculateAnimationState, calculateDynamicWordSpacing, calculateEmphasisMultiplier, calculateGTSValues, calculateJoy, calculateJoyBulge, calculateNormalizedTime, calculateWeightFromVolume, calculateWidthFromSpeechRate, calculateWordEmphasisEffects, calculateWordLetterSpacing, capEmotionIntensity, computeProsodyWeight, createPublishedAnimationResolver, decodeAnimationUrl, ensureFont, findSubtitleForWord, generateTextShadow, getAnimationUrlForEmotion, getCombinedBlurAmount, getFontFamilyCSS, getJoyAnimationMode, getJoyFilter, getJoyTransform, getMergedSubtitles, getMotionBlurAmount, getSubtitleAnimations, getSubtitleText, getSubtitleTiming, getSubtitleWords, getWordEmphasis, hasMergedSubtitles, hockeyStickIntensity, isInEmphasisRange, isInStrongEmphasisRange, meetsEmotionThreshold, preloadAnimationFonts, processEmotionsWithImportance, resolveEffectiveGts, sampleParameterCurve, selectEmotion, selectFontFamily, shouldUseAngryFont, shouldUseJoyFont, shouldUseSadnessFont, splitTextIntoLetters, subtitleManager };