@nice2dev/ui-audio 0.1.0 → 1.0.3

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.
Files changed (93) hide show
  1. package/CHANGELOG.md +217 -1
  2. package/dist/__benchmarks__/audio-latency.bench.d.ts +2 -0
  3. package/dist/__benchmarks__/audio-latency.bench.d.ts.map +1 -0
  4. package/dist/constants/index.d.ts +6 -0
  5. package/dist/constants/index.d.ts.map +1 -0
  6. package/dist/constants/karaokeScoringConfig.d.ts.map +1 -1
  7. package/dist/core/NiceAudioErrorBoundary.d.ts +28 -0
  8. package/dist/core/NiceAudioErrorBoundary.d.ts.map +1 -0
  9. package/dist/editor/NiceSampleBrowser.d.ts +79 -0
  10. package/dist/editor/NiceSampleBrowser.d.ts.map +1 -0
  11. package/dist/editor/Waveform.d.ts +53 -1
  12. package/dist/editor/Waveform.d.ts.map +1 -1
  13. package/dist/editor/hooks/useProjectCRUD.d.ts.map +1 -1
  14. package/dist/editor/nav/SaveLoadControls.d.ts.map +1 -1
  15. package/dist/editor/useEditorRecording.d.ts.map +1 -1
  16. package/dist/engine/NiceAudioEffects.d.ts +186 -0
  17. package/dist/engine/NiceAudioEffects.d.ts.map +1 -0
  18. package/dist/engine/NiceAudioEffectsRack.d.ts +17 -0
  19. package/dist/engine/NiceAudioEffectsRack.d.ts.map +1 -0
  20. package/dist/engine/NiceAudioWorklet.d.ts +184 -0
  21. package/dist/engine/NiceAudioWorklet.d.ts.map +1 -0
  22. package/dist/engine/NiceMultitrackExport.d.ts +165 -0
  23. package/dist/engine/NiceMultitrackExport.d.ts.map +1 -0
  24. package/dist/engine/audioContext.d.ts.map +1 -1
  25. package/dist/engine/audioKeyboard.d.ts.map +1 -1
  26. package/dist/engine/audioPlaybackEngine.d.ts.map +1 -1
  27. package/dist/index.cjs +373 -34
  28. package/dist/index.d.ts +95 -7
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.mjs +9988 -5652
  31. package/dist/karaoke/AudioPitchAnalyzer.d.ts.map +1 -1
  32. package/dist/karaoke/KaraokeSummaryOverlay.d.ts +22 -0
  33. package/dist/karaoke/KaraokeSummaryOverlay.d.ts.map +1 -0
  34. package/dist/karaoke/rendering/fontCatalog.d.ts.map +1 -1
  35. package/dist/karaoke/rendering/glossyBarRenderer.d.ts.map +1 -1
  36. package/dist/karaoke/rendering/karaokeLyrics.d.ts.map +1 -1
  37. package/dist/karaoke/rendering/karaokeNoteParsing.d.ts.map +1 -1
  38. package/dist/karaoke/rendering/karaokeSettings.d.ts.map +1 -1
  39. package/dist/karaoke/rendering/karaokeTimelineRenderer.d.ts.map +1 -1
  40. package/dist/karaoke/rendering/karaokeTimelineTypes.d.ts.map +1 -1
  41. package/dist/lighting/NiceDMXTimeline.d.ts +226 -0
  42. package/dist/lighting/NiceDMXTimeline.d.ts.map +1 -0
  43. package/dist/models/index.d.ts +16 -0
  44. package/dist/models/index.d.ts.map +1 -0
  45. package/dist/models/modelsAiVideo.d.ts.map +1 -1
  46. package/dist/player/GenericPlayer.d.ts +34 -1
  47. package/dist/player/GenericPlayer.d.ts.map +1 -1
  48. package/dist/playlist/GenericPlaylist.d.ts.map +1 -1
  49. package/dist/playlist/PlaylistBrowser.d.ts.map +1 -1
  50. package/dist/playlist/PlaylistImportWizard.d.ts +42 -0
  51. package/dist/playlist/PlaylistImportWizard.d.ts.map +1 -0
  52. package/dist/playlist/PlaylistList.d.ts.map +1 -1
  53. package/dist/radio/NiceRadioPlayer.d.ts +141 -0
  54. package/dist/radio/NiceRadioPlayer.d.ts.map +1 -0
  55. package/dist/streaming/NiceStreamingVisualizer.d.ts +86 -0
  56. package/dist/streaming/NiceStreamingVisualizer.d.ts.map +1 -0
  57. package/dist/streaming/NiceVoiceChatOverlay.d.ts +97 -0
  58. package/dist/streaming/NiceVoiceChatOverlay.d.ts.map +1 -0
  59. package/dist/streaming/index.d.ts +11 -0
  60. package/dist/streaming/index.d.ts.map +1 -0
  61. package/dist/streaming/liveStreamManager.d.ts +194 -0
  62. package/dist/streaming/liveStreamManager.d.ts.map +1 -0
  63. package/dist/streaming/useLiveStream.d.ts +19 -0
  64. package/dist/streaming/useLiveStream.d.ts.map +1 -0
  65. package/dist/streaming/webrtcAudio.d.ts +111 -0
  66. package/dist/streaming/webrtcAudio.d.ts.map +1 -0
  67. package/dist/ui-audio.css +1 -1
  68. package/dist/utils/BaseStreamClient.d.ts.map +1 -1
  69. package/dist/utils/audioDragDrop.d.ts +72 -0
  70. package/dist/utils/audioDragDrop.d.ts.map +1 -0
  71. package/dist/utils/crepeStreaming.d.ts.map +1 -1
  72. package/dist/utils/index.d.ts +40 -0
  73. package/dist/utils/index.d.ts.map +1 -0
  74. package/dist/utils/latencyEstimate.d.ts +1 -1
  75. package/dist/utils/latencyEstimate.d.ts.map +1 -1
  76. package/dist/utils/midiCCMapping.d.ts +93 -0
  77. package/dist/utils/midiCCMapping.d.ts.map +1 -0
  78. package/dist/utils/musicPlayerUtils.d.ts.map +1 -1
  79. package/dist/utils/pianoRollUtils.d.ts +58 -0
  80. package/dist/utils/pianoRollUtils.d.ts.map +1 -0
  81. package/dist/utils/sanitize.d.ts +24 -0
  82. package/dist/utils/sanitize.d.ts.map +1 -0
  83. package/dist/utils/shortcutManager.d.ts +81 -0
  84. package/dist/utils/shortcutManager.d.ts.map +1 -0
  85. package/dist/utils/undoRedoUtils.d.ts +45 -0
  86. package/dist/utils/undoRedoUtils.d.ts.map +1 -1
  87. package/dist/workers/audioWorkletProcessor.d.ts +92 -0
  88. package/dist/workers/audioWorkletProcessor.d.ts.map +1 -0
  89. package/dist/workers/useAudioWorklet.d.ts +82 -0
  90. package/dist/workers/useAudioWorklet.d.ts.map +1 -0
  91. package/dist/workers/useWorker.d.ts +1 -0
  92. package/dist/workers/useWorker.d.ts.map +1 -1
  93. package/package.json +64 -19
@@ -0,0 +1,111 @@
1
+ /**
2
+ * WebRTC Audio Utilities — P2P audio chat / jam session support
3
+ *
4
+ * Provides helpers for establishing peer-to-peer audio connections
5
+ * using WebRTC with ICE candidates, offer/answer negotiation, and
6
+ * audio stream handling.
7
+ *
8
+ * @module @nice2dev/ui-audio/streaming
9
+ */
10
+ export interface WebRTCAudioConfig {
11
+ /** STUN/TURN servers for ICE negotiation */
12
+ iceServers?: RTCIceServer[];
13
+ /** Audio constraints for getUserMedia */
14
+ audioConstraints?: MediaTrackConstraints;
15
+ /** Enable echo cancellation (default: true) */
16
+ echoCancellation?: boolean;
17
+ /** Enable noise suppression (default: true) */
18
+ noiseSuppression?: boolean;
19
+ /** Enable auto gain control (default: true) */
20
+ autoGainControl?: boolean;
21
+ }
22
+ export interface PeerConnection {
23
+ id: string;
24
+ pc: RTCPeerConnection;
25
+ remoteStream: MediaStream | null;
26
+ state: RTCPeerConnectionState;
27
+ }
28
+ export interface SignalingMessage {
29
+ type: 'offer' | 'answer' | 'ice-candidate' | 'leave';
30
+ from: string;
31
+ to: string;
32
+ payload: RTCSessionDescriptionInit | RTCIceCandidateInit | null;
33
+ }
34
+ export type OnRemoteStreamCallback = (peerId: string, stream: MediaStream) => void;
35
+ export type OnPeerStateChangeCallback = (peerId: string, state: RTCPeerConnectionState) => void;
36
+ export type OnSignalingMessageCallback = (message: SignalingMessage) => void;
37
+ /**
38
+ * Manages WebRTC peer-to-peer audio connections for voice chat / jam sessions.
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * const manager = new WebRTCAudioManager({ iceServers: [...] });
43
+ * await manager.initialize();
44
+ *
45
+ * manager.onRemoteStream = (peerId, stream) => {
46
+ * // Attach stream to <audio> element
47
+ * };
48
+ *
49
+ * manager.onSignalingMessage = (msg) => {
50
+ * // Send to signaling server (WebSocket, SignalR, etc.)
51
+ * socket.send(JSON.stringify(msg));
52
+ * };
53
+ *
54
+ * // When initiating a call:
55
+ * await manager.createOffer('peer-123');
56
+ *
57
+ * // When receiving signaling messages:
58
+ * manager.handleSignalingMessage(incomingMessage);
59
+ * ```
60
+ */
61
+ export declare class WebRTCAudioManager {
62
+ private localStream;
63
+ private peers;
64
+ private config;
65
+ private localUserId;
66
+ /** Callback when a remote peer's audio stream is available */
67
+ onRemoteStream: OnRemoteStreamCallback | null;
68
+ /** Callback when a peer's connection state changes */
69
+ onPeerStateChange: OnPeerStateChangeCallback | null;
70
+ /** Callback when a signaling message needs to be sent */
71
+ onSignalingMessage: OnSignalingMessageCallback | null;
72
+ constructor(localUserId: string, config?: WebRTCAudioConfig);
73
+ /** Initialize local audio stream (must be called before creating connections) */
74
+ initialize(): Promise<MediaStream>;
75
+ /** Get the local audio stream */
76
+ getLocalStream(): MediaStream | null;
77
+ /** Get all connected peer IDs */
78
+ getPeerIds(): string[];
79
+ /** Get a peer's connection state */
80
+ getPeerState(peerId: string): RTCPeerConnectionState | null;
81
+ /** Create a new peer connection and send an offer */
82
+ createOffer(peerId: string): Promise<void>;
83
+ /** Handle an incoming signaling message */
84
+ handleSignalingMessage(message: SignalingMessage): Promise<void>;
85
+ /** Disconnect from a specific peer */
86
+ removePeer(peerId: string): void;
87
+ /** Disconnect from all peers and release local stream */
88
+ disconnect(): void;
89
+ /** Mute/unmute local audio */
90
+ setMuted(muted: boolean): void;
91
+ /** Check if local audio is muted */
92
+ isMuted(): boolean;
93
+ private createPeerConnection;
94
+ private handleOffer;
95
+ private handleAnswer;
96
+ private handleIceCandidate;
97
+ private sendSignalingMessage;
98
+ }
99
+ /**
100
+ * Check if WebRTC is supported in the current browser.
101
+ */
102
+ export declare function isWebRTCSupported(): boolean;
103
+ /**
104
+ * Enumerate available audio input devices.
105
+ */
106
+ export declare function getAudioInputDevices(): Promise<MediaDeviceInfo[]>;
107
+ /**
108
+ * Create an audio context with optimal settings for voice chat.
109
+ */
110
+ export declare function createVoiceChatAudioContext(): AudioContext;
111
+ //# sourceMappingURL=webrtcAudio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webrtcAudio.d.ts","sourceRoot":"","sources":["../../src/streaming/webrtcAudio.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IACzC,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+CAA+C;IAC/C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,iBAAiB,CAAC;IACtB,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,KAAK,EAAE,sBAAsB,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,eAAe,GAAG,OAAO,CAAC;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,yBAAyB,GAAG,mBAAmB,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;AACnF,MAAM,MAAM,yBAAyB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;AAChG,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAuB7E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,KAAK,CAA0C;IACvD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,WAAW,CAAS;IAE5B,8DAA8D;IACvD,cAAc,EAAE,sBAAsB,GAAG,IAAI,CAAQ;IAC5D,sDAAsD;IAC/C,iBAAiB,EAAE,yBAAyB,GAAG,IAAI,CAAQ;IAClE,yDAAyD;IAClD,kBAAkB,EAAE,0BAA0B,GAAG,IAAI,CAAQ;gBAExD,WAAW,EAAE,MAAM,EAAE,MAAM,GAAE,iBAAsB;IAa/D,iFAAiF;IAC3E,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC;IAWxC,iCAAiC;IACjC,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC,iCAAiC;IACjC,UAAU,IAAI,MAAM,EAAE;IAItB,oCAAoC;IACpC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAI3D,qDAAqD;IAC/C,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhD,2CAA2C;IACrC,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBtE,sCAAsC;IACtC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQhC,yDAAyD;IACzD,UAAU,IAAI,IAAI;IAwBlB,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ9B,oCAAoC;IACpC,OAAO,IAAI,OAAO;IAUlB,OAAO,CAAC,oBAAoB;YAuDd,WAAW;YAmBX,YAAY;YAOZ,kBAAkB;IAOhC,OAAO,CAAC,oBAAoB;CAG7B;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAGvE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,YAAY,CAK1D"}
package/dist/ui-audio.css CHANGED
@@ -1 +1 @@
1
- ._panelNarrow_se2i3_3{max-width:520px}._panelWide_se2i3_9{max-width:820px}._smallLabel_se2i3_19{font-size:12px}._noteText_se2i3_29{font-size:13px;color:#888}._buttonRow_se2i3_41{display:flex;gap:8px}._noteTextMargin_se2i3_49{font-size:13px;color:#888;margin-top:4px}._rangeW100_se2i3_63{width:100px}._zoomValue_se2i3_69{font-size:12px;min-width:35px}._selectW100_se2i3_77{width:100px}._inputW70_se2i3_83{width:70px}._masterVolGroup_se2i3_93{min-width:min(220px,100%)}._rangeW140_se2i3_99{width:140px}._volumeValue_se2i3_105{font-size:12px;width:42px;text-align:right}._selectW140_se2i3_115{width:140px}._freqGroup_se2i3_121{min-width:min(200px,100%)}._freqValue_se2i3_127{font-size:12px;width:60px;text-align:right}._narrowGroup_se2i3_137{min-width:min(170px,100%)}._rangeW120_se2i3_143{width:120px}._smallValue_se2i3_149{font-size:12px;width:40px;text-align:right}._presetDivider_se2i3_159{border-top:1px solid #444}._presetLabel_se2i3_165{font-size:11px;font-weight:600;color:#aaa}._presetBtn_se2i3_175{font-size:11px;padding:2px 8px}._deletePresetSelect_se2i3_183{width:140px;font-size:11px}._presetNameInput_se2i3_191{width:160px;font-size:11px}._savePresetBtn_se2i3_199{font-size:11px;padding:2px 10px}._countInAlert_se2i3_211{font-size:12px;color:#f57c00}._inputW80_se2i3_219{width:80px}._levelLabel_se2i3_225{font-size:12px;color:#555}._levelMeter_se2i3_233{position:relative;background:#f1f1f1;height:12px;border-radius:6px;overflow:hidden;width:80px}._levelBar_se2i3_249{position:absolute;left:0;top:0;bottom:0;transition:width 80ms linear}
1
+ ._panelNarrow_se2i3_3{max-width:520px}._panelWide_se2i3_9{max-width:820px}._smallLabel_se2i3_19{font-size:12px}._noteText_se2i3_29{font-size:13px;color:#888}._buttonRow_se2i3_41{display:flex;gap:8px}._noteTextMargin_se2i3_49{font-size:13px;color:#888;margin-top:4px}._rangeW100_se2i3_63{width:100px}._zoomValue_se2i3_69{font-size:12px;min-width:35px}._selectW100_se2i3_77{width:100px}._inputW70_se2i3_83{width:70px}._masterVolGroup_se2i3_93{min-width:min(220px,100%)}._rangeW140_se2i3_99{width:140px}._volumeValue_se2i3_105{font-size:12px;width:42px;text-align:right}._selectW140_se2i3_115{width:140px}._freqGroup_se2i3_121{min-width:min(200px,100%)}._freqValue_se2i3_127{font-size:12px;width:60px;text-align:right}._narrowGroup_se2i3_137{min-width:min(170px,100%)}._rangeW120_se2i3_143{width:120px}._smallValue_se2i3_149{font-size:12px;width:40px;text-align:right}._presetDivider_se2i3_159{border-top:1px solid #444}._presetLabel_se2i3_165{font-size:11px;font-weight:600;color:#aaa}._presetBtn_se2i3_175{font-size:11px;padding:2px 8px}._deletePresetSelect_se2i3_183{width:140px;font-size:11px}._presetNameInput_se2i3_191{width:160px;font-size:11px}._savePresetBtn_se2i3_199{font-size:11px;padding:2px 10px}._countInAlert_se2i3_211{font-size:12px;color:#f57c00}._inputW80_se2i3_219{width:80px}._levelLabel_se2i3_225{font-size:12px;color:#555}._levelMeter_se2i3_233{position:relative;background:#f1f1f1;height:12px;border-radius:6px;overflow:hidden;width:80px}._levelBar_se2i3_249{position:absolute;left:0;top:0;bottom:0;transition:width 80ms linear}.nice-dmx-timeline{display:flex;flex-direction:column;height:100%;min-height:300px;background:linear-gradient(to bottom,#1a1a2e,#0f0f1a);border-radius:8px;overflow:hidden;color:#e0e0e0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:13px}.nice-dmx-timeline__toolbar{display:flex;align-items:center;gap:16px;padding:8px 12px;background:#0000004d;border-bottom:1px solid rgba(255,255,255,.1)}.nice-dmx-timeline__transport{display:flex;gap:4px}.nice-dmx-timeline__transport button{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background:#8b5cf64d;border:none;border-radius:4px;color:#fff;cursor:pointer;font-size:14px;transition:all .15s}.nice-dmx-timeline__transport button:hover{background:#8b5cf680}.nice-dmx-timeline__transport button:active{transform:scale(.95)}.nice-dmx-timeline__time{font-family:Consolas,Monaco,monospace;font-size:18px;font-weight:600;color:#22d3ee;min-width:100px}.nice-dmx-timeline__tools{display:flex;align-items:center;gap:4px}.nice-dmx-timeline__tools button{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:#ffffff1a;border:none;border-radius:4px;color:#aaa;cursor:pointer;transition:all .15s}.nice-dmx-timeline__tools button:hover{background:#fff3;color:#fff}.nice-dmx-timeline__tools button.active{background:#8b5cf666;color:#fff}.nice-dmx-timeline__zoom{font-size:11px;color:#888;min-width:40px;text-align:center}.nice-dmx-timeline__bpm{display:flex;align-items:center;gap:6px;font-size:12px;color:#888}.nice-dmx-timeline__bpm span{color:#f472b6;font-weight:600}.nice-dmx-timeline__blackout{margin-left:auto;padding:6px 12px;background:#ef44444d;border:none;border-radius:4px;color:#fff;cursor:pointer;font-size:14px;transition:all .15s}.nice-dmx-timeline__blackout:hover{background:#ef444480}.nice-dmx-timeline__content{flex:1;display:flex;overflow:hidden}.nice-dmx-timeline__headers{width:180px;min-width:150px;background:#0003;border-right:1px solid rgba(255,255,255,.1);overflow-y:auto;padding-top:32px}.nice-dmx-timeline__header{display:flex;align-items:center;gap:8px;height:48px;padding:0 12px;border-bottom:1px solid rgba(255,255,255,.05);cursor:pointer;transition:background .15s}.nice-dmx-timeline__header:hover{background:#8b5cf61a}.nice-dmx-timeline__header--selected{background:#8b5cf633}.nice-dmx-timeline__track-color{width:8px;height:8px;border-radius:50%}.nice-dmx-timeline__track-name{flex:1;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-dmx-timeline__track-controls{display:flex;gap:4px}.nice-dmx-timeline__track-controls button{width:20px;height:20px;display:flex;align-items:center;justify-content:center;background:#ffffff1a;border:none;border-radius:3px;color:#888;cursor:pointer;font-size:10px;transition:all .15s}.nice-dmx-timeline__track-controls button:hover{background:#fff3;color:#fff}.nice-dmx-timeline__track-controls button.active{background:#ef444466;color:#fff}.nice-dmx-timeline__add-track{width:100%;padding:12px;background:none;border:none;border-top:1px dashed rgba(255,255,255,.1);color:#666;cursor:pointer;text-align:center;transition:all .15s}.nice-dmx-timeline__add-track:hover{background:#8b5cf61a;color:#8b5cf6}.nice-dmx-timeline__tracks{flex:1;overflow:auto;position:relative}.nice-dmx-timeline__ruler{position:sticky;top:0;height:32px;background:#0006;border-bottom:1px solid rgba(255,255,255,.1);z-index:10}.nice-dmx-timeline__beat{position:absolute;top:0;bottom:0;width:1px;background:#ffffff1a}.nice-dmx-timeline__beat--measure{background:#ffffff4d}.nice-dmx-timeline__beat-label{position:absolute;top:4px;left:4px;font-size:10px;color:#888}.nice-dmx-timeline__track{position:relative;height:48px;border-bottom:1px solid rgba(255,255,255,.05);background:linear-gradient(90deg,rgba(255,255,255,.02) 0%,transparent 1px,transparent 100%);background-size:100px 100%}.nice-dmx-timeline__track--muted{opacity:.4}.nice-dmx-timeline__cue{position:absolute;top:4px;height:calc(100% - 8px);border-radius:4px;cursor:pointer;overflow:hidden;transition:box-shadow .15s}.nice-dmx-timeline__cue:hover{box-shadow:0 0 0 2px #ffffff4d}.nice-dmx-timeline__cue--selected{box-shadow:0 0 0 2px #fff}.nice-dmx-timeline__cue-name{position:absolute;top:4px;left:6px;right:6px;font-size:11px;font-weight:500;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.5);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nice-dmx-timeline__cue-fade{position:absolute;top:0;bottom:0;background:linear-gradient(to right,rgba(0,0,0,.8),transparent)}.nice-dmx-timeline__cue-fade--in{left:0}.nice-dmx-timeline__cue-fade--out{right:0;transform:scaleX(-1)}.nice-dmx-timeline__playhead{position:absolute;top:0;bottom:0;width:2px;background:#ef4444;z-index:20;pointer-events:none}.nice-dmx-timeline__playhead:before{content:"";position:absolute;top:0;left:50%;transform:translate(-50%);width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:8px solid #ef4444}.nice-dmx-timeline__tracks::-webkit-scrollbar,.nice-dmx-timeline__headers::-webkit-scrollbar{width:8px;height:8px}.nice-dmx-timeline__tracks::-webkit-scrollbar-track,.nice-dmx-timeline__headers::-webkit-scrollbar-track{background:transparent}.nice-dmx-timeline__tracks::-webkit-scrollbar-thumb,.nice-dmx-timeline__headers::-webkit-scrollbar-thumb{background:#fff3;border-radius:4px}.nice-dmx-timeline__tracks::-webkit-scrollbar-thumb:hover,.nice-dmx-timeline__headers::-webkit-scrollbar-thumb:hover{background:#ffffff4d}@media(max-width:768px){.nice-dmx-timeline__toolbar{flex-wrap:wrap;gap:8px}.nice-dmx-timeline__headers{width:120px;min-width:100px}.nice-dmx-timeline__track-controls,.nice-dmx-timeline__bpm{display:none}}
@@ -1 +1 @@
1
- {"version":3,"file":"BaseStreamClient.d.ts","sourceRoot":"","sources":["../../src/utils/BaseStreamClient.ts"],"names":[],"mappings":"AAWA,wBAAgB,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAahG;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,CAOjE;AAID,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,+FAA+F;IAC/F,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAOD;;;;;;;;;GASG;AACH,8BAAsB,gBAAgB;IAElC,SAAS,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC;IACzB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;IAGjC,SAAS,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IAClC,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,IAAI,CAAC,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAS;IAG7B,SAAS,CAAC,MAAM,UAAS;IACzB,SAAS,CAAC,OAAO,UAAS;IAG1B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,aAAa,CAAK;IAE1B,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;gBAE/B,IAAI,EAAE,iBAAiB;IAMnC,2CAA2C;IAC3C,SAAS,CAAC,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC;IAErC,kEAAkE;IAClE,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAEtD,iFAAiF;IACjF,SAAS,CAAC,cAAc,IAAI,IAAI;IAKhC,yEAAyE;IACzE,SAAS,KAAK,UAAU,IAAI,OAAO,CAElC;IAED,gDAAgD;IAChD,SAAS,KAAK,WAAW,IAAI,MAAM,CAElC;IAID,SAAS,CAAC,EAAE,IAAI,MAAM;IAMtB,SAAS,CAAC,SAAS,IAAI,IAAI;IAgF3B,OAAO,CAAC,gBAAgB;YAqEV,eAAe;IA+B7B,SAAS,CAAC,cAAc,IAAI,IAAI;IAmB1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAWtB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9D,IAAI,IAAI,IAAI;CAiBf"}
1
+ {"version":3,"file":"BaseStreamClient.d.ts","sourceRoot":"","sources":["../../src/utils/BaseStreamClient.ts"],"names":[],"mappings":"AAYA,wBAAgB,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAahG;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,CAOjE;AAID,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,+FAA+F;IAC/F,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAOD;;;;;;;;;GASG;AACH,8BAAsB,gBAAgB;IAElC,SAAS,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC;IACzB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;IAGjC,SAAS,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IAClC,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,IAAI,CAAC,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAS;IAG7B,SAAS,CAAC,MAAM,UAAS;IACzB,SAAS,CAAC,OAAO,UAAS;IAG1B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,aAAa,CAAK;IAE1B,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;gBAE/B,IAAI,EAAE,iBAAiB;IAMnC,2CAA2C;IAC3C,SAAS,CAAC,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC;IAErC,kEAAkE;IAClE,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAEtD,iFAAiF;IACjF,SAAS,CAAC,cAAc,IAAI,IAAI;IAKhC,yEAAyE;IACzE,SAAS,KAAK,UAAU,IAAI,OAAO,CAElC;IAED,gDAAgD;IAChD,SAAS,KAAK,WAAW,IAAI,MAAM,CAElC;IAID,SAAS,CAAC,EAAE,IAAI,MAAM;IAMtB,SAAS,CAAC,SAAS,IAAI,IAAI;IAgF3B,OAAO,CAAC,gBAAgB;YAqEV,eAAe;IA+B7B,SAAS,CAAC,cAAc,IAAI,IAAI;IAmB1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAWtB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9D,IAAI,IAAI,IAAI;CAiBf"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * audioDragDrop.ts — Drag-and-drop audio file import utilities.
3
+ *
4
+ * Features:
5
+ * - Validate dropped files (type, size, extension)
6
+ * - Extract audio metadata from dropped files
7
+ * - Create drop zone handlers
8
+ * - Support for multiple file drop
9
+ */
10
+ export interface AudioDropResult {
11
+ file: File;
12
+ name: string;
13
+ extension: string;
14
+ sizeBytes: number;
15
+ mimeType: string;
16
+ duration?: number;
17
+ sampleRate?: number;
18
+ channels?: number;
19
+ }
20
+ export interface AudioDropValidation {
21
+ /** Maximum file size in bytes (default: 500MB) */
22
+ maxSize?: number;
23
+ /** Allowed MIME types (default: audio/*) */
24
+ allowedTypes?: string[];
25
+ /** Allowed extensions (without dot) */
26
+ allowedExtensions?: string[];
27
+ /** Max number of files in a single drop (default: 20) */
28
+ maxFiles?: number;
29
+ }
30
+ export interface AudioDropError {
31
+ file: File;
32
+ reason: "type" | "size" | "extension" | "decode" | "limit";
33
+ message: string;
34
+ }
35
+ export interface AudioDropEvent {
36
+ accepted: AudioDropResult[];
37
+ rejected: AudioDropError[];
38
+ }
39
+ /** Validate a list of files against audio constraints. */
40
+ export declare function validateAudioFiles(files: File[], validation?: AudioDropValidation): {
41
+ valid: File[];
42
+ errors: AudioDropError[];
43
+ };
44
+ /** Decode an audio file and extract basic metadata (duration, channels, sampleRate). */
45
+ export declare function probeAudioFile(file: File): Promise<AudioDropResult>;
46
+ export interface DropZoneCallbacks {
47
+ onDrop: (event: AudioDropEvent) => void;
48
+ onDragEnter?: () => void;
49
+ onDragLeave?: () => void;
50
+ validation?: AudioDropValidation;
51
+ /** Whether to probe audio metadata (slower but provides duration/channels). */
52
+ probe?: boolean;
53
+ }
54
+ /**
55
+ * Create event handlers for a drag-and-drop zone.
56
+ * Returns props to spread on a container element.
57
+ */
58
+ export declare function createDropZoneHandlers(callbacks: DropZoneCallbacks): {
59
+ onDragEnter: (e: React.DragEvent | DragEvent) => void;
60
+ onDragOver: (e: React.DragEvent | DragEvent) => void;
61
+ onDragLeave: (e: React.DragEvent | DragEvent) => void;
62
+ onDrop: (e: React.DragEvent | DragEvent) => Promise<void>;
63
+ };
64
+ /**
65
+ * Open a file picker dialog for audio files.
66
+ * Returns selected files (same validation as drop zone).
67
+ */
68
+ export declare function openAudioFilePicker(options?: {
69
+ multiple?: boolean;
70
+ validation?: AudioDropValidation;
71
+ }): Promise<AudioDropEvent>;
72
+ //# sourceMappingURL=audioDragDrop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioDragDrop.d.ts","sourceRoot":"","sources":["../../src/utils/audioDragDrop.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uCAAuC;IACvC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAkDD,0DAA0D;AAC1D,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,EAAE,EACb,UAAU,GAAE,mBAAwB,GACnC;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,MAAM,EAAE,cAAc,EAAE,CAAA;CAAE,CA+B7C;AAMD,wFAAwF;AACxF,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAqBzE;AAMD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,iBAAiB;qBAI9C,KAAK,CAAC,SAAS,GAAG,SAAS;oBAO5B,KAAK,CAAC,SAAS,GAAG,SAAS;qBAU1B,KAAK,CAAC,SAAS,GAAG,SAAS;gBAO1B,KAAK,CAAC,SAAS,GAAG,SAAS;EAoChD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,mBAAmB,CAAA;CAAO,GACrE,OAAO,CAAC,cAAc,CAAC,CA4BzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"crepeStreaming.d.ts","sourceRoot":"","sources":["../../src/utils/crepeStreaming.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvB,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAE3I,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG;IACnD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,gBAAgB;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;gBAEnC,IAAI,EAAE,kBAAkB;IAKpC,SAAS,KAAK,GAAG,IAAI,MAAM,CAE1B;IAED,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK7C,SAAS,CAAC,cAAc,IAAI,IAAI;CAKjC;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,8BAIjE"}
1
+ {"version":3,"file":"crepeStreaming.d.ts","sourceRoot":"","sources":["../../src/utils/crepeStreaming.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAElJ,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG;IACnD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,gBAAgB;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;gBAEnC,IAAI,EAAE,kBAAkB;IAKpC,SAAS,KAAK,GAAG,IAAI,MAAM,CAE1B;IAED,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK7C,SAAS,CAAC,cAAc,IAAI,IAAI;CAKjC;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,8BAIjE"}
@@ -0,0 +1,40 @@
1
+ export * from './audioEditorUtils';
2
+ export * from './audioFxUtils';
3
+ export { generateUltrastarText } from './audioPitchAlgorithms';
4
+ export * from './audioPitchAnalyzeFile';
5
+ export * from './audioTimelineUtils';
6
+ export * from './audioMidiUtils';
7
+ export * from './karaokeHelpers';
8
+ export * from './karaokeMetadata';
9
+ export * from './karaokeScoring';
10
+ export * from './arpeggiator';
11
+ export * from './articulationEngine';
12
+ export * from './envelopeFollower';
13
+ export * from './lfoEngine';
14
+ export * from './stepSequencer';
15
+ export * from './vocalEffectsEngine';
16
+ export * from './vocalPerformanceMetrics';
17
+ export * from './BaseStreamClient';
18
+ export * from './crepeStreaming';
19
+ export * from './librosaStreaming';
20
+ export * from './ccAutomation';
21
+ export * from './chordScale';
22
+ export * from './clipLauncher';
23
+ export * from './colorResolver';
24
+ export * from './drawTool';
25
+ export * from './grooveTemplates';
26
+ export * from './macroSystem';
27
+ export * from './undoRedoUtils';
28
+ export * from './musicPlayerUtils';
29
+ export * from './songDataHelpers';
30
+ export * from './padKaraokeSession';
31
+ export * from './pianoRollUtils';
32
+ export * from './gameAudio';
33
+ export * from './latencyEstimate';
34
+ export * from './shortcutManager';
35
+ export * from './audioDragDrop';
36
+ export * from './midiCCMapping';
37
+ export { logger } from './logger';
38
+ export type { ScopedLogger } from './logger';
39
+ export * from './sanitize';
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAGA,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,aAAa,CAAC;AAG5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,cAAc,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- export declare function makeClickReference(totalMs: number, sampleRate: number, clickAtMs?: number, clickWidthMs?: number): Float32Array<ArrayBuffer>;
1
+ export declare function makeClickReference(totalMs: number, sampleRate: number, clickAtMs?: number, clickWidthMs?: number): Float32Array;
2
2
  export declare function estimateLatencyMsFromRecording(recorded: Float32Array, sampleRate: number, clickAtMs?: number, clickWidthMs?: number): number | null;
3
3
  declare const _default: {
4
4
  estimateLatencyMsFromRecording: typeof estimateLatencyMsFromRecording;
@@ -1 +1 @@
1
- {"version":3,"file":"latencyEstimate.d.ts","sourceRoot":"","sources":["../../src/utils/latencyEstimate.ts"],"names":[],"mappings":"AAIA,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,SAAK,EAAE,YAAY,SAAK,6BAYxG;AA8CD,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,SAAK,EAAE,YAAY,SAAK,GAAI,MAAM,GAAG,IAAI,CAc5I;;;;;AAED,wBAAsE"}
1
+ {"version":3,"file":"latencyEstimate.d.ts","sourceRoot":"","sources":["../../src/utils/latencyEstimate.ts"],"names":[],"mappings":"AAIA,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,SAAK,EAAE,YAAY,SAAK,gBAYxG;AA8CD,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,SAAK,EAAE,YAAY,SAAK,GAAI,MAAM,GAAG,IAAI,CAc5I;;;;;AAED,wBAAsE"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * midiCCMapping.ts — MIDI CC Mapping System for supported controllers.
3
+ *
4
+ * Provides a controller-agnostic CC mapping layer that pairs MIDI CC numbers
5
+ * with editor parameters. Includes built-in profiles for common controllers
6
+ * and a custom profile builder.
7
+ */
8
+ /** Physical control type. */
9
+ export type MidiControlType = "knob" | "fader" | "button" | "pad" | "encoder";
10
+ /** A single mapping entry: CC number → parameter. */
11
+ export interface MidiCCMap {
12
+ /** CC number (0-127). */
13
+ cc: number;
14
+ /** Target parameter ID in the editor. */
15
+ paramId: string;
16
+ /** Human label for display. */
17
+ label: string;
18
+ /** Physical control type (for UI rendering). */
19
+ controlType: MidiControlType;
20
+ /** Min output value (default 0). */
21
+ min: number;
22
+ /** Max output value (default 127). */
23
+ max: number;
24
+ /** Invert value direction? */
25
+ inverted: boolean;
26
+ }
27
+ /** Controller profile definition. */
28
+ export interface MidiControllerProfile {
29
+ id: string;
30
+ name: string;
31
+ /** Substring to match against MIDI device name for auto-detection. */
32
+ deviceMatch: string;
33
+ /** Mappings — one per CC. */
34
+ mappings: MidiCCMap[];
35
+ }
36
+ /** Resolved CC event after mapping. */
37
+ export interface MappedCCEvent {
38
+ paramId: string;
39
+ label: string;
40
+ /** Raw 0-127 CC value. */
41
+ rawValue: number;
42
+ /** Value scaled to [min, max] range. */
43
+ scaledValue: number;
44
+ /** Normalized 0-1 value. */
45
+ normalizedValue: number;
46
+ }
47
+ /**
48
+ * M-Audio Oxygen 25 MkIV profile.
49
+ * 8 knobs (CC 21-28), 1 fader (CC 7), transport buttons.
50
+ */
51
+ export declare const OXYGEN25_PROFILE: MidiControllerProfile;
52
+ /** Akai MPK Mini profile. 8 knobs (CC 1-8), 8 pads (notes). */
53
+ export declare const MPK_MINI_PROFILE: MidiControllerProfile;
54
+ /** Arturia MiniLab profile. 16 knobs + 8 pads. */
55
+ export declare const MINILAB_PROFILE: MidiControllerProfile;
56
+ /** Novation Launch Control XL profile. 24 knobs + 8 faders. */
57
+ export declare const LAUNCH_CONTROL_PROFILE: MidiControllerProfile;
58
+ /** Generic profile — CC 1, 7, 10, 11 (Mod, Volume, Pan, Expression). */
59
+ export declare const GENERIC_PROFILE: MidiControllerProfile;
60
+ /** All built-in profiles. */
61
+ export declare const CONTROLLER_PROFILES: MidiControllerProfile[];
62
+ export declare class MidiCCMapper {
63
+ private profile;
64
+ private ccMap;
65
+ private onChange;
66
+ constructor(profile?: MidiControllerProfile);
67
+ /** Switch to a different controller profile. */
68
+ setProfile(profile: MidiControllerProfile): void;
69
+ /** Get the current profile. */
70
+ getProfile(): MidiControllerProfile;
71
+ /** Auto-detect profile from MIDI device name. */
72
+ autoDetect(deviceName: string): MidiControllerProfile | null;
73
+ /** Register a change handler. */
74
+ onMappedChange(handler: (event: MappedCCEvent) => void): void;
75
+ /** Process a raw CC event. Returns the mapped event or null if no mapping. */
76
+ handleCC(cc: number, rawValue: number): MappedCCEvent | null;
77
+ /** Add or update a single CC mapping. */
78
+ setMapping(cc: number, paramId: string, label: string, controlType?: MidiControlType): void;
79
+ /** Remove a CC mapping. */
80
+ removeMapping(cc: number): void;
81
+ /** Get all current mappings. */
82
+ getMappings(): MidiCCMap[];
83
+ /** Get mapping for a specific CC. */
84
+ getMapping(cc: number): MidiCCMap | undefined;
85
+ /** Export current profile as JSON for persistence. */
86
+ exportConfig(): MidiControllerProfile;
87
+ /** Import a saved profile config. */
88
+ importConfig(config: MidiControllerProfile): void;
89
+ /** Create a custom profile from scratch. */
90
+ static createCustomProfile(name: string, mappings: Omit<MidiCCMap, "min" | "max" | "inverted">[]): MidiControllerProfile;
91
+ private rebuildMap;
92
+ }
93
+ //# sourceMappingURL=midiCCMapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"midiCCMapping.d.ts","sourceRoot":"","sources":["../../src/utils/midiCCMapping.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,6BAA6B;AAC7B,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE9E,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACxB,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,WAAW,EAAE,eAAe,CAAC;IAC7B,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qCAAqC;AACrC,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,QAAQ,EAAE,SAAS,EAAE,CAAC;CACvB;AAED,uCAAuC;AACvC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;CACzB;AAgBD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,qBAqB9B,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,EAAE,qBAc9B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,eAAe,EAAE,qBAe7B,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,EAAE,qBAQpC,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,eAAe,EAAE,qBAU7B,CAAC;AAEF,6BAA6B;AAC7B,eAAO,MAAM,mBAAmB,EAAE,qBAAqB,EAMtD,CAAC;AAMF,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,QAAQ,CAAiD;gBAErD,OAAO,CAAC,EAAE,qBAAqB;IAK3C,gDAAgD;IAChD,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;IAKhD,+BAA+B;IAC/B,UAAU,IAAI,qBAAqB;IAInC,iDAAiD;IACjD,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI;IAY5D,iCAAiC;IACjC,cAAc,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAI7D,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAoB5D,yCAAyC;IACzC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,GAAE,eAAwB,GAAG,IAAI;IAoBnG,2BAA2B;IAC3B,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAK/B,gCAAgC;IAChC,WAAW,IAAI,SAAS,EAAE;IAI1B,qCAAqC;IACrC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI7C,sDAAsD;IACtD,YAAY,IAAI,qBAAqB;IAOrC,qCAAqC;IACrC,YAAY,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI;IAQjD,4CAA4C;IAC5C,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,UAAU,CAAC,EAAE,GAAG,qBAAqB;IAcxH,OAAO,CAAC,UAAU;CAMnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"musicPlayerUtils.d.ts","sourceRoot":"","sources":["../../src/utils/musicPlayerUtils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;AAErD,eAAO,MAAM,YAAY,GAAI,GAAG,MAAM,YAAmC,CAAC;AAC1E,eAAO,MAAM,MAAM,GAAI,IAAI,MAAM,YAAqC,CAAC;AACvE,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,YAA2D,CAAC;AAElG,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,WAKrC,CAAC;AAEF,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,UAM1C"}
1
+ {"version":3,"file":"musicPlayerUtils.d.ts","sourceRoot":"","sources":["../../src/utils/musicPlayerUtils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;AAErD,eAAO,MAAM,YAAY,MAAO,MAAM,YAAmC,CAAC;AAC1E,eAAO,MAAM,MAAM,OAAQ,MAAM,YAAqC,CAAC;AACvE,eAAO,MAAM,WAAW,OAAQ,MAAM,YAA2D,CAAC;AAElG,eAAO,MAAM,UAAU,QAAS,MAAM,WAKrC,CAAC;AAEF,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,UAM1C"}
@@ -0,0 +1,58 @@
1
+ import { MidiNote } from '../models/editor/midiTypes';
2
+ export type QuantizeValue = '1/4' | '1/8' | '1/16' | '1/32' | '1/4T' | '1/8T' | '1/16T';
3
+ /** Duration of one quantize grid step in beats (quarter notes). */
4
+ export declare function quantizeStepInBeats(value: QuantizeValue): number;
5
+ /** Convert a quantize step from beats to seconds at a given BPM. */
6
+ export declare function quantizeStepInSeconds(value: QuantizeValue, bpm: number): number;
7
+ /** Snap a time value to the nearest grid step. */
8
+ export declare function snapTimeToQuantize(time: number, value: QuantizeValue, bpm: number): number;
9
+ /** Options for quantizing MIDI notes. */
10
+ export interface QuantizeOptions {
11
+ /** Quantize grid value. */
12
+ value: QuantizeValue;
13
+ /** Tempo in BPM. */
14
+ bpm: number;
15
+ /** Strength 0-1. 1.0 = full snap, 0.5 = halfway to grid. Default: 1.0 */
16
+ strength?: number;
17
+ /** Quantize note starts. Default: true */
18
+ quantizeStarts?: boolean;
19
+ /** Quantize note durations (snap to grid length). Default: false */
20
+ quantizeDurations?: boolean;
21
+ }
22
+ /**
23
+ * Quantize an array of MIDI notes. Returns new array with adjusted start/duration.
24
+ * Does not mutate the original notes.
25
+ */
26
+ export declare function quantizeMidiNotes(notes: MidiNote[], options: QuantizeOptions): MidiNote[];
27
+ export interface HumanizeOptions {
28
+ /** Max timing offset in seconds. Default: 0.02 (20ms) */
29
+ timingRange?: number;
30
+ /** Max velocity offset (±). Default: 10 */
31
+ velocityRange?: number;
32
+ /** Seed for deterministic results. Default: random */
33
+ seed?: number;
34
+ }
35
+ /**
36
+ * Add slight random offsets to notes for a more human feel.
37
+ * Returns new array, original is not mutated.
38
+ */
39
+ export declare function humanizeMidiNotes(notes: MidiNote[], options?: HumanizeOptions): MidiNote[];
40
+ export interface LoopRegion {
41
+ /** Start time in seconds. */
42
+ start: number;
43
+ /** End time in seconds. */
44
+ end: number;
45
+ /** Whether A→B looping is active. */
46
+ enabled: boolean;
47
+ }
48
+ /** Create a default (disabled) loop region. */
49
+ export declare function createLoopRegion(): LoopRegion;
50
+ /** Set loop region from a selection. */
51
+ export declare function setLoopFromSelection(start: number, end: number): LoopRegion;
52
+ /** Snap loop region boundaries to grid. */
53
+ export declare function snapLoopToGrid(region: LoopRegion, quantize: QuantizeValue, bpm: number): LoopRegion;
54
+ /** Check if a time value falls within the loop region. */
55
+ export declare function isInLoopRegion(time: number, region: LoopRegion): boolean;
56
+ /** Calculate loop-wrapped time (if time exceeds end, wrap back to start). */
57
+ export declare function wrapTimeInLoop(time: number, region: LoopRegion): number;
58
+ //# sourceMappingURL=pianoRollUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pianoRollUtils.d.ts","sourceRoot":"","sources":["../../src/utils/pianoRollUtils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAM3D,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAExF,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAUhE;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1F;AAED,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,eAAe,GAAG,QAAQ,EAAE,CAoBzF;AAMD,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAWD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAE,eAAoB,GAAG,QAAQ,EAAE,CAgB9F;AAMD,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,IAAI,UAAU,CAE7C;AAED,wCAAwC;AACxC,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,UAAU,CAGZ;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,MAAM,GACV,UAAU,CAMZ;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAGxE;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAQvE"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * sanitize.ts — XSS prevention utilities for user-provided text/metadata.
3
+ *
4
+ * Use these functions when rendering user-provided strings in contexts where
5
+ * React's automatic escaping is not available (e.g. canvas text, SVG templates,
6
+ * title attributes constructed from user data).
7
+ */
8
+ /**
9
+ * Escape HTML special characters in a string.
10
+ * Use when inserting user text into raw HTML/SVG template strings.
11
+ */
12
+ export declare function escapeHtml(str: string): string;
13
+ /**
14
+ * Validate a URL for use in href/src attributes.
15
+ * Allows only http:, https:, data:image, and blob: URLs.
16
+ * Rejects javascript:, data:text/html, and other dangerous schemes.
17
+ */
18
+ export declare function isSafeUrl(url: string): boolean;
19
+ /**
20
+ * Strip all HTML tags from a string, leaving only plain text.
21
+ * Use for lyrics/metadata that should never contain HTML.
22
+ */
23
+ export declare function stripHtmlTags(str: string): string;
24
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAa9C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * shortcutManager.ts — Configurable keyboard shortcut manager for audio editor.
3
+ *
4
+ * Features:
5
+ * - Register/unregister shortcuts with modifiers (Ctrl, Shift, Alt, Meta)
6
+ * - Groups & categories for organized shortcut display
7
+ * - Shortcut conflicts detection
8
+ * - Scope support (global / editor / piano-roll / timeline)
9
+ * - Serializable config for user persistence
10
+ */
11
+ export type ShortcutScope = "global" | "editor" | "piano-roll" | "timeline" | "mixer" | "player";
12
+ export interface ShortcutModifiers {
13
+ ctrl?: boolean;
14
+ shift?: boolean;
15
+ alt?: boolean;
16
+ meta?: boolean;
17
+ }
18
+ export interface ShortcutBinding {
19
+ key: string;
20
+ modifiers?: ShortcutModifiers;
21
+ }
22
+ export interface ShortcutAction {
23
+ id: string;
24
+ label: string;
25
+ group: string;
26
+ scope: ShortcutScope;
27
+ binding: ShortcutBinding;
28
+ callback: () => void;
29
+ enabled?: boolean;
30
+ }
31
+ export interface ShortcutConfig {
32
+ id: string;
33
+ binding: ShortcutBinding;
34
+ }
35
+ export declare class ShortcutManager {
36
+ private actions;
37
+ private activeScopes;
38
+ private enabled;
39
+ private listener;
40
+ /** Register a shortcut action. */
41
+ register(action: ShortcutAction): void;
42
+ /** Unregister a shortcut action by ID. */
43
+ unregister(id: string): void;
44
+ /** Update the key binding for a registered action. */
45
+ rebind(id: string, newBinding: ShortcutBinding): void;
46
+ /** Set which scopes are currently active. */
47
+ setActiveScopes(scopes: ShortcutScope[]): void;
48
+ /** Enable/disable the entire manager. */
49
+ setEnabled(on: boolean): void;
50
+ /** Enable/disable a single action. */
51
+ setActionEnabled(id: string, on: boolean): void;
52
+ /** Find conflicting bindings within active scopes. */
53
+ findConflicts(): Array<[ShortcutAction, ShortcutAction]>;
54
+ /** Get all registered actions grouped by group name. */
55
+ getGrouped(): Record<string, ShortcutAction[]>;
56
+ /** Get all registered actions as a flat list. */
57
+ getAll(): ShortcutAction[];
58
+ /** Export current bindings for persistence. */
59
+ exportConfig(): ShortcutConfig[];
60
+ /** Import bindings from saved config. */
61
+ importConfig(configs: ShortcutConfig[]): void;
62
+ /** Format a binding for display (e.g. "Ctrl+Z"). */
63
+ formatBinding(id: string): string;
64
+ /** Handle a keyboard event — returns true if a shortcut was triggered. */
65
+ handleKeyDown(e: KeyboardEvent): boolean;
66
+ /** Attach to window keydown events. Call detach() to clean up. */
67
+ attach(): void;
68
+ /** Detach from window keydown events. */
69
+ detach(): void;
70
+ /** Remove all registered actions and detach. */
71
+ destroy(): void;
72
+ }
73
+ /**
74
+ * Creates and returns a ShortcutManager pre-configured with
75
+ * default audio editor shortcuts. Callbacks are stubs that
76
+ * should be overridden by the consumer.
77
+ */
78
+ export declare function createDefaultShortcuts(callbacks?: Partial<Record<string, () => void>>): ShortcutManager;
79
+ /** Pretty-print a ShortcutBinding for UI display. */
80
+ export declare function formatShortcut(binding: ShortcutBinding): string;
81
+ //# sourceMappingURL=shortcutManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shortcutManager.d.ts","sourceRoot":"","sources":["../../src/utils/shortcutManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEjG,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,eAAe,CAAC;CAC1B;AAiCD,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAAsC;IAC1D,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAA6C;IAE7D,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAItC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI5B,sDAAsD;IACtD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,GAAG,IAAI;IAOrD,6CAA6C;IAC7C,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI;IAM9C,yCAAyC;IACzC,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IAI7B,sCAAsC;IACtC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI;IAK/C,sDAAsD;IACtD,aAAa,IAAI,KAAK,CAAC,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IAkBxD,wDAAwD;IACxD,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IAS9C,iDAAiD;IACjD,MAAM,IAAI,cAAc,EAAE;IAI1B,+CAA+C;IAC/C,YAAY,IAAI,cAAc,EAAE;IAOhC,yCAAyC;IACzC,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI;IAM7C,oDAAoD;IACpD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAMjC,0EAA0E;IAC1E,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,OAAO;IAgBxC,kEAAkE;IAClE,MAAM,IAAI,IAAI;IAad,yCAAyC;IACzC,MAAM,IAAI,IAAI;IAOd,gDAAgD;IAChD,OAAO,IAAI,IAAI;CAIhB;AAMD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,GAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAM,GAAG,eAAe,CAyD3G;AAED,qDAAqD;AACrD,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAE/D"}
@@ -2,4 +2,49 @@ import { AudioProject } from '../models/modelsEditor';
2
2
  export declare function setProjectWithUndo(next: AudioProject, project: AudioProject | null, setUndoStack: React.Dispatch<React.SetStateAction<AudioProject[]>>, setRedoStack: React.Dispatch<React.SetStateAction<AudioProject[]>>, setProject: React.Dispatch<React.SetStateAction<AudioProject | null>>): void;
3
3
  export declare function handleUndo(project: AudioProject | null, setUndoStack: React.Dispatch<React.SetStateAction<AudioProject[]>>, setRedoStack: React.Dispatch<React.SetStateAction<AudioProject[]>>, setProject: React.Dispatch<React.SetStateAction<AudioProject | null>>): void;
4
4
  export declare function handleRedo(project: AudioProject | null, setUndoStack: React.Dispatch<React.SetStateAction<AudioProject[]>>, setRedoStack: React.Dispatch<React.SetStateAction<AudioProject[]>>, setProject: React.Dispatch<React.SetStateAction<AudioProject | null>>): void;
5
+ export interface EditorUndoAction<T = unknown> {
6
+ label: string;
7
+ /** Category: track, midi, fx, mix, arrangement, etc. */
8
+ category: string;
9
+ /** Timestamp when action was performed */
10
+ timestamp: number;
11
+ /** Forward action data */
12
+ newState: T;
13
+ /** Previous state for undo */
14
+ oldState: T;
15
+ }
16
+ export interface EditorUndoOptions {
17
+ maxSize?: number;
18
+ /** Optional callback when undo/redo is performed */
19
+ onChange?: (action: EditorUndoAction, direction: "undo" | "redo") => void;
20
+ }
21
+ /**
22
+ * A generic class-based undo/redo manager that works with any serializable state.
23
+ * Supports labels, categories, timestamps, and configurable max stack size.
24
+ */
25
+ export declare class EditorUndoManager<T = unknown> {
26
+ private undoStack;
27
+ private redoStack;
28
+ private maxSize;
29
+ private onChange?;
30
+ constructor(options?: EditorUndoOptions);
31
+ /** Push a new undoable action. Clears redo stack. */
32
+ push(label: string, category: string, oldState: T, newState: T): void;
33
+ /** Undo the last action. Returns the old state to apply, or null. */
34
+ undo(): T | null;
35
+ /** Redo the last undone action. Returns the new state to apply, or null. */
36
+ redo(): T | null;
37
+ get canUndo(): boolean;
38
+ get canRedo(): boolean;
39
+ get undoLabel(): string | null;
40
+ get redoLabel(): string | null;
41
+ get undoCount(): number;
42
+ get redoCount(): number;
43
+ /** Get the history of undo actions (most recent first). */
44
+ getHistory(): EditorUndoAction<T>[];
45
+ /** Clear all undo/redo history. */
46
+ clear(): void;
47
+ /** Jump to a specific point in history by index (0 = most recent). */
48
+ undoTo(index: number): T | null;
49
+ }
5
50
  //# sourceMappingURL=undoRedoUtils.d.ts.map