@blibliki/engine 0.3.7 → 0.3.8
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.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +189 -213
- package/dist/index.d.ts +189 -213
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Engine.ts +52 -2
- package/src/core/Route.ts +14 -2
- package/src/core/midi/MidiDeviceManager.ts +4 -0
- package/src/core/module/Module.ts +0 -38
- package/src/core/module/PolyModule.ts +1 -6
- package/src/index.ts +1 -1
- package/src/modules/MidiSelector.ts +29 -9
- package/src/modules/Oscillator.ts +6 -7
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var de=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var pt=Object.prototype.hasOwnProperty;var dt=(r,e)=>{for(var t in e)de(r,t,{get:e[t],enumerable:!0})},at=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ut(e))!pt.call(r,i)&&i!==t&&de(r,i,{get:()=>e[i],enumerable:!(o=st(e,i))||o.enumerable});return r};var lt=r=>at(de({},"__esModule",{value:!0}),r);var At={};dt(At,{Context:()=>nt.Context,Engine:()=>x,MidiDevice:()=>v,MidiMappingMode:()=>se,MidiPortState:()=>R,ModuleType:()=>K,Note:()=>d,OscillatorWave:()=>J,TransportState:()=>rt.TransportState,moduleSchemas:()=>ue});module.exports=lt(At);var it=require("@blibliki/transport"),b=require("@blibliki/utils");var re=require("@blibliki/utils");var Ae=require("@blibliki/utils"),Oe=require("es-toolkit");var oe=require("@blibliki/utils");var m=class{id;engineId;moduleType;audioModules;inputs;outputs;monoModuleConstructor;_props;superInitialized=!1;_voices;_name;pendingUIUpdates=!1;constructor(e,t){let{id:o,name:i,moduleType:n,voices:s,monoModuleConstructor:l,props:u}=t;this.audioModules=[],this.monoModuleConstructor=l,this.id=o??(0,oe.uuidv4)(),this.engineId=e,this.name=i,this.moduleType=n,this.voices=s||1,this._props=u,this.inputs=new A(this),this.outputs=new O(this),this.superInitialized=!0,queueMicrotask(()=>{this.props=u})}get name(){return this._name}set name(e){this._name=e,this.audioModules.forEach(t=>t.name=e)}get props(){return this._props}set props(e){this._props={...this._props,...e},this.audioModules.forEach(t=>t.props=e)}get voices(){return this._voices}set voices(e){this._voices=e,this.adjustNumberOfModules(),this.rePlugAll()}start(e){this.audioModules.forEach(t=>{t.start(e)})}stop(e){this.audioModules.forEach(t=>{t.stop(e)})}serialize(){return{id:this.id,name:this.name,moduleType:this.moduleType,voices:this.voices,props:this.props,inputs:this.inputs.serialize(),outputs:this.outputs.serialize()}}plug({audioModule:e,from:t,to:o}){let i=this.outputs.findByName(t),n=e.inputs.findByName(o);i.plug(n)}rePlugAll(e){this.superInitialized&&(this.inputs.rePlugAll(e),this.outputs.rePlugAll(e))}unPlugAll(){this.inputs.unPlugAll(),this.outputs.unPlugAll()}dispose(){this.inputs.unPlugAll(),this.outputs.unPlugAll(),this.audioModules.forEach(e=>{e.dispose()})}onMidiEvent=e=>{let t=e.voiceNo??0;this.findVoice(t).onMidiEvent(e)};triggerPropsUpdate=()=>{this.pendingUIUpdates||(this.pendingUIUpdates=!0,this.sheduleTriggerUpdate())};sheduleTriggerUpdate(){requestAnimationFrame(()=>{this.engine._triggerPropsUpdate({id:this.id,moduleType:this.moduleType,voices:this.voices,name:this.name,props:this.props}),this.pendingUIUpdates=!1})}findVoice(e){let t=this.audioModules.find(o=>o.voiceNo===e);if(!t)throw Error(`Voice ${e} on module ${this.name} not found`);return t}registerDefaultIOs(e="both"){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent}),(e==="in"||e==="both")&&this.registerAudioInput({name:"in"}),(e==="out"||e==="both")&&this.registerAudioOutput({name:"out"})}registerAudioInput(e){return this.inputs.add({...e,ioType:"polyAudioInput"})}registerAudioOutput(e){return this.outputs.add({...e,ioType:"polyAudioOutput"})}registerMidiInput(e){return this.inputs.add({...e,ioType:"midiInput"})}registerMidiOutput(e){return this.outputs.add({...e,ioType:"midiOutput"})}adjustNumberOfModules(){if(this.audioModules.length!==this.voices){if(this.audioModules.length>this.voices)this.audioModules.pop()?.dispose();else{let e=this.audioModules.length,t=(0,oe.deterministicId)(this.id,e.toString()),o=this.monoModuleConstructor(this.engineId,{id:t,name:this.name,moduleType:this.moduleType,voiceNo:e,props:{...this.props}});this.audioModules.push(o)}this.adjustNumberOfModules()}}get engine(){return x.getById(this.engineId)}get context(){return this.engine.context}};var Se=require("@blibliki/utils");var le=class{id;ioType;name;module;connections;constructor(e,t){this.module=e,this.name=t.name,this.ioType=t.ioType,this.id=(0,Se.deterministicId)(this.module.id,this.name),this.connections=[]}plug(e,t=!0){this.connections.push(e),t&&e.plug(this,!1)}unPlug(e,t=!0){this.connections=this.connections.filter(o=>o.id!==e.id),t&&e.unPlug(this,!1)}rePlugAll(e){let t=this.connections;this.unPlugAll(),e&&e(),t.forEach(o=>{this.plug(o)})}unPlugAll(){this.connections.forEach(e=>{this.unPlug(e)})}isAudio(){return this.ioType==="audioInput"||this.ioType==="audioOutput"||this.ioType==="polyAudioInput"||this.ioType==="polyAudioOutput"}isMidi(){return this.ioType==="midiInput"||this.ioType==="midiOutput"}serialize(){return{id:this.id,name:this.name,ioType:this.ioType,moduleId:this.module.id}}},g=class extends le{plug(e,t){super.plug(e,t)}unPlug(e,t){super.unPlug(e,t)}};var P=class extends g{plug(e,t=!0){super.plug(e,t),!(!t&&e instanceof C)&&ie(this,e,!0)}unPlug(e,t=!0){super.unPlug(e,t),!(!t&&e instanceof C)&&ie(this,e,!1)}findIOByVoice(e){return this.module.findVoice(e).inputs.findByName(this.name)}},C=class extends g{plug(e,t=!0){super.plug(e,t),!(!t&&e instanceof P)&&ie(this,e,!0)}unPlug(e,t=!0){super.unPlug(e,t),!(!t&&e instanceof P)&&ie(this,e,!1)}findIOByVoice(e){return this.module.findVoice(e).outputs.findByName(this.name)}};function ie(r,e,t){if(e instanceof P||e instanceof C){let o=Math.max(r.module.voices,e.module.voices);for(let i=0;i<o;i++){let n=r.findIOByVoice(i%r.module.voices),s=e.findIOByVoice(i%e.module.voices);t?n.plug(s):n.unPlug(s)}}else for(let o=0;o<r.module.voices;o++){let i=r.findIOByVoice(o);t?i.plug(e):i.unPlug(e)}}var D=class extends g{getAudioNode;constructor(e,t){super(e,t),this.getAudioNode=t.getAudioNode}},F=class extends g{getAudioNode;constructor(e,t){super(e,t),this.getAudioNode=t.getAudioNode}plug(e,t=!0){if(super.plug(e,t),e instanceof P)return;let o=e.getAudioNode();o instanceof AudioParam?this.getAudioNode().connect(o):this.getAudioNode().connect(o)}unPlug(e,t=!0){if(super.unPlug(e,t),e instanceof P)return;let o=e.getAudioNode();try{o instanceof AudioParam?this.getAudioNode().disconnect(o):this.getAudioNode().disconnect(o)}catch{}}};var N=class extends g{onMidiEvent;constructor(e,t){super(e,t),this.onMidiEvent=t.onMidiEvent}},G=class extends g{onMidiEvent=e=>{this.midiConnections.forEach(t=>{t.onMidiEvent(e)})};get midiConnections(){return this.connections.filter(e=>e instanceof N)}};var V=class{module;collection=[];collectionType;constructor(e,t){this.collectionType=e,this.module=t}add(e){let t;switch(this.validateUniqName(e.name),e.ioType){case"audioInput":if(this.module instanceof m)throw Error("Not compatible");t=new D(this.module,e);break;case"audioOutput":if(this.module instanceof m)throw Error("Not compatible");t=new F(this.module,e);break;case"polyAudioInput":if(this.module instanceof p)throw Error("Not compatible");t=new P(this.module,e);break;case"polyAudioOutput":if(this.module instanceof p)throw Error("Not compatible");t=new C(this.module,e);break;case"midiInput":t=new N(this.module,e);break;case"midiOutput":t=new G(this.module,e);break;default:(0,Ae.assertNever)(e)}return this.collection.push(t),t}unPlugAll(){this.collection.forEach(e=>{e.unPlugAll()})}rePlugAll(e){this.collection.forEach(t=>{t.rePlugAll(e)})}find(e){let t=this.collection.find(o=>o.id===e);if(!t)throw Error(`The io with id ${e} is not exists`);return t}findByName(e){let t=this.collection.find(o=>o.name===e);if(!t)throw Error(`The io with name ${e} is not exists`);return t}serialize(){return(0,Oe.sortBy)(this.collection,[e=>e.isMidi()?-1:1]).map(e=>e.serialize())}validateUniqName(e){if(this.collection.some(t=>t.name===e))throw Error(`An io with name ${e} is already exists`)}},A=class extends V{constructor(e){super("Input",e)}},O=class extends V{constructor(e){super("Output",e)}};var Me=require("webmidi");var ct=new Map([["C0",16.35],["C#0",17.32],["Db0",17.32],["D0",18.35],["D#0",19.45],["Eb0",19.45],["E0",20.6],["F0",21.83],["F#0",23.12],["Gb0",23.12],["G0",24.5],["G#0",25.96],["Ab0",25.96],["A0",27.5],["A#0",29.14],["Bb0",29.14],["B0",30.87],["C1",32.7],["C#1",34.65],["Db1",34.65],["D1",36.71],["D#1",38.89],["Eb1",38.89],["E1",41.2],["F1",43.65],["F#1",46.25],["Gb1",46.25],["G1",49],["G#1",51.91],["Ab1",51.91],["A1",55],["A#1",58.27],["Bb1",58.27],["B1",61.74],["C2",65.41],["C#2",69.3],["Db2",69.3],["D2",73.42],["D#2",77.78],["Eb2",77.78],["E2",82.41],["F2",87.31],["F#2",92.5],["Gb2",92.5],["G2",98],["G#2",103.83],["Ab2",103.83],["A2",110],["A#2",116.54],["Bb2",116.54],["B2",123.47],["C3",130.81],["C#3",138.59],["Db3",138.59],["D3",146.83],["D#3",155.56],["Eb3",155.56],["E3",164.81],["F3",174.61],["F#3",185],["Gb3",185],["G3",196],["G#3",207.65],["Ab3",207.65],["A3",220],["A#3",233.08],["Bb3",233.08],["B3",246.94],["C4",261.63],["C#4",277.18],["Db4",277.18],["D4",293.66],["D#4",311.13],["Eb4",311.13],["E4",329.63],["F4",349.23],["F#4",369.99],["Gb4",369.99],["G4",392],["G#4",415.3],["Ab4",415.3],["A4",440],["A#4",466.16],["Bb4",466.16],["B4",493.88],["C5",523.25],["C#5",554.37],["Db5",554.37],["D5",587.33],["D#5",622.25],["Eb5",622.25],["E5",659.26],["F5",698.46],["F#5",739.99],["Gb5",739.99],["G5",783.99],["G#5",830.61],["Ab5",830.61],["A5",880],["A#5",932.33],["Bb5",932.33],["B5",987.77],["C6",1046.5],["C#6",1108.73],["Db6",1108.73],["D6",1174.66],["D#6",1244.51],["Eb6",1244.51],["E6",1318.51],["F6",1396.91],["F#6",1479.98],["Gb6",1479.98],["G6",1567.98],["G#6",1661.22],["Ab6",1661.22],["A6",1760],["A#6",1864.66],["Bb6",1864.66],["B6",1975.53],["C7",2093],["C#7",2217.46],["Db7",2217.46],["D7",2349.32],["D#7",2489.02],["Eb7",2489.02],["E7",2637.02],["F7",2793.83],["F#7",2959.96],["Gb7",2959.96],["G7",3135.96],["G#7",3322.44],["Ab7",3322.44],["A7",3520],["A#7",3729.31],["Bb7",3729.31],["B7",3951.07],["C8",4186.01],["C#8",4434.92],["Db8",4434.92],["D8",4698.64],["D#8",4978.03],["Eb8",4978.03]]),ce=ct;var me=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],mt=2,d=class r{static _notes;name;octave;velocity=1;duration;static fromFrequency(e){let t;for(let[o,i]of ce)if(i===e){t=o;break}if(!t)throw Error("Not matching frequency with a note");return new r(t)}static fromEvent(e){let t=me[e.data[1]%12],o=Math.floor(e.data[1]/12)-2;return new r(`${t}${o}`)}static notes(e=3){return me.map(t=>new r(`${t}${e}`))}constructor(e){typeof e=="string"?this.fromString(e):this.fromProps(e)}get isSemi(){return this.name.endsWith("#")}get fullName(){return`${this.name}${this.octave}`}get frequency(){return ce.get(`${this.name}${this.octave}`)}midiData(e=!0){let t=e?144:128;return new Uint8Array([t,this.midiNumber,this.velocity*100])}get midiNumber(){return(this.octave+mt)*12+this.noteIndex}get noteIndex(){return me.indexOf(this.name)}valueOf(){return this.fullName}serialize(){return{name:this.name,octave:this.octave,frequency:this.frequency,velocity:this.velocity,duration:this.duration}}fromString(e){let t=/(\w#?)(\d)?/.exec(e)??[];this.name=t[1],this.octave=t[2]?parseInt(t[2]):1}fromProps(e){Object.assign(this,e)}};var f=class r{note;voiceNo;triggeredAt;message;static fromNote(e,t=!0,o){let i=e instanceof d?e:new d(e);return new r(new Me.Message(i.midiData(t)),o)}static fromCC(e,t,o){return new r(new Me.Message(new Uint8Array([176,e,t])),o)}constructor(e,t){this.message=e,this.triggeredAt=t,this.defineNotes()}get type(){return this.message.type}get isNote(){return this.type==="noteon"||this.type==="noteoff"}get isCC(){return this.type==="controlchange"}get cc(){if(this.isCC)return this.message.dataBytes[0]}get ccValue(){if(this.isCC)return this.message.dataBytes[1]}defineNotes(){this.isNote&&(this.note||(this.note=d.fromEvent(this.message)))}get rawMessage(){return this.message}clone(e){let t=new r(this.message,this.triggeredAt);return t.voiceNo=e,t}};var p=class{id;engineId;name;moduleType;voiceNo;audioNode;inputs;outputs;_props;superInitialized=!1;activeNotes;pendingUIUpdates=!1;constructor(e,t){let{id:o,name:i,moduleType:n,voiceNo:s,audioNodeConstructor:l,props:u}=t;this.id=o??(0,re.uuidv4)(),this.engineId=e,this.name=i,this.moduleType=n,this.voiceNo=s??0,this.activeNotes=[],this.audioNode=l?.(this.context),this._props=u,this.inputs=new A(this),this.outputs=new O(this),this.superInitialized=!0,queueMicrotask(()=>{this.props=u})}get props(){return this._props}set props(e){let t={...e};Object.keys(e).forEach(o=>{let i=e[o];if(i!==void 0){let n=this.callPropHook("onSet",o,i);n!==void 0&&(t[o]=n)}}),this._props={...this._props,...t},Object.keys(t).forEach(o=>{let i=t[o];i!==void 0&&this.callPropHook("onAfterSet",o,i)})}callPropHook(e,t,o){let i=`${e}${(0,re.upperFirst)(t)}`,n=this[i];if(typeof n=="function")return n.call(this,o)}serialize(){return{id:this.id,name:this.name,moduleType:this.moduleType,voiceNo:this.voiceNo,props:this.props,inputs:this.inputs.serialize(),outputs:this.outputs.serialize()}}plug({audioModule:e,from:t,to:o}){let i=this.outputs.findByName(t),n=e.inputs.findByName(o);i.plug(n)}rePlugAll(e){this.inputs.rePlugAll(e),this.outputs.rePlugAll(e)}unPlugAll(){this.inputs.unPlugAll(),this.outputs.unPlugAll()}start(e){}stop(e){}triggerAttack(e,t){this.activeNotes.some(o=>o.fullName===e.fullName)||this.activeNotes.push(e)}triggerRelease(e,t){this.activeNotes=this.activeNotes.filter(o=>o.fullName!==e.fullName)}handleCC(e,t){}onMidiEvent=e=>{let{note:t,triggeredAt:o}=e;switch(e.type){case"noteon":{this.triggerAttack(t,o);break}case"noteoff":this.triggerRelease(t,o);break;case"controlchange":this.handleCC(e,o);break;default:throw Error("This type is not a note")}};triggerPropsUpdate=()=>{this.pendingUIUpdates||(this.pendingUIUpdates=!0,this.sheduleTriggerUpdate())};sheduleTriggerUpdate(){requestAnimationFrame(()=>{this.engine._triggerPropsUpdate({id:this.id,moduleType:this.moduleType,voiceNo:this.voiceNo,name:this.name,props:this.props}),this.pendingUIUpdates=!1})}dispose(){this.inputs.unPlugAll(),this.outputs.unPlugAll()}registerDefaultIOs(e="both"){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent}),this.audioNode&&((e==="in"||e==="both")&&this.registerAudioInput({name:"in",getAudioNode:()=>this.audioNode}),(e==="out"||e==="both")&&this.registerAudioOutput({name:"out",getAudioNode:()=>this.audioNode}))}registerAudioInput(e){return this.inputs.add({...e,ioType:"audioInput"})}registerAudioOutput(e){return this.outputs.add({...e,ioType:"audioOutput"})}registerMidiInput(e){return this.inputs.add({...e,ioType:"midiInput"})}registerMidiOutput(e){return this.outputs.add({...e,ioType:"midiOutput"})}get engine(){return x.getById(this.engineId)}get context(){return this.engine.context}};var Ce=require("@blibliki/utils"),q=class{engine;routes;constructor(e){this.engine=e,this.routes=new Map}addRoute(e){let t=e.id??(0,Ce.uuidv4)(),o={...e,id:t};return this.routes.set(t,o),this.plug(t),o}removeRoute(e){this.unPlug(e),this.routes.delete(e)}clear(){for(let e in this.routes)this.removeRoute(e)}plug(e){let{sourceIO:t,destinationIO:o}=this.getIOs(e);t.plug(o)}unPlug(e){let{sourceIO:t,destinationIO:o}=this.getIOs(e);t.unPlug(o)}find(e){let t=this.routes.get(e);if(!t)throw Error(`Route with id ${e} not found`);return t}getIOs(e){let t=this.find(e),{source:o,destination:i}=t,n=this.engine.findIO(o.moduleId,o.ioName,"output"),s=this.engine.findIO(i.moduleId,i.ioName,"input");return{sourceIO:n,destinationIO:s}}};var S=require("webmidi");var R=(t=>(t.connected="connected",t.disconnected="disconnected",t))(R||{}),v=class{id;name;eventListerCallbacks=[];context;input;constructor(e,t){this.id=e.id,this.name=e.name||`Device ${e.id}`,this.input=e,this.context=t,this.connect()}get state(){return this.input.state}connect(){this.input.addListener("midimessage",e=>{this.processEvent(e)})}disconnect(){this.input.removeListener()}serialize(){let{id:e,name:t,state:o}=this;return{id:e,name:t,state:o}}addEventListener(e){this.eventListerCallbacks.push(e)}removeEventListener(e){this.eventListerCallbacks=this.eventListerCallbacks.filter(t=>t!==e)}processEvent(e){let t=new f(e.message,this.context.browserToContextTime(e.timestamp));switch(t.type){case"noteon":case"noteoff":case"controlchange":this.eventListerCallbacks.forEach(o=>{o(t)})}}};var Mt={a:new d("C3"),s:new d("D3"),d:new d("E3"),f:new d("F3"),g:new d("G3"),h:new d("A3"),j:new d("B3"),k:new d("C4"),l:new d("D4"),w:new d("C#3"),e:new d("D#3"),t:new d("F#3"),y:new d("G#3"),u:new d("A#3"),o:new d("C#4"),p:new d("D#4")},ht=()=>({id:"computer_keyboard",name:"Computer Keyboard",state:"connected"}),E=class{id;name;state;eventListerCallbacks=[];context;constructor(e){let{id:t,name:o,state:i}=ht();this.id=t,this.name=o,this.state=i,this.context=e,document.addEventListener("keydown",this.onKeyTrigger(!0)),document.addEventListener("keyup",this.onKeyTrigger(!1))}addEventListener(e){this.eventListerCallbacks.push(e)}removeEventListener(e){this.eventListerCallbacks=this.eventListerCallbacks.filter(t=>t!==e)}serialize(){let{id:e,name:t,state:o}=this;return{id:e,name:t,state:o}}onKeyTrigger=e=>t=>{let o=this.extractNote(t);if(!o)return;let i=f.fromNote(o,e,this.context.browserToContextTime(t.timeStamp));this.eventListerCallbacks.forEach(n=>{n(i)})};extractNote(e){if(!e.repeat)return Mt[e.key]}};var w=class{devices=new Map;initialized=!1;listeners=[];context;constructor(e){this.context=e,this.addComputerKeyboard()}async initialize(){await this.initializeDevices(),this.listenChanges(),this.initialized=!0}find(e){return this.devices.get(e)}addListener(e){this.listeners.push(e)}async initializeDevices(){if(!this.initialized)try{await S.WebMidi.enable(),S.WebMidi.inputs.forEach(e=>{this.devices.has(e.id)||this.devices.set(e.id,new v(e,this.context))})}catch(e){console.error("Error enabling WebMidi:",e)}}addComputerKeyboard(){if(typeof document>"u")return;let e=new E(this.context);this.devices.set(e.id,e)}listenChanges(){S.WebMidi.addListener("connected",e=>{let t=e.port;if(t instanceof S.Output||this.devices.has(t.id))return;let o=new v(t,this.context);this.devices.set(o.id,o),this.listeners.forEach(i=>{i(o)})}),S.WebMidi.addListener("disconnected",e=>{let t=e.port;if(t instanceof S.Output)return;let o=this.devices.get(t.id);o&&(o instanceof E||(o.disconnect(),this.devices.delete(o.id),this.listeners.forEach(i=>{i(o)})))})}};var ot=require("@blibliki/utils");var be={},Ne={},fe=class extends p{activeNote=null;triggeredAt=0;constructor(e,t){let o={...Ne,...t.props};super(e,{...t,props:o})}midiTriggered=e=>{let{triggeredAt:t,note:o,type:i}=e;if(!o)return;let n=o.fullName;switch(i){case"noteon":this.activeNote=n,this.triggeredAt=t;break;case"noteoff":this.activeNote=null;break;default:throw Error("This type is not a note")}}},z=class extends m{midiOutput;constructor(e,t){let o={...Ne,...t.props},i=(n,s)=>new fe(n,s);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerInputs(),this.registerOutputs()}onMidiEvent=e=>{let t;switch(e.type){case"noteon":t=this.findFreeVoice();break;case"noteoff":t=this.audioModules.find(o=>o.activeNote===e.note.fullName);break;default:throw Error("This type is not a note")}t&&(t.midiTriggered(e),e.voiceNo=t.voiceNo,this.midiOutput.onMidiEvent(e))};findFreeVoice(){let e=this.audioModules.find(t=>!t.activeNote);return e??=this.audioModules.sort((t,o)=>t.triggeredAt-o.triggeredAt)[0],e}registerInputs(){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent})}registerOutputs(){this.midiOutput=this.registerMidiOutput({name:"midi out"})}};var Ee={value:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Value"}},ft={value:1},L=class extends p{isStated=!1;constructor(e,t){let o={...ft,...t.props},i=n=>new ConstantSourceNode(n.audioContext);super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs("out")}onAfterSetValue=e=>{this.audioNode.offset.value=e};start(e){this.isStated||(this.isStated=!0,this.audioNode.start(e))}stop(e){this.isStated&&(this.audioNode.stop(e),this.rePlugAll(()=>{this.audioNode=new ConstantSourceNode(this.context.audioContext,{offset:this.props.value})}),this.isStated=!1)}triggerAttack=(e,t)=>{this.audioNode.offset.setValueAtTime(e.frequency,t),this.start(t)};triggerRelease=()=>{}};var ye=require("@blibliki/utils");var we={attack:.01,decay:0,sustain:1,release:0},ke={attack:{kind:"number",min:1e-4,max:20,step:.01,exp:3,label:"Attack"},decay:{kind:"number",min:0,max:20,step:.01,exp:3,label:"Decay"},sustain:{kind:"number",min:0,max:1,step:.01,label:"Sustain"},release:{kind:"number",min:0,max:20,step:.01,exp:3,label:"Release"}},ge=class extends p{constructor(e,t){let o={...we,...t.props},i=n=>{let s=new GainNode(n.audioContext);return s.gain.value=0,s};super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs()}triggerAttack(e,t){super.triggerAttack(e,t);let o=this.props.attack,i=this.props.decay,n=this.props.sustain;(0,ye.cancelAndHoldAtTime)(this.audioNode.gain,t),this.audioNode.gain.value===0&&this.audioNode.gain.setValueAtTime(.001,t),this.audioNode.gain.exponentialRampToValueAtTime(1,t+o),n>0?this.audioNode.gain.exponentialRampToValueAtTime(n,t+o+i):this.audioNode.gain.exponentialRampToValueAtTime(.001,t+o+i)}triggerRelease(e,t){if(super.triggerRelease(e,t),this.activeNotes.length>0)return;let o=this.props.release,i=(0,ye.cancelAndHoldAtTime)(this.audioNode.gain,t);i>=1e-4&&(this.audioNode.gain.setValueAtTime(i,t),this.audioNode.gain.exponentialRampToValueAtTime(1e-4,t+o-1e-4)),this.audioNode.gain.setValueAtTime(0,t+o)}},U=class extends m{constructor(e,t){let o={...we,...t.props},i=(n,s)=>new ge(n,s);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerDefaultIOs()}};var De={gain:{kind:"number",min:0,max:1/0,step:.01,label:"Gain"}},Fe={gain:1},_=class extends p{constructor(e,t){let o={...Fe,...t.props},i=n=>new GainNode(n.audioContext);super(e,{...t,audioNodeConstructor:i,props:o}),this.registerDefaultIOs(),this.registerAdditionalInputs()}onAfterSetGain=e=>{this.audioNode.gain.value=e};registerAdditionalInputs(){this.registerAudioInput({name:"gain",getAudioNode:()=>this.audioNode.gain})}},B=class extends m{constructor(e,t){let o={...Fe,...t.props},i=(n,s)=>new _(n,s);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerAdditionalInputs(),this.registerDefaultIOs()}registerAdditionalInputs(){this.registerAudioInput({name:"gain"})}};var Ge=20,Pe=2e4,Ve={cutoff:Pe,envelopeAmount:0,type:"lowpass",Q:1},qe={cutoff:{kind:"number",min:Ge,max:Pe,step:1,exp:5,label:"Cutoff"},envelopeAmount:{kind:"number",min:-1,max:1,step:.01,label:"Envelope Amount"},type:{kind:"enum",options:["lowpass","highpass","bandpass"],label:"Type"},Q:{kind:"number",min:1e-4,max:1e3,step:.1,exp:5,label:"Q"}},Ie=class extends p{scale;amount;constructor(e,t){let o={...Ve,...t.props},i=n=>new BiquadFilterNode(n.audioContext,{type:o.type,frequency:0,Q:o.Q});super(e,{...t,props:o,audioNodeConstructor:i}),this.amount=new _(e,{name:"amount",moduleType:"Gain",props:{gain:o.envelopeAmount}}),this.scale=ne(e,{name:"scale",moduleType:"Scale",props:{min:Ge,max:Pe,current:this.props.cutoff}}),this.amount.plug({audioModule:this.scale,from:"out",to:"in"}),this.scale.audioNode.connect(this.audioNode.frequency),this.registerDefaultIOs(),this.registerInputs()}onAfterSetType=e=>{this.audioNode.type=e};onAfterSetCutoff=e=>{this.scale.props={current:e}};onAfterSetQ=e=>{this.audioNode.Q.value=e};onAfterSetEnvelopeAmount=e=>{this.amount.props={gain:e}};registerInputs(){this.registerAudioInput({name:"cutoff",getAudioNode:()=>this.audioNode.frequency}),this.registerAudioInput({name:"cutoffMod",getAudioNode:()=>this.amount.audioNode}),this.registerAudioInput({name:"Q",getAudioNode:()=>this.audioNode.Q})}},H=class extends m{constructor(e,t){let o={...Ve,...t.props},i=(n,s)=>new Ie(n,s);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerInputs(),this.registerDefaultIOs()}registerInputs(){this.registerAudioInput({name:"cutoff"}),this.registerAudioInput({name:"cutoffMod"}),this.registerAudioInput({name:"Q"})}};var Re={fftSize:{kind:"enum",options:[32,64,128,256,512,1024,2048,4096,8192,16384,32768],label:"FFT size"}},yt={fftSize:512},$=class extends p{_buffer;constructor(e,t){let o={...yt,...t.props},i=n=>new AnalyserNode(n.audioContext);super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs("in")}onAfterSetFftSize=e=>{this._buffer=new Float32Array(e)};get buffer(){return this._buffer?this._buffer:(this._buffer=new Float32Array(this.props.fftSize),this._buffer)}getValue(){return this.getValues()[0]}getValues(){return this.audioNode.getFloatTimeDomainData(this.buffer),this.buffer}};var gt={},ze={},W=class extends p{constructor(e,t){let o={...gt,...t.props},i=n=>n.destination;super(e,{...t,audioNodeConstructor:i,props:o}),this.registerDefaultIOs("in")}};var se=(s=>(s.direct="direct",s.directRev="directRev",s.toggleInc="toggleInc",s.toggleDec="toggleDec",s.incDec="incDec",s.incDecRev="incDecRev",s))(se||{}),Le={pages:{kind:"array",label:"Midi mapping pages"},activePage:{kind:"number",label:"Active page",min:0,max:100,step:1},globalMappings:{kind:"array",label:"Global midi mappings"}},It={pages:[{name:"Page 1",mappings:[{}]}],activePage:0,globalMappings:[{}]};function Pt({value:r,midiValue:e,propSchema:t,mapping:o}){let i=t.min??0,n=t.max??1,s=t.exp??1,{threshold:l=64,mode:u}=o,c=(r-i)/(n-i),M=Math.pow(c,1/s)*127;return M=e>=l&&u==="incDec"||e<=l&&u==="incDecRev"?M+1:M-1,Math.round(Math.max(0,Math.min(127,M)))}var j=class extends p{constructor(e,t){let o={...It,...t.props};super(e,{...t,props:o}),this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent})}onSetActivePage=e=>Math.max(Math.min(e,this.props.pages.length-1),0);handleCC=(e,t)=>{this.checkAutoAssign(e);let o=this.props.pages[this.props.activePage];[...this.props.globalMappings.filter(i=>i.cc===e.cc),...o.mappings.filter(i=>i.cc===e.cc)].forEach(i=>{this.forwardMapping(e,i,t)})};forwardMapping=(e,t,o)=>{if(t.moduleId===void 0||t.moduleType===void 0||t.propName===void 0)return;let i=t.propName,n=e.ccValue;if(n===void 0)return;let s=t.mode??"direct";if((s==="toggleInc"||s==="toggleDec")&&n!==127)return;let l=this.engine.findModule(t.moduleId),u=ue[l.moduleType][i],c;switch(u.kind){case"number":{let h=l.props[i];if(s==="incDec"||s==="incDecRev"?n=Pt({value:h,propSchema:u,mapping:t,midiValue:n}):s==="directRev"&&(n=127-n),s==="toggleInc")c=h+(u.step??1);else if(s==="toggleDec")c=h-(u.step??1);else{let M=u.min??0,I=u.max??1,y=n/127,a=Math.pow(y,u.exp??1);if(c=M+a*(I-M),u.step!==void 0&&(!u.exp||u.exp===1)){let k=Math.round((c-M)/u.step);c=M+k*u.step}}break}case"enum":{let h=Math.floor(n/127*u.options.length),M=Math.min(h,u.options.length-1);c=u.options[M];break}case"boolean":c=n>=64;break;case"string":throw Error("MidiMapper not support string type of values");case"array":throw Error("MidiMapper not support array type of values");default:throw Error("MidiMapper unknown type")}l.props={[i]:c},l.triggerPropsUpdate()};checkAutoAssign(e){if(e.cc===void 0)return;let t=this.props.pages[this.props.activePage],o=this.props.globalMappings.some(({autoAssign:u})=>u),i=t.mappings.some(({autoAssign:u})=>u);if(!o&&!i)return;let n=o?this.props.globalMappings.map(u=>u.autoAssign?{...u,cc:e.cc,autoAssign:!1}:u):this.props.globalMappings,s=i?t.mappings.map(u=>u.autoAssign?{...u,cc:e.cc,autoAssign:!1}:u):t.mappings,l=this.props.pages.map((u,c)=>c===this.props.activePage?{...u,mappings:s}:u);this.props={pages:l,globalMappings:n},this.triggerPropsUpdate()}};var Ue={selectedId:{kind:"string",label:"Midi device ID"}},Tt={selectedId:void 0},Q=class extends p{midiOutput;_forwardMidiEvent;constructor(e,t){let o={...Tt,...t.props};super(e,{...t,props:o}),this.addEventListener(this.props.selectedId),this.registerOutputs()}onSetSelectedId=e=>(this.removeEventListener(),this.addEventListener(e),e);get forwardMidiEvent(){return this._forwardMidiEvent?this._forwardMidiEvent:(this._forwardMidiEvent=e=>{this.midiOutput.onMidiEvent(e)},this._forwardMidiEvent)}addEventListener(e){if(!e)return;this.engine.findMidiDevice(e)?.addEventListener(this.forwardMidiEvent)}removeEventListener(){if(!this.props.selectedId)return;this.engine.findMidiDevice(this.props.selectedId)?.removeEventListener(this.forwardMidiEvent)}registerOutputs(){this.midiOutput=this.registerMidiOutput({name:"midi out"})}};var _e=require("@blibliki/utils");var Be=-18,J=(i=>(i.sine="sine",i.triangle="triangle",i.square="square",i.sawtooth="sawtooth",i))(J||{}),He={wave:{kind:"enum",options:Object.values(J),label:"Waveform"},frequency:{kind:"number",min:0,max:25e3,step:1,label:"Frequency"},fine:{kind:"number",min:-1,max:1,step:.01,label:"Fine"},coarse:{kind:"number",min:-12,max:12,step:1,label:"Coarse"},octave:{kind:"number",min:-1,max:2,step:1,label:"Octave"},lowGain:{kind:"boolean",label:`Use ${Be}db Gain`}},Ke={wave:"sine",frequency:440,fine:0,coarse:0,octave:0,lowGain:!1},Te=class extends p{isStated=!1;lowOutputGain;detuneGain;constructor(e,t){let o={...Ke,...t.props},i=n=>new OscillatorNode(n.audioContext);super(e,{...t,props:o,audioNodeConstructor:i}),this.lowOutputGain=new GainNode(this.context.audioContext,{gain:(0,_e.dbToGain)(Be)}),this.applyOutputGain(),this.initializeGainDetune(),this.registerInputs(),this.registerOutputs()}onAfterSetWave=e=>{this.audioNode.type=e};onAfterSetFrequency=()=>{this.updateFrequency()};onAfterSetFine=()=>{this.updateFrequency()};onAfterSetCoarse=()=>{this.updateFrequency()};onAfterSetOctave=()=>{this.updateFrequency()};onAfterSetLowGain=()=>{this.rePlugAll()};start(e){this.isStated||(this.isStated=!0,this.audioNode.start(e))}stop(e){this.isStated&&(this.audioNode.stop(e),this.rePlugAll(()=>{this.audioNode=new OscillatorNode(this.context.audioContext,{type:this.props.wave,frequency:this.finalFrequency}),this.applyOutputGain(),this.detuneGain.connect(this.audioNode.detune)}),this.isStated=!1)}triggerAttack=(e,t)=>{super.triggerAttack(e,t),this.props={frequency:e.frequency},this.updateFrequency(t),this.start(t)};triggerRelease(e,t){super.triggerRelease(e,t);let o=this.activeNotes.length?this.activeNotes[this.activeNotes.length-1]:null;o&&(this.props={frequency:o.frequency},this.updateFrequency(t))}get finalFrequency(){let{frequency:e,coarse:t,octave:o,fine:i}=this.props;return e*Math.pow(2,t/12+o+i/12)}updateFrequency(e){this.finalFrequency!==void 0&&(e?this.audioNode.frequency.setValueAtTime(this.finalFrequency,e):this.audioNode.frequency.value=this.finalFrequency)}applyOutputGain(){this.audioNode.connect(this.lowOutputGain)}initializeGainDetune(){this.detuneGain=new GainNode(this.context.audioContext,{gain:100}),this.detuneGain.connect(this.audioNode.detune)}registerInputs(){this.registerAudioInput({name:"detune",getAudioNode:()=>this.detuneGain})}registerOutputs(){this.registerAudioOutput({name:"out",getAudioNode:()=>this.props.lowGain?this.lowOutputGain:this.audioNode})}},Y=class extends m{constructor(e,t){let o={...Ke,...t.props},i=(n,s)=>new Te(n,s);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerInputs(),this.registerDefaultIOs("out")}start(e){this.audioModules.forEach(t=>{t.start(e)})}stop(e){this.audioModules.forEach(t=>{t.stop(e)})}registerInputs(){this.registerAudioInput({name:"detune"})}};var je=require("@blibliki/utils");var $e=URL.createObjectURL(new Blob(["(",(()=>{class r extends AudioWorkletProcessor{s0;s1;constructor(){super(),this.s0=0,this.s1=0}static get parameterDescriptors(){return[{name:"cutoff",defaultValue:1e3,minValue:20,maxValue:2e4},{name:"resonance",defaultValue:0,minValue:0,maxValue:4}]}process(t,o,i){let n=t[0],s=o[0],l=i.cutoff,u=i.resonance;for(let c=0;c<n.length;c++){let h=n[c],M=s[c];for(let I=0;I<h.length;I++){let y=h[I],a=l.length>1?l[I]:l[0],k=Math.max(20,Math.min(2e4,a)),pe=Math.log(k/20)/Math.log(2e4/20),T=Math.pow(.5,(1-pe)/.125),xe=1-Math.pow(.5,((u.length>1?u[I]:u[0])+.125)/.125)*T;this.s0=xe*this.s0-T*this.s1+T*y,this.s1=xe*this.s1+T*this.s0,M[I]=this.s1}}return!0}}registerProcessor("filter-processor",r)}).toString(),")()"],{type:"application/javascript"}));var We=URL.createObjectURL(new Blob(["(",(()=>{class r extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:"min",defaultValue:1e-10},{name:"max",defaultValue:1},{name:"current",defaultValue:.5}]}process(t,o,i){let n=t[0],s=o[0],l=i.min,u=i.max,c=i.current;if(!n.length||n[0].length===0){for(let h of s){let M=(i.current.length>1,i.current[0]);h.fill(M)}return!0}for(let h=0;h<n.length;h++){let M=n[h],I=s[h];for(let y=0;y<M.length;y++){let a=M[y],k=l.length>1?l[y]:l[0],pe=u.length>1?u[y]:u[0],T=c.length>1?c[y]:c[0];a<0?I[y]=T*Math.pow(k/T,-a):I[y]=T*Math.pow(pe/T,a)}}return!0}}registerProcessor("scale-processor",r)}).toString(),")()"],{type:"application/javascript"}));async function Qe(r){await r.addModule(We),await r.addModule($e)}function Ye(r,e){switch(e){case"ScaleProcessor":return r.newAudioWorklet("scale-processor");case"FilterProcessor":return r.newAudioWorklet("filter-processor");default:(0,je.assertNever)(e)}}var Je={min:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Min"},max:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Max"},current:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Current"}},vt={min:0,max:1,current:.5},X=class extends p{constructor(e,t){let o={...vt,...t.props},i=n=>Ye(n,"ScaleProcessor");super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs()}get current(){return this.audioNode.parameters.get("current")}get min(){return this.audioNode.parameters.get("min")}get max(){return this.audioNode.parameters.get("max")}onAfterSetMin=e=>{this.min.value=e};onAfterSetMax=e=>{this.max.value=e};onAfterSetCurrent=e=>{this.current.value=e}};var Xe={steps:{kind:"number",min:1,max:16,step:1,label:"Steps"},bars:{kind:"number",min:1,max:16,step:1,label:"Steps"}},xt={sequences:[],steps:16,bars:1},Z=class extends p{midiOutput;constructor(e,t){let o={...xt,...t.props};super(e,{...t,props:o})}};var Ze={pan:{kind:"number",min:-1,max:1,step:.01,label:"Pan"}},et={pan:0},ve=class extends p{constructor(e,t){let o={...et,...t.props},i=n=>new StereoPannerNode(n.audioContext);super(e,{...t,audioNodeConstructor:i,props:o}),this.registerDefaultIOs(),this.registerAdditionalInputs()}onAfterSetPan=e=>{this.audioNode.pan.value=e};registerAdditionalInputs(){this.registerAudioInput({name:"pan",getAudioNode:()=>this.audioNode.pan})}},ee=class extends m{constructor(e,t){let o={...et,...t.props},i=(n,s)=>new ve(n,s);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerAdditionalInputs(),this.registerDefaultIOs()}registerAdditionalInputs(){this.registerAudioInput({name:"pan"})}};var tt={activeNotes:{kind:"array",label:"Active notes"}},St={activeNotes:[]},te=class extends p{midiOutput;constructor(e,t){let o={...St,...t.props};super(e,{...t,props:o}),this.registerInputs(),this.registerOutputs()}sendMidi(e){this.midiOutput.onMidiEvent(e)}triggerAttack=(e,t)=>{this.props={activeNotes:[...this.props.activeNotes,e.fullName]},this.triggerPropsUpdate(),this.sendMidi(f.fromNote(e,!0,t))};triggerRelease=(e,t)=>{this.props={activeNotes:this.props.activeNotes.filter(o=>o!==e.fullName)},this.triggerPropsUpdate(),this.sendMidi(f.fromNote(e,!1,t))};registerInputs(){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent})}registerOutputs(){this.midiOutput=this.registerMidiOutput({name:"midi out"})}};var K=(a=>(a.Master="Master",a.Oscillator="Oscillator",a.Gain="Gain",a.MidiSelector="MidiSelector",a.Envelope="Envelope",a.Filter="Filter",a.Scale="Scale",a.StereoPanner="StereoPanner",a.Inspector="Inspector",a.Constant="Constant",a.MidiMapper="MidiMapper",a.VirtualMidi="VirtualMidi",a.StepSequencer="StepSequencer",a.VoiceScheduler="VoiceScheduler",a))(K||{}),ue={Oscillator:He,Gain:De,Master:ze,MidiSelector:Ue,Envelope:ke,Filter:qe,Scale:Je,StereoPanner:Ze,Inspector:Re,Constant:Ee,MidiMapper:Le,VirtualMidi:tt,StepSequencer:Xe,VoiceScheduler:be};function ne(r,e){switch(e.moduleType){case"Oscillator":return new Y(r,e);case"Gain":return new B(r,e);case"Master":return new W(r,e);case"MidiSelector":return new Q(r,e);case"Envelope":return new U(r,e);case"Filter":return new H(r,e);case"Scale":return new X(r,e);case"StereoPanner":return new ee(r,e);case"Inspector":return new $(r,e);case"Constant":return new L(r,e);case"MidiMapper":return new j(r,e);case"VirtualMidi":return new te(r,e);case"StepSequencer":return new Z(r,e);case"VoiceScheduler":return new z(r,e);default:(0,ot.assertNever)(e)}}var x=class r{static _engines=new Map;static _currentId;propsUpdateCallbacks=[];id;context;isInitialized=!1;routes;transport;modules;midiDeviceManager;static getById(e){let t=r._engines.get(e);return(0,b.assertDefined)(t),t}static get current(){return(0,b.assertDefined)(this._currentId),this.getById(this._currentId)}constructor(e){this.id=(0,b.uuidv4)(),this.context=e,this.transport=new it.Transport(this.context,{generator:(t,o)=>[],consumer:t=>{},onJump:t=>{},onStart:this.onStart,onStop:this.onStop,silence:t=>{}}),this.routes=new q(this),this.modules=new Map,this.midiDeviceManager=new w(this.context),r._engines.set(this.id,this),r._currentId=this.id}get state(){return this.transport.state}async initialize(){this.isInitialized||(await Qe(this.context),await this.midiDeviceManager.initialize(),this.isInitialized=!0)}addModule(e){let t=ne(this.id,e);return this.modules.set(t.id,t),t.serialize()}updateModule(e){let t=this.findModule(e.id);if(t.moduleType!==e.moduleType)throw Error(`The module id ${e.id} isn't moduleType ${e.moduleType}`);let o=(0,b.pick)(e.changes,["name","props"]);return Object.assign(t,o),t instanceof m&&e.changes.voices!==void 0&&(t.voices=e.changes.voices),t.serialize()}removeModule(e){this.modules.delete(e)}addRoute(e){return this.routes.addRoute(e)}removeRoute(e){this.routes.removeRoute(e)}validRoute(e){let{source:t,destination:o}=e,i=this.findIO(t.moduleId,t.ioName,"output"),n=this.findIO(o.moduleId,o.ioName,"input");return i.isMidi()&&n.isMidi()||i.isAudio()&&n.isAudio()}async start(){await this.resume(),this.transport.start()}stop(){this.transport.stop(),this.transport.reset()}pause(){this.transport.stop()}get bpm(){return this.transport.bpm}set bpm(e){this.transport.bpm=e}get timeSignature(){return this.transport.timeSignature}set timeSignature(e){this.transport.timeSignature=e}async resume(){await this.context.resume()}dispose(){this.stop(),this.routes.clear(),this.modules.forEach(e=>{e.dispose()}),this.modules.clear()}findModule(e){let t=this.modules.get(e);if(!t)throw Error(`The module with id ${e} is not exists`);return t}findIO(e,t,o){return this.findModule(e)[`${o}s`].findByName(t)}findMidiDevice(e){return this.midiDeviceManager.find(e)}onPropsUpdate(e){this.propsUpdateCallbacks.push(e)}_triggerPropsUpdate(e){this.propsUpdateCallbacks.forEach(t=>{t(e)})}triggerVirtualMidi(e,t,o){let i=this.findModule(e);if(i.moduleType!=="VirtualMidi")throw Error("This is not a virtual mid");i.sendMidi(f.fromNote(t,o==="noteOn",this.context.currentTime))}onStart=e=>{this.modules.forEach(t=>{t.start(e)})};onStop=e=>{this.modules.forEach(t=>{t.stop(e)})}};var rt=require("@blibliki/transport"),nt=require("@blibliki/utils");
|
|
1
|
+
"use strict";var de=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var ut=Object.getOwnPropertyNames;var pt=Object.prototype.hasOwnProperty;var dt=(r,e)=>{for(var t in e)de(r,t,{get:e[t],enumerable:!0})},at=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ut(e))!pt.call(r,i)&&i!==t&&de(r,i,{get:()=>e[i],enumerable:!(o=st(e,i))||o.enumerable});return r};var lt=r=>at(de({},"__esModule",{value:!0}),r);var At={};dt(At,{Context:()=>nt.Context,Engine:()=>x,MidiDevice:()=>v,MidiMappingMode:()=>se,MidiPortState:()=>R,ModuleType:()=>K,Note:()=>a,OscillatorWave:()=>J,TransportState:()=>rt.TransportState,moduleSchemas:()=>ue});module.exports=lt(At);var it=require("@blibliki/transport"),S=require("@blibliki/utils");var re=require("@blibliki/utils");var Ce=require("@blibliki/utils"),be=require("es-toolkit");var oe=require("@blibliki/utils");var m=class{id;engineId;moduleType;audioModules;inputs;outputs;monoModuleConstructor;_props;_voices;_name;pendingUIUpdates=!1;constructor(e,t){let{id:o,name:i,moduleType:n,voices:u,monoModuleConstructor:d,props:s}=t;this.audioModules=[],this.monoModuleConstructor=d,this.id=o??(0,oe.uuidv4)(),this.engineId=e,this.name=i,this.moduleType=n,this._props=s,this.inputs=new O(this),this.outputs=new C(this),queueMicrotask(()=>{this.voices=u||1,this.props=s})}get name(){return this._name}set name(e){this._name=e,this.audioModules.forEach(t=>t.name=e)}get props(){return this._props}set props(e){this._props={...this._props,...e},this.audioModules.forEach(t=>t.props=e)}get voices(){return this._voices}set voices(e){this._voices=e,this.adjustNumberOfModules(),this.rePlugAll()}start(e){this.audioModules.forEach(t=>{t.start(e)})}stop(e){this.audioModules.forEach(t=>{t.stop(e)})}serialize(){return{id:this.id,name:this.name,moduleType:this.moduleType,voices:this.voices,props:this.props,inputs:this.inputs.serialize(),outputs:this.outputs.serialize()}}plug({audioModule:e,from:t,to:o}){let i=this.outputs.findByName(t),n=e.inputs.findByName(o);i.plug(n)}rePlugAll(e){this.inputs.rePlugAll(e),this.outputs.rePlugAll(e)}unPlugAll(){this.inputs.unPlugAll(),this.outputs.unPlugAll()}dispose(){this.inputs.unPlugAll(),this.outputs.unPlugAll(),this.audioModules.forEach(e=>{e.dispose()})}onMidiEvent=e=>{let t=e.voiceNo??0;this.findVoice(t).onMidiEvent(e)};triggerPropsUpdate=()=>{this.pendingUIUpdates||(this.pendingUIUpdates=!0,this.sheduleTriggerUpdate())};sheduleTriggerUpdate(){requestAnimationFrame(()=>{this.engine._triggerPropsUpdate({id:this.id,moduleType:this.moduleType,voices:this.voices,name:this.name,props:this.props}),this.pendingUIUpdates=!1})}findVoice(e){let t=this.audioModules.find(o=>o.voiceNo===e);if(!t)throw Error(`Voice ${e} on module ${this.name} not found`);return t}registerDefaultIOs(e="both"){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent}),(e==="in"||e==="both")&&this.registerAudioInput({name:"in"}),(e==="out"||e==="both")&&this.registerAudioOutput({name:"out"})}registerAudioInput(e){return this.inputs.add({...e,ioType:"polyAudioInput"})}registerAudioOutput(e){return this.outputs.add({...e,ioType:"polyAudioOutput"})}registerMidiInput(e){return this.inputs.add({...e,ioType:"midiInput"})}registerMidiOutput(e){return this.outputs.add({...e,ioType:"midiOutput"})}adjustNumberOfModules(){if(this.audioModules.length!==this.voices){if(this.audioModules.length>this.voices)this.audioModules.pop()?.dispose();else{let e=this.audioModules.length,t=(0,oe.deterministicId)(this.id,e.toString()),o=this.monoModuleConstructor(this.engineId,{id:t,name:this.name,moduleType:this.moduleType,voiceNo:e,props:{...this.props}});this.audioModules.push(o)}this.adjustNumberOfModules()}}get engine(){return x.getById(this.engineId)}get context(){return this.engine.context}};var Oe=require("@blibliki/utils");var le=class{id;ioType;name;module;connections;constructor(e,t){this.module=e,this.name=t.name,this.ioType=t.ioType,this.id=(0,Oe.deterministicId)(this.module.id,this.name),this.connections=[]}plug(e,t=!0){this.connections.push(e),t&&e.plug(this,!1)}unPlug(e,t=!0){this.connections=this.connections.filter(o=>o.id!==e.id),t&&e.unPlug(this,!1)}rePlugAll(e){let t=this.connections;this.unPlugAll(),e&&e(),t.forEach(o=>{this.plug(o)})}unPlugAll(){this.connections.forEach(e=>{this.unPlug(e)})}isAudio(){return this.ioType==="audioInput"||this.ioType==="audioOutput"||this.ioType==="polyAudioInput"||this.ioType==="polyAudioOutput"}isMidi(){return this.ioType==="midiInput"||this.ioType==="midiOutput"}serialize(){return{id:this.id,name:this.name,ioType:this.ioType,moduleId:this.module.id}}},g=class extends le{plug(e,t){super.plug(e,t)}unPlug(e,t){super.unPlug(e,t)}};var P=class extends g{plug(e,t=!0){super.plug(e,t),!(!t&&e instanceof b)&&ie(this,e,!0)}unPlug(e,t=!0){super.unPlug(e,t),!(!t&&e instanceof b)&&ie(this,e,!1)}findIOByVoice(e){return this.module.findVoice(e).inputs.findByName(this.name)}},b=class extends g{plug(e,t=!0){super.plug(e,t),!(!t&&e instanceof P)&&ie(this,e,!0)}unPlug(e,t=!0){super.unPlug(e,t),!(!t&&e instanceof P)&&ie(this,e,!1)}findIOByVoice(e){return this.module.findVoice(e).outputs.findByName(this.name)}};function ie(r,e,t){if(e instanceof P||e instanceof b){let o=Math.max(r.module.voices,e.module.voices);for(let i=0;i<o;i++){let n=r.findIOByVoice(i%r.module.voices),u=e.findIOByVoice(i%e.module.voices);t?n.plug(u):n.unPlug(u)}}else for(let o=0;o<r.module.voices;o++){let i=r.findIOByVoice(o);t?i.plug(e):i.unPlug(e)}}var D=class extends g{getAudioNode;constructor(e,t){super(e,t),this.getAudioNode=t.getAudioNode}},F=class extends g{getAudioNode;constructor(e,t){super(e,t),this.getAudioNode=t.getAudioNode}plug(e,t=!0){if(super.plug(e,t),e instanceof P)return;let o=e.getAudioNode();o instanceof AudioParam?this.getAudioNode().connect(o):this.getAudioNode().connect(o)}unPlug(e,t=!0){if(super.unPlug(e,t),e instanceof P)return;let o=e.getAudioNode();try{o instanceof AudioParam?this.getAudioNode().disconnect(o):this.getAudioNode().disconnect(o)}catch{}}};var N=class extends g{onMidiEvent;constructor(e,t){super(e,t),this.onMidiEvent=t.onMidiEvent}},G=class extends g{onMidiEvent=e=>{this.midiConnections.forEach(t=>{t.onMidiEvent(e)})};get midiConnections(){return this.connections.filter(e=>e instanceof N)}};var V=class{module;collection=[];collectionType;constructor(e,t){this.collectionType=e,this.module=t}add(e){let t;switch(this.validateUniqName(e.name),e.ioType){case"audioInput":if(this.module instanceof m)throw Error("Not compatible");t=new D(this.module,e);break;case"audioOutput":if(this.module instanceof m)throw Error("Not compatible");t=new F(this.module,e);break;case"polyAudioInput":if(this.module instanceof p)throw Error("Not compatible");t=new P(this.module,e);break;case"polyAudioOutput":if(this.module instanceof p)throw Error("Not compatible");t=new b(this.module,e);break;case"midiInput":t=new N(this.module,e);break;case"midiOutput":t=new G(this.module,e);break;default:(0,Ce.assertNever)(e)}return this.collection.push(t),t}unPlugAll(){this.collection.forEach(e=>{e.unPlugAll()})}rePlugAll(e){this.collection.forEach(t=>{t.rePlugAll(e)})}find(e){let t=this.collection.find(o=>o.id===e);if(!t)throw Error(`The io with id ${e} is not exists`);return t}findByName(e){let t=this.collection.find(o=>o.name===e);if(!t)throw Error(`The io with name ${e} is not exists`);return t}serialize(){return(0,be.sortBy)(this.collection,[e=>e.isMidi()?-1:1]).map(e=>e.serialize())}validateUniqName(e){if(this.collection.some(t=>t.name===e))throw Error(`An io with name ${e} is already exists`)}},O=class extends V{constructor(e){super("Input",e)}},C=class extends V{constructor(e){super("Output",e)}};var Me=require("webmidi");var ct=new Map([["C0",16.35],["C#0",17.32],["Db0",17.32],["D0",18.35],["D#0",19.45],["Eb0",19.45],["E0",20.6],["F0",21.83],["F#0",23.12],["Gb0",23.12],["G0",24.5],["G#0",25.96],["Ab0",25.96],["A0",27.5],["A#0",29.14],["Bb0",29.14],["B0",30.87],["C1",32.7],["C#1",34.65],["Db1",34.65],["D1",36.71],["D#1",38.89],["Eb1",38.89],["E1",41.2],["F1",43.65],["F#1",46.25],["Gb1",46.25],["G1",49],["G#1",51.91],["Ab1",51.91],["A1",55],["A#1",58.27],["Bb1",58.27],["B1",61.74],["C2",65.41],["C#2",69.3],["Db2",69.3],["D2",73.42],["D#2",77.78],["Eb2",77.78],["E2",82.41],["F2",87.31],["F#2",92.5],["Gb2",92.5],["G2",98],["G#2",103.83],["Ab2",103.83],["A2",110],["A#2",116.54],["Bb2",116.54],["B2",123.47],["C3",130.81],["C#3",138.59],["Db3",138.59],["D3",146.83],["D#3",155.56],["Eb3",155.56],["E3",164.81],["F3",174.61],["F#3",185],["Gb3",185],["G3",196],["G#3",207.65],["Ab3",207.65],["A3",220],["A#3",233.08],["Bb3",233.08],["B3",246.94],["C4",261.63],["C#4",277.18],["Db4",277.18],["D4",293.66],["D#4",311.13],["Eb4",311.13],["E4",329.63],["F4",349.23],["F#4",369.99],["Gb4",369.99],["G4",392],["G#4",415.3],["Ab4",415.3],["A4",440],["A#4",466.16],["Bb4",466.16],["B4",493.88],["C5",523.25],["C#5",554.37],["Db5",554.37],["D5",587.33],["D#5",622.25],["Eb5",622.25],["E5",659.26],["F5",698.46],["F#5",739.99],["Gb5",739.99],["G5",783.99],["G#5",830.61],["Ab5",830.61],["A5",880],["A#5",932.33],["Bb5",932.33],["B5",987.77],["C6",1046.5],["C#6",1108.73],["Db6",1108.73],["D6",1174.66],["D#6",1244.51],["Eb6",1244.51],["E6",1318.51],["F6",1396.91],["F#6",1479.98],["Gb6",1479.98],["G6",1567.98],["G#6",1661.22],["Ab6",1661.22],["A6",1760],["A#6",1864.66],["Bb6",1864.66],["B6",1975.53],["C7",2093],["C#7",2217.46],["Db7",2217.46],["D7",2349.32],["D#7",2489.02],["Eb7",2489.02],["E7",2637.02],["F7",2793.83],["F#7",2959.96],["Gb7",2959.96],["G7",3135.96],["G#7",3322.44],["Ab7",3322.44],["A7",3520],["A#7",3729.31],["Bb7",3729.31],["B7",3951.07],["C8",4186.01],["C#8",4434.92],["Db8",4434.92],["D8",4698.64],["D#8",4978.03],["Eb8",4978.03]]),ce=ct;var me=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],mt=2,a=class r{static _notes;name;octave;velocity=1;duration;static fromFrequency(e){let t;for(let[o,i]of ce)if(i===e){t=o;break}if(!t)throw Error("Not matching frequency with a note");return new r(t)}static fromEvent(e){let t=me[e.data[1]%12],o=Math.floor(e.data[1]/12)-2;return new r(`${t}${o}`)}static notes(e=3){return me.map(t=>new r(`${t}${e}`))}constructor(e){typeof e=="string"?this.fromString(e):this.fromProps(e)}get isSemi(){return this.name.endsWith("#")}get fullName(){return`${this.name}${this.octave}`}get frequency(){return ce.get(`${this.name}${this.octave}`)}midiData(e=!0){let t=e?144:128;return new Uint8Array([t,this.midiNumber,this.velocity*100])}get midiNumber(){return(this.octave+mt)*12+this.noteIndex}get noteIndex(){return me.indexOf(this.name)}valueOf(){return this.fullName}serialize(){return{name:this.name,octave:this.octave,frequency:this.frequency,velocity:this.velocity,duration:this.duration}}fromString(e){let t=/(\w#?)(\d)?/.exec(e)??[];this.name=t[1],this.octave=t[2]?parseInt(t[2]):1}fromProps(e){Object.assign(this,e)}};var f=class r{note;voiceNo;triggeredAt;message;static fromNote(e,t=!0,o){let i=e instanceof a?e:new a(e);return new r(new Me.Message(i.midiData(t)),o)}static fromCC(e,t,o){return new r(new Me.Message(new Uint8Array([176,e,t])),o)}constructor(e,t){this.message=e,this.triggeredAt=t,this.defineNotes()}get type(){return this.message.type}get isNote(){return this.type==="noteon"||this.type==="noteoff"}get isCC(){return this.type==="controlchange"}get cc(){if(this.isCC)return this.message.dataBytes[0]}get ccValue(){if(this.isCC)return this.message.dataBytes[1]}defineNotes(){this.isNote&&(this.note||(this.note=a.fromEvent(this.message)))}get rawMessage(){return this.message}clone(e){let t=new r(this.message,this.triggeredAt);return t.voiceNo=e,t}};var p=class{id;engineId;name;moduleType;voiceNo;audioNode;inputs;outputs;_props;activeNotes;pendingUIUpdates=!1;constructor(e,t){let{id:o,name:i,moduleType:n,voiceNo:u,audioNodeConstructor:d,props:s}=t;this.id=o??(0,re.uuidv4)(),this.engineId=e,this.name=i,this.moduleType=n,this.voiceNo=u??0,this.activeNotes=[],this.audioNode=d?.(this.context),this._props=s,this.inputs=new O(this),this.outputs=new C(this),queueMicrotask(()=>{this.props=s})}get props(){return this._props}set props(e){let t={...e};Object.keys(e).forEach(o=>{let i=e[o];if(i!==void 0){let n=this.callPropHook("onSet",o,i);n!==void 0&&(t[o]=n)}}),this._props={...this._props,...t},Object.keys(t).forEach(o=>{let i=t[o];i!==void 0&&this.callPropHook("onAfterSet",o,i)})}callPropHook(e,t,o){let i=`${e}${(0,re.upperFirst)(t)}`,n=this[i];if(typeof n=="function")return n.call(this,o)}serialize(){return{id:this.id,name:this.name,moduleType:this.moduleType,voiceNo:this.voiceNo,props:this.props,inputs:this.inputs.serialize(),outputs:this.outputs.serialize()}}plug({audioModule:e,from:t,to:o}){let i=this.outputs.findByName(t),n=e.inputs.findByName(o);i.plug(n)}rePlugAll(e){this.inputs.rePlugAll(e),this.outputs.rePlugAll(e)}unPlugAll(){this.inputs.unPlugAll(),this.outputs.unPlugAll()}start(e){}stop(e){}triggerAttack(e,t){this.activeNotes.some(o=>o.fullName===e.fullName)||this.activeNotes.push(e)}triggerRelease(e,t){this.activeNotes=this.activeNotes.filter(o=>o.fullName!==e.fullName)}handleCC(e,t){}onMidiEvent=e=>{let{note:t,triggeredAt:o}=e;switch(e.type){case"noteon":{this.triggerAttack(t,o);break}case"noteoff":this.triggerRelease(t,o);break;case"controlchange":this.handleCC(e,o);break;default:throw Error("This type is not a note")}};triggerPropsUpdate=()=>{this.pendingUIUpdates||(this.pendingUIUpdates=!0,this.sheduleTriggerUpdate())};sheduleTriggerUpdate(){requestAnimationFrame(()=>{this.engine._triggerPropsUpdate({id:this.id,moduleType:this.moduleType,voiceNo:this.voiceNo,name:this.name,props:this.props}),this.pendingUIUpdates=!1})}dispose(){this.inputs.unPlugAll(),this.outputs.unPlugAll()}registerDefaultIOs(e="both"){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent}),this.audioNode&&((e==="in"||e==="both")&&this.registerAudioInput({name:"in",getAudioNode:()=>this.audioNode}),(e==="out"||e==="both")&&this.registerAudioOutput({name:"out",getAudioNode:()=>this.audioNode}))}registerAudioInput(e){return this.inputs.add({...e,ioType:"audioInput"})}registerAudioOutput(e){return this.outputs.add({...e,ioType:"audioOutput"})}registerMidiInput(e){return this.inputs.add({...e,ioType:"midiInput"})}registerMidiOutput(e){return this.outputs.add({...e,ioType:"midiOutput"})}get engine(){return x.getById(this.engineId)}get context(){return this.engine.context}};var Ne=require("@blibliki/utils"),q=class{engine;routes;constructor(e){this.engine=e,this.routes=new Map}addRoute(e){let t=e.id??(0,Ne.uuidv4)(),o={...e,id:t};return this.routes.set(t,o),this.plug(t),o}removeRoute(e){this.unPlug(e),this.routes.delete(e)}clear(){this.routes.forEach((e,t)=>{this.removeRoute(t)})}replug(){this.routes.forEach((e,t)=>{let{sourceIO:o,destinationIO:i}=this.getIOs(t);o.rePlugAll(),i.rePlugAll()})}serialize(){return Array.from(this.routes.values())}plug(e){let{sourceIO:t,destinationIO:o}=this.getIOs(e);t.plug(o)}unPlug(e){let{sourceIO:t,destinationIO:o}=this.getIOs(e);t.unPlug(o)}find(e){let t=this.routes.get(e);if(!t)throw Error(`Route with id ${e} not found`);return t}getIOs(e){let t=this.find(e),{source:o,destination:i}=t,n=this.engine.findIO(o.moduleId,o.ioName,"output"),u=this.engine.findIO(i.moduleId,i.ioName,"input");return{sourceIO:n,destinationIO:u}}};var A=require("webmidi");var R=(t=>(t.connected="connected",t.disconnected="disconnected",t))(R||{}),v=class{id;name;eventListerCallbacks=[];context;input;constructor(e,t){this.id=e.id,this.name=e.name||`Device ${e.id}`,this.input=e,this.context=t,this.connect()}get state(){return this.input.state}connect(){this.input.addListener("midimessage",e=>{this.processEvent(e)})}disconnect(){this.input.removeListener()}serialize(){let{id:e,name:t,state:o}=this;return{id:e,name:t,state:o}}addEventListener(e){this.eventListerCallbacks.push(e)}removeEventListener(e){this.eventListerCallbacks=this.eventListerCallbacks.filter(t=>t!==e)}processEvent(e){let t=new f(e.message,this.context.browserToContextTime(e.timestamp));switch(t.type){case"noteon":case"noteoff":case"controlchange":this.eventListerCallbacks.forEach(o=>{o(t)})}}};var Mt={a:new a("C3"),s:new a("D3"),d:new a("E3"),f:new a("F3"),g:new a("G3"),h:new a("A3"),j:new a("B3"),k:new a("C4"),l:new a("D4"),w:new a("C#3"),e:new a("D#3"),t:new a("F#3"),y:new a("G#3"),u:new a("A#3"),o:new a("C#4"),p:new a("D#4")},ht=()=>({id:"computer_keyboard",name:"Computer Keyboard",state:"connected"}),E=class{id;name;state;eventListerCallbacks=[];context;constructor(e){let{id:t,name:o,state:i}=ht();this.id=t,this.name=o,this.state=i,this.context=e,document.addEventListener("keydown",this.onKeyTrigger(!0)),document.addEventListener("keyup",this.onKeyTrigger(!1))}addEventListener(e){this.eventListerCallbacks.push(e)}removeEventListener(e){this.eventListerCallbacks=this.eventListerCallbacks.filter(t=>t!==e)}serialize(){let{id:e,name:t,state:o}=this;return{id:e,name:t,state:o}}onKeyTrigger=e=>t=>{let o=this.extractNote(t);if(!o)return;let i=f.fromNote(o,e,this.context.browserToContextTime(t.timeStamp));this.eventListerCallbacks.forEach(n=>{n(i)})};extractNote(e){if(!e.repeat)return Mt[e.key]}};var k=class{devices=new Map;initialized=!1;listeners=[];context;constructor(e){this.context=e,this.addComputerKeyboard()}async initialize(){await this.initializeDevices(),this.listenChanges(),this.initialized=!0}find(e){return this.devices.get(e)}findByName(e){return Array.from(this.devices.values()).find(t=>t.name===e)}addListener(e){this.listeners.push(e)}async initializeDevices(){if(!this.initialized)try{await A.WebMidi.enable(),A.WebMidi.inputs.forEach(e=>{this.devices.has(e.id)||this.devices.set(e.id,new v(e,this.context))})}catch(e){console.error("Error enabling WebMidi:",e)}}addComputerKeyboard(){if(typeof document>"u")return;let e=new E(this.context);this.devices.set(e.id,e)}listenChanges(){A.WebMidi.addListener("connected",e=>{let t=e.port;if(t instanceof A.Output||this.devices.has(t.id))return;let o=new v(t,this.context);this.devices.set(o.id,o),this.listeners.forEach(i=>{i(o)})}),A.WebMidi.addListener("disconnected",e=>{let t=e.port;if(t instanceof A.Output)return;let o=this.devices.get(t.id);o&&(o instanceof E||(o.disconnect(),this.devices.delete(o.id),this.listeners.forEach(i=>{i(o)})))})}};var ot=require("@blibliki/utils");var Ee={},ke={},fe=class extends p{activeNote=null;triggeredAt=0;constructor(e,t){let o={...ke,...t.props};super(e,{...t,props:o})}midiTriggered=e=>{let{triggeredAt:t,note:o,type:i}=e;if(!o)return;let n=o.fullName;switch(i){case"noteon":this.activeNote=n,this.triggeredAt=t;break;case"noteoff":this.activeNote=null;break;default:throw Error("This type is not a note")}}},z=class extends m{midiOutput;constructor(e,t){let o={...ke,...t.props},i=(n,u)=>new fe(n,u);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerInputs(),this.registerOutputs()}onMidiEvent=e=>{let t;switch(e.type){case"noteon":t=this.findFreeVoice();break;case"noteoff":t=this.audioModules.find(o=>o.activeNote===e.note.fullName);break;default:throw Error("This type is not a note")}t&&(t.midiTriggered(e),e.voiceNo=t.voiceNo,this.midiOutput.onMidiEvent(e))};findFreeVoice(){let e=this.audioModules.find(t=>!t.activeNote);return e??=this.audioModules.sort((t,o)=>t.triggeredAt-o.triggeredAt)[0],e}registerInputs(){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent})}registerOutputs(){this.midiOutput=this.registerMidiOutput({name:"midi out"})}};var we={value:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Value"}},ft={value:1},L=class extends p{isStated=!1;constructor(e,t){let o={...ft,...t.props},i=n=>new ConstantSourceNode(n.audioContext);super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs("out")}onAfterSetValue=e=>{this.audioNode.offset.value=e};start(e){this.isStated||(this.isStated=!0,this.audioNode.start(e))}stop(e){this.isStated&&(this.audioNode.stop(e),this.rePlugAll(()=>{this.audioNode=new ConstantSourceNode(this.context.audioContext,{offset:this.props.value})}),this.isStated=!1)}triggerAttack=(e,t)=>{this.audioNode.offset.setValueAtTime(e.frequency,t),this.start(t)};triggerRelease=()=>{}};var ye=require("@blibliki/utils");var De={attack:.01,decay:0,sustain:1,release:0},Fe={attack:{kind:"number",min:1e-4,max:20,step:.01,exp:3,label:"Attack"},decay:{kind:"number",min:0,max:20,step:.01,exp:3,label:"Decay"},sustain:{kind:"number",min:0,max:1,step:.01,label:"Sustain"},release:{kind:"number",min:0,max:20,step:.01,exp:3,label:"Release"}},ge=class extends p{constructor(e,t){let o={...De,...t.props},i=n=>{let u=new GainNode(n.audioContext);return u.gain.value=0,u};super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs()}triggerAttack(e,t){super.triggerAttack(e,t);let o=this.props.attack,i=this.props.decay,n=this.props.sustain;(0,ye.cancelAndHoldAtTime)(this.audioNode.gain,t),this.audioNode.gain.value===0&&this.audioNode.gain.setValueAtTime(.001,t),this.audioNode.gain.exponentialRampToValueAtTime(1,t+o),n>0?this.audioNode.gain.exponentialRampToValueAtTime(n,t+o+i):this.audioNode.gain.exponentialRampToValueAtTime(.001,t+o+i)}triggerRelease(e,t){if(super.triggerRelease(e,t),this.activeNotes.length>0)return;let o=this.props.release,i=(0,ye.cancelAndHoldAtTime)(this.audioNode.gain,t);i>=1e-4&&(this.audioNode.gain.setValueAtTime(i,t),this.audioNode.gain.exponentialRampToValueAtTime(1e-4,t+o-1e-4)),this.audioNode.gain.setValueAtTime(0,t+o)}},U=class extends m{constructor(e,t){let o={...De,...t.props},i=(n,u)=>new ge(n,u);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerDefaultIOs()}};var Ge={gain:{kind:"number",min:0,max:1/0,step:.01,label:"Gain"}},Ve={gain:1},_=class extends p{constructor(e,t){let o={...Ve,...t.props},i=n=>new GainNode(n.audioContext);super(e,{...t,audioNodeConstructor:i,props:o}),this.registerDefaultIOs(),this.registerAdditionalInputs()}onAfterSetGain=e=>{this.audioNode.gain.value=e};registerAdditionalInputs(){this.registerAudioInput({name:"gain",getAudioNode:()=>this.audioNode.gain})}},B=class extends m{constructor(e,t){let o={...Ve,...t.props},i=(n,u)=>new _(n,u);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerAdditionalInputs(),this.registerDefaultIOs()}registerAdditionalInputs(){this.registerAudioInput({name:"gain"})}};var qe=20,Pe=2e4,Re={cutoff:Pe,envelopeAmount:0,type:"lowpass",Q:1},ze={cutoff:{kind:"number",min:qe,max:Pe,step:1,exp:5,label:"Cutoff"},envelopeAmount:{kind:"number",min:-1,max:1,step:.01,label:"Envelope Amount"},type:{kind:"enum",options:["lowpass","highpass","bandpass"],label:"Type"},Q:{kind:"number",min:1e-4,max:1e3,step:.1,exp:5,label:"Q"}},Ie=class extends p{scale;amount;constructor(e,t){let o={...Re,...t.props},i=n=>new BiquadFilterNode(n.audioContext,{type:o.type,frequency:0,Q:o.Q});super(e,{...t,props:o,audioNodeConstructor:i}),this.amount=new _(e,{name:"amount",moduleType:"Gain",props:{gain:o.envelopeAmount}}),this.scale=ne(e,{name:"scale",moduleType:"Scale",props:{min:qe,max:Pe,current:this.props.cutoff}}),this.amount.plug({audioModule:this.scale,from:"out",to:"in"}),this.scale.audioNode.connect(this.audioNode.frequency),this.registerDefaultIOs(),this.registerInputs()}onAfterSetType=e=>{this.audioNode.type=e};onAfterSetCutoff=e=>{this.scale.props={current:e}};onAfterSetQ=e=>{this.audioNode.Q.value=e};onAfterSetEnvelopeAmount=e=>{this.amount.props={gain:e}};registerInputs(){this.registerAudioInput({name:"cutoff",getAudioNode:()=>this.audioNode.frequency}),this.registerAudioInput({name:"cutoffMod",getAudioNode:()=>this.amount.audioNode}),this.registerAudioInput({name:"Q",getAudioNode:()=>this.audioNode.Q})}},H=class extends m{constructor(e,t){let o={...Re,...t.props},i=(n,u)=>new Ie(n,u);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerInputs(),this.registerDefaultIOs()}registerInputs(){this.registerAudioInput({name:"cutoff"}),this.registerAudioInput({name:"cutoffMod"}),this.registerAudioInput({name:"Q"})}};var Le={fftSize:{kind:"enum",options:[32,64,128,256,512,1024,2048,4096,8192,16384,32768],label:"FFT size"}},yt={fftSize:512},$=class extends p{_buffer;constructor(e,t){let o={...yt,...t.props},i=n=>new AnalyserNode(n.audioContext);super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs("in")}onAfterSetFftSize=e=>{this._buffer=new Float32Array(e)};get buffer(){return this._buffer?this._buffer:(this._buffer=new Float32Array(this.props.fftSize),this._buffer)}getValue(){return this.getValues()[0]}getValues(){return this.audioNode.getFloatTimeDomainData(this.buffer),this.buffer}};var gt={},Ue={},W=class extends p{constructor(e,t){let o={...gt,...t.props},i=n=>n.destination;super(e,{...t,audioNodeConstructor:i,props:o}),this.registerDefaultIOs("in")}};var se=(u=>(u.direct="direct",u.directRev="directRev",u.toggleInc="toggleInc",u.toggleDec="toggleDec",u.incDec="incDec",u.incDecRev="incDecRev",u))(se||{}),_e={pages:{kind:"array",label:"Midi mapping pages"},activePage:{kind:"number",label:"Active page",min:0,max:100,step:1},globalMappings:{kind:"array",label:"Global midi mappings"}},It={pages:[{name:"Page 1",mappings:[{}]}],activePage:0,globalMappings:[{}]};function Pt({value:r,midiValue:e,propSchema:t,mapping:o}){let i=t.min??0,n=t.max??1,u=t.exp??1,{threshold:d=64,mode:s}=o,c=(r-i)/(n-i),M=Math.pow(c,1/u)*127;return M=e>=d&&s==="incDec"||e<=d&&s==="incDecRev"?M+1:M-1,Math.round(Math.max(0,Math.min(127,M)))}var j=class extends p{constructor(e,t){let o={...It,...t.props};super(e,{...t,props:o}),this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent})}onSetActivePage=e=>Math.max(Math.min(e,this.props.pages.length-1),0);handleCC=(e,t)=>{this.checkAutoAssign(e);let o=this.props.pages[this.props.activePage];[...this.props.globalMappings.filter(i=>i.cc===e.cc),...o.mappings.filter(i=>i.cc===e.cc)].forEach(i=>{this.forwardMapping(e,i,t)})};forwardMapping=(e,t,o)=>{if(t.moduleId===void 0||t.moduleType===void 0||t.propName===void 0)return;let i=t.propName,n=e.ccValue;if(n===void 0)return;let u=t.mode??"direct";if((u==="toggleInc"||u==="toggleDec")&&n!==127)return;let d=this.engine.findModule(t.moduleId),s=ue[d.moduleType][i],c;switch(s.kind){case"number":{let h=d.props[i];if(u==="incDec"||u==="incDecRev"?n=Pt({value:h,propSchema:s,mapping:t,midiValue:n}):u==="directRev"&&(n=127-n),u==="toggleInc")c=h+(s.step??1);else if(u==="toggleDec")c=h-(s.step??1);else{let M=s.min??0,I=s.max??1,y=n/127,l=Math.pow(y,s.exp??1);if(c=M+l*(I-M),s.step!==void 0&&(!s.exp||s.exp===1)){let w=Math.round((c-M)/s.step);c=M+w*s.step}}break}case"enum":{let h=Math.floor(n/127*s.options.length),M=Math.min(h,s.options.length-1);c=s.options[M];break}case"boolean":c=n>=64;break;case"string":throw Error("MidiMapper not support string type of values");case"array":throw Error("MidiMapper not support array type of values");default:throw Error("MidiMapper unknown type")}d.props={[i]:c},d.triggerPropsUpdate()};checkAutoAssign(e){if(e.cc===void 0)return;let t=this.props.pages[this.props.activePage],o=this.props.globalMappings.some(({autoAssign:s})=>s),i=t.mappings.some(({autoAssign:s})=>s);if(!o&&!i)return;let n=o?this.props.globalMappings.map(s=>s.autoAssign?{...s,cc:e.cc,autoAssign:!1}:s):this.props.globalMappings,u=i?t.mappings.map(s=>s.autoAssign?{...s,cc:e.cc,autoAssign:!1}:s):t.mappings,d=this.props.pages.map((s,c)=>c===this.props.activePage?{...s,mappings:u}:s);this.props={pages:d,globalMappings:n},this.triggerPropsUpdate()}};var Be={selectedId:{kind:"string",label:"Midi device ID"},selectedName:{kind:"string",label:"Midi device name"}},Tt={selectedId:void 0,selectedName:void 0},Q=class extends p{midiOutput;_forwardMidiEvent;constructor(e,t){let o={...Tt,...t.props};super(e,{...t,props:o});let i=(this.props.selectedId&&this.engine.findMidiDevice(this.props.selectedId))??(this.props.selectedName&&this.engine.findMidiDeviceByName(this.props.selectedName));i&&this.addEventListener(i),this.registerOutputs()}onSetSelectedId=e=>{if(this.removeEventListener(),!e)return e;let t=this.engine.findMidiDevice(e);return t&&(this.props={selectedName:t.name},this.addEventListener(t)),e};get forwardMidiEvent(){return this._forwardMidiEvent?this._forwardMidiEvent:(this._forwardMidiEvent=e=>{this.midiOutput.onMidiEvent(e)},this._forwardMidiEvent)}addEventListener(e){e.addEventListener(this.forwardMidiEvent)}removeEventListener(){if(!this.props.selectedId)return;this.engine.findMidiDevice(this.props.selectedId)?.removeEventListener(this.forwardMidiEvent)}registerOutputs(){this.midiOutput=this.registerMidiOutput({name:"midi out"})}};var Te=require("@blibliki/utils");var ve=-18,J=(i=>(i.sine="sine",i.triangle="triangle",i.square="square",i.sawtooth="sawtooth",i))(J||{}),He={wave:{kind:"enum",options:Object.values(J),label:"Waveform"},frequency:{kind:"number",min:0,max:25e3,step:1,label:"Frequency"},fine:{kind:"number",min:-1,max:1,step:.01,label:"Fine"},coarse:{kind:"number",min:-12,max:12,step:1,label:"Coarse"},octave:{kind:"number",min:-1,max:2,step:1,label:"Octave"},lowGain:{kind:"boolean",label:`Use ${ve}db Gain`}},Ke={wave:"sine",frequency:440,fine:0,coarse:0,octave:0,lowGain:!1},Se=class extends p{isStated=!1;outputGain;detuneGain;constructor(e,t){let o={...Ke,...t.props},i=n=>new OscillatorNode(n.audioContext);super(e,{...t,props:o,audioNodeConstructor:i}),this.outputGain=new GainNode(this.context.audioContext,{gain:(0,Te.dbToGain)(ve)}),this.applyOutputGain(),this.initializeGainDetune(),this.registerInputs(),this.registerOutputs()}onAfterSetWave=e=>{this.audioNode.type=e};onAfterSetFrequency=()=>{this.updateFrequency()};onAfterSetFine=()=>{this.updateFrequency()};onAfterSetCoarse=()=>{this.updateFrequency()};onAfterSetOctave=()=>{this.updateFrequency()};onAfterSetLowGain=e=>{this.outputGain.gain.value=e?(0,Te.dbToGain)(ve):1};start(e){this.isStated||(this.isStated=!0,this.audioNode.start(e))}stop(e){this.isStated&&(this.audioNode.stop(e),this.rePlugAll(()=>{this.audioNode=new OscillatorNode(this.context.audioContext,{type:this.props.wave,frequency:this.finalFrequency}),this.applyOutputGain(),this.detuneGain.connect(this.audioNode.detune)}),this.isStated=!1)}triggerAttack=(e,t)=>{super.triggerAttack(e,t),this.props={frequency:e.frequency},this.updateFrequency(t),this.start(t)};triggerRelease(e,t){super.triggerRelease(e,t);let o=this.activeNotes.length?this.activeNotes[this.activeNotes.length-1]:null;o&&(this.props={frequency:o.frequency},this.updateFrequency(t))}get finalFrequency(){let{frequency:e,coarse:t,octave:o,fine:i}=this.props;return e*Math.pow(2,t/12+o+i/12)}updateFrequency(e){this.finalFrequency!==void 0&&(e?this.audioNode.frequency.setValueAtTime(this.finalFrequency,e):this.audioNode.frequency.value=this.finalFrequency)}applyOutputGain(){this.audioNode.connect(this.outputGain)}initializeGainDetune(){this.detuneGain=new GainNode(this.context.audioContext,{gain:100}),this.detuneGain.connect(this.audioNode.detune)}registerInputs(){this.registerAudioInput({name:"detune",getAudioNode:()=>this.detuneGain})}registerOutputs(){this.registerAudioOutput({name:"out",getAudioNode:()=>this.outputGain})}},Y=class extends m{constructor(e,t){let o={...Ke,...t.props},i=(n,u)=>new Se(n,u);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerInputs(),this.registerDefaultIOs("out")}start(e){this.audioModules.forEach(t=>{t.start(e)})}stop(e){this.audioModules.forEach(t=>{t.stop(e)})}registerInputs(){this.registerAudioInput({name:"detune"})}};var je=require("@blibliki/utils");var $e=URL.createObjectURL(new Blob(["(",(()=>{class r extends AudioWorkletProcessor{s0;s1;constructor(){super(),this.s0=0,this.s1=0}static get parameterDescriptors(){return[{name:"cutoff",defaultValue:1e3,minValue:20,maxValue:2e4},{name:"resonance",defaultValue:0,minValue:0,maxValue:4}]}process(t,o,i){let n=t[0],u=o[0],d=i.cutoff,s=i.resonance;for(let c=0;c<n.length;c++){let h=n[c],M=u[c];for(let I=0;I<h.length;I++){let y=h[I],l=d.length>1?d[I]:d[0],w=Math.max(20,Math.min(2e4,l)),pe=Math.log(w/20)/Math.log(2e4/20),T=Math.pow(.5,(1-pe)/.125),Ae=1-Math.pow(.5,((s.length>1?s[I]:s[0])+.125)/.125)*T;this.s0=Ae*this.s0-T*this.s1+T*y,this.s1=Ae*this.s1+T*this.s0,M[I]=this.s1}}return!0}}registerProcessor("filter-processor",r)}).toString(),")()"],{type:"application/javascript"}));var We=URL.createObjectURL(new Blob(["(",(()=>{class r extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:"min",defaultValue:1e-10},{name:"max",defaultValue:1},{name:"current",defaultValue:.5}]}process(t,o,i){let n=t[0],u=o[0],d=i.min,s=i.max,c=i.current;if(!n.length||n[0].length===0){for(let h of u){let M=(i.current.length>1,i.current[0]);h.fill(M)}return!0}for(let h=0;h<n.length;h++){let M=n[h],I=u[h];for(let y=0;y<M.length;y++){let l=M[y],w=d.length>1?d[y]:d[0],pe=s.length>1?s[y]:s[0],T=c.length>1?c[y]:c[0];l<0?I[y]=T*Math.pow(w/T,-l):I[y]=T*Math.pow(pe/T,l)}}return!0}}registerProcessor("scale-processor",r)}).toString(),")()"],{type:"application/javascript"}));async function Qe(r){await r.addModule(We),await r.addModule($e)}function Ye(r,e){switch(e){case"ScaleProcessor":return r.newAudioWorklet("scale-processor");case"FilterProcessor":return r.newAudioWorklet("filter-processor");default:(0,je.assertNever)(e)}}var Je={min:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Min"},max:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Max"},current:{kind:"number",min:-1/0,max:1/0,step:.01,label:"Current"}},vt={min:0,max:1,current:.5},X=class extends p{constructor(e,t){let o={...vt,...t.props},i=n=>Ye(n,"ScaleProcessor");super(e,{...t,props:o,audioNodeConstructor:i}),this.registerDefaultIOs()}get current(){return this.audioNode.parameters.get("current")}get min(){return this.audioNode.parameters.get("min")}get max(){return this.audioNode.parameters.get("max")}onAfterSetMin=e=>{this.min.value=e};onAfterSetMax=e=>{this.max.value=e};onAfterSetCurrent=e=>{this.current.value=e}};var Xe={steps:{kind:"number",min:1,max:16,step:1,label:"Steps"},bars:{kind:"number",min:1,max:16,step:1,label:"Steps"}},St={sequences:[],steps:16,bars:1},Z=class extends p{midiOutput;constructor(e,t){let o={...St,...t.props};super(e,{...t,props:o})}};var Ze={pan:{kind:"number",min:-1,max:1,step:.01,label:"Pan"}},et={pan:0},xe=class extends p{constructor(e,t){let o={...et,...t.props},i=n=>new StereoPannerNode(n.audioContext);super(e,{...t,audioNodeConstructor:i,props:o}),this.registerDefaultIOs(),this.registerAdditionalInputs()}onAfterSetPan=e=>{this.audioNode.pan.value=e};registerAdditionalInputs(){this.registerAudioInput({name:"pan",getAudioNode:()=>this.audioNode.pan})}},ee=class extends m{constructor(e,t){let o={...et,...t.props},i=(n,u)=>new xe(n,u);super(e,{...t,props:o,monoModuleConstructor:i}),this.registerAdditionalInputs(),this.registerDefaultIOs()}registerAdditionalInputs(){this.registerAudioInput({name:"pan"})}};var tt={activeNotes:{kind:"array",label:"Active notes"}},xt={activeNotes:[]},te=class extends p{midiOutput;constructor(e,t){let o={...xt,...t.props};super(e,{...t,props:o}),this.registerInputs(),this.registerOutputs()}sendMidi(e){this.midiOutput.onMidiEvent(e)}triggerAttack=(e,t)=>{this.props={activeNotes:[...this.props.activeNotes,e.fullName]},this.triggerPropsUpdate(),this.sendMidi(f.fromNote(e,!0,t))};triggerRelease=(e,t)=>{this.props={activeNotes:this.props.activeNotes.filter(o=>o!==e.fullName)},this.triggerPropsUpdate(),this.sendMidi(f.fromNote(e,!1,t))};registerInputs(){this.registerMidiInput({name:"midi in",onMidiEvent:this.onMidiEvent})}registerOutputs(){this.midiOutput=this.registerMidiOutput({name:"midi out"})}};var K=(l=>(l.Master="Master",l.Oscillator="Oscillator",l.Gain="Gain",l.MidiSelector="MidiSelector",l.Envelope="Envelope",l.Filter="Filter",l.Scale="Scale",l.StereoPanner="StereoPanner",l.Inspector="Inspector",l.Constant="Constant",l.MidiMapper="MidiMapper",l.VirtualMidi="VirtualMidi",l.StepSequencer="StepSequencer",l.VoiceScheduler="VoiceScheduler",l))(K||{}),ue={Oscillator:He,Gain:Ge,Master:Ue,MidiSelector:Be,Envelope:Fe,Filter:ze,Scale:Je,StereoPanner:Ze,Inspector:Le,Constant:we,MidiMapper:_e,VirtualMidi:tt,StepSequencer:Xe,VoiceScheduler:Ee};function ne(r,e){switch(e.moduleType){case"Oscillator":return new Y(r,e);case"Gain":return new B(r,e);case"Master":return new W(r,e);case"MidiSelector":return new Q(r,e);case"Envelope":return new U(r,e);case"Filter":return new H(r,e);case"Scale":return new X(r,e);case"StereoPanner":return new ee(r,e);case"Inspector":return new $(r,e);case"Constant":return new L(r,e);case"MidiMapper":return new j(r,e);case"VirtualMidi":return new te(r,e);case"StepSequencer":return new Z(r,e);case"VoiceScheduler":return new z(r,e);default:(0,ot.assertNever)(e)}}var x=class r{static _engines=new Map;static _currentId;propsUpdateCallbacks=[];id;context;isInitialized=!1;routes;transport;modules;midiDeviceManager;static getById(e){let t=r._engines.get(e);return(0,S.assertDefined)(t),t}static get current(){return(0,S.assertDefined)(this._currentId),this.getById(this._currentId)}static async load(e){let{bpm:t,timeSignature:o,modules:i,routes:n}=e,u=new S.Context,d=new r(u);return await d.initialize(),d.timeSignature=o,d.bpm=t,i.forEach(s=>{d.addModule(s)}),n.forEach(s=>{d.addRoute(s)}),d}constructor(e){this.id=(0,S.uuidv4)(),this.context=e,this.transport=new it.Transport(this.context,{generator:(t,o)=>[],consumer:t=>{},onJump:t=>{},onStart:this.onStart,onStop:this.onStop,silence:t=>{}}),this.routes=new q(this),this.modules=new Map,this.midiDeviceManager=new k(this.context),r._engines.set(this.id,this),r._currentId=this.id}get state(){return this.transport.state}async initialize(){this.isInitialized||(await Qe(this.context),await this.midiDeviceManager.initialize(),this.isInitialized=!0)}addModule(e){let t=ne(this.id,e);return this.modules.set(t.id,t),t.serialize()}updateModule(e){let t=this.findModule(e.id);if(t.moduleType!==e.moduleType)throw Error(`The module id ${e.id} isn't moduleType ${e.moduleType}`);let o=(0,S.pick)(e.changes,["name","props"]);return Object.assign(t,o),t instanceof m&&e.changes.voices!==void 0&&(t.voices=e.changes.voices),t.serialize()}removeModule(e){this.modules.delete(e)}addRoute(e){return this.routes.addRoute(e)}removeRoute(e){this.routes.removeRoute(e)}validRoute(e){let{source:t,destination:o}=e,i=this.findIO(t.moduleId,t.ioName,"output"),n=this.findIO(o.moduleId,o.ioName,"input");return i.isMidi()&&n.isMidi()||i.isAudio()&&n.isAudio()}async start(){await this.resume(),this.transport.start()}stop(){this.transport.stop(),this.transport.reset()}pause(){this.transport.stop()}get bpm(){return this.transport.bpm}set bpm(e){this.transport.bpm=e}get timeSignature(){return this.transport.timeSignature}set timeSignature(e){this.transport.timeSignature=e}async resume(){await this.context.resume()}dispose(){this.stop(),this.routes.clear(),this.modules.forEach(e=>{e.dispose()}),this.modules.clear()}serialize(){return{bpm:this.bpm,timeSignature:this.timeSignature,modules:Array.from(this.modules.values()).map(e=>e.serialize()),routes:this.routes.serialize()}}findModule(e){let t=this.modules.get(e);if(!t)throw Error(`The module with id ${e} is not exists`);return t}findIO(e,t,o){return this.findModule(e)[`${o}s`].findByName(t)}findMidiDevice(e){return this.midiDeviceManager.find(e)}findMidiDeviceByName(e){return this.midiDeviceManager.findByName(e)}onPropsUpdate(e){this.propsUpdateCallbacks.push(e)}_triggerPropsUpdate(e){this.propsUpdateCallbacks.forEach(t=>{t(e)})}triggerVirtualMidi(e,t,o){let i=this.findModule(e);if(i.moduleType!=="VirtualMidi")throw Error("This is not a virtual mid");i.sendMidi(f.fromNote(t,o==="noteOn",this.context.currentTime))}onStart=e=>{this.modules.forEach(t=>{t.start(e)})};onStop=e=>{this.modules.forEach(t=>{t.stop(e)})}};var rt=require("@blibliki/transport"),nt=require("@blibliki/utils");
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|