vector-score 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,12 +6,12 @@ A lightweight, SVG-based TypeScript library for rendering musical staves, notes,
6
6
 
7
7
  ## Features
8
8
 
9
- * **Multiple Staff Types**: Supports Treble, Bass, Alto, and Grand staves.
10
- * **Rhythm Staff**: Dedicated staff for rhythm exercises with customizable time signatures and bar handling.
11
- * **Scrolling Staff** Staff made to allow for 'endless' style of notes.
12
- * **SVG Rendering**: Crisp, scalable vector graphics suitable for any screen size.
13
- * **Flexible Note Input**: Simple string-based syntax for defining notes, chords, and rests.
14
- * **Interactive Features**: Includes methods for error feedback (highlighting wrong notes) and note justification.
9
+ * **Multiple Staff Types**: Supports Treble, Bass, Alto, and Grand staves (MusicStaff and ScrollingStaff).
10
+ * [**Music Staff**](#Standard-Music-Staff):Standard music staff for notation.
11
+ * [**Rhythm Staff**](#Rhythm-Staff): Dedicated staff for rhythm exercises with customizable time signatures and bar handling.
12
+ * [**Scrolling Staff**](#Scrolling-Staff) Staff made to allow for 'endless' style of notes.
13
+ * **SVG Rendering**: Scalable Vector graphics suitable for any screen size.
14
+ * **Flexible Note Input**: Simple string-based syntax for defining notes.
15
15
 
16
16
  ## Installation
17
17
 
@@ -45,7 +45,7 @@ Create a container element in your HTML where the staff will be rendered.
45
45
 
46
46
  ### 2. Import and Initialize
47
47
 
48
- ### Standard Music Staff (Treble, Bass, Alto)
48
+ ### Standard Music Staff
49
49
 
50
50
  ```typescript
51
51
  import { MusicStaff } from 'vector-score';
@@ -224,6 +224,7 @@ Notes are defined using a specific string format parsed by the library:
224
224
  ### MusicStaffOptions
225
225
  * `width`: Total width of the SVG in pixels.
226
226
  * `scale`: Zoom factor (default: 1).
227
+ * `noteStartX`: Position where notes start to draw.
227
228
  * `staffType`: `'treble' | 'bass' | 'alto' | 'grand'`.
228
229
  * `spaceAbove`: Padding units above the staff (in staff line spaces).
229
230
  * `spaceBelow`: Padding units below the staff (in staff line spaces).
@@ -235,6 +236,23 @@ Notes are defined using a specific string format parsed by the library:
235
236
  * `barsCount`: Number of measures to draw.
236
237
  * `currentBeatUIColor`: CSS color string for current beat UI.
237
238
  * *Inherits sizing and color options from MusicStaffOptions.*
239
+ * `width`: Total width of the SVG in pixels.
240
+ * `scale`: Zoom factor (default: 1).
241
+ * `topNumber`: The top number of the time signature (e.g., 4 for 4/4 time).
242
+ * `barsCount`: Number of measures to draw.
243
+ * `spaceAbove`: Padding units above the staff (in staff line spaces).
244
+ * `spaceBelow`: Padding units below the staff (in staff line spaces).
245
+ * `staffColor`: CSS color string for lines and notes.
246
+ * `staffBackgroundColor`: CSS color string for background.
247
+ * `currentBeatUIColor`: CSS color string for current beat UI indicator.
238
248
 
239
249
  ### ScrollingStaffOptions
240
- * same as MusicStaffOptions
250
+ * `width`: Total width of the SVG in pixels.
251
+ * `scale`: Zoom factor (default: 1).
252
+ * `noteStartX`: Position where notes start to draw.
253
+ * `staffType`: `'treble' | 'bass' | 'alto' | 'grand'`.
254
+ * `spaceAbove`: Padding units above the staff (in staff line spaces).
255
+ * `spaceBelow`: Padding units below the staff (in staff line spaces).
256
+ * `staffColor`: CSS color string for lines and notes.
257
+ * `staffBackgroundColor`: CSS color string for background.
258
+ * `onNotesOut`: Callback function for when there are no more notes on the staff to advance.
@@ -2,6 +2,7 @@ import { StaffTypes } from '../types';
2
2
  export type MusicStaffOptions = {
3
3
  width?: number;
4
4
  scale?: number;
5
+ noteStartX?: number;
5
6
  staffType?: StaffTypes;
6
7
  spaceAbove?: number;
7
8
  spaceBelow?: number;
@@ -15,6 +16,7 @@ export default class MusicStaff {
15
16
  private options;
16
17
  private noteEntries;
17
18
  private noteCursorX;
19
+ private noteStartX;
18
20
  /**
19
21
  * Creates an instance of a MusicStaff, A single staff.
20
22
  *
@@ -2,6 +2,7 @@ import { StaffTypes } from '../types';
2
2
  export type ScrollingStaffOptions = {
3
3
  width?: number;
4
4
  scale?: number;
5
+ noteStartX?: number;
5
6
  staffType?: StaffTypes;
6
7
  spaceAbove?: number;
7
8
  spaceBelow?: number;
@@ -19,6 +20,7 @@ export default class ScrollingStaff {
19
20
  private noteBuffer;
20
21
  private notesLayer;
21
22
  private noteCursorX;
23
+ private noteStartX;
22
24
  /**
23
25
  * Creates an instance of a ScrollingStaff, A single staff that takes in a queue of notes that can be advanced with in a 'endless' style of staff.
24
26
  *
@@ -420,7 +420,7 @@ class O {
420
420
  // from get rootSvgElement().
421
421
  // HEIGHT and YOfsset should be set externally, values are calculated internally.
422
422
  constructor(e, t) {
423
- this.rootElementRef = e, this.width = t.width, this.scale = t.scale, this.width > m && (this.width = m, console.warn(`Width provided for the staff ${this.width} exceeds the limit ${m}. Please use this value to fix positioning issues.`)), this.svgElementRef = document.createElementNS(u, "svg"), this.svgElementRef.classList.add("vs-svg-renderer-root"), this.svgElementRef.style.maxWidth = "100%", this.svgElementRef.style.height = "auto", this.svgElementRef.style.display = "block", this.svgElementRef.setAttribute("color", t.staffColor), this.svgElementRef.style.backgroundColor = t.staffBackgroundColor, this.makeGlyphDefs(t.useGlyphs), this.parentGroupContainer = this.createGroup("svg-renderer-parent"), this.svgElementRef.appendChild(this.parentGroupContainer), this.musicStaffLayer = this.createGroup("music-staff-layer"), this.musicNotesLayer = this.createGroup("music-notes-layer"), this.musicUILayer = this.createGroup("music-ui-layer"), this.parentGroupContainer.appendChild(this.musicStaffLayer), this.parentGroupContainer.appendChild(this.musicNotesLayer), this.parentGroupContainer.appendChild(this.musicUILayer), this.musicNotesLayer.setAttribute("transform", "translate(38, 0)");
423
+ this.rootElementRef = e, this.width = t.width, this.scale = t.scale, this.width > m && (this.width = m, console.warn(`Width provided for the staff ${this.width} exceeds the limit ${m}. Please use this value to fix positioning issues.`)), this.svgElementRef = document.createElementNS(u, "svg"), this.svgElementRef.classList.add("vs-svg-renderer-root"), this.svgElementRef.style.maxWidth = "100%", this.svgElementRef.style.height = "auto", this.svgElementRef.style.display = "block", this.svgElementRef.setAttribute("color", t.staffColor), this.svgElementRef.style.backgroundColor = t.staffBackgroundColor, this.makeGlyphDefs(t.useGlyphs), this.parentGroupContainer = this.createGroup("svg-renderer-parent"), this.svgElementRef.appendChild(this.parentGroupContainer), this.musicStaffLayer = this.createGroup("music-staff-layer"), this.musicNotesLayer = this.createGroup("music-notes-layer"), this.musicUILayer = this.createGroup("music-ui-layer"), this.parentGroupContainer.appendChild(this.musicStaffLayer), this.parentGroupContainer.appendChild(this.musicNotesLayer), this.parentGroupContainer.appendChild(this.musicUILayer);
424
424
  }
425
425
  // Creates SVG defs for all glyphs in GLYPH_ENTRIES, applies global scale and offsets, appends to root SVG
426
426
  makeGlyphDefs(e) {
@@ -514,6 +514,7 @@ class j {
514
514
  options;
515
515
  noteEntries = [];
516
516
  noteCursorX = 0;
517
+ noteStartX;
517
518
  /**
518
519
  * Creates an instance of a MusicStaff, A single staff.
519
520
  *
@@ -524,6 +525,7 @@ class j {
524
525
  this.options = {
525
526
  width: 300,
526
527
  scale: 1,
528
+ noteStartX: 0,
527
529
  staffType: "treble",
528
530
  spaceAbove: 0,
529
531
  spaceBelow: 0,
@@ -563,7 +565,7 @@ class j {
563
565
  let r = this.options.spaceBelow * 10;
564
566
  this.options.staffType === "grand" && (r -= 10 / 2), this.svgRendererInstance.addTotalRootSvgHeight(r);
565
567
  }
566
- this.svgRendererInstance.applySizingToRootSvg(), this.svgRendererInstance.commitElementsToDOM(s);
568
+ this.noteStartX = 38 + this.options.noteStartX, this.svgRendererInstance.getLayerByName("notes").setAttribute("transform", `translate(${this.noteStartX}, 0)`), this.svgRendererInstance.applySizingToRootSvg(), this.svgRendererInstance.commitElementsToDOM(s);
567
569
  }
568
570
  /**
569
571
  * Draws a note on the staff.
@@ -742,7 +744,7 @@ class j {
742
744
  this.noteEntries = [], this.svgRendererInstance.destroy();
743
745
  }
744
746
  }
745
- const E = 30, G = 19, C = 12, k = 4, W = 6, v = 1, L = 38, Z = [
747
+ const E = 30, v = 19, C = 12, k = 4, W = 6, G = 1, L = 38, Z = [
746
748
  "TIME_4",
747
749
  "TIME_3",
748
750
  "NOTE_HEAD_WHOLE",
@@ -818,10 +820,10 @@ class Q {
818
820
  this.rendererInstance.addTotalRootSvgHeight(E * 2);
819
821
  const n = this.rendererInstance.createGroup("time-signature");
820
822
  o.appendChild(n);
821
- const a = E - G;
822
- this.rendererInstance.drawGlyph(r, n), this.rendererInstance.drawGlyph("TIME_4", n, { yOffset: G }), n.setAttribute("transform", `translate(0, ${a})`);
823
+ const a = E - v;
824
+ this.rendererInstance.drawGlyph(r, n), this.rendererInstance.drawGlyph("TIME_4", n, { yOffset: v }), n.setAttribute("transform", `translate(0, ${a})`);
823
825
  let i = this.options.width - 38;
824
- this.options.barsCount > 1 && (i -= (this.options.barsCount - 1) * C), i -= v, this.rendererInstance.drawLine(0, E, this.options.width - v, E, o), this.barSpacing = i / this.options.barsCount, this.quarterNoteSpacing = Math.round(this.barSpacing / this.options.topNumber), this.maxBeatCount = this.options.barsCount * this.options.topNumber;
826
+ this.options.barsCount > 1 && (i -= (this.options.barsCount - 1) * C), i -= G, this.rendererInstance.drawLine(0, E, this.options.width - G, E, o), this.barSpacing = i / this.options.barsCount, this.quarterNoteSpacing = Math.round(this.barSpacing / this.options.topNumber), this.maxBeatCount = this.options.barsCount * this.options.topNumber;
825
827
  let c = this.barSpacing + 38;
826
828
  const l = E / 2, f = E + l;
827
829
  for (let p = 0; p < this.options.barsCount - 1; p++)
@@ -1083,6 +1085,7 @@ class z {
1083
1085
  noteBuffer = [];
1084
1086
  notesLayer;
1085
1087
  noteCursorX = 0;
1088
+ noteStartX;
1086
1089
  /**
1087
1090
  * Creates an instance of a ScrollingStaff, A single staff that takes in a queue of notes that can be advanced with in a 'endless' style of staff.
1088
1091
  *
@@ -1093,6 +1096,7 @@ class z {
1093
1096
  this.options = {
1094
1097
  width: 300,
1095
1098
  scale: 1,
1099
+ noteStartX: 0,
1096
1100
  staffType: "treble",
1097
1101
  spaceAbove: 0,
1098
1102
  spaceBelow: 0,
@@ -1132,10 +1136,10 @@ class z {
1132
1136
  let r = this.options.spaceBelow * 10;
1133
1137
  this.options.staffType === "grand" && (r -= 10 / 2), this.svgRendererInstance.addTotalRootSvgHeight(r);
1134
1138
  }
1135
- this.notesLayer = this.svgRendererInstance.getLayerByName("notes"), this.notesLayer.classList.add("vs-scrolling-notes-layer"), this.svgRendererInstance.applySizingToRootSvg(), this.svgRendererInstance.commitElementsToDOM(s);
1139
+ this.notesLayer = this.svgRendererInstance.getLayerByName("notes"), this.notesLayer.classList.add("vs-scrolling-notes-layer"), this.noteStartX = 38 + this.options.noteStartX, this.svgRendererInstance.getLayerByName("notes").setAttribute("transform", `translate(${this.noteStartX}, 0)`), this.svgRendererInstance.applySizingToRootSvg(), this.svgRendererInstance.commitElementsToDOM(s);
1136
1140
  }
1137
1141
  renderFirstNoteGroups() {
1138
- const e = this.options.width - 38 + q;
1142
+ const e = this.options.width - this.options.noteStartX + q;
1139
1143
  for (; this.noteBuffer.length > 0 && this.noteCursorX < e; )
1140
1144
  this.renderNextNote(), this.noteCursorX += _;
1141
1145
  this.activeEntries.length > 1 && (this.noteCursorX -= _);
@@ -1 +1 @@
1
- (function(d,T){typeof exports=="object"&&typeof module<"u"?T(exports):typeof define=="function"&&define.amd?define(["exports"],T):(d=typeof globalThis<"u"?globalThis:d||self,T(d.VectorScore={}))})(this,(function(d){"use strict";const w={treble:{staffType:"treble",paddingTop:13,paddingBottom:3,topLineNote:{name:"F",octave:5},topLineYPos:0,bottomLineYPos:40},bass:{staffType:"bass",paddingTop:0,paddingBottom:0,topLineNote:{name:"A",octave:3},topLineYPos:0,bottomLineYPos:40},alto:{staffType:"alto",paddingTop:0,paddingBottom:0,topLineNote:{name:"G",octave:4},topLineYPos:0,bottomLineYPos:40},grand:{staffType:"grand",paddingTop:13,paddingBottom:0,topLineNote:{name:"F",octave:5},topLineYPos:0,bottomLineYPos:110}},E={w:4,h:2,q:1,e:.5,s:.25},U={CLEF_TREBLE:{path:"m150 273 10 58c2 7 2 7 12 7 59 0 96 46 96 97 0 45-26 79-67 95-5 2-6 2-5 7 4 25 12 63 12 85 0 68-52 80-79 80-61 0-76-39-76-65 0-25 16-46 43-46 24 0 38 19 38 41 0 23-14 34-27 38-9 2-13 4-13 6 0 6 11 12 32 12 24 0 64-7 64-66 0-19-6-54-11-81-1-5-1-4-6-3l-27 2C48 540 0 474 0 404c0-80 61-138 119-185 5-4 4-5 3-10-2-16-5-42-5-65 0-42 9-92 39-125 8-9 20-19 26-19 4 0 15 11 21 20 16 24 26 58 26 93 0 61-33 112-76 153-3 2-3 2-3 7Zm38-211c-24 0-53 38-53 101l2 37c1 5 3 5 5 3 32-28 70-64 70-108 0-22-11-33-24-33Zm-44 272-8-51c-1-4-2-5-6-1-18 15-37 30-61 56-33 38-37 70-37 93 0 56 45 95 115 95l23-2c6-2 6-2 5-6l-20-119c-1-5-1-5-8-3-24 6-40 24-40 46 0 19 12 36 29 43 3 1 6 3 6 5 0 3-2 5-5 5l-11-3c-27-9-46-34-46-70 0-34 23-66 58-78 8-2 8-2 6-10Zm28 64 20 114c0 5 1 5 6 2 22-11 38-31 38-56 0-36-27-63-60-66-4 0-5 1-4 6Z",xOffset:0,yOffset:-14},CLEF_BASS:{path:"M101 0c68 0 110 46 110 114 0 120-102 190-199 237l-7 2c-3 0-5-2-5-5s2-5 6-7c92-52 146-114 146-223 0-62-18-103-60-103-40 0-64 29-64 44 0 4 1 8 7 8 5 0 9-3 19-3 20 0 38 15 38 41 0 24-17 41-42 41-32 0-48-27-48-58C2 50 33 0 101 0Zm148 32c13 0 22 10 22 22s-9 22-22 22c-12 0-21-10-21-22s9-22 21-22Zm1 99c12 0 21 9 21 21s-9 22-21 22-21-10-21-22 9-21 21-21Z",xOffset:0,yOffset:0},CLEF_ALTO:{path:"M91 9v174c0 3 2 2 3 2 11-3 27-13 36-58 1-6 3-10 7-10s6 4 8 11c5 17 15 37 43 37 25 0 32-25 32-77s-9-75-42-75c-5 0-33 2-33 10 0 2 6 5 11 6 7 3 15 11 15 26 0 17-11 27-26 27-17 0-31-11-31-32 0-25 22-50 69-50 65 0 93 45 93 87 0 54-30 92-83 92-11 0-18-2-24-4-4-1-8-1-11 1-6 3-14 16-14 24s8 21 14 24c3 2 7 2 11 1 6-2 13-4 24-4 53 0 83 38 83 92 0 42-28 87-93 87-47 0-69-25-69-50 0-21 14-32 31-32 15 0 26 10 26 27 0 15-8 23-15 26-5 1-11 4-11 6 0 8 28 10 33 10 33 0 42-23 42-75s-7-77-32-77c-28 0-38 20-43 37-2 7-4 11-8 11s-6-4-7-10c-9-45-25-55-36-58-1 0-3-1-3 2v174c0 5-3 8-8 8h-1c-5 0-8-3-8-8V9c0-5 3-8 8-8h1c5 0 8 3 8 8ZM8 1h34c6 0 9 3 9 8v382c0 5-3 8-9 8H8c-5 0-8-3-8-8V9c0-5 3-8 8-8Z",xOffset:0,yOffset:0},NOTE_HEAD_WHOLE:{path:"M77 0c34 0 74 19 74 45 0 24-19 45-77 45C21 90 0 68 0 45 0 20 30 0 77 0Zm-9 8c-17 0-30 5-30 24 0 22 23 50 47 50 16 0 28-8 28-26 0-21-20-48-45-48Z",xOffset:0,yOffset:-4.5},NOTE_HEAD_HALF:{path:"M35 90C15 90 0 79 0 60 0 42 17 0 70 0c21 0 36 12 36 30 0 12-12 60-71 60Zm-8-14c18 0 68-31 68-47l-2-6c-3-5-7-8-14-8-17 0-68 29-68 46l2 7c2 4 7 8 14 8Z",xOffset:0,yOffset:-4.5},NOTE_HEAD_QUARTER:{path:"M35 90C16 90 0 79 0 60 0 29 32 0 71 0c20 0 35 12 35 30 0 30-40 60-71 60Z",xOffset:0,yOffset:-4.5},EIGHTH_NOTE:{path:"M142 89c20 32 36 70 36 110 0 25-8 55-8 55-2 5-5 7-8 6h-1c-2-1-5-4-5-9l1-5c5-14 8-29 8-44 0-19-3-37-8-48-10-23-33-58-53-70v179c0 30-38 60-70 60-19 0-34-11-34-30 0-31 31-60 70-60 11 0 19 3 25 8V3c0-2 2-3 3-3 6 0 9 2 10 7 5 31 18 57 34 82Z",xOffset:0,yOffset:-28},EIGHTH_NOTE_FLIPPED:{path:"M9 323H0V60C0 29 32 0 71 0c20 0 35 12 35 30 0 30-40 60-71 60-19 0-26-9-26-9v158s58-56 58-89c0 0 0-25-8-43-5-12 10-17 14-6 13 34 9 48 9 48 0 39-41 97-41 97-20 27-32 77-32 77Z",xOffset:0,yOffset:-4},REST_WHOLE:{path:"M0 0h104v53H0V0Z",xOffset:0,yOffset:0},REST_HALF:{path:"M0 0h104v53H0V0Z",xOffset:0,yOffset:-5},REST_QUARTER:{path:"m28 151-18-22s-3-4-3-9c0-3 1-7 5-11 16-17 22-33 22-46 0-27-21-45-23-49l-1-6c0-5 4-8 7-8s5 1 7 3l61 71 1 7-1 5c-10 15-23 34-25 55v3c0 20 11 35 25 52 4 4 14 16 14 20 0 2-2 2-5 1-6-2-19-6-29-6-16 0-23 12-23 27 0 8 5 22 11 22 3 3 6 6 6 9s-2 5-7 5l-9-3c-27-21-43-39-43-57s13-35 32-35c3 0 10 3 14 0l-2-6-16-22Z",xOffset:0,yOffset:-16},REST_EIGHTH:{path:"M61 35c18 0 41-35 47-32 0 1 5 3 5 8l-5 17S64 189 62 190c-4 4-11 5-16 5-3 0-13 0-13-6 8-30 41-122 42-128 1-5 1-10-1-10-4 0-3 3-19 8C16 71 0 46 0 31 0 14 14 0 31 0c5 0 30 1 30 35Z",xOffset:0,yOffset:-10},ACCIDENTAL_SHARP:{path:"m67 66-8 3c-2 0-3 6-3 8v26c0 4 2 5 3 5l8-2 1-1c1 0 2 1 2 3v20c0 1-1 4-3 4l-8 4c-2 0-3 4-3 6v40c0 2-2 4-5 4-2 0-4-2-4-4v-35c0-2-1-5-4-5h-1l-17 7c-1 1-3 3-3 6v40c0 2-1 3-4 3-2 0-4-1-4-3v-35c0-1-1-5-3-5l-1 1-7 2v1c-2 0-3-1-3-3v-20c0-2 1-4 3-5l8-3c2-1 3-3 3-6V94c0-3-2-5-4-5l-7 3c-2 0-3-1-3-3V69l3-4 8-3c1-1 3-4 3-8V16c0-2 2-4 5-4 2 0 3 2 3 4v34c0 2 1 5 4 5l18-7c2-1 3-5 3-8V3c0-2 2-3 5-3 2 0 4 1 4 3v35c0 2 2 3 4 3l7-2h1c1 0 2 0 2 2v20c0 2-1 4-3 5Zm-20 46c2-11 2-23 0-34l-4-2c-7 0-20 6-21 11v35l4 1c6 0 20-5 21-11Z",xOffset:-8,yOffset:-10},ACCIDENTAL_FLAT:{path:"M4 196C1 193 0 9 0 9c0-6 5-9 10-9 3 0 6 2 6 5l-2 91c0 3 1 5 3 6h2l7-4c5-3 12-6 18-6 15 1 29 13 29 31 0 15-10 35-39 55-8 5-16 14-25 19l-2 1c-1 0-2 0-3-2Zm11-28c0 1 1 5 4 5l3-1c14-9 29-27 29-44 0-8-4-19-14-19-7 0-20 10-22 16l-1 10 1 33Z",xOffset:-8,yOffset:-14},ACCIDENTAL_NATURAL:{path:"m41 47 5-2h1l2 2v147c0 3-2 4-3 4h-4c-2 0-4-1-4-4v-43c0-2-2-3-5-3-8 0-25 7-29 8l-1 1c-2 0-3-1-3-3V4c0-3 1-4 4-4h3c2 0 4 1 4 4v48c0 2 1 2 3 2 7 0 26-7 26-7h1ZM11 88v31l3 1c8 0 24-6 24-12V78l-2-1c-7 0-25 7-25 11Z",xOffset:-8,yOffset:-10},ACCIDENTAL_DOUBLE_SHARP:{path:"M68 33h3c6 0 13 0 15-2l2-15C88 4 86 0 72 0c-6 0-12 1-14 4-2 1-2 7-2 13-1 5-8 17-12 17-5 0-9-10-11-15l-1-2c0-6-1-12-3-13-2-3-8-4-13-4C10 0 4 1 2 4L0 17l2 14c2 2 9 2 15 2h4c5 2 16 8 16 12 0 3-13 10-17 12h-3c-6 0-13 1-15 3L0 74l2 14 14 2 13-2c2-2 3-8 3-14 1-5 7-17 12-17 4 0 10 13 12 17 0 6 0 12 2 14l14 2c15 0 16-2 16-17l-2-13c-4-2-11-3-15-3h-3c-5-2-17-7-17-12 0-2 13-10 17-12Z",xOffset:-10,yOffset:-4},ACCIDENTAL_DOUBLE_FLAT:{path:"M102 93h2c15 0 29 12 29 30 0 15-10 35-39 55-8 5-16 14-26 19l-2 1-2-2-3-43c-6 7-15 16-27 25-7 5-15 14-25 19l-2 1c-1 0-2 0-3-2C2 193 0 8 0 8c0-5 6-8 10-8 3 0 6 2 6 5l-2 91c0 3 1 5 3 6h2c3 0 5-3 8-4 5-3 9-5 15-5h2c6 0 12 1 17 5L60 8c0-5 5-8 10-8 3 0 6 2 6 5l-2 91c0 3 1 5 3 6h2c3 0 5-3 7-4 6-3 10-5 16-5Zm-80 78c14-9 29-25 29-43 0-8-3-19-13-19-8 0-21 10-23 16l-1 11 1 31c0 2 1 5 4 5l3-1Zm59 0c15-9 29-25 29-43 0-6-2-12-5-16-2-2-4-3-8-3-7 0-21 10-23 16v8l1 34c0 2 1 5 3 5l3-1Z",xOffset:-14,yOffset:-14},TIME_4:{path:"M53 0h66S70 76 20 124h61V86l47-50v89h22v19h-22v27c0 9 13 9 13 9h9v10H61v-10h10s10 0 10-10v-26H0v-20S54 67 53 0Z",xOffset:0,yOffset:0},TIME_3:{path:"M2 43c0 21 15 30 30 30 5 0 28-2 28-27 0-11-16-20-16-24 0-14 56-15 56 26 0 26-19 38-31 38H45v13h24c12 0 33 15 33 41 0 38-54 40-54 25 0-3 10-11 10-21 0-20-15-27-27-27-17 0-32 8-31 30 1 30 36 43 75 43 36 0 75-19 75-50 0-34-23-47-37-47v-2c4 0 35-13 35-39 0-37-35-52-75-52C39 0 3 14 2 43Z",xOffset:0,yOffset:0}},M=/^(?<name>[A-Ga-g])(?<accidental>##|bb|[#bn]?)(?<octave>\d)(?<duration>[whqeWHQE]?)$/,Y=/^[whqeWHQE]$/,I=["C","D","E","F","G","A","B"];function m(h){const e=h.match(M);if(!e||!e.groups)throw new Error(`Invalid note string format: ${h}. Expected format: [A-Ga-g][#|b]?[0-9][w|h|q|e].`);let{name:t,accidental:s,octave:r,duration:o}=e.groups;if(t=t.toUpperCase(),o=o.toLowerCase(),!t)throw new Error(`Invalid note name: ${t}. Valid note names are: C, D, E, F, G, A, B.`);if(!r)throw new Error(`Invalid octave: ${r}. Octave must be a number between 0 and 9.`);o||(o="w");const n={name:t,octave:parseInt(r),duration:o};return s&&(n.accidental=s),n}function C(h){const e=h.match(Y);if(!e)throw new Error(`Invalid note duration '${h}'. Use w | h | q | e.`);return e.toString().toLowerCase()}function L(h){let e;switch(h){case"treble":e="CLEF_TREBLE";break;case"bass":e="CLEF_BASS";break;case"alto":e="CLEF_ALTO";break}if(!e)throw new Error(`Invalid clef type: ${h}. Valid clef types are: treble, bass, alto.`);return e}function b(h,e){const t=I.indexOf(h.name)-I.indexOf(e.name);let s=h.octave-e.octave;return s*=7,t+s}function F(h){let e=I.indexOf(h.name);return e+=h.octave*12,e}function G(h,e){return I.findIndex(s=>s===h)+1+e*7}const g=48,v=40+30/2,B=20,D=90;class H{params;rendererRef;width=0;constructor(e,t){this.rendererRef=e;const s=w[t];if(!s)throw new Error(`Staff type ${t} is not supported`);this.params=s}drawStaffLines=(e,t)=>{let s=e;for(let r=0;r<5;r++)this.rendererRef.drawLine(0,s,this.width,s,t),s+=10;return s-10};drawStaff=e=>{this.width=e;const t=this.rendererRef.getLayerByName("staff");let s=this.drawStaffLines(0,t),r=this.drawStaffLines(s+30,t);this.rendererRef.drawLine(0,0,0,r,t),this.rendererRef.drawLine(this.width,0,this.width,r,t);let o=r,n=1;const a=L("treble"),i=L("bass");this.rendererRef.drawGlyph(a,t),this.rendererRef.drawGlyph(i,t,{yOffset:s+30}),o+=this.params.paddingBottom+1,n+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(o),this.rendererRef.addTotalRootSvgYOffset(n)};shouldNoteFlip(e){const t=Math.abs(e-D),s=Math.abs(e-B);return e===v?!1:t<=s?!(e>=D):e<=B}getLedgerLinesX(e,t){const s=[],r=F(e);let o=e.duration==="w"?17:12.5;if(r===g)return s.push({x1:-2,x2:o,yPos:0}),s;if(t<this.params.topLineYPos){let n=this.params.topLineYPos-10;for(;n>=t;)s.push({x1:-2,x2:o,yPos:n-t}),n-=10}else if(t>this.params.bottomLineYPos){let n=this.params.bottomLineYPos+10;for(;n<=t;)s.push({x1:-2,x2:o,yPos:n-t}),n+=10}return s}calculateNoteYPos=e=>{let s=b(this.params.topLineNote,e)*(10/2);const r=F(e);return r<g?s+=10:r===g&&(s=v),s}}const $=20;class A{params;rendererRef;constructor(e,t){this.rendererRef=e;const s=w[t];if(!s)throw new Error(`Staff type ${t} is not supported`);this.params=s}drawStaff=e=>{const t=this.rendererRef.getLayerByName("staff");let s=0;for(let a=0;a<5;a++)this.rendererRef.drawLine(0,s,e,s,t),s+=10;this.rendererRef.drawLine(0,0,0,s-10,t),this.rendererRef.drawLine(e,0,e,s-10,t);let r=s-10+1,o=1;const n=L(this.params.staffType);this.rendererRef.drawGlyph(n,t),r+=this.params.paddingTop+this.params.paddingBottom,o+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(r),this.rendererRef.addTotalRootSvgYOffset(o)};shouldNoteFlip(e){return e<=$}getLedgerLinesX(e,t){const s=[];let r=e.duration==="w"?17:12.5;if(t<this.params.topLineYPos){let o=this.params.topLineYPos-10;for(;o>=t;)s.push({x1:-2,x2:r,yPos:o-t}),o-=10}else if(t>this.params.bottomLineYPos){let o=this.params.bottomLineYPos+10;for(;o<=t;)s.push({x1:-2,x2:r,yPos:o-t}),o+=10}return s}calculateNoteYPos=e=>b(this.params.topLineNote,e)*(10/2)}class P{svgRendererInstance;strategyInstance;constructor(e,t){this.svgRendererInstance=e,this.strategyInstance=t}drawStem(e,t){t?this.svgRendererInstance.drawLine(0,0,0,28,e):this.svgRendererInstance.drawLine(10,0,10,-28,e)}chordOffsetConsecutiveAccidentals(e){let t=0,s=0,r=0;for(let o=0;o<e.length;o++){const n=e[o];if(n.noteObj.accidental&&r<3?(t+=-8,s=Math.min(s,t),r++):n.noteObj.accidental&&r<=3?(t=-8,r=1):(t=0,r=0),t!==0){const i=Array.from(n.noteGroup.getElementsByTagName("use")).find(c=>c.getAttribute("href")?.includes("ACCIDENTAL"));if(!i)continue;i.setAttribute("transform",`translate(${t+8}, 0)`)}}return-s}chordOffsetCloseNotes(e){let t=e[0],s=0;for(let r=1;r<e.length;r++){const o=e[r];if(G(o.noteObj.name,o.noteObj.octave)-G(t.noteObj.name,t.noteObj.octave)===1){s=28/2,o.noteGroup.setAttribute("transform",`translate(${s}, ${o.noteYPos})`);const i=Array.from(o.noteGroup.getElementsByTagName("use")).find(c=>c.getAttribute("href")?.includes("ACCIDENTAL"));if(i){const c=i.getAttribute("transform")?.match(/([-]?\d+)/),l=c&&c[0];let f=-s;l&&(f+=Number(l)),i.setAttribute("transform",`translate(${f}, 0)`)}r++,t=e[r];continue}t=o}return s}renderNote(e){const t=this.svgRendererInstance.createGroup("note"),s=m(e),r=this.strategyInstance.calculateNoteYPos({name:s.name,octave:s.octave});let o=this.strategyInstance.shouldNoteFlip(r);switch(s.duration){case"h":this.svgRendererInstance.drawGlyph("NOTE_HEAD_HALF",t),this.drawStem(t,o);break;case"q":this.svgRendererInstance.drawGlyph("NOTE_HEAD_QUARTER",t),this.drawStem(t,o);break;case"e":o?this.svgRendererInstance.drawGlyph("EIGHTH_NOTE_FLIPPED",t):this.svgRendererInstance.drawGlyph("EIGHTH_NOTE",t);break;default:this.svgRendererInstance.drawGlyph("NOTE_HEAD_WHOLE",t)}let n=0;switch(s.accidental){case"#":this.svgRendererInstance.drawGlyph("ACCIDENTAL_SHARP",t),n-=-8;break;case"b":this.svgRendererInstance.drawGlyph("ACCIDENTAL_FLAT",t),n-=-8;break;case"n":this.svgRendererInstance.drawGlyph("ACCIDENTAL_NATURAL",t),n-=-8;break;case"##":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_SHARP",t),n-=-10;break;case"bb":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_FLAT",t),n-=-14;break}return this.strategyInstance.getLedgerLinesX(s,r).forEach(i=>{this.svgRendererInstance.drawLine(i.x1,i.yPos,i.x2,i.yPos,t)}),{noteGroup:t,noteObj:s,noteYPos:r,accidentalOffset:n,cursorOffset:0}}renderChord(e){const t=this.svgRendererInstance.createGroup("chord"),s=[];for(const n of e){const a=this.renderNote(n);a.noteGroup.setAttribute("transform",`translate(0, ${a.noteYPos})`),t.appendChild(a.noteGroup),s.push({noteGroup:a.noteGroup,noteObj:a.noteObj,noteYPos:a.noteYPos,cursorOffset:0,accidentalOffset:0})}const r=this.chordOffsetConsecutiveAccidentals(s),o=this.chordOffsetCloseNotes(s);return{noteGroup:t,noteObj:s[0].noteObj,noteYPos:0,accidentalOffset:r,cursorOffset:o}}}const p="http://www.w3.org/2000/svg",k=.1,S=1200;class O{rootElementRef;svgElementRef;parentGroupContainer;musicStaffLayer;musicNotesLayer;musicUILayer;width;scale;totalYOffset=0;totalHeight=0;constructor(e,t){this.rootElementRef=e,this.width=t.width,this.scale=t.scale,this.width>S&&(this.width=S,console.warn(`Width provided for the staff ${this.width} exceeds the limit ${S}. Please use this value to fix positioning issues.`)),this.svgElementRef=document.createElementNS(p,"svg"),this.svgElementRef.classList.add("vs-svg-renderer-root"),this.svgElementRef.style.maxWidth="100%",this.svgElementRef.style.height="auto",this.svgElementRef.style.display="block",this.svgElementRef.setAttribute("color",t.staffColor),this.svgElementRef.style.backgroundColor=t.staffBackgroundColor,this.makeGlyphDefs(t.useGlyphs),this.parentGroupContainer=this.createGroup("svg-renderer-parent"),this.svgElementRef.appendChild(this.parentGroupContainer),this.musicStaffLayer=this.createGroup("music-staff-layer"),this.musicNotesLayer=this.createGroup("music-notes-layer"),this.musicUILayer=this.createGroup("music-ui-layer"),this.parentGroupContainer.appendChild(this.musicStaffLayer),this.parentGroupContainer.appendChild(this.musicNotesLayer),this.parentGroupContainer.appendChild(this.musicUILayer),this.musicNotesLayer.setAttribute("transform","translate(38, 0)")}makeGlyphDefs(e){const t=document.createElementNS(p,"defs");Object.entries(U).filter(([r])=>e.includes(r)).forEach(([r,o])=>{const n=document.createElementNS(p,"path");n.setAttribute("id",`glyph-${r}`),n.setAttribute("d",o.path),n.setAttribute("fill","currentColor"),n.setAttribute("transform",`translate(${o.xOffset}, ${o.yOffset}) scale(${k})`),t.appendChild(n)}),this.rootSvgElement.appendChild(t)}createGroup(e){const t=document.createElementNS(p,"g");return e&&t.classList.add(`vs-${e}`),t}commitElementsToDOM(e,t=this.rootElementRef){const s=document.createDocumentFragment();Array.isArray(e)?e.forEach(r=>{s.appendChild(r)}):s.appendChild(e),t.appendChild(s)}getLayerByName(e){switch(e){case"staff":return this.musicStaffLayer;case"notes":return this.musicNotesLayer;case"ui":return this.musicUILayer;default:throw new Error(`Layer with name '${e}' does not exist.`)}}addTotalRootSvgHeight(e){this.totalHeight+=e}addTotalRootSvgYOffset(e){this.totalYOffset+=e}applySizingToRootSvg(){this.parentGroupContainer.setAttribute("transform",`translate(0, ${this.totalYOffset})`);let e=this.width*this.scale;const t=(this.totalHeight+this.totalYOffset)*this.scale;e+=2,this.svgElementRef.setAttribute("width",e.toString()),this.svgElementRef.setAttribute("height",t.toString()),this.svgElementRef.setAttribute("viewBox",`0 0 ${this.width} ${this.totalHeight+this.totalYOffset}`)}get rootSvgElement(){return this.svgElementRef}get parentGroupElement(){return this.parentGroupContainer}drawLine(e,t,s,r,o){const n=document.createElementNS(p,"line");n.setAttribute("x1",e.toString()),n.setAttribute("y1",t.toString()),n.setAttribute("x2",s.toString()),n.setAttribute("y2",r.toString()),n.setAttribute("stroke","currentColor"),n.setAttribute("stroke-width","1"),o.appendChild(n)}drawRect(e,t,s,r){const o=document.createElementNS(p,"rect");return o.setAttribute("width",e.toString()),o.setAttribute("height",t.toString()),o.setAttribute("x",(r?.x??0).toString()),o.setAttribute("y",(r?.y??0).toString()),r?.fill?o.setAttribute("fill",r.fill):o.setAttribute("fill","currentColor"),s.appendChild(o),o}drawGlyph(e,t,s){s={xOffset:0,yOffset:0,...s};const r=document.createElementNS(p,"use");r.setAttribute("href",`#glyph-${e}`),(s.xOffset||s.yOffset)&&r.setAttribute("transform",`translate(${s.xOffset}, ${s.yOffset})`),t.appendChild(r)}destroy(){this.rootElementRef&&this.svgElementRef&&this.rootElementRef.contains(this.svgElementRef)&&this.rootElementRef.removeChild(this.svgElementRef)}}const W=["CLEF_TREBLE","CLEF_BASS","CLEF_ALTO","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","EIGHTH_NOTE_FLIPPED","ACCIDENTAL_SHARP","ACCIDENTAL_FLAT","ACCIDENTAL_NATURAL","ACCIDENTAL_DOUBLE_SHARP","ACCIDENTAL_DOUBLE_FLAT"];class Z{svgRendererInstance;strategyInstance;noteRendererInstance;options;noteEntries=[];noteCursorX=0;constructor(e,t){this.options={width:300,scale:1,staffType:"treble",spaceAbove:0,spaceBelow:0,staffColor:"black",staffBackgroundColor:"transparent",...t},this.svgRendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:W});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new H(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new A(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new A(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new A(this.svgRendererInstance,"alto");break;default:throw new Error(`The staff type ${this.options.staffType} is not supported. Please use "treble", "bass", "alto", or "grand".`)}if(this.strategyInstance.drawStaff(this.options.width),this.noteRendererInstance=new P(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const r=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(r)}if(this.options.spaceBelow){let r=this.options.spaceBelow*10;this.options.staffType==="grand"&&(r-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(r)}this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.svgRendererInstance.getLayerByName("notes"),r=[];for(const o of t){let n;try{n=this.noteRendererInstance.renderNote(o)}catch(a){throw r.length>0&&this.svgRendererInstance.commitElementsToDOM(r,s),a}n.noteGroup.setAttribute("transform",`translate(${this.noteCursorX+n.accidentalOffset}, ${n.noteYPos})`),this.noteEntries.push({gElement:n.noteGroup,note:n.noteObj,xPos:this.noteCursorX+n.accidentalOffset,yPos:n.noteYPos,accidentalXOffset:n.accidentalOffset}),this.noteCursorX+=28+n.accidentalOffset,r.push(n.noteGroup)}this.svgRendererInstance.commitElementsToDOM(r,s)}drawChord(e){if(e.length<2)throw new Error("Provide more than one note for a chord.");const t=this.svgRendererInstance.getLayerByName("notes"),s=this.noteRendererInstance.renderChord(e);s.noteGroup.setAttribute("transform",`translate(${this.noteCursorX+s.accidentalOffset}, 0)`),this.noteEntries.push({gElement:s.noteGroup,note:m(e[0]),xPos:this.noteCursorX+s.accidentalOffset,yPos:0,accidentalXOffset:s.accidentalOffset}),this.noteCursorX+=28+s.accidentalOffset+s.cursorOffset,this.svgRendererInstance.commitElementsToDOM(s.noteGroup,t)}justifyNotes(){const e=this.options.width-38,t=this.noteEntries.length;if(t<=0||e<=0)return;const s=Math.round(e/t);this.noteEntries.map((o,n)=>{const a=(n+.5)*s,i=o.gElement.getBBox(),c=a-i.width/2-i.x,l=Math.round(c*10)/10;return{entry:o,newX:l,isChord:o.gElement.classList.contains("chord")}}).forEach(o=>{const{entry:n,newX:a,isChord:i}=o;i?n.gElement.setAttribute("transform",`translate(${a}, 0)`):n.gElement.setAttribute("transform",`translate(${a}, ${n.yPos})`),n.xPos=a})}clearAllNotes(){this.noteCursorX=0,this.svgRendererInstance.getLayerByName("notes").replaceChildren(),this.noteEntries=[]}changeNoteByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Note index was out of bounds.");const s=this.noteEntries[t],r=this.noteRendererInstance.renderNote(e),n=s.xPos-s.accidentalXOffset+r.accidentalOffset;r.noteGroup.setAttribute("transform",`translate(${n}, ${r.noteYPos})`),this.svgRendererInstance.getLayerByName("notes").replaceChild(r.noteGroup,s.gElement),this.noteEntries[t]={gElement:r.noteGroup,note:r.noteObj,xPos:n,yPos:r.noteYPos,accidentalXOffset:r.accidentalOffset}}changeChordByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Chord index was out of bounds.");if(e.length<2)throw new Error("Notes provided need to be more than one to be considered a chord.");const s=this.noteEntries[t],r=this.noteRendererInstance.renderChord(e),n=s.xPos-s.accidentalXOffset+r.accidentalOffset;r.noteGroup.setAttribute("transform",`translate(${n}, 0)`),this.svgRendererInstance.getLayerByName("notes").replaceChild(r.noteGroup,s.gElement),this.noteEntries[t]={gElement:r.noteGroup,note:m(e[0]),xPos:n,yPos:0,accidentalXOffset:r.accidentalOffset}}addClassToNoteByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Note index was out of bounds.");this.noteEntries[t].gElement.classList.add(e)}removeClassToNoteByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Note index was out of bounds.");this.noteEntries[t].gElement.classList.remove(e)}destroy(){this.noteEntries=[],this.svgRendererInstance.destroy()}}const u=30,X=19,y=12,V=4,j=6,x=1,R=38,q=["TIME_4","TIME_3","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","REST_WHOLE","REST_HALF","REST_QUARTER","REST_EIGHTH"];class Q{rendererInstance;options;barSpacing;quarterNoteSpacing;noteCursorX=0;noteEntries=[];maxBeatCount;currentBeatCount=0;currentBeatUICount=0;currentBeatUIElement=null;currentBeatUIXPos=R;constructor(e,t){this.options={width:300,scale:1,topNumber:4,barsCount:2,spaceAbove:0,spaceBelow:0,staffColor:"black",staffBackgroundColor:"white",currentBeatUIColor:"#24ff7450",...t},this.rendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:q});const s=this.rendererInstance.rootSvgElement;let r="TIME_4";switch(this.options.topNumber){case 3:r="TIME_3";break;case 4:r="TIME_4";break;default:throw new Error(`Time signature ${this.options.topNumber} not supported. Please use either 3 or 4.`)}if(this.options.barsCount<1||this.options.barsCount>3)throw new Error(`Bars count ${this.options.barsCount} not supported. Please use 1 - 3`);if(this.options.spaceAbove){const _=this.options.spaceAbove*10;this.rendererInstance.addTotalRootSvgYOffset(_)}if(this.options.spaceBelow){let _=this.options.spaceBelow*10;this.rendererInstance.addTotalRootSvgHeight(_)}const o=this.rendererInstance.getLayerByName("staff");this.rendererInstance.addTotalRootSvgHeight(u*2);const n=this.rendererInstance.createGroup("time-signature");o.appendChild(n);const a=u-X;this.rendererInstance.drawGlyph(r,n),this.rendererInstance.drawGlyph("TIME_4",n,{yOffset:X}),n.setAttribute("transform",`translate(0, ${a})`);let i=this.options.width-38;this.options.barsCount>1&&(i-=(this.options.barsCount-1)*y),i-=x,this.rendererInstance.drawLine(0,u,this.options.width-x,u,o),this.barSpacing=i/this.options.barsCount,this.quarterNoteSpacing=Math.round(this.barSpacing/this.options.topNumber),this.maxBeatCount=this.options.barsCount*this.options.topNumber;let c=this.barSpacing+38;const l=u/2,f=u+l;for(let _=0;_<this.options.barsCount-1;_++)this.rendererInstance.drawLine(c,l,c,f,o),c+=this.barSpacing;this.rendererInstance.getLayerByName("notes").setAttribute("transform",`translate(38, ${u})`),this.rendererInstance.applySizingToRootSvg(),this.rendererInstance.commitElementsToDOM(s)}createBeatUIElement(){const e=this.rendererInstance.getLayerByName("ui");this.currentBeatUIElement=this.rendererInstance.drawRect(this.quarterNoteSpacing/2,u*2,e,{x:R,fill:this.options.currentBeatUIColor})}handleNewBar(){this.noteCursorX+=y}translateGroupByDuration(e,t){return t.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.quarterNoteSpacing*e}drawStem(e,t){this.rendererInstance.drawLine(10+(t??0),0,10+(t??0),-28,e)}renderNote(e,t){switch(e){case"w":this.rendererInstance.drawGlyph("NOTE_HEAD_WHOLE",t);break;case"h":this.rendererInstance.drawGlyph("NOTE_HEAD_HALF",t),this.drawStem(t);break;case"q":this.rendererInstance.drawGlyph("NOTE_HEAD_QUARTER",t),this.drawStem(t);break;case"e":this.rendererInstance.drawGlyph("EIGHTH_NOTE",t),this.drawStem(t);break}}renderRest(e,t){switch(e){case"w":this.rendererInstance.drawGlyph("REST_WHOLE",t);break;case"h":this.rendererInstance.drawGlyph("REST_HALF",t);break;case"q":this.rendererInstance.drawGlyph("REST_QUARTER",t);break;case"e":this.rendererInstance.drawGlyph("REST_EIGHTH",t);break}}checkAndCreateNewBar(){const e=this.currentBeatCount>0&&this.currentBeatCount%this.options.topNumber===0,t=this.currentBeatCount<this.maxBeatCount;e&&t&&this.handleNewBar()}checkAndFillBarWithRests(e){const t=this.options.topNumber-this.currentBeatCount%this.options.topNumber;if(e>t){const s=this.createRemainingRests(t);return this.handleNewBar(),s}return null}createRemainingRests(e){const t=[];let s=e;for(;s>0;){const r=this.rendererInstance.createGroup("rest");let o=0;s-E.h>=0?(this.rendererInstance.drawGlyph("REST_HALF",r),o=E.h):s-E.q>=0?(this.rendererInstance.drawGlyph("REST_QUARTER",r),o=E.q):(this.rendererInstance.drawGlyph("REST_EIGHTH",r),o=E.e),s-=o,this.currentBeatCount+=o,r.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=o*this.quarterNoteSpacing,t.push(r)}return t}renderBeamRect(e,t,s,r){this.rendererInstance.drawRect(e-t,V,s,{x:10,y:-28+(r??0),fill:this.options.staffColor})}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayerByName("notes"),r=[];for(const o of t){let n="w";try{n=C(o)}catch(f){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),f}const a=E[n];if(this.currentBeatCount>=this.maxBeatCount)throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),new Error("Max beat count reached. Can't add additional notes.");this.checkAndCreateNewBar();const i=this.checkAndFillBarWithRests(a);i&&i.forEach(f=>{r.push(f),this.noteEntries.push(f)});const c=this.rendererInstance.createGroup("note"),l=this.translateGroupByDuration(a,c);this.noteCursorX+=l,this.currentBeatCount+=a,this.renderNote(n,c),r.push(c),this.noteEntries.push(c)}this.rendererInstance.commitElementsToDOM(r,s)}drawRest(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayerByName("notes"),r=[];for(const o of t){let n="w";try{n=C(o)}catch(f){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),f}const a=this.rendererInstance.createGroup("rest"),i=E[n],c=i*this.quarterNoteSpacing;if(this.currentBeatCount>=this.maxBeatCount)throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),new Error("Max beat count reached. Can't add additional notes.");this.checkAndCreateNewBar();const l=this.checkAndFillBarWithRests(i);l&&l.forEach(f=>{r.push(f),this.noteEntries.push(f)}),this.renderRest(n,a),a.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=c,this.currentBeatCount+=i,r.push(a),this.noteEntries.push(a)}this.rendererInstance.commitElementsToDOM(r,s)}drawBeamedNotes(e,t){if(t<2)throw new Error("Must provide a value greater than 2 for beamed note.");if(this.currentBeatCount>=this.maxBeatCount)throw new Error("Max beat count reached. Can't add additional beamed note.");let s="s";e==="s"?s="s":s=C(e),this.checkAndCreateNewBar();const r=this.rendererInstance.getLayerByName("notes"),o=E[s],n=o*this.quarterNoteSpacing,a=this.options.topNumber-this.currentBeatCount%this.options.topNumber,i=Math.min(t,a/o),c=this.rendererInstance.createGroup("beamed-note");c.setAttribute("transform",`translate(${this.noteCursorX}, 0)`);let l=0;for(let f=0;f<i;f++)this.rendererInstance.drawGlyph("NOTE_HEAD_QUARTER",c,{xOffset:l}),this.drawStem(c,l),l+=n,this.currentBeatCount+=o;this.renderBeamRect(l,n,c),e==="s"&&this.renderBeamRect(l,n,c,j),this.noteCursorX+=l,this.noteEntries.push(c),this.rendererInstance.commitElementsToDOM(c,r)}incrementCurrentBeatUI(){if(this.currentBeatUIElement||this.createBeatUIElement(),this.currentBeatUICount>=this.maxBeatCount){this.currentBeatUIElement.setAttribute("display","none");return}this.currentBeatUIElement?.getAttribute("display")==="none"&&this.currentBeatUIElement.removeAttribute("display"),this.currentBeatUICount++,this.currentBeatUICount>this.options.topNumber&&this.currentBeatUICount%this.options.topNumber===1&&(this.currentBeatUIXPos+=y),this.currentBeatUICount>1&&(this.currentBeatUIXPos+=this.quarterNoteSpacing),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString())}resetCurrentBeatUI(){this.currentBeatUICount=0,this.currentBeatUIXPos=R,this.currentBeatUIElement&&(this.currentBeatUIElement.setAttribute("display","none"),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString()))}clearAllNotes(){this.noteCursorX=0,this.currentBeatCount=0,this.rendererInstance.getLayerByName("notes").replaceChildren(),this.noteEntries=[]}destroy(){this.noteEntries=[],this.rendererInstance.destroy()}}const z=["CLEF_TREBLE","CLEF_BASS","CLEF_ALTO","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","EIGHTH_NOTE_FLIPPED","ACCIDENTAL_SHARP","ACCIDENTAL_FLAT","ACCIDENTAL_NATURAL","ACCIDENTAL_DOUBLE_SHARP","ACCIDENTAL_DOUBLE_FLAT"],N=60,K=N;class J{svgRendererInstance;strategyInstance;noteRendererInstance;options;activeEntries=[];noteBuffer=[];notesLayer;noteCursorX=0;constructor(e,t){this.options={width:300,scale:1,staffType:"treble",spaceAbove:0,spaceBelow:0,staffColor:"black",staffBackgroundColor:"transparent",...t},this.svgRendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:z});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new H(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new A(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new A(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new A(this.svgRendererInstance,"alto");break;default:throw new Error(`The staff type ${this.options.staffType} is not supported. Please use "treble", "bass", "alto", or "grand".`)}if(this.strategyInstance.drawStaff(this.options.width),this.noteRendererInstance=new P(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const r=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(r)}if(this.options.spaceBelow){let r=this.options.spaceBelow*10;this.options.staffType==="grand"&&(r-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(r)}this.notesLayer=this.svgRendererInstance.getLayerByName("notes"),this.notesLayer.classList.add("vs-scrolling-notes-layer"),this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}renderFirstNoteGroups(){const e=this.options.width-38+K;for(;this.noteBuffer.length>0&&this.noteCursorX<e;)this.renderNextNote(),this.noteCursorX+=N;this.activeEntries.length>1&&(this.noteCursorX-=N)}renderNextNote(){if(this.noteBuffer.length<1)return;const e=this.noteBuffer[0],t=this.svgRendererInstance.createGroup("note-wrapper");if(e.type==="chord"){const s=this.noteRendererInstance.renderChord(e.notes);s.noteGroup.setAttribute("transform",`translate(0, ${s.noteYPos})`),t.appendChild(s.noteGroup)}else{const s=this.noteRendererInstance.renderNote(e.notes[0]);s.noteGroup.setAttribute("transform",`translate(0, ${s.noteYPos})`),t.appendChild(s.noteGroup)}t.style.transform=`translate(${this.noteCursorX}px, 0px)`,this.activeEntries.push({noteWrapper:t,xPos:this.noteCursorX}),this.noteBuffer.shift(),this.notesLayer.appendChild(t)}queueNotes(e){this.clearAllNotes();for(const t of e)Array.isArray(t)?this.noteBuffer.push({type:"chord",notes:t}):this.noteBuffer.push({type:"note",notes:[t]});this.renderFirstNoteGroups()}advanceNotes(){if(this.activeEntries.length<=0){this.clearAllNotes(),this.options.onNotesOut&&this.options.onNotesOut();return}this.activeEntries.forEach(t=>{t.xPos-=N,t.noteWrapper.style.transform=`translate(${t.xPos}px, 0px)`});const e=this.activeEntries[0];e.xPos<=0&&(this.notesLayer.removeChild(e.noteWrapper),this.activeEntries.shift()),this.renderNextNote()}clearAllNotes(){this.noteCursorX=0,this.notesLayer.replaceChildren(),this.activeEntries=[],this.noteBuffer=[]}destroy(){this.svgRendererInstance.destroy(),this.activeEntries=[],this.noteBuffer=[]}}d.MusicStaff=Z,d.RhythmStaff=Q,d.ScrollingStaff=J,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(d,I){typeof exports=="object"&&typeof module<"u"?I(exports):typeof define=="function"&&define.amd?define(["exports"],I):(d=typeof globalThis<"u"?globalThis:d||self,I(d.VectorScore={}))})(this,(function(d){"use strict";const w={treble:{staffType:"treble",paddingTop:13,paddingBottom:3,topLineNote:{name:"F",octave:5},topLineYPos:0,bottomLineYPos:40},bass:{staffType:"bass",paddingTop:0,paddingBottom:0,topLineNote:{name:"A",octave:3},topLineYPos:0,bottomLineYPos:40},alto:{staffType:"alto",paddingTop:0,paddingBottom:0,topLineNote:{name:"G",octave:4},topLineYPos:0,bottomLineYPos:40},grand:{staffType:"grand",paddingTop:13,paddingBottom:0,topLineNote:{name:"F",octave:5},topLineYPos:0,bottomLineYPos:110}},E={w:4,h:2,q:1,e:.5,s:.25},U={CLEF_TREBLE:{path:"m150 273 10 58c2 7 2 7 12 7 59 0 96 46 96 97 0 45-26 79-67 95-5 2-6 2-5 7 4 25 12 63 12 85 0 68-52 80-79 80-61 0-76-39-76-65 0-25 16-46 43-46 24 0 38 19 38 41 0 23-14 34-27 38-9 2-13 4-13 6 0 6 11 12 32 12 24 0 64-7 64-66 0-19-6-54-11-81-1-5-1-4-6-3l-27 2C48 540 0 474 0 404c0-80 61-138 119-185 5-4 4-5 3-10-2-16-5-42-5-65 0-42 9-92 39-125 8-9 20-19 26-19 4 0 15 11 21 20 16 24 26 58 26 93 0 61-33 112-76 153-3 2-3 2-3 7Zm38-211c-24 0-53 38-53 101l2 37c1 5 3 5 5 3 32-28 70-64 70-108 0-22-11-33-24-33Zm-44 272-8-51c-1-4-2-5-6-1-18 15-37 30-61 56-33 38-37 70-37 93 0 56 45 95 115 95l23-2c6-2 6-2 5-6l-20-119c-1-5-1-5-8-3-24 6-40 24-40 46 0 19 12 36 29 43 3 1 6 3 6 5 0 3-2 5-5 5l-11-3c-27-9-46-34-46-70 0-34 23-66 58-78 8-2 8-2 6-10Zm28 64 20 114c0 5 1 5 6 2 22-11 38-31 38-56 0-36-27-63-60-66-4 0-5 1-4 6Z",xOffset:0,yOffset:-14},CLEF_BASS:{path:"M101 0c68 0 110 46 110 114 0 120-102 190-199 237l-7 2c-3 0-5-2-5-5s2-5 6-7c92-52 146-114 146-223 0-62-18-103-60-103-40 0-64 29-64 44 0 4 1 8 7 8 5 0 9-3 19-3 20 0 38 15 38 41 0 24-17 41-42 41-32 0-48-27-48-58C2 50 33 0 101 0Zm148 32c13 0 22 10 22 22s-9 22-22 22c-12 0-21-10-21-22s9-22 21-22Zm1 99c12 0 21 9 21 21s-9 22-21 22-21-10-21-22 9-21 21-21Z",xOffset:0,yOffset:0},CLEF_ALTO:{path:"M91 9v174c0 3 2 2 3 2 11-3 27-13 36-58 1-6 3-10 7-10s6 4 8 11c5 17 15 37 43 37 25 0 32-25 32-77s-9-75-42-75c-5 0-33 2-33 10 0 2 6 5 11 6 7 3 15 11 15 26 0 17-11 27-26 27-17 0-31-11-31-32 0-25 22-50 69-50 65 0 93 45 93 87 0 54-30 92-83 92-11 0-18-2-24-4-4-1-8-1-11 1-6 3-14 16-14 24s8 21 14 24c3 2 7 2 11 1 6-2 13-4 24-4 53 0 83 38 83 92 0 42-28 87-93 87-47 0-69-25-69-50 0-21 14-32 31-32 15 0 26 10 26 27 0 15-8 23-15 26-5 1-11 4-11 6 0 8 28 10 33 10 33 0 42-23 42-75s-7-77-32-77c-28 0-38 20-43 37-2 7-4 11-8 11s-6-4-7-10c-9-45-25-55-36-58-1 0-3-1-3 2v174c0 5-3 8-8 8h-1c-5 0-8-3-8-8V9c0-5 3-8 8-8h1c5 0 8 3 8 8ZM8 1h34c6 0 9 3 9 8v382c0 5-3 8-9 8H8c-5 0-8-3-8-8V9c0-5 3-8 8-8Z",xOffset:0,yOffset:0},NOTE_HEAD_WHOLE:{path:"M77 0c34 0 74 19 74 45 0 24-19 45-77 45C21 90 0 68 0 45 0 20 30 0 77 0Zm-9 8c-17 0-30 5-30 24 0 22 23 50 47 50 16 0 28-8 28-26 0-21-20-48-45-48Z",xOffset:0,yOffset:-4.5},NOTE_HEAD_HALF:{path:"M35 90C15 90 0 79 0 60 0 42 17 0 70 0c21 0 36 12 36 30 0 12-12 60-71 60Zm-8-14c18 0 68-31 68-47l-2-6c-3-5-7-8-14-8-17 0-68 29-68 46l2 7c2 4 7 8 14 8Z",xOffset:0,yOffset:-4.5},NOTE_HEAD_QUARTER:{path:"M35 90C16 90 0 79 0 60 0 29 32 0 71 0c20 0 35 12 35 30 0 30-40 60-71 60Z",xOffset:0,yOffset:-4.5},EIGHTH_NOTE:{path:"M142 89c20 32 36 70 36 110 0 25-8 55-8 55-2 5-5 7-8 6h-1c-2-1-5-4-5-9l1-5c5-14 8-29 8-44 0-19-3-37-8-48-10-23-33-58-53-70v179c0 30-38 60-70 60-19 0-34-11-34-30 0-31 31-60 70-60 11 0 19 3 25 8V3c0-2 2-3 3-3 6 0 9 2 10 7 5 31 18 57 34 82Z",xOffset:0,yOffset:-28},EIGHTH_NOTE_FLIPPED:{path:"M9 323H0V60C0 29 32 0 71 0c20 0 35 12 35 30 0 30-40 60-71 60-19 0-26-9-26-9v158s58-56 58-89c0 0 0-25-8-43-5-12 10-17 14-6 13 34 9 48 9 48 0 39-41 97-41 97-20 27-32 77-32 77Z",xOffset:0,yOffset:-4},REST_WHOLE:{path:"M0 0h104v53H0V0Z",xOffset:0,yOffset:0},REST_HALF:{path:"M0 0h104v53H0V0Z",xOffset:0,yOffset:-5},REST_QUARTER:{path:"m28 151-18-22s-3-4-3-9c0-3 1-7 5-11 16-17 22-33 22-46 0-27-21-45-23-49l-1-6c0-5 4-8 7-8s5 1 7 3l61 71 1 7-1 5c-10 15-23 34-25 55v3c0 20 11 35 25 52 4 4 14 16 14 20 0 2-2 2-5 1-6-2-19-6-29-6-16 0-23 12-23 27 0 8 5 22 11 22 3 3 6 6 6 9s-2 5-7 5l-9-3c-27-21-43-39-43-57s13-35 32-35c3 0 10 3 14 0l-2-6-16-22Z",xOffset:0,yOffset:-16},REST_EIGHTH:{path:"M61 35c18 0 41-35 47-32 0 1 5 3 5 8l-5 17S64 189 62 190c-4 4-11 5-16 5-3 0-13 0-13-6 8-30 41-122 42-128 1-5 1-10-1-10-4 0-3 3-19 8C16 71 0 46 0 31 0 14 14 0 31 0c5 0 30 1 30 35Z",xOffset:0,yOffset:-10},ACCIDENTAL_SHARP:{path:"m67 66-8 3c-2 0-3 6-3 8v26c0 4 2 5 3 5l8-2 1-1c1 0 2 1 2 3v20c0 1-1 4-3 4l-8 4c-2 0-3 4-3 6v40c0 2-2 4-5 4-2 0-4-2-4-4v-35c0-2-1-5-4-5h-1l-17 7c-1 1-3 3-3 6v40c0 2-1 3-4 3-2 0-4-1-4-3v-35c0-1-1-5-3-5l-1 1-7 2v1c-2 0-3-1-3-3v-20c0-2 1-4 3-5l8-3c2-1 3-3 3-6V94c0-3-2-5-4-5l-7 3c-2 0-3-1-3-3V69l3-4 8-3c1-1 3-4 3-8V16c0-2 2-4 5-4 2 0 3 2 3 4v34c0 2 1 5 4 5l18-7c2-1 3-5 3-8V3c0-2 2-3 5-3 2 0 4 1 4 3v35c0 2 2 3 4 3l7-2h1c1 0 2 0 2 2v20c0 2-1 4-3 5Zm-20 46c2-11 2-23 0-34l-4-2c-7 0-20 6-21 11v35l4 1c6 0 20-5 21-11Z",xOffset:-8,yOffset:-10},ACCIDENTAL_FLAT:{path:"M4 196C1 193 0 9 0 9c0-6 5-9 10-9 3 0 6 2 6 5l-2 91c0 3 1 5 3 6h2l7-4c5-3 12-6 18-6 15 1 29 13 29 31 0 15-10 35-39 55-8 5-16 14-25 19l-2 1c-1 0-2 0-3-2Zm11-28c0 1 1 5 4 5l3-1c14-9 29-27 29-44 0-8-4-19-14-19-7 0-20 10-22 16l-1 10 1 33Z",xOffset:-8,yOffset:-14},ACCIDENTAL_NATURAL:{path:"m41 47 5-2h1l2 2v147c0 3-2 4-3 4h-4c-2 0-4-1-4-4v-43c0-2-2-3-5-3-8 0-25 7-29 8l-1 1c-2 0-3-1-3-3V4c0-3 1-4 4-4h3c2 0 4 1 4 4v48c0 2 1 2 3 2 7 0 26-7 26-7h1ZM11 88v31l3 1c8 0 24-6 24-12V78l-2-1c-7 0-25 7-25 11Z",xOffset:-8,yOffset:-10},ACCIDENTAL_DOUBLE_SHARP:{path:"M68 33h3c6 0 13 0 15-2l2-15C88 4 86 0 72 0c-6 0-12 1-14 4-2 1-2 7-2 13-1 5-8 17-12 17-5 0-9-10-11-15l-1-2c0-6-1-12-3-13-2-3-8-4-13-4C10 0 4 1 2 4L0 17l2 14c2 2 9 2 15 2h4c5 2 16 8 16 12 0 3-13 10-17 12h-3c-6 0-13 1-15 3L0 74l2 14 14 2 13-2c2-2 3-8 3-14 1-5 7-17 12-17 4 0 10 13 12 17 0 6 0 12 2 14l14 2c15 0 16-2 16-17l-2-13c-4-2-11-3-15-3h-3c-5-2-17-7-17-12 0-2 13-10 17-12Z",xOffset:-10,yOffset:-4},ACCIDENTAL_DOUBLE_FLAT:{path:"M102 93h2c15 0 29 12 29 30 0 15-10 35-39 55-8 5-16 14-26 19l-2 1-2-2-3-43c-6 7-15 16-27 25-7 5-15 14-25 19l-2 1c-1 0-2 0-3-2C2 193 0 8 0 8c0-5 6-8 10-8 3 0 6 2 6 5l-2 91c0 3 1 5 3 6h2c3 0 5-3 8-4 5-3 9-5 15-5h2c6 0 12 1 17 5L60 8c0-5 5-8 10-8 3 0 6 2 6 5l-2 91c0 3 1 5 3 6h2c3 0 5-3 7-4 6-3 10-5 16-5Zm-80 78c14-9 29-25 29-43 0-8-3-19-13-19-8 0-21 10-23 16l-1 11 1 31c0 2 1 5 4 5l3-1Zm59 0c15-9 29-25 29-43 0-6-2-12-5-16-2-2-4-3-8-3-7 0-21 10-23 16v8l1 34c0 2 1 5 3 5l3-1Z",xOffset:-14,yOffset:-14},TIME_4:{path:"M53 0h66S70 76 20 124h61V86l47-50v89h22v19h-22v27c0 9 13 9 13 9h9v10H61v-10h10s10 0 10-10v-26H0v-20S54 67 53 0Z",xOffset:0,yOffset:0},TIME_3:{path:"M2 43c0 21 15 30 30 30 5 0 28-2 28-27 0-11-16-20-16-24 0-14 56-15 56 26 0 26-19 38-31 38H45v13h24c12 0 33 15 33 41 0 38-54 40-54 25 0-3 10-11 10-21 0-20-15-27-27-27-17 0-32 8-31 30 1 30 36 43 75 43 36 0 75-19 75-50 0-34-23-47-37-47v-2c4 0 35-13 35-39 0-37-35-52-75-52C39 0 3 14 2 43Z",xOffset:0,yOffset:0}},M=/^(?<name>[A-Ga-g])(?<accidental>##|bb|[#bn]?)(?<octave>\d)(?<duration>[whqeWHQE]?)$/,Y=/^[whqeWHQE]$/,T=["C","D","E","F","G","A","B"];function m(h){const e=h.match(M);if(!e||!e.groups)throw new Error(`Invalid note string format: ${h}. Expected format: [A-Ga-g][#|b]?[0-9][w|h|q|e].`);let{name:t,accidental:s,octave:r,duration:o}=e.groups;if(t=t.toUpperCase(),o=o.toLowerCase(),!t)throw new Error(`Invalid note name: ${t}. Valid note names are: C, D, E, F, G, A, B.`);if(!r)throw new Error(`Invalid octave: ${r}. Octave must be a number between 0 and 9.`);o||(o="w");const n={name:t,octave:parseInt(r),duration:o};return s&&(n.accidental=s),n}function C(h){const e=h.match(Y);if(!e)throw new Error(`Invalid note duration '${h}'. Use w | h | q | e.`);return e.toString().toLowerCase()}function L(h){let e;switch(h){case"treble":e="CLEF_TREBLE";break;case"bass":e="CLEF_BASS";break;case"alto":e="CLEF_ALTO";break}if(!e)throw new Error(`Invalid clef type: ${h}. Valid clef types are: treble, bass, alto.`);return e}function b(h,e){const t=T.indexOf(h.name)-T.indexOf(e.name);let s=h.octave-e.octave;return s*=7,t+s}function F(h){let e=T.indexOf(h.name);return e+=h.octave*12,e}function v(h,e){return T.findIndex(s=>s===h)+1+e*7}const g=48,G=40+30/2,B=20,D=90;class H{params;rendererRef;width=0;constructor(e,t){this.rendererRef=e;const s=w[t];if(!s)throw new Error(`Staff type ${t} is not supported`);this.params=s}drawStaffLines=(e,t)=>{let s=e;for(let r=0;r<5;r++)this.rendererRef.drawLine(0,s,this.width,s,t),s+=10;return s-10};drawStaff=e=>{this.width=e;const t=this.rendererRef.getLayerByName("staff");let s=this.drawStaffLines(0,t),r=this.drawStaffLines(s+30,t);this.rendererRef.drawLine(0,0,0,r,t),this.rendererRef.drawLine(this.width,0,this.width,r,t);let o=r,n=1;const a=L("treble"),i=L("bass");this.rendererRef.drawGlyph(a,t),this.rendererRef.drawGlyph(i,t,{yOffset:s+30}),o+=this.params.paddingBottom+1,n+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(o),this.rendererRef.addTotalRootSvgYOffset(n)};shouldNoteFlip(e){const t=Math.abs(e-D),s=Math.abs(e-B);return e===G?!1:t<=s?!(e>=D):e<=B}getLedgerLinesX(e,t){const s=[],r=F(e);let o=e.duration==="w"?17:12.5;if(r===g)return s.push({x1:-2,x2:o,yPos:0}),s;if(t<this.params.topLineYPos){let n=this.params.topLineYPos-10;for(;n>=t;)s.push({x1:-2,x2:o,yPos:n-t}),n-=10}else if(t>this.params.bottomLineYPos){let n=this.params.bottomLineYPos+10;for(;n<=t;)s.push({x1:-2,x2:o,yPos:n-t}),n+=10}return s}calculateNoteYPos=e=>{let s=b(this.params.topLineNote,e)*(10/2);const r=F(e);return r<g?s+=10:r===g&&(s=G),s}}const $=20;class A{params;rendererRef;constructor(e,t){this.rendererRef=e;const s=w[t];if(!s)throw new Error(`Staff type ${t} is not supported`);this.params=s}drawStaff=e=>{const t=this.rendererRef.getLayerByName("staff");let s=0;for(let a=0;a<5;a++)this.rendererRef.drawLine(0,s,e,s,t),s+=10;this.rendererRef.drawLine(0,0,0,s-10,t),this.rendererRef.drawLine(e,0,e,s-10,t);let r=s-10+1,o=1;const n=L(this.params.staffType);this.rendererRef.drawGlyph(n,t),r+=this.params.paddingTop+this.params.paddingBottom,o+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(r),this.rendererRef.addTotalRootSvgYOffset(o)};shouldNoteFlip(e){return e<=$}getLedgerLinesX(e,t){const s=[];let r=e.duration==="w"?17:12.5;if(t<this.params.topLineYPos){let o=this.params.topLineYPos-10;for(;o>=t;)s.push({x1:-2,x2:r,yPos:o-t}),o-=10}else if(t>this.params.bottomLineYPos){let o=this.params.bottomLineYPos+10;for(;o<=t;)s.push({x1:-2,x2:r,yPos:o-t}),o+=10}return s}calculateNoteYPos=e=>b(this.params.topLineNote,e)*(10/2)}class P{svgRendererInstance;strategyInstance;constructor(e,t){this.svgRendererInstance=e,this.strategyInstance=t}drawStem(e,t){t?this.svgRendererInstance.drawLine(0,0,0,28,e):this.svgRendererInstance.drawLine(10,0,10,-28,e)}chordOffsetConsecutiveAccidentals(e){let t=0,s=0,r=0;for(let o=0;o<e.length;o++){const n=e[o];if(n.noteObj.accidental&&r<3?(t+=-8,s=Math.min(s,t),r++):n.noteObj.accidental&&r<=3?(t=-8,r=1):(t=0,r=0),t!==0){const i=Array.from(n.noteGroup.getElementsByTagName("use")).find(c=>c.getAttribute("href")?.includes("ACCIDENTAL"));if(!i)continue;i.setAttribute("transform",`translate(${t+8}, 0)`)}}return-s}chordOffsetCloseNotes(e){let t=e[0],s=0;for(let r=1;r<e.length;r++){const o=e[r];if(v(o.noteObj.name,o.noteObj.octave)-v(t.noteObj.name,t.noteObj.octave)===1){s=28/2,o.noteGroup.setAttribute("transform",`translate(${s}, ${o.noteYPos})`);const i=Array.from(o.noteGroup.getElementsByTagName("use")).find(c=>c.getAttribute("href")?.includes("ACCIDENTAL"));if(i){const c=i.getAttribute("transform")?.match(/([-]?\d+)/),l=c&&c[0];let f=-s;l&&(f+=Number(l)),i.setAttribute("transform",`translate(${f}, 0)`)}r++,t=e[r];continue}t=o}return s}renderNote(e){const t=this.svgRendererInstance.createGroup("note"),s=m(e),r=this.strategyInstance.calculateNoteYPos({name:s.name,octave:s.octave});let o=this.strategyInstance.shouldNoteFlip(r);switch(s.duration){case"h":this.svgRendererInstance.drawGlyph("NOTE_HEAD_HALF",t),this.drawStem(t,o);break;case"q":this.svgRendererInstance.drawGlyph("NOTE_HEAD_QUARTER",t),this.drawStem(t,o);break;case"e":o?this.svgRendererInstance.drawGlyph("EIGHTH_NOTE_FLIPPED",t):this.svgRendererInstance.drawGlyph("EIGHTH_NOTE",t);break;default:this.svgRendererInstance.drawGlyph("NOTE_HEAD_WHOLE",t)}let n=0;switch(s.accidental){case"#":this.svgRendererInstance.drawGlyph("ACCIDENTAL_SHARP",t),n-=-8;break;case"b":this.svgRendererInstance.drawGlyph("ACCIDENTAL_FLAT",t),n-=-8;break;case"n":this.svgRendererInstance.drawGlyph("ACCIDENTAL_NATURAL",t),n-=-8;break;case"##":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_SHARP",t),n-=-10;break;case"bb":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_FLAT",t),n-=-14;break}return this.strategyInstance.getLedgerLinesX(s,r).forEach(i=>{this.svgRendererInstance.drawLine(i.x1,i.yPos,i.x2,i.yPos,t)}),{noteGroup:t,noteObj:s,noteYPos:r,accidentalOffset:n,cursorOffset:0}}renderChord(e){const t=this.svgRendererInstance.createGroup("chord"),s=[];for(const n of e){const a=this.renderNote(n);a.noteGroup.setAttribute("transform",`translate(0, ${a.noteYPos})`),t.appendChild(a.noteGroup),s.push({noteGroup:a.noteGroup,noteObj:a.noteObj,noteYPos:a.noteYPos,cursorOffset:0,accidentalOffset:0})}const r=this.chordOffsetConsecutiveAccidentals(s),o=this.chordOffsetCloseNotes(s);return{noteGroup:t,noteObj:s[0].noteObj,noteYPos:0,accidentalOffset:r,cursorOffset:o}}}const p="http://www.w3.org/2000/svg",k=.1,S=1200;class O{rootElementRef;svgElementRef;parentGroupContainer;musicStaffLayer;musicNotesLayer;musicUILayer;width;scale;totalYOffset=0;totalHeight=0;constructor(e,t){this.rootElementRef=e,this.width=t.width,this.scale=t.scale,this.width>S&&(this.width=S,console.warn(`Width provided for the staff ${this.width} exceeds the limit ${S}. Please use this value to fix positioning issues.`)),this.svgElementRef=document.createElementNS(p,"svg"),this.svgElementRef.classList.add("vs-svg-renderer-root"),this.svgElementRef.style.maxWidth="100%",this.svgElementRef.style.height="auto",this.svgElementRef.style.display="block",this.svgElementRef.setAttribute("color",t.staffColor),this.svgElementRef.style.backgroundColor=t.staffBackgroundColor,this.makeGlyphDefs(t.useGlyphs),this.parentGroupContainer=this.createGroup("svg-renderer-parent"),this.svgElementRef.appendChild(this.parentGroupContainer),this.musicStaffLayer=this.createGroup("music-staff-layer"),this.musicNotesLayer=this.createGroup("music-notes-layer"),this.musicUILayer=this.createGroup("music-ui-layer"),this.parentGroupContainer.appendChild(this.musicStaffLayer),this.parentGroupContainer.appendChild(this.musicNotesLayer),this.parentGroupContainer.appendChild(this.musicUILayer)}makeGlyphDefs(e){const t=document.createElementNS(p,"defs");Object.entries(U).filter(([r])=>e.includes(r)).forEach(([r,o])=>{const n=document.createElementNS(p,"path");n.setAttribute("id",`glyph-${r}`),n.setAttribute("d",o.path),n.setAttribute("fill","currentColor"),n.setAttribute("transform",`translate(${o.xOffset}, ${o.yOffset}) scale(${k})`),t.appendChild(n)}),this.rootSvgElement.appendChild(t)}createGroup(e){const t=document.createElementNS(p,"g");return e&&t.classList.add(`vs-${e}`),t}commitElementsToDOM(e,t=this.rootElementRef){const s=document.createDocumentFragment();Array.isArray(e)?e.forEach(r=>{s.appendChild(r)}):s.appendChild(e),t.appendChild(s)}getLayerByName(e){switch(e){case"staff":return this.musicStaffLayer;case"notes":return this.musicNotesLayer;case"ui":return this.musicUILayer;default:throw new Error(`Layer with name '${e}' does not exist.`)}}addTotalRootSvgHeight(e){this.totalHeight+=e}addTotalRootSvgYOffset(e){this.totalYOffset+=e}applySizingToRootSvg(){this.parentGroupContainer.setAttribute("transform",`translate(0, ${this.totalYOffset})`);let e=this.width*this.scale;const t=(this.totalHeight+this.totalYOffset)*this.scale;e+=2,this.svgElementRef.setAttribute("width",e.toString()),this.svgElementRef.setAttribute("height",t.toString()),this.svgElementRef.setAttribute("viewBox",`0 0 ${this.width} ${this.totalHeight+this.totalYOffset}`)}get rootSvgElement(){return this.svgElementRef}get parentGroupElement(){return this.parentGroupContainer}drawLine(e,t,s,r,o){const n=document.createElementNS(p,"line");n.setAttribute("x1",e.toString()),n.setAttribute("y1",t.toString()),n.setAttribute("x2",s.toString()),n.setAttribute("y2",r.toString()),n.setAttribute("stroke","currentColor"),n.setAttribute("stroke-width","1"),o.appendChild(n)}drawRect(e,t,s,r){const o=document.createElementNS(p,"rect");return o.setAttribute("width",e.toString()),o.setAttribute("height",t.toString()),o.setAttribute("x",(r?.x??0).toString()),o.setAttribute("y",(r?.y??0).toString()),r?.fill?o.setAttribute("fill",r.fill):o.setAttribute("fill","currentColor"),s.appendChild(o),o}drawGlyph(e,t,s){s={xOffset:0,yOffset:0,...s};const r=document.createElementNS(p,"use");r.setAttribute("href",`#glyph-${e}`),(s.xOffset||s.yOffset)&&r.setAttribute("transform",`translate(${s.xOffset}, ${s.yOffset})`),t.appendChild(r)}destroy(){this.rootElementRef&&this.svgElementRef&&this.rootElementRef.contains(this.svgElementRef)&&this.rootElementRef.removeChild(this.svgElementRef)}}const W=["CLEF_TREBLE","CLEF_BASS","CLEF_ALTO","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","EIGHTH_NOTE_FLIPPED","ACCIDENTAL_SHARP","ACCIDENTAL_FLAT","ACCIDENTAL_NATURAL","ACCIDENTAL_DOUBLE_SHARP","ACCIDENTAL_DOUBLE_FLAT"];class Z{svgRendererInstance;strategyInstance;noteRendererInstance;options;noteEntries=[];noteCursorX=0;noteStartX;constructor(e,t){this.options={width:300,scale:1,noteStartX:0,staffType:"treble",spaceAbove:0,spaceBelow:0,staffColor:"black",staffBackgroundColor:"transparent",...t},this.svgRendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:W});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new H(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new A(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new A(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new A(this.svgRendererInstance,"alto");break;default:throw new Error(`The staff type ${this.options.staffType} is not supported. Please use "treble", "bass", "alto", or "grand".`)}if(this.strategyInstance.drawStaff(this.options.width),this.noteRendererInstance=new P(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const r=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(r)}if(this.options.spaceBelow){let r=this.options.spaceBelow*10;this.options.staffType==="grand"&&(r-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(r)}this.noteStartX=38+this.options.noteStartX,this.svgRendererInstance.getLayerByName("notes").setAttribute("transform",`translate(${this.noteStartX}, 0)`),this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.svgRendererInstance.getLayerByName("notes"),r=[];for(const o of t){let n;try{n=this.noteRendererInstance.renderNote(o)}catch(a){throw r.length>0&&this.svgRendererInstance.commitElementsToDOM(r,s),a}n.noteGroup.setAttribute("transform",`translate(${this.noteCursorX+n.accidentalOffset}, ${n.noteYPos})`),this.noteEntries.push({gElement:n.noteGroup,note:n.noteObj,xPos:this.noteCursorX+n.accidentalOffset,yPos:n.noteYPos,accidentalXOffset:n.accidentalOffset}),this.noteCursorX+=28+n.accidentalOffset,r.push(n.noteGroup)}this.svgRendererInstance.commitElementsToDOM(r,s)}drawChord(e){if(e.length<2)throw new Error("Provide more than one note for a chord.");const t=this.svgRendererInstance.getLayerByName("notes"),s=this.noteRendererInstance.renderChord(e);s.noteGroup.setAttribute("transform",`translate(${this.noteCursorX+s.accidentalOffset}, 0)`),this.noteEntries.push({gElement:s.noteGroup,note:m(e[0]),xPos:this.noteCursorX+s.accidentalOffset,yPos:0,accidentalXOffset:s.accidentalOffset}),this.noteCursorX+=28+s.accidentalOffset+s.cursorOffset,this.svgRendererInstance.commitElementsToDOM(s.noteGroup,t)}justifyNotes(){const e=this.options.width-38,t=this.noteEntries.length;if(t<=0||e<=0)return;const s=Math.round(e/t);this.noteEntries.map((o,n)=>{const a=(n+.5)*s,i=o.gElement.getBBox(),c=a-i.width/2-i.x,l=Math.round(c*10)/10;return{entry:o,newX:l,isChord:o.gElement.classList.contains("chord")}}).forEach(o=>{const{entry:n,newX:a,isChord:i}=o;i?n.gElement.setAttribute("transform",`translate(${a}, 0)`):n.gElement.setAttribute("transform",`translate(${a}, ${n.yPos})`),n.xPos=a})}clearAllNotes(){this.noteCursorX=0,this.svgRendererInstance.getLayerByName("notes").replaceChildren(),this.noteEntries=[]}changeNoteByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Note index was out of bounds.");const s=this.noteEntries[t],r=this.noteRendererInstance.renderNote(e),n=s.xPos-s.accidentalXOffset+r.accidentalOffset;r.noteGroup.setAttribute("transform",`translate(${n}, ${r.noteYPos})`),this.svgRendererInstance.getLayerByName("notes").replaceChild(r.noteGroup,s.gElement),this.noteEntries[t]={gElement:r.noteGroup,note:r.noteObj,xPos:n,yPos:r.noteYPos,accidentalXOffset:r.accidentalOffset}}changeChordByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Chord index was out of bounds.");if(e.length<2)throw new Error("Notes provided need to be more than one to be considered a chord.");const s=this.noteEntries[t],r=this.noteRendererInstance.renderChord(e),n=s.xPos-s.accidentalXOffset+r.accidentalOffset;r.noteGroup.setAttribute("transform",`translate(${n}, 0)`),this.svgRendererInstance.getLayerByName("notes").replaceChild(r.noteGroup,s.gElement),this.noteEntries[t]={gElement:r.noteGroup,note:m(e[0]),xPos:n,yPos:0,accidentalXOffset:r.accidentalOffset}}addClassToNoteByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Note index was out of bounds.");this.noteEntries[t].gElement.classList.add(e)}removeClassToNoteByIndex(e,t){if(t>=this.noteEntries.length)throw new Error("Note index was out of bounds.");this.noteEntries[t].gElement.classList.remove(e)}destroy(){this.noteEntries=[],this.svgRendererInstance.destroy()}}const u=30,X=19,y=12,V=4,j=6,x=1,R=38,q=["TIME_4","TIME_3","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","REST_WHOLE","REST_HALF","REST_QUARTER","REST_EIGHTH"];class Q{rendererInstance;options;barSpacing;quarterNoteSpacing;noteCursorX=0;noteEntries=[];maxBeatCount;currentBeatCount=0;currentBeatUICount=0;currentBeatUIElement=null;currentBeatUIXPos=R;constructor(e,t){this.options={width:300,scale:1,topNumber:4,barsCount:2,spaceAbove:0,spaceBelow:0,staffColor:"black",staffBackgroundColor:"white",currentBeatUIColor:"#24ff7450",...t},this.rendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:q});const s=this.rendererInstance.rootSvgElement;let r="TIME_4";switch(this.options.topNumber){case 3:r="TIME_3";break;case 4:r="TIME_4";break;default:throw new Error(`Time signature ${this.options.topNumber} not supported. Please use either 3 or 4.`)}if(this.options.barsCount<1||this.options.barsCount>3)throw new Error(`Bars count ${this.options.barsCount} not supported. Please use 1 - 3`);if(this.options.spaceAbove){const _=this.options.spaceAbove*10;this.rendererInstance.addTotalRootSvgYOffset(_)}if(this.options.spaceBelow){let _=this.options.spaceBelow*10;this.rendererInstance.addTotalRootSvgHeight(_)}const o=this.rendererInstance.getLayerByName("staff");this.rendererInstance.addTotalRootSvgHeight(u*2);const n=this.rendererInstance.createGroup("time-signature");o.appendChild(n);const a=u-X;this.rendererInstance.drawGlyph(r,n),this.rendererInstance.drawGlyph("TIME_4",n,{yOffset:X}),n.setAttribute("transform",`translate(0, ${a})`);let i=this.options.width-38;this.options.barsCount>1&&(i-=(this.options.barsCount-1)*y),i-=x,this.rendererInstance.drawLine(0,u,this.options.width-x,u,o),this.barSpacing=i/this.options.barsCount,this.quarterNoteSpacing=Math.round(this.barSpacing/this.options.topNumber),this.maxBeatCount=this.options.barsCount*this.options.topNumber;let c=this.barSpacing+38;const l=u/2,f=u+l;for(let _=0;_<this.options.barsCount-1;_++)this.rendererInstance.drawLine(c,l,c,f,o),c+=this.barSpacing;this.rendererInstance.getLayerByName("notes").setAttribute("transform",`translate(38, ${u})`),this.rendererInstance.applySizingToRootSvg(),this.rendererInstance.commitElementsToDOM(s)}createBeatUIElement(){const e=this.rendererInstance.getLayerByName("ui");this.currentBeatUIElement=this.rendererInstance.drawRect(this.quarterNoteSpacing/2,u*2,e,{x:R,fill:this.options.currentBeatUIColor})}handleNewBar(){this.noteCursorX+=y}translateGroupByDuration(e,t){return t.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.quarterNoteSpacing*e}drawStem(e,t){this.rendererInstance.drawLine(10+(t??0),0,10+(t??0),-28,e)}renderNote(e,t){switch(e){case"w":this.rendererInstance.drawGlyph("NOTE_HEAD_WHOLE",t);break;case"h":this.rendererInstance.drawGlyph("NOTE_HEAD_HALF",t),this.drawStem(t);break;case"q":this.rendererInstance.drawGlyph("NOTE_HEAD_QUARTER",t),this.drawStem(t);break;case"e":this.rendererInstance.drawGlyph("EIGHTH_NOTE",t),this.drawStem(t);break}}renderRest(e,t){switch(e){case"w":this.rendererInstance.drawGlyph("REST_WHOLE",t);break;case"h":this.rendererInstance.drawGlyph("REST_HALF",t);break;case"q":this.rendererInstance.drawGlyph("REST_QUARTER",t);break;case"e":this.rendererInstance.drawGlyph("REST_EIGHTH",t);break}}checkAndCreateNewBar(){const e=this.currentBeatCount>0&&this.currentBeatCount%this.options.topNumber===0,t=this.currentBeatCount<this.maxBeatCount;e&&t&&this.handleNewBar()}checkAndFillBarWithRests(e){const t=this.options.topNumber-this.currentBeatCount%this.options.topNumber;if(e>t){const s=this.createRemainingRests(t);return this.handleNewBar(),s}return null}createRemainingRests(e){const t=[];let s=e;for(;s>0;){const r=this.rendererInstance.createGroup("rest");let o=0;s-E.h>=0?(this.rendererInstance.drawGlyph("REST_HALF",r),o=E.h):s-E.q>=0?(this.rendererInstance.drawGlyph("REST_QUARTER",r),o=E.q):(this.rendererInstance.drawGlyph("REST_EIGHTH",r),o=E.e),s-=o,this.currentBeatCount+=o,r.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=o*this.quarterNoteSpacing,t.push(r)}return t}renderBeamRect(e,t,s,r){this.rendererInstance.drawRect(e-t,V,s,{x:10,y:-28+(r??0),fill:this.options.staffColor})}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayerByName("notes"),r=[];for(const o of t){let n="w";try{n=C(o)}catch(f){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),f}const a=E[n];if(this.currentBeatCount>=this.maxBeatCount)throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),new Error("Max beat count reached. Can't add additional notes.");this.checkAndCreateNewBar();const i=this.checkAndFillBarWithRests(a);i&&i.forEach(f=>{r.push(f),this.noteEntries.push(f)});const c=this.rendererInstance.createGroup("note"),l=this.translateGroupByDuration(a,c);this.noteCursorX+=l,this.currentBeatCount+=a,this.renderNote(n,c),r.push(c),this.noteEntries.push(c)}this.rendererInstance.commitElementsToDOM(r,s)}drawRest(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayerByName("notes"),r=[];for(const o of t){let n="w";try{n=C(o)}catch(f){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),f}const a=this.rendererInstance.createGroup("rest"),i=E[n],c=i*this.quarterNoteSpacing;if(this.currentBeatCount>=this.maxBeatCount)throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),new Error("Max beat count reached. Can't add additional notes.");this.checkAndCreateNewBar();const l=this.checkAndFillBarWithRests(i);l&&l.forEach(f=>{r.push(f),this.noteEntries.push(f)}),this.renderRest(n,a),a.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=c,this.currentBeatCount+=i,r.push(a),this.noteEntries.push(a)}this.rendererInstance.commitElementsToDOM(r,s)}drawBeamedNotes(e,t){if(t<2)throw new Error("Must provide a value greater than 2 for beamed note.");if(this.currentBeatCount>=this.maxBeatCount)throw new Error("Max beat count reached. Can't add additional beamed note.");let s="s";e==="s"?s="s":s=C(e),this.checkAndCreateNewBar();const r=this.rendererInstance.getLayerByName("notes"),o=E[s],n=o*this.quarterNoteSpacing,a=this.options.topNumber-this.currentBeatCount%this.options.topNumber,i=Math.min(t,a/o),c=this.rendererInstance.createGroup("beamed-note");c.setAttribute("transform",`translate(${this.noteCursorX}, 0)`);let l=0;for(let f=0;f<i;f++)this.rendererInstance.drawGlyph("NOTE_HEAD_QUARTER",c,{xOffset:l}),this.drawStem(c,l),l+=n,this.currentBeatCount+=o;this.renderBeamRect(l,n,c),e==="s"&&this.renderBeamRect(l,n,c,j),this.noteCursorX+=l,this.noteEntries.push(c),this.rendererInstance.commitElementsToDOM(c,r)}incrementCurrentBeatUI(){if(this.currentBeatUIElement||this.createBeatUIElement(),this.currentBeatUICount>=this.maxBeatCount){this.currentBeatUIElement.setAttribute("display","none");return}this.currentBeatUIElement?.getAttribute("display")==="none"&&this.currentBeatUIElement.removeAttribute("display"),this.currentBeatUICount++,this.currentBeatUICount>this.options.topNumber&&this.currentBeatUICount%this.options.topNumber===1&&(this.currentBeatUIXPos+=y),this.currentBeatUICount>1&&(this.currentBeatUIXPos+=this.quarterNoteSpacing),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString())}resetCurrentBeatUI(){this.currentBeatUICount=0,this.currentBeatUIXPos=R,this.currentBeatUIElement&&(this.currentBeatUIElement.setAttribute("display","none"),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString()))}clearAllNotes(){this.noteCursorX=0,this.currentBeatCount=0,this.rendererInstance.getLayerByName("notes").replaceChildren(),this.noteEntries=[]}destroy(){this.noteEntries=[],this.rendererInstance.destroy()}}const z=["CLEF_TREBLE","CLEF_BASS","CLEF_ALTO","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","EIGHTH_NOTE_FLIPPED","ACCIDENTAL_SHARP","ACCIDENTAL_FLAT","ACCIDENTAL_NATURAL","ACCIDENTAL_DOUBLE_SHARP","ACCIDENTAL_DOUBLE_FLAT"],N=60,K=N;class J{svgRendererInstance;strategyInstance;noteRendererInstance;options;activeEntries=[];noteBuffer=[];notesLayer;noteCursorX=0;noteStartX;constructor(e,t){this.options={width:300,scale:1,noteStartX:0,staffType:"treble",spaceAbove:0,spaceBelow:0,staffColor:"black",staffBackgroundColor:"transparent",...t},this.svgRendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:z});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new H(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new A(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new A(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new A(this.svgRendererInstance,"alto");break;default:throw new Error(`The staff type ${this.options.staffType} is not supported. Please use "treble", "bass", "alto", or "grand".`)}if(this.strategyInstance.drawStaff(this.options.width),this.noteRendererInstance=new P(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const r=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(r)}if(this.options.spaceBelow){let r=this.options.spaceBelow*10;this.options.staffType==="grand"&&(r-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(r)}this.notesLayer=this.svgRendererInstance.getLayerByName("notes"),this.notesLayer.classList.add("vs-scrolling-notes-layer"),this.noteStartX=38+this.options.noteStartX,this.svgRendererInstance.getLayerByName("notes").setAttribute("transform",`translate(${this.noteStartX}, 0)`),this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}renderFirstNoteGroups(){const e=this.options.width-this.options.noteStartX+K;for(;this.noteBuffer.length>0&&this.noteCursorX<e;)this.renderNextNote(),this.noteCursorX+=N;this.activeEntries.length>1&&(this.noteCursorX-=N)}renderNextNote(){if(this.noteBuffer.length<1)return;const e=this.noteBuffer[0],t=this.svgRendererInstance.createGroup("note-wrapper");if(e.type==="chord"){const s=this.noteRendererInstance.renderChord(e.notes);s.noteGroup.setAttribute("transform",`translate(0, ${s.noteYPos})`),t.appendChild(s.noteGroup)}else{const s=this.noteRendererInstance.renderNote(e.notes[0]);s.noteGroup.setAttribute("transform",`translate(0, ${s.noteYPos})`),t.appendChild(s.noteGroup)}t.style.transform=`translate(${this.noteCursorX}px, 0px)`,this.activeEntries.push({noteWrapper:t,xPos:this.noteCursorX}),this.noteBuffer.shift(),this.notesLayer.appendChild(t)}queueNotes(e){this.clearAllNotes();for(const t of e)Array.isArray(t)?this.noteBuffer.push({type:"chord",notes:t}):this.noteBuffer.push({type:"note",notes:[t]});this.renderFirstNoteGroups()}advanceNotes(){if(this.activeEntries.length<=0){this.clearAllNotes(),this.options.onNotesOut&&this.options.onNotesOut();return}this.activeEntries.forEach(t=>{t.xPos-=N,t.noteWrapper.style.transform=`translate(${t.xPos}px, 0px)`});const e=this.activeEntries[0];e.xPos<=0&&(this.notesLayer.removeChild(e.noteWrapper),this.activeEntries.shift()),this.renderNextNote()}clearAllNotes(){this.noteCursorX=0,this.notesLayer.replaceChildren(),this.activeEntries=[],this.noteBuffer=[]}destroy(){this.svgRendererInstance.destroy(),this.activeEntries=[],this.noteBuffer=[]}}d.MusicStaff=Z,d.RhythmStaff=Q,d.ScrollingStaff=J,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vector-score",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "keywords": [