@marmooo/midy 0.0.5 → 0.0.7
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/esm/midy-GM1.d.ts +22 -10
- package/esm/midy-GM1.d.ts.map +1 -1
- package/esm/midy-GM1.js +126 -73
- package/esm/midy-GM2.d.ts +24 -10
- package/esm/midy-GM2.d.ts.map +1 -1
- package/esm/midy-GM2.js +145 -82
- package/esm/midy-GMLite.d.ts +16 -8
- package/esm/midy-GMLite.d.ts.map +1 -1
- package/esm/midy-GMLite.js +79 -60
- package/esm/midy.d.ts +24 -10
- package/esm/midy.d.ts.map +1 -1
- package/esm/midy.js +145 -111
- package/package.json +1 -1
- package/script/midy-GM1.d.ts +22 -10
- package/script/midy-GM1.d.ts.map +1 -1
- package/script/midy-GM1.js +126 -73
- package/script/midy-GM2.d.ts +24 -10
- package/script/midy-GM2.d.ts.map +1 -1
- package/script/midy-GM2.js +145 -82
- package/script/midy-GMLite.d.ts +16 -8
- package/script/midy-GMLite.d.ts.map +1 -1
- package/script/midy-GMLite.js +79 -60
- package/script/midy.d.ts +24 -10
- package/script/midy.d.ts.map +1 -1
- package/script/midy.js +145 -111
package/esm/midy-GMLite.js
CHANGED
|
@@ -183,17 +183,16 @@ export class MidyGMLite {
|
|
|
183
183
|
this.totalTime = this.calcTotalTime();
|
|
184
184
|
}
|
|
185
185
|
setChannelAudioNodes(audioContext) {
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
});
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
gainNode.connect(this.masterGain);
|
|
186
|
+
const { gainLeft, gainRight } = this.panToGain(MidyGMLite.channelSettings.pan);
|
|
187
|
+
const gainL = new GainNode(audioContext, { gain: gainLeft });
|
|
188
|
+
const gainR = new GainNode(audioContext, { gain: gainRight });
|
|
189
|
+
const merger = new ChannelMergerNode(audioContext, { numberOfInputs: 2 });
|
|
190
|
+
gainL.connect(merger, 0, 0);
|
|
191
|
+
gainR.connect(merger, 0, 1);
|
|
192
|
+
merger.connect(this.masterGain);
|
|
194
193
|
return {
|
|
195
|
-
|
|
196
|
-
|
|
194
|
+
gainL,
|
|
195
|
+
gainR,
|
|
197
196
|
};
|
|
198
197
|
}
|
|
199
198
|
createChannels(audioContext) {
|
|
@@ -278,7 +277,7 @@ export class MidyGMLite {
|
|
|
278
277
|
this.handleProgramChange(event.channel, event.programNumber);
|
|
279
278
|
break;
|
|
280
279
|
case "pitchBend":
|
|
281
|
-
this.
|
|
280
|
+
this.setPitchBend(event.channel, event.value);
|
|
282
281
|
break;
|
|
283
282
|
case "sysEx":
|
|
284
283
|
this.handleSysEx(event.data);
|
|
@@ -358,7 +357,6 @@ export class MidyGMLite {
|
|
|
358
357
|
const tmpChannels = new Array(16);
|
|
359
358
|
for (let i = 0; i < tmpChannels.length; i++) {
|
|
360
359
|
tmpChannels[i] = {
|
|
361
|
-
durationTicks: new Map(),
|
|
362
360
|
programNumber: -1,
|
|
363
361
|
bank: this.channels[i].bank,
|
|
364
362
|
};
|
|
@@ -375,16 +373,6 @@ export class MidyGMLite {
|
|
|
375
373
|
instruments.add(`${channel.bank}:0`);
|
|
376
374
|
channel.programNumber = 0;
|
|
377
375
|
}
|
|
378
|
-
channel.durationTicks.set(event.noteNumber, {
|
|
379
|
-
ticks: event.ticks,
|
|
380
|
-
noteOn: event,
|
|
381
|
-
});
|
|
382
|
-
break;
|
|
383
|
-
}
|
|
384
|
-
case "noteOff": {
|
|
385
|
-
const { ticks, noteOn } = tmpChannels[event.channel].durationTicks
|
|
386
|
-
.get(event.noteNumber);
|
|
387
|
-
noteOn.durationTicks = event.ticks - ticks;
|
|
388
376
|
break;
|
|
389
377
|
}
|
|
390
378
|
case "programChange": {
|
|
@@ -398,8 +386,8 @@ export class MidyGMLite {
|
|
|
398
386
|
});
|
|
399
387
|
});
|
|
400
388
|
const priority = {
|
|
401
|
-
|
|
402
|
-
|
|
389
|
+
controller: 0,
|
|
390
|
+
sysEx: 1,
|
|
403
391
|
};
|
|
404
392
|
timeline.sort((a, b) => {
|
|
405
393
|
if (a.ticks !== b.ticks)
|
|
@@ -504,7 +492,8 @@ export class MidyGMLite {
|
|
|
504
492
|
return noteList[0];
|
|
505
493
|
}
|
|
506
494
|
connectNoteEffects(channel, gainNode) {
|
|
507
|
-
gainNode.connect(channel.
|
|
495
|
+
gainNode.connect(channel.gainL);
|
|
496
|
+
gainNode.connect(channel.gainR);
|
|
508
497
|
}
|
|
509
498
|
cbToRatio(cb) {
|
|
510
499
|
return Math.pow(10, cb / 200);
|
|
@@ -521,9 +510,7 @@ export class MidyGMLite {
|
|
|
521
510
|
}
|
|
522
511
|
setVolumeEnvelope(channel, note) {
|
|
523
512
|
const { instrumentKey, startTime, velocity } = note;
|
|
524
|
-
note.gainNode = new GainNode(this.audioContext, {
|
|
525
|
-
gain: 0,
|
|
526
|
-
});
|
|
513
|
+
note.gainNode = new GainNode(this.audioContext, { gain: 0 });
|
|
527
514
|
let volume = (velocity / 127) * channel.volume * channel.expression;
|
|
528
515
|
if (volume === 0)
|
|
529
516
|
volume = 1e-6; // exponentialRampToValueAtTime() requires a non-zero value
|
|
@@ -713,21 +700,15 @@ export class MidyGMLite {
|
|
|
713
700
|
}
|
|
714
701
|
handlePitchBendMessage(channelNumber, lsb, msb) {
|
|
715
702
|
const pitchBend = msb * 128 + lsb;
|
|
716
|
-
this.
|
|
703
|
+
this.setPitchBend(channelNumber, pitchBend);
|
|
717
704
|
}
|
|
718
|
-
|
|
719
|
-
const now = this.audioContext.currentTime;
|
|
705
|
+
setPitchBend(channelNumber, pitchBend) {
|
|
720
706
|
const channel = this.channels[channelNumber];
|
|
707
|
+
const prevPitchBend = channel.pitchBend;
|
|
721
708
|
channel.pitchBend = (pitchBend - 8192) / 8192;
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const { bufferSource, instrumentKey, noteNumber } = activeNote;
|
|
726
|
-
const playbackRate = calcPlaybackRate(instrumentKey, noteNumber, semitoneOffset);
|
|
727
|
-
bufferSource.playbackRate
|
|
728
|
-
.cancelScheduledValues(now)
|
|
729
|
-
.setValueAtTime(playbackRate * pressure, now);
|
|
730
|
-
});
|
|
709
|
+
const detuneChange = (channel.pitchBend - prevPitchBend) *
|
|
710
|
+
channel.pitchBendRange * 100;
|
|
711
|
+
this.updateDetune(channel, detuneChange);
|
|
731
712
|
}
|
|
732
713
|
handleControlChange(channelNumber, controller, value) {
|
|
733
714
|
switch (controller) {
|
|
@@ -746,9 +727,9 @@ export class MidyGMLite {
|
|
|
746
727
|
case 64:
|
|
747
728
|
return this.setSustainPedal(channelNumber, value);
|
|
748
729
|
case 100:
|
|
749
|
-
return this.setRPNMSB(channelNumber, value);
|
|
750
|
-
case 101:
|
|
751
730
|
return this.setRPNLSB(channelNumber, value);
|
|
731
|
+
case 101:
|
|
732
|
+
return this.setRPNMSB(channelNumber, value);
|
|
752
733
|
case 120:
|
|
753
734
|
return this.allSoundOff(channelNumber);
|
|
754
735
|
case 121:
|
|
@@ -780,12 +761,17 @@ export class MidyGMLite {
|
|
|
780
761
|
channel.volume = volume / 127;
|
|
781
762
|
this.updateChannelGain(channel);
|
|
782
763
|
}
|
|
764
|
+
panToGain(pan) {
|
|
765
|
+
const theta = Math.PI / 2 * Math.max(0, pan - 1) / 126;
|
|
766
|
+
return {
|
|
767
|
+
gainLeft: Math.cos(theta),
|
|
768
|
+
gainRight: Math.sin(theta),
|
|
769
|
+
};
|
|
770
|
+
}
|
|
783
771
|
setPan(channelNumber, pan) {
|
|
784
|
-
const now = this.audioContext.currentTime;
|
|
785
772
|
const channel = this.channels[channelNumber];
|
|
786
|
-
channel.pan = pan
|
|
787
|
-
|
|
788
|
-
channel.pannerNode.pan.setValueAtTime(channel.pan, now);
|
|
773
|
+
channel.pan = pan;
|
|
774
|
+
this.updateChannelGain(channel);
|
|
789
775
|
}
|
|
790
776
|
setExpression(channelNumber, expression) {
|
|
791
777
|
const channel = this.channels[channelNumber];
|
|
@@ -795,8 +781,13 @@ export class MidyGMLite {
|
|
|
795
781
|
updateChannelGain(channel) {
|
|
796
782
|
const now = this.audioContext.currentTime;
|
|
797
783
|
const volume = channel.volume * channel.expression;
|
|
798
|
-
channel.
|
|
799
|
-
channel.
|
|
784
|
+
const { gainLeft, gainRight } = this.panToGain(channel.pan);
|
|
785
|
+
channel.gainL.gain
|
|
786
|
+
.cancelScheduledValues(now)
|
|
787
|
+
.setValueAtTime(volume * gainLeft, now);
|
|
788
|
+
channel.gainR.gain
|
|
789
|
+
.cancelScheduledValues(now)
|
|
790
|
+
.setValueAtTime(volume * gainRight, now);
|
|
800
791
|
}
|
|
801
792
|
setSustainPedal(channelNumber, value) {
|
|
802
793
|
const isOn = value >= 64;
|
|
@@ -805,6 +796,17 @@ export class MidyGMLite {
|
|
|
805
796
|
this.releaseSustainPedal(channelNumber, value);
|
|
806
797
|
}
|
|
807
798
|
}
|
|
799
|
+
handleRPN(channelNumber) {
|
|
800
|
+
const channel = this.channels[channelNumber];
|
|
801
|
+
const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
|
|
802
|
+
switch (rpn) {
|
|
803
|
+
case 0:
|
|
804
|
+
this.handlePitchBendRangeMessage(channelNumber);
|
|
805
|
+
break;
|
|
806
|
+
default:
|
|
807
|
+
console.warn(`Channel ${channelNumber}: Unsupported RPN MSB=${channel.rpnMSB} LSB=${channel.rpnLSB}`);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
808
810
|
setRPNMSB(channelNumber, value) {
|
|
809
811
|
this.channels[channelNumber].rpnMSB = value;
|
|
810
812
|
}
|
|
@@ -813,16 +815,33 @@ export class MidyGMLite {
|
|
|
813
815
|
}
|
|
814
816
|
setDataEntry(channelNumber, value, isMSB) {
|
|
815
817
|
const channel = this.channels[channelNumber];
|
|
816
|
-
const rpn = channel.rpnMSB * 128 + channel.rpnLSB;
|
|
817
818
|
isMSB ? channel.dataMSB = value : channel.dataLSB = value;
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
819
|
+
this.handleRPN(channelNumber);
|
|
820
|
+
}
|
|
821
|
+
updateDetune(channel, detuneChange) {
|
|
822
|
+
const now = this.audioContext.currentTime;
|
|
823
|
+
const activeNotes = this.getActiveNotes(channel, now);
|
|
824
|
+
activeNotes.forEach((activeNote) => {
|
|
825
|
+
const { bufferSource } = activeNote;
|
|
826
|
+
const detune = bufferSource.detune.value + detuneChange;
|
|
827
|
+
bufferSource.detune
|
|
828
|
+
.cancelScheduledValues(now)
|
|
829
|
+
.setValueAtTime(detune, now);
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
handlePitchBendRangeMessage(channelNumber) {
|
|
833
|
+
const channel = this.channels[channelNumber];
|
|
834
|
+
this.limitData(channel, 0, 127, 0, 99);
|
|
835
|
+
const pitchBendRange = channel.dataMSB + channel.dataLSB / 100;
|
|
836
|
+
this.setPitchBendRange(channelNumber, pitchBendRange);
|
|
837
|
+
}
|
|
838
|
+
setPitchBendRange(channelNumber, pitchBendRange) {
|
|
839
|
+
const channel = this.channels[channelNumber];
|
|
840
|
+
const prevPitchBendRange = channel.pitchBendRange;
|
|
841
|
+
channel.pitchBendRange = pitchBendRange;
|
|
842
|
+
const detuneChange = (channel.pitchBendRange - prevPitchBendRange) *
|
|
843
|
+
channel.pitchBend * 100;
|
|
844
|
+
this.updateDetune(channel, detuneChange);
|
|
826
845
|
}
|
|
827
846
|
allSoundOff(channelNumber) {
|
|
828
847
|
const now = this.audioContext.currentTime;
|
|
@@ -899,9 +918,9 @@ export class MidyGMLite {
|
|
|
899
918
|
}
|
|
900
919
|
handleMasterVolumeSysEx(data) {
|
|
901
920
|
const volume = (data[5] * 128 + data[4]) / 16383;
|
|
902
|
-
this.
|
|
921
|
+
this.setMasterVolume(volume);
|
|
903
922
|
}
|
|
904
|
-
|
|
923
|
+
setMasterVolume(volume) {
|
|
905
924
|
if (volume < 0 && 1 < volume) {
|
|
906
925
|
console.error("Master Volume is out of range");
|
|
907
926
|
}
|
|
@@ -942,7 +961,7 @@ Object.defineProperty(MidyGMLite, "channelSettings", {
|
|
|
942
961
|
writable: true,
|
|
943
962
|
value: {
|
|
944
963
|
volume: 100 / 127,
|
|
945
|
-
pan:
|
|
964
|
+
pan: 64,
|
|
946
965
|
bank: 0,
|
|
947
966
|
dataMSB: 0,
|
|
948
967
|
dataLSB: 0,
|
package/esm/midy.d.ts
CHANGED
|
@@ -84,8 +84,8 @@ export class Midy {
|
|
|
84
84
|
lfoFilterDepth: number;
|
|
85
85
|
lfoAmplitudeDepth: number;
|
|
86
86
|
};
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
gainL: any;
|
|
88
|
+
gainR: any;
|
|
89
89
|
reverbEffect: {
|
|
90
90
|
convolverNode: any;
|
|
91
91
|
dryGain: any;
|
|
@@ -131,8 +131,8 @@ export class Midy {
|
|
|
131
131
|
loadSoundFont(soundFontUrl: any): Promise<void>;
|
|
132
132
|
loadMIDI(midiUrl: any): Promise<void>;
|
|
133
133
|
setChannelAudioNodes(audioContext: any): {
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
gainL: any;
|
|
135
|
+
gainR: any;
|
|
136
136
|
reverbEffect: {
|
|
137
137
|
convolverNode: any;
|
|
138
138
|
dryGain: any;
|
|
@@ -164,8 +164,8 @@ export class Midy {
|
|
|
164
164
|
lfoFilterDepth: number;
|
|
165
165
|
lfoAmplitudeDepth: number;
|
|
166
166
|
};
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
gainL: any;
|
|
168
|
+
gainR: any;
|
|
169
169
|
reverbEffect: {
|
|
170
170
|
convolverNode: any;
|
|
171
171
|
dryGain: any;
|
|
@@ -261,12 +261,16 @@ export class Midy {
|
|
|
261
261
|
handleProgramChange(channelNumber: any, program: any): void;
|
|
262
262
|
handleChannelPressure(channelNumber: any, pressure: any): void;
|
|
263
263
|
handlePitchBendMessage(channelNumber: any, lsb: any, msb: any): void;
|
|
264
|
-
|
|
264
|
+
setPitchBend(channelNumber: any, pitchBend: any): void;
|
|
265
265
|
handleControlChange(channelNumber: any, controller: any, value: any): any;
|
|
266
266
|
setBankMSB(channelNumber: any, msb: any): void;
|
|
267
267
|
setModulation(channelNumber: any, modulation: any): void;
|
|
268
268
|
setPortamentoTime(channelNumber: any, portamentoTime: any): void;
|
|
269
269
|
setVolume(channelNumber: any, volume: any): void;
|
|
270
|
+
panToGain(pan: any): {
|
|
271
|
+
gainLeft: number;
|
|
272
|
+
gainRight: number;
|
|
273
|
+
};
|
|
270
274
|
setPan(channelNumber: any, pan: any): void;
|
|
271
275
|
setExpression(channelNumber: any, expression: any): void;
|
|
272
276
|
setBankLSB(channelNumber: any, lsb: any): void;
|
|
@@ -280,11 +284,21 @@ export class Midy {
|
|
|
280
284
|
setVibratoRate(channelNumber: any, vibratoRate: any): void;
|
|
281
285
|
setVibratoDepth(channelNumber: any, vibratoDepth: any): void;
|
|
282
286
|
setVibratoDelay(channelNumber: any, vibratoDelay: any): void;
|
|
287
|
+
limitData(channel: any, minMSB: any, maxMSB: any, minLSB: any, maxLSB: any): void;
|
|
288
|
+
limitDataMSB(channel: any, minMSB: any, maxMSB: any): void;
|
|
289
|
+
handleRPN(channelNumber: any, value: any): void;
|
|
283
290
|
incrementRPNValue(channelNumber: any): void;
|
|
284
291
|
decrementRPNValue(channelNumber: any): void;
|
|
285
292
|
setRPNMSB(channelNumber: any, value: any): void;
|
|
286
293
|
setRPNLSB(channelNumber: any, value: any): void;
|
|
287
294
|
setDataEntry(channelNumber: any, value: any, isMSB: any): void;
|
|
295
|
+
updateDetune(channel: any, detuneChange: any): void;
|
|
296
|
+
handlePitchBendRangeMessage(channelNumber: any): void;
|
|
297
|
+
setPitchBendRange(channelNumber: any, pitchBendRange: any): void;
|
|
298
|
+
handleFineTuningMessage(channelNumber: any): void;
|
|
299
|
+
setFineTuning(channelNumber: any, fineTuning: any): void;
|
|
300
|
+
handleCoarseTuningMessage(channelNumber: any): void;
|
|
301
|
+
setCoarseTuning(channelNumber: any, coarseTuning: any): void;
|
|
288
302
|
allSoundOff(channelNumber: any): any[];
|
|
289
303
|
resetAllControllers(channelNumber: any): void;
|
|
290
304
|
allNotesOff(channelNumber: any): any[];
|
|
@@ -297,11 +311,11 @@ export class Midy {
|
|
|
297
311
|
GM2SystemOn(): void;
|
|
298
312
|
handleUniversalRealTimeExclusiveMessage(data: any): void;
|
|
299
313
|
handleMasterVolumeSysEx(data: any): void;
|
|
300
|
-
|
|
314
|
+
setMasterVolume(volume: any): void;
|
|
301
315
|
handleMasterFineTuningSysEx(data: any): void;
|
|
302
|
-
|
|
316
|
+
setMasterFineTuning(fineTuning: any): void;
|
|
303
317
|
handleMasterCoarseTuningSysEx(data: any): void;
|
|
304
|
-
|
|
318
|
+
setMasterCoarseTuning(coarseTuning: any): void;
|
|
305
319
|
handleExclusiveMessage(data: any): void;
|
|
306
320
|
handleSysEx(data: any): void;
|
|
307
321
|
scheduleTask(callback: any, startTime: any): Promise<any>;
|
package/esm/midy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"midy.d.ts","sourceRoot":"","sources":["../src/midy.js"],"names":[],"mappings":"AAuBA;IAwBE;;;;;;;;;;;;;;;;;;;;MAoBE;IAEF;;;;;;;;;;;MAWE;IAEF;;;;;;;MAOE;IAEF,+BAMC;IAzED,qBAAmB;IACnB,kBAAc;IACd,qBAAmB;IACnB,yBAAqB;IACrB,2BAAuB;IACvB,cAAa;IACb,cAAa;IACb,0BAAwB;IACxB,kBAAc;IACd,mBAAiB;IACjB,kBAAc;IACd,mBAAe;IACf,kBAAgB;IAChB,sBAA2C;IAC3C,mBAAkB;IAClB,mBAAkB;IAClB,kBAAiB;IACjB,oBAAmB;IACnB,mBAAkB;IAClB,gBAAc;IACd,mBAAiB;IACjB,oBAAkB;IA+ChB,kBAAgC;IAChC,gBAA4C;IAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAiD;IAInD,4BAMC;IAED,mCASC;IAED,gDAMC;IAED,sCASC;IAED;;;;;;;;;;;;;;MAqBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiBC;IAED,+DAyBC;IAED,mEAWC;IAED,qDAOC;IAED,2EAyDC;IAED,mCAOC;IAED,0BA+CC;IAED,uDAEC;IAED,wDAEC;IAED;;;MAgGC;IAED,4BAsBC;IAED,uBAKC;IAED,aAGC;IAED,cAKC;IAED,wBAIC;IAED,0BAKC;IAED,wBAOC;IAED,sBAGC;IAED,uDASC;IAED,6CAQC;IAED;;;;MAoCC;IAED;;;;;MAqCC;IAED,sDA6BC;IAED,2BAEC;IAED,4BAEC;IAED,sCAKC;IAED,mFAGC;IAED,iDAiBC;IAED,iDAiCC;IAED,0DAmBC;IAED,uDAcC;IAED,wHAqCC;IAED,gDAQC;IAED,kGAgCC;IAED,0EAGC;IAED,sIAwDC;IAED,0FAGC;IAED,kEAeC;IAED,oEAYC;IAED,gEAqBC;IAED,sFAcC;IAED,4DAIC;IAED,+DAcC;IAED,qEAGC;IAED,uDAOC;IAED,0EAkEC;IAED,+CAEC;IAED,yDAiBC;IAED,iEAEC;IAED,iDAIC;IAED;;;MAMC;IAED,2CAIC;IAED,yDAIC;IAED,+CAEC;IAED,sCAUC;IAED,sDAMC;IAED,oDAEC;IAED,iDASC;IAED,iDAIC;IAED,wDAWC;IAED,uDAGC;IAED,2DAGC;IAED,6DAGC;IAED,6DASC;IAED,kFAeC;IAED,2DAMC;IAGD,gDAqBC;IAED,4CAEC;IAED,4CAEC;IAED,gDAEC;IAED,gDAEC;IAED,+DAIC;IAED,oDAUC;IAED,sDAKC;IAED,iEAOC;IAED,kDAKC;IAED,yDAGC;IAED,oDAKC;IAED,6DAGC;IAED,uCAoBC;IAED,8CAEC;IAED,uCAoBC;IAED,gBAEC;IAED,eAEC;IAED,eAEC;IAED,eAEC;IAED,4DAmBC;IAED,oBAQC;IAED,oBAQC;IAED,yDAgDC;IAED,yCAGC;IAED,mCAQC;IAED,6CAGC;IAED,2CAMC;IAED,+CAGC;IAED,+CAMC;IAED,wCAEC;IAED,6BASC;IAED,0DAUC;CACF;AA1hDD;IASE,gFAKC;IAbD,kBAAa;IACb,cAAS;IACT,gBAAW;IACX,YAAO;IACP,gBAAW;IACX,YAAO;IACP,gBAAW;IAGT,gBAA4B;IAC5B,cAAwB;IACxB,eAA0B;IAC1B,mBAAkC;CAErC"}
|