@waveform-playlist/core 11.3.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -22,24 +22,35 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  InteractionState: () => InteractionState,
24
24
  MAX_CANVAS_WIDTH: () => MAX_CANVAS_WIDTH,
25
+ MIN_PIXELS_PER_UNIT: () => MIN_PIXELS_PER_UNIT,
25
26
  PPQN: () => PPQN,
27
+ appendPeaks: () => appendPeaks,
28
+ appendToAudioBuffer: () => appendToAudioBuffer,
26
29
  applyFadeIn: () => applyFadeIn,
27
30
  applyFadeOut: () => applyFadeOut,
31
+ calculateDuration: () => calculateDuration,
28
32
  clipDurationTime: () => clipDurationTime,
29
33
  clipEndTime: () => clipEndTime,
30
34
  clipOffsetTime: () => clipOffsetTime,
31
35
  clipPixelWidth: () => clipPixelWidth,
32
36
  clipStartTime: () => clipStartTime,
33
37
  clipsOverlap: () => clipsOverlap,
38
+ computeMusicalTicks: () => computeMusicalTicks,
39
+ concatenateAudioData: () => concatenateAudioData,
40
+ createAudioBuffer: () => createAudioBuffer,
34
41
  createClip: () => createClip,
35
42
  createClipFromSeconds: () => createClipFromSeconds,
43
+ createClipFromTicks: () => createClipFromTicks,
36
44
  createTimeline: () => createTimeline,
37
45
  createTrack: () => createTrack,
38
46
  dBToNormalized: () => dBToNormalized,
47
+ detectMeterChanges: () => detectMeterChanges,
39
48
  exponentialCurve: () => exponentialCurve,
40
49
  findGaps: () => findGaps,
50
+ gainToDb: () => gainToDb,
41
51
  gainToNormalized: () => gainToNormalized,
42
52
  generateCurve: () => generateCurve,
53
+ generatePeaks: () => generatePeaks,
43
54
  getClipsAtSample: () => getClipsAtSample,
44
55
  getClipsInRange: () => getClipsInRange,
45
56
  getShortcutLabel: () => getShortcutLabel,
@@ -55,12 +66,14 @@ __export(index_exports, {
55
66
  samplesToTicks: () => samplesToTicks,
56
67
  secondsToPixels: () => secondsToPixels,
57
68
  secondsToSamples: () => secondsToSamples,
69
+ snapTickToGrid: () => snapTickToGrid,
58
70
  snapToGrid: () => snapToGrid,
71
+ snapToTicks: () => snapToTicks,
59
72
  sortClipsByTime: () => sortClipsByTime,
60
73
  ticksPerBar: () => ticksPerBar,
61
74
  ticksPerBeat: () => ticksPerBeat,
62
- ticksToBarBeatLabel: () => ticksToBarBeatLabel,
63
- ticksToSamples: () => ticksToSamples
75
+ ticksToSamples: () => ticksToSamples,
76
+ trackChannelCount: () => trackChannelCount
64
77
  });
65
78
  module.exports = __toCommonJS(index_exports);
66
79
 
@@ -68,10 +81,50 @@ module.exports = __toCommonJS(index_exports);
68
81
  var MAX_CANVAS_WIDTH = 1e3;
69
82
 
70
83
  // src/types/clip.ts
84
+ function createClipFromTicks(options) {
85
+ const { startTick, ticksToSeconds, bpm, ppqn } = options;
86
+ if (startTick < 0) {
87
+ throw new Error("createClipFromTicks: startTick must be non-negative");
88
+ }
89
+ let toSeconds;
90
+ if (ticksToSeconds) {
91
+ toSeconds = ticksToSeconds;
92
+ } else if (bpm !== void 0 && ppqn !== void 0) {
93
+ toSeconds = (tick) => tick * 60 / (ppqn * bpm);
94
+ } else {
95
+ throw new Error(
96
+ "createClipFromTicks: either ticksToSeconds callback or both bpm and ppqn are required"
97
+ );
98
+ }
99
+ const sampleRate = options.audioBuffer?.sampleRate ?? options.sampleRate ?? options.waveformData?.sample_rate;
100
+ if (sampleRate === void 0) {
101
+ throw new Error("createClipFromTicks: sampleRate is required when audioBuffer is not provided");
102
+ }
103
+ const startSample = Math.round(toSeconds(startTick) * sampleRate);
104
+ return createClip({
105
+ audioBuffer: options.audioBuffer,
106
+ startSample,
107
+ startTick,
108
+ durationSamples: options.durationSamples,
109
+ offsetSamples: options.offsetSamples,
110
+ gain: options.gain,
111
+ name: options.name,
112
+ color: options.color,
113
+ fadeIn: options.fadeIn,
114
+ fadeOut: options.fadeOut,
115
+ waveformData: options.waveformData,
116
+ sampleRate: options.sampleRate,
117
+ sourceDurationSamples: options.sourceDurationSamples,
118
+ midiNotes: options.midiNotes,
119
+ midiChannel: options.midiChannel,
120
+ midiProgram: options.midiProgram
121
+ });
122
+ }
71
123
  function createClip(options) {
72
124
  const {
73
125
  audioBuffer,
74
126
  startSample,
127
+ startTick,
75
128
  offsetSamples = 0,
76
129
  gain = 1,
77
130
  name,
@@ -105,6 +158,7 @@ function createClip(options) {
105
158
  id: generateId(),
106
159
  audioBuffer,
107
160
  startSample,
161
+ startTick,
108
162
  durationSamples,
109
163
  offsetSamples,
110
164
  sampleRate,
@@ -151,6 +205,7 @@ function createClipFromSeconds(options) {
151
205
  return createClip({
152
206
  audioBuffer,
153
207
  startSample: Math.round(startTime * sampleRate),
208
+ startTick: options.startTick,
154
209
  durationSamples: Math.round(duration * sampleRate),
155
210
  offsetSamples: Math.round(offset * sampleRate),
156
211
  sampleRate,
@@ -300,14 +355,6 @@ function samplesToTicks(samples, bpm, sampleRate, ppqn = PPQN) {
300
355
  function snapToGrid(ticks, gridSizeTicks) {
301
356
  return Math.round(ticks / gridSizeTicks) * gridSizeTicks;
302
357
  }
303
- function ticksToBarBeatLabel(ticks, timeSignature, ppqn = PPQN) {
304
- const barTicks = ticksPerBar(timeSignature, ppqn);
305
- const beatTicks = ticksPerBeat(timeSignature, ppqn);
306
- const bar = Math.floor(ticks / barTicks) + 1;
307
- const beatInBar = Math.floor(ticks % barTicks / beatTicks) + 1;
308
- if (beatInBar === 1) return `${bar}`;
309
- return `${bar}.${beatInBar}`;
310
- }
311
358
 
312
359
  // src/utils/dBUtils.ts
313
360
  var DEFAULT_FLOOR = -100;
@@ -332,12 +379,313 @@ function normalizedToDb(normalized, floor = DEFAULT_FLOOR) {
332
379
  const clamped = Math.max(0, normalized);
333
380
  return clamped * -floor + floor;
334
381
  }
382
+ function gainToDb(gain) {
383
+ return 20 * Math.log10(Math.max(gain, 1e-4));
384
+ }
335
385
  function gainToNormalized(gain, floor = DEFAULT_FLOOR) {
336
386
  if (gain <= 0) return 0;
337
387
  const db = 20 * Math.log10(gain);
338
388
  return dBToNormalized(db, floor);
339
389
  }
340
390
 
391
+ // src/utils/musicalTicks.ts
392
+ function snapToTicks(snapTo, timeSignature, ppqn = 960) {
393
+ const ts = timeSignature;
394
+ switch (snapTo) {
395
+ case "bar":
396
+ return ticksPerBar(ts, ppqn);
397
+ case "beat":
398
+ return ticksPerBeat(ts, ppqn);
399
+ case "1/2":
400
+ return ppqn * 2;
401
+ case "1/4":
402
+ return ppqn;
403
+ case "1/8":
404
+ return ppqn / 2;
405
+ case "1/16":
406
+ return ppqn / 4;
407
+ case "1/32":
408
+ return ppqn / 8;
409
+ case "1/2T":
410
+ return Math.round(ppqn * 2 * 2 / 3);
411
+ case "1/4T":
412
+ return Math.round(ppqn * 2 / 3);
413
+ case "1/8T":
414
+ return Math.round(ppqn * 2 / 6);
415
+ case "1/16T":
416
+ return Math.round(ppqn * 2 / 12);
417
+ case "off":
418
+ return 0;
419
+ }
420
+ }
421
+ var MIN_PIXELS_PER_UNIT = 8;
422
+ var MIN_PIXELS_PER_LABEL = 60;
423
+ function computeMusicalTicks(params) {
424
+ const { meterEntries, ticksPerPixel, startPixel, endPixel, ppqn = 960 } = params;
425
+ const firstMeter = meterEntries[0] ?? { tick: 0, numerator: 4, denominator: 4 };
426
+ if (ticksPerPixel <= 0 || ppqn <= 0 || firstMeter.denominator <= 0) {
427
+ return { ticks: [], pixelsPerQuarterNote: 0, zoomLevel: "coarse" };
428
+ }
429
+ const pixelsPerQuarterNote = ppqn / ticksPerPixel;
430
+ const tpEighth = ppqn / 2;
431
+ const tpSixteenth = ppqn / 4;
432
+ const pixelsPerEighth = tpEighth / ticksPerPixel;
433
+ const pixelsPerSixteenth = tpSixteenth / ticksPerPixel;
434
+ let zoomLevel;
435
+ if (pixelsPerQuarterNote * 4 < MIN_PIXELS_PER_UNIT) {
436
+ zoomLevel = "coarse";
437
+ } else if (pixelsPerQuarterNote < MIN_PIXELS_PER_UNIT) {
438
+ zoomLevel = "bar";
439
+ } else if (pixelsPerEighth < MIN_PIXELS_PER_UNIT) {
440
+ zoomLevel = "beat";
441
+ } else if (pixelsPerSixteenth < MIN_PIXELS_PER_UNIT) {
442
+ zoomLevel = "eighth";
443
+ } else {
444
+ zoomLevel = "sixteenth";
445
+ }
446
+ let coarseQuarterNoteStep;
447
+ let coarseQuarterNotes = 0;
448
+ if (zoomLevel === "coarse") {
449
+ coarseQuarterNotes = 2;
450
+ while (coarseQuarterNotes * ppqn / ticksPerPixel < MIN_PIXELS_PER_UNIT) {
451
+ coarseQuarterNotes *= 2;
452
+ }
453
+ coarseQuarterNoteStep = coarseQuarterNotes;
454
+ }
455
+ const startTick = startPixel * ticksPerPixel;
456
+ const endTick = endPixel * ticksPerPixel;
457
+ const segments = [];
458
+ {
459
+ let cumulativeBars = 0;
460
+ for (let i = 0; i < meterEntries.length; i++) {
461
+ const meter = meterEntries[i];
462
+ const segmentStart = meter.tick;
463
+ const segmentEnd = i + 1 < meterEntries.length ? meterEntries[i + 1].tick : Number.MAX_SAFE_INTEGER;
464
+ const ts = [meter.numerator, meter.denominator];
465
+ const tpBar = ticksPerBar(ts, ppqn);
466
+ segments.push({
467
+ segmentStartTick: segmentStart,
468
+ segmentEndTick: segmentEnd,
469
+ meter,
470
+ barOffset: cumulativeBars
471
+ });
472
+ if (segmentEnd !== Number.MAX_SAFE_INTEGER) {
473
+ const segmentLen = segmentEnd - segmentStart;
474
+ cumulativeBars += Math.floor(segmentLen / tpBar);
475
+ }
476
+ }
477
+ }
478
+ const ticks = [];
479
+ for (const { segmentStartTick, segmentEndTick, meter, barOffset } of segments) {
480
+ const ts = [meter.numerator, meter.denominator];
481
+ const tpBeat = ticksPerBeat(ts, ppqn);
482
+ const tpBar = ticksPerBar(ts, ppqn);
483
+ let stepTicks;
484
+ if (zoomLevel === "coarse") {
485
+ stepTicks = coarseQuarterNotes * ppqn;
486
+ } else if (zoomLevel === "bar") {
487
+ stepTicks = tpBar;
488
+ } else if (zoomLevel === "beat") {
489
+ stepTicks = tpBeat;
490
+ } else if (zoomLevel === "eighth") {
491
+ stepTicks = tpEighth;
492
+ } else {
493
+ stepTicks = tpSixteenth;
494
+ }
495
+ const segmentTickStart = Math.max(segmentStartTick, startTick);
496
+ const segmentTickEnd = Math.min(segmentEndTick - 1, endTick);
497
+ if (segmentTickStart > segmentTickEnd) {
498
+ continue;
499
+ }
500
+ const offsetIntoSegment = segmentTickStart - segmentStartTick;
501
+ const firstStepOffset = Math.floor(offsetIntoSegment / stepTicks) * stepTicks;
502
+ const firstStepTick = segmentStartTick + firstStepOffset;
503
+ for (let tick = firstStepTick; tick <= segmentTickEnd && tick < segmentEndTick; tick += stepTicks) {
504
+ const pixel = tick / ticksPerPixel;
505
+ if (pixel < startPixel || pixel > endPixel) {
506
+ continue;
507
+ }
508
+ const tickOffsetInSegment = tick - segmentStartTick;
509
+ let type;
510
+ if (tickOffsetInSegment % tpBar === 0) {
511
+ type = "major";
512
+ } else if (tickOffsetInSegment % tpBeat === 0) {
513
+ type = "minor";
514
+ } else {
515
+ type = "minorMinor";
516
+ }
517
+ const barIndexInSegment = Math.floor(tickOffsetInSegment / tpBar);
518
+ const barIndex = barOffset + barIndexInSegment;
519
+ let label;
520
+ if (type === "major") {
521
+ label = `${barIndex + 1}`;
522
+ } else if (type === "minor" && tpBeat / ticksPerPixel >= MIN_PIXELS_PER_LABEL) {
523
+ const beatInBar = Math.floor(tickOffsetInSegment % tpBar / tpBeat) + 1;
524
+ label = `${barIndex + 1}.${beatInBar}`;
525
+ }
526
+ ticks.push({ pixel, type, barIndex, ...label !== void 0 ? { label } : {} });
527
+ }
528
+ }
529
+ ticks.sort((a, b) => a.pixel - b.pixel);
530
+ const result = {
531
+ ticks,
532
+ pixelsPerQuarterNote,
533
+ zoomLevel,
534
+ ...coarseQuarterNoteStep !== void 0 ? { coarseQuarterNoteStep } : {}
535
+ };
536
+ return result;
537
+ }
538
+ function snapTickToGrid(tick, snapTo, meterEntries, ppqn = 960) {
539
+ if (snapTo === "off") return tick;
540
+ let meter = meterEntries[0] ?? { tick: 0, numerator: 4, denominator: 4 };
541
+ for (const entry of meterEntries) {
542
+ if (entry.tick <= tick) {
543
+ meter = entry;
544
+ } else {
545
+ break;
546
+ }
547
+ }
548
+ const ts = [meter.numerator, meter.denominator];
549
+ const gridSize = snapToTicks(snapTo, ts, ppqn);
550
+ if (gridSize <= 0) return tick;
551
+ const offset = tick - meter.tick;
552
+ return meter.tick + Math.round(offset / gridSize) * gridSize;
553
+ }
554
+
555
+ // src/utils/meterDetection.ts
556
+ function detectMeterChanges(beats, firstBeatTick, ppqn) {
557
+ const DEFAULT_NUMERATOR = 4;
558
+ const DENOMINATOR = 4;
559
+ const defaultResult = [
560
+ { tick: 0, numerator: DEFAULT_NUMERATOR, denominator: DENOMINATOR }
561
+ ];
562
+ if (beats.length === 0) {
563
+ return defaultResult;
564
+ }
565
+ const firstDownbeatIndex = beats.findIndex((b) => b.beat === 1);
566
+ if (firstDownbeatIndex === -1) {
567
+ return defaultResult;
568
+ }
569
+ const bars = [];
570
+ let barStartBeatIndex = firstDownbeatIndex;
571
+ for (let i = firstDownbeatIndex + 1; i < beats.length; i++) {
572
+ if (beats[i].beat === 1) {
573
+ bars.push({ beatIndex: barStartBeatIndex, count: i - barStartBeatIndex });
574
+ barStartBeatIndex = i;
575
+ }
576
+ }
577
+ if (bars.length === 0) {
578
+ return defaultResult;
579
+ }
580
+ const rawEntries = [];
581
+ let prevNumerator = -1;
582
+ for (const bar of bars) {
583
+ const numerator = bar.count;
584
+ if (numerator !== prevNumerator) {
585
+ const tick = firstBeatTick + bar.beatIndex * ppqn;
586
+ rawEntries.push({ tick, numerator, denominator: DENOMINATOR });
587
+ prevNumerator = numerator;
588
+ }
589
+ }
590
+ if (rawEntries.length === 0) {
591
+ return defaultResult;
592
+ }
593
+ if (rawEntries[0].tick === 0) {
594
+ return rawEntries;
595
+ }
596
+ const tick0Entry = {
597
+ tick: 0,
598
+ numerator: rawEntries[0].numerator,
599
+ denominator: DENOMINATOR
600
+ };
601
+ const rest = rawEntries[0].numerator === tick0Entry.numerator ? rawEntries.slice(1) : rawEntries;
602
+ return [tick0Entry, ...rest];
603
+ }
604
+
605
+ // src/utils/peaksGenerator.ts
606
+ function generatePeaks(samples, samplesPerPixel, bits = 16) {
607
+ const numPeaks = Math.ceil(samples.length / samplesPerPixel);
608
+ const peakArray = bits === 8 ? new Int8Array(numPeaks * 2) : new Int16Array(numPeaks * 2);
609
+ const maxValue = 2 ** (bits - 1);
610
+ for (let i = 0; i < numPeaks; i++) {
611
+ const start = i * samplesPerPixel;
612
+ const end = Math.min(start + samplesPerPixel, samples.length);
613
+ let min = 0;
614
+ let max = 0;
615
+ for (let j = start; j < end; j++) {
616
+ const value = samples[j];
617
+ if (value < min) min = value;
618
+ if (value > max) max = value;
619
+ }
620
+ peakArray[i * 2] = Math.max(-maxValue, Math.floor(min * maxValue));
621
+ peakArray[i * 2 + 1] = Math.min(maxValue - 1, Math.floor(max * maxValue));
622
+ }
623
+ return peakArray;
624
+ }
625
+ function appendPeaks(existingPeaks, newSamples, samplesPerPixel, totalSamplesProcessed, bits = 16) {
626
+ const maxValue = 2 ** (bits - 1);
627
+ const remainder = totalSamplesProcessed % samplesPerPixel;
628
+ let offset = 0;
629
+ if (remainder > 0 && existingPeaks.length > 0) {
630
+ const samplesToComplete = samplesPerPixel - remainder;
631
+ const endIndex = Math.min(samplesToComplete, newSamples.length);
632
+ let min = existingPeaks[existingPeaks.length - 2] / maxValue;
633
+ let max = existingPeaks[existingPeaks.length - 1] / maxValue;
634
+ for (let i = 0; i < endIndex; i++) {
635
+ const value = newSamples[i];
636
+ if (value < min) min = value;
637
+ if (value > max) max = value;
638
+ }
639
+ const updated = new (bits === 8 ? Int8Array : Int16Array)(existingPeaks.length);
640
+ updated.set(existingPeaks);
641
+ updated[existingPeaks.length - 2] = Math.max(-maxValue, Math.floor(min * maxValue));
642
+ updated[existingPeaks.length - 1] = Math.min(maxValue - 1, Math.floor(max * maxValue));
643
+ offset = endIndex;
644
+ const newPeaks2 = generatePeaks(newSamples.slice(offset), samplesPerPixel, bits);
645
+ const result2 = new (bits === 8 ? Int8Array : Int16Array)(updated.length + newPeaks2.length);
646
+ result2.set(updated);
647
+ result2.set(newPeaks2, updated.length);
648
+ return result2;
649
+ }
650
+ const newPeaks = generatePeaks(newSamples.slice(offset), samplesPerPixel, bits);
651
+ const result = new (bits === 8 ? Int8Array : Int16Array)(existingPeaks.length + newPeaks.length);
652
+ result.set(existingPeaks);
653
+ result.set(newPeaks, existingPeaks.length);
654
+ return result;
655
+ }
656
+
657
+ // src/utils/audioBufferUtils.ts
658
+ function concatenateAudioData(chunks) {
659
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
660
+ const result = new Float32Array(totalLength);
661
+ let offset = 0;
662
+ for (const chunk of chunks) {
663
+ result.set(chunk, offset);
664
+ offset += chunk.length;
665
+ }
666
+ return result;
667
+ }
668
+ function createAudioBuffer(audioContext, channelData, sampleRate, channelCount = 1) {
669
+ const channels = channelData instanceof Float32Array ? [channelData] : channelData;
670
+ const length = channels[0]?.length ?? 0;
671
+ const buffer = audioContext.createBuffer(channelCount, length, sampleRate);
672
+ for (let ch = 0; ch < Math.min(channelCount, channels.length); ch++) {
673
+ buffer.copyToChannel(new Float32Array(channels[ch]), ch);
674
+ }
675
+ return buffer;
676
+ }
677
+ function appendToAudioBuffer(audioContext, existingBuffer, newSamples, sampleRate) {
678
+ if (!existingBuffer) {
679
+ return createAudioBuffer(audioContext, [newSamples], sampleRate);
680
+ }
681
+ const existingData = existingBuffer.getChannelData(0);
682
+ const combined = concatenateAudioData([existingData, newSamples]);
683
+ return createAudioBuffer(audioContext, [combined], sampleRate);
684
+ }
685
+ function calculateDuration(sampleCount, sampleRate) {
686
+ return sampleCount / sampleRate;
687
+ }
688
+
341
689
  // src/clipTimeHelpers.ts
342
690
  function clipStartTime(clip) {
343
691
  return clip.startSample / clip.sampleRate;
@@ -351,6 +699,12 @@ function clipOffsetTime(clip) {
351
699
  function clipDurationTime(clip) {
352
700
  return clip.durationSamples / clip.sampleRate;
353
701
  }
702
+ function trackChannelCount(track) {
703
+ return track.clips.reduce(
704
+ (max, clip) => Math.max(max, clip.audioBuffer?.numberOfChannels ?? 1),
705
+ 1
706
+ );
707
+ }
354
708
  function clipPixelWidth(startSample, durationSamples, samplesPerPixel) {
355
709
  return Math.floor((startSample + durationSamples) / samplesPerPixel) - Math.floor(startSample / samplesPerPixel);
356
710
  }
@@ -488,24 +842,35 @@ var getShortcutLabel = (shortcut) => {
488
842
  0 && (module.exports = {
489
843
  InteractionState,
490
844
  MAX_CANVAS_WIDTH,
845
+ MIN_PIXELS_PER_UNIT,
491
846
  PPQN,
847
+ appendPeaks,
848
+ appendToAudioBuffer,
492
849
  applyFadeIn,
493
850
  applyFadeOut,
851
+ calculateDuration,
494
852
  clipDurationTime,
495
853
  clipEndTime,
496
854
  clipOffsetTime,
497
855
  clipPixelWidth,
498
856
  clipStartTime,
499
857
  clipsOverlap,
858
+ computeMusicalTicks,
859
+ concatenateAudioData,
860
+ createAudioBuffer,
500
861
  createClip,
501
862
  createClipFromSeconds,
863
+ createClipFromTicks,
502
864
  createTimeline,
503
865
  createTrack,
504
866
  dBToNormalized,
867
+ detectMeterChanges,
505
868
  exponentialCurve,
506
869
  findGaps,
870
+ gainToDb,
507
871
  gainToNormalized,
508
872
  generateCurve,
873
+ generatePeaks,
509
874
  getClipsAtSample,
510
875
  getClipsInRange,
511
876
  getShortcutLabel,
@@ -521,11 +886,13 @@ var getShortcutLabel = (shortcut) => {
521
886
  samplesToTicks,
522
887
  secondsToPixels,
523
888
  secondsToSamples,
889
+ snapTickToGrid,
524
890
  snapToGrid,
891
+ snapToTicks,
525
892
  sortClipsByTime,
526
893
  ticksPerBar,
527
894
  ticksPerBeat,
528
- ticksToBarBeatLabel,
529
- ticksToSamples
895
+ ticksToSamples,
896
+ trackChannelCount
530
897
  });
531
898
  //# sourceMappingURL=index.js.map