vector-score 1.1.0 → 1.2.1

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.
@@ -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 N={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},F=8,k=40,v={sharp:["F","C","G","D","A","E","B"],flat:["B","E","A","D","G","C","F"]},D={C:{type:"sharp",count:0},G:{type:"sharp",count:1},D:{type:"sharp",count:2},A:{type:"sharp",count:3},E:{type:"sharp",count:4},B:{type:"sharp",count:5},"F#":{type:"sharp",count:6},F:{type:"flat",count:1},Bb:{type:"flat",count:2},Eb:{type:"flat",count:3},Ab:{type:"flat",count:4},Db:{type:"flat",count:5},Gb:{type:"flat",count:6}},C={treble:{sharp:[5,5,5,5,4,5,4],flat:[4,5,4,5,4,5,4]},bass:{sharp:[3,3,3,3,2,3,2],flat:[2,3,2,3,2,3,3]},alto:{sharp:[4,4,4,4,3,4,4],flat:[4,5,4,5,4,5,4]},grand:{sharp:[],flat:[]}};function $(h){const e=D[h];if(!e)throw new Error(`Unknown key signature "${h}". Valid keys: ${Object.keys(D).join(", ")}`);return e}function W(h,e,t,s){const n=$(t);if(n.count===0)return 0;const r=n.type==="sharp"?"ACCIDENTAL_SHARP":"ACCIDENTAL_FLAT",o=h.getLayerByName("staff");return e.getKeySignatureYPositions(n.type,n.count).forEach(i=>{i.forEach((c,l)=>{h.drawGlyph(r,o,{xOffset:s+l*F,yOffset:c})})}),n.count*F}const Z={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}},V=/^(?<name>[A-Ga-g])(?<accidental>##|bb|[#bn]?)(?<octave>\d)(?<duration>[whqeWHQE]?)$/,j=/^[whqeWHQE]$/,g=["C","D","E","F","G","A","B"];function m(h){const e=h.match(V);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:n,duration:r}=e.groups;t=t.toUpperCase(),r=r.toLowerCase(),r||(r="w");const o={name:t,octave:parseInt(n),duration:r};return s&&(o.accidental=s),o}function L(h){const e=h.match(j);if(!e)throw new Error(`Invalid note duration '${h}'. Use w | h | q | e.`);return e[0].toString().toLowerCase()}function y(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){let e=g.indexOf(h.name);return e+=h.octave*12,e}function I(h,e){return g.indexOf(h.name)-g.indexOf(e.name)+(h.octave-e.octave)*7}const O=48,H=40+30/2,P=20,X=90;class x{params;rendererRef;width=0;trebleStaffHeight=0;constructor(e,t){this.rendererRef=e;const s=N[t];if(!s)throw new Error(`Staff type ${t} is not supported`);this.params=s}drawStaffLines=(e,t)=>{let s=e;for(let n=0;n<5;n++)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),n=this.drawStaffLines(s+30,t);this.rendererRef.drawLine(0,0,0,n,t),this.rendererRef.drawLine(this.width,0,this.width,n,t),this.trebleStaffHeight=s;let r=n,o=1;const a=y("treble"),i=y("bass");this.rendererRef.drawGlyph(a,t),this.rendererRef.drawGlyph(i,t,{yOffset:s+30}),r+=this.params.paddingBottom+1,o+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(r),this.rendererRef.addTotalRootSvgYOffset(o)};shouldNoteFlip(e){const t=Math.abs(e-X),s=Math.abs(e-P);return e===H?!1:t<=s?!(e>=X):e<=P}getLedgerLinesX(e,t){const s=[],n=B(e);let r=e.duration==="w"?17:12.5;if(n===O)return s.push({x1:-2,x2:r,yPos:0}),s;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=>{let s=I(this.params.topLineNote,e)*(10/2);const n=B(e);return n<O?s+=10:n===O&&(s=H),s};getKeySignatureYPositions(e,t){const s=v[e].slice(0,t),n=C.treble[e],r=C.bass[e],o=s.map((i,c)=>I(N.treble.topLineNote,{name:i,octave:n[c]})*(10/2)),a=s.map((i,c)=>I(N.bass.topLineNote,{name:i,octave:r[c]})*(10/2)+this.trebleStaffHeight+30);return[o,a]}}const q=20;class A{params;rendererRef;constructor(e,t){this.rendererRef=e;const s=N[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 n=s-10+1,r=1;const o=y(this.params.staffType);this.rendererRef.drawGlyph(o,t),n+=this.params.paddingTop+this.params.paddingBottom,r+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(n),this.rendererRef.addTotalRootSvgYOffset(r)};shouldNoteFlip(e){return e<=q}getLedgerLinesX(e,t){const s=[];let n=e.duration==="w"?17:12.5;if(t<this.params.topLineYPos){let r=this.params.topLineYPos-10;for(;r>=t;)s.push({x1:-2,x2:n,yPos:r-t}),r-=10}else if(t>this.params.bottomLineYPos){let r=this.params.bottomLineYPos+10;for(;r<=t;)s.push({x1:-2,x2:n,yPos:r-t}),r+=10}return s}calculateNoteYPos=e=>I(this.params.topLineNote,e)*(10/2);getKeySignatureYPositions(e,t){const s=v[e].slice(0,t),n=C[this.params.staffType][e];return[s.map((o,a)=>this.calculateNoteYPos({name:o,octave:n[a]}))]}}class U{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,n=0;for(let r=0;r<e.length;r++){const o=e[r];if(o.noteObj.accidental&&n<3?(t+=-8,s=Math.min(s,t),n++):o.noteObj.accidental&&n<=3?(t=-8,n=1):(t=0,n=0),t!==0){const i=Array.from(o.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 n=1;n<e.length;n++){const r=e[n];if(-I(t.noteObj,r.noteObj)===1){s=28/2,r.noteGroup.setAttribute("transform",`translate(${s}, ${r.noteYPos})`);const i=Array.from(r.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)`)}n++,t=e[n];continue}t=r}return s}renderNote(e){const t=this.svgRendererInstance.createGroup("note"),s=m(e),n=this.strategyInstance.calculateNoteYPos({name:s.name,octave:s.octave});let r=this.strategyInstance.shouldNoteFlip(n);switch(s.duration){case"h":this.svgRendererInstance.drawGlyph("NOTE_HEAD_HALF",t),this.drawStem(t,r);break;case"q":this.svgRendererInstance.drawGlyph("NOTE_HEAD_QUARTER",t),this.drawStem(t,r);break;case"e":r?this.svgRendererInstance.drawGlyph("EIGHTH_NOTE_FLIPPED",t):this.svgRendererInstance.drawGlyph("EIGHTH_NOTE",t);break;default:this.svgRendererInstance.drawGlyph("NOTE_HEAD_WHOLE",t)}let o=0;switch(s.accidental){case"#":this.svgRendererInstance.drawGlyph("ACCIDENTAL_SHARP",t),o-=-8;break;case"b":this.svgRendererInstance.drawGlyph("ACCIDENTAL_FLAT",t),o-=-8;break;case"n":this.svgRendererInstance.drawGlyph("ACCIDENTAL_NATURAL",t),o-=-8;break;case"##":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_SHARP",t),o-=-10;break;case"bb":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_FLAT",t),o-=-14;break}return this.strategyInstance.getLedgerLinesX(s,n).forEach(i=>{this.svgRendererInstance.drawLine(i.x1,i.yPos,i.x2,i.yPos,t)}),{noteGroup:t,noteObj:s,noteYPos:n,accidentalOffset:o,cursorOffset:0}}renderChord(e){const t=this.svgRendererInstance.createGroup("chord"),s=[];for(const o of e){const a=this.renderNote(o);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 n=this.chordOffsetConsecutiveAccidentals(s),r=this.chordOffsetCloseNotes(s);return{noteGroup:t,noteObj:s[0].noteObj,noteYPos:0,accidentalOffset:n,cursorOffset:r}}}const p="http://www.w3.org/2000/svg",K=.1,R=1200;class b{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>R&&(this.width=R,console.warn(`Width provided for the staff ${this.width} exceeds the limit ${R}. 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(Z).filter(([n])=>e.includes(n)).forEach(([n,r])=>{const o=document.createElementNS(p,"path");o.setAttribute("id",`glyph-${n}`),o.setAttribute("d",r.path),o.setAttribute("fill","currentColor"),o.setAttribute("transform",`translate(${r.xOffset}, ${r.yOffset}) scale(${K})`),t.appendChild(o)}),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(n=>{s.appendChild(n)}):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,n,r){const o=document.createElementNS(p,"line");o.setAttribute("x1",e.toString()),o.setAttribute("y1",t.toString()),o.setAttribute("x2",s.toString()),o.setAttribute("y2",n.toString()),o.setAttribute("stroke","currentColor"),o.setAttribute("stroke-width","1"),r.appendChild(o)}drawRect(e,t,s,n){const r=document.createElementNS(p,"rect");return r.setAttribute("width",e.toString()),r.setAttribute("height",t.toString()),r.setAttribute("x",(n?.x??0).toString()),r.setAttribute("y",(n?.y??0).toString()),n?.fill?r.setAttribute("fill",n.fill):r.setAttribute("fill","currentColor"),s.appendChild(r),r}drawGlyph(e,t,s){s={xOffset:0,yOffset:0,...s};const n=document.createElementNS(p,"use");n.setAttribute("href",`#glyph-${e}`),(s.xOffset||s.yOffset)&&n.setAttribute("transform",`translate(${s.xOffset}, ${s.yOffset})`),t.appendChild(n)}destroy(){this.rootElementRef&&this.svgElementRef&&this.rootElementRef.contains(this.svgElementRef)&&this.rootElementRef.removeChild(this.svgElementRef)}}const Q=["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 b(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:Q});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new x(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 U(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)}let n=0;this.options.keySignature&&(n=this.createKeySignature(this.options.keySignature)),this.noteStartX=38+this.options.noteStartX+n,this.svgRendererInstance.getLayerByName("notes").setAttribute("transform",`translate(${this.noteStartX}, 0)`),this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}createKeySignature(e){return W(this.svgRendererInstance,this.strategyInstance,e,k)}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.svgRendererInstance.getLayerByName("notes"),n=[];for(const r of t){let o;try{o=this.noteRendererInstance.renderNote(r)}catch(a){throw n.length>0&&this.svgRendererInstance.commitElementsToDOM(n,s),a}o.noteGroup.setAttribute("transform",`translate(${this.noteCursorX+o.accidentalOffset}, ${o.noteYPos})`),this.noteEntries.push({gElement:o.noteGroup,note:o.noteObj,xPos:this.noteCursorX+o.accidentalOffset,yPos:o.noteYPos,accidentalXOffset:o.accidentalOffset}),this.noteCursorX+=28+o.accidentalOffset,n.push(o.noteGroup)}this.svgRendererInstance.commitElementsToDOM(n,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-this.noteStartX,t=this.noteEntries.length;if(t<=0||e<=0)return;const s=Math.round(e/t);this.noteEntries.map((r,o)=>{const a=(o+.5)*s,i=r.gElement.getBBox(),c=a-i.width/2-i.x,l=Math.round(c*10)/10;return{entry:r,newX:l,isChord:r.gElement.classList.contains("chord")}}).forEach(r=>{const{entry:o,newX:a,isChord:i}=r;i?o.gElement.setAttribute("transform",`translate(${a}, 0)`):o.gElement.setAttribute("transform",`translate(${a}, ${o.yPos})`),o.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],n=this.noteRendererInstance.renderNote(e),o=s.xPos-s.accidentalXOffset+n.accidentalOffset;n.noteGroup.setAttribute("transform",`translate(${o}, ${n.noteYPos})`),this.svgRendererInstance.getLayerByName("notes").replaceChild(n.noteGroup,s.gElement),this.noteEntries[t]={gElement:n.noteGroup,note:n.noteObj,xPos:o,yPos:n.noteYPos,accidentalXOffset:n.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],n=this.noteRendererInstance.renderChord(e),o=s.xPos-s.accidentalXOffset+n.accidentalOffset;n.noteGroup.setAttribute("transform",`translate(${o}, 0)`),this.svgRendererInstance.getLayerByName("notes").replaceChild(n.noteGroup,s.gElement),this.noteEntries[t]={gElement:n.noteGroup,note:m(e[0]),xPos:o,yPos:0,accidentalXOffset:n.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,M=19,w=12,J=4,tt=6,Y=1,G=38,et=["TIME_4","TIME_3","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","REST_WHOLE","REST_HALF","REST_QUARTER","REST_EIGHTH"];class st{rendererInstance;options;barSpacing;quarterNoteSpacing;noteCursorX=0;noteEntries=[];maxBeatCount;currentBeatCount=0;currentBeatUICount=0;currentBeatUIElement=null;currentBeatUIXPos=G;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 b(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:et});const s=this.rendererInstance.rootSvgElement;let n="TIME_4";switch(this.options.topNumber){case 3:n="TIME_3";break;case 4:n="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 r=this.rendererInstance.getLayerByName("staff");this.rendererInstance.addTotalRootSvgHeight(u*2);const o=this.rendererInstance.createGroup("time-signature");r.appendChild(o);const a=u-M;this.rendererInstance.drawGlyph(n,o),this.rendererInstance.drawGlyph("TIME_4",o,{yOffset:M}),o.setAttribute("transform",`translate(0, ${a})`);let i=this.options.width-38;this.options.barsCount>1&&(i-=(this.options.barsCount-1)*w),i-=Y,this.rendererInstance.drawLine(0,u,this.options.width-Y,u,r),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,r),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:G,fill:this.options.currentBeatUIColor})}handleNewBar(){this.noteCursorX+=w}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 n=this.rendererInstance.createGroup("rest");let r=0;s-E.h>=0?(this.rendererInstance.drawGlyph("REST_HALF",n),r=E.h):s-E.q>=0?(this.rendererInstance.drawGlyph("REST_QUARTER",n),r=E.q):(this.rendererInstance.drawGlyph("REST_EIGHTH",n),r=E.e),s-=r,this.currentBeatCount+=r,n.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=r*this.quarterNoteSpacing,t.push(n)}return t}renderBeamRect(e,t,s,n){this.rendererInstance.drawRect(e-t,J,s,{x:10,y:-28+(n??0),fill:this.options.staffColor})}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayerByName("notes"),n=[];for(const r of t){let o="w";try{o=L(r)}catch(f){throw n.length>0&&this.rendererInstance.commitElementsToDOM(n,s),f}const a=E[o];if(this.currentBeatCount>=this.maxBeatCount)throw n.length>0&&this.rendererInstance.commitElementsToDOM(n,s),new Error("Max beat count reached. Can't add additional notes.");this.checkAndCreateNewBar();const i=this.checkAndFillBarWithRests(a);i&&i.forEach(f=>{n.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(o,c),n.push(c),this.noteEntries.push(c)}this.rendererInstance.commitElementsToDOM(n,s)}drawRest(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayerByName("notes"),n=[];for(const r of t){let o="w";try{o=L(r)}catch(f){throw n.length>0&&this.rendererInstance.commitElementsToDOM(n,s),f}const a=this.rendererInstance.createGroup("rest"),i=E[o],c=i*this.quarterNoteSpacing;if(this.currentBeatCount>=this.maxBeatCount)throw n.length>0&&this.rendererInstance.commitElementsToDOM(n,s),new Error("Max beat count reached. Can't add additional notes.");this.checkAndCreateNewBar();const l=this.checkAndFillBarWithRests(i);l&&l.forEach(f=>{n.push(f),this.noteEntries.push(f)}),this.renderRest(o,a),a.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=c,this.currentBeatCount+=i,n.push(a),this.noteEntries.push(a)}this.rendererInstance.commitElementsToDOM(n,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=L(e),this.checkAndCreateNewBar();const n=this.rendererInstance.getLayerByName("notes"),r=E[s],o=r*this.quarterNoteSpacing,a=this.options.topNumber-this.currentBeatCount%this.options.topNumber,i=Math.min(t,a/r),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+=o,this.currentBeatCount+=r;this.renderBeamRect(l,o,c),e==="s"&&this.renderBeamRect(l,o,c,tt),this.noteCursorX+=l,this.noteEntries.push(c),this.rendererInstance.commitElementsToDOM(c,n)}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+=w),this.currentBeatUICount>1&&(this.currentBeatUIXPos+=this.quarterNoteSpacing),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString())}resetCurrentBeatUI(){this.currentBeatUICount=0,this.currentBeatUIXPos=G,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 nt=["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"],S=60,rt=S;class ot{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 b(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:nt});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new x(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 U(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const n=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(n)}if(this.options.spaceBelow){let n=this.options.spaceBelow*10;this.options.staffType==="grand"&&(n-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(n)}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+rt;for(;this.noteBuffer.length>0&&this.noteCursorX<e;)this.renderNextNote(),this.noteCursorX+=S;this.activeEntries.length>1&&(this.noteCursorX-=S)}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-=S,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=st,d.ScrollingStaff=ot,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(p,R){typeof exports=="object"&&typeof module<"u"?R(exports):typeof define=="function"&&define.amd?define(["exports"],R):(p=typeof globalThis<"u"?globalThis:p||self,R(p.VectorScore={}))})(this,(function(p){"use strict";const y={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}},I={w:4,h:2,q:1,e:.5,s:.25},ht=6,lt=5,_=22,m=30,u=10,E=6,dt=4,ft=u*2,k=51,ut=12,Et=4,W=1,G=4,Z=1,V=E*2+G+4,q=16,S=12,z=q,gt=2,j=8,pt=40,K={sharp:["F","C","G","D","A","E","B"],flat:["B","E","A","D","G","C","F"]},Q={C:{type:"sharp",count:0},G:{type:"sharp",count:1},D:{type:"sharp",count:2},A:{type:"sharp",count:3},E:{type:"sharp",count:4},B:{type:"sharp",count:5},"F#":{type:"sharp",count:6},F:{type:"flat",count:1},Bb:{type:"flat",count:2},Eb:{type:"flat",count:3},Ab:{type:"flat",count:4},Db:{type:"flat",count:5},Gb:{type:"flat",count:6}},v={treble:{sharp:[5,5,5,5,4,5,4],flat:[4,5,4,5,4,5,4]},bass:{sharp:[3,3,3,3,2,3,2],flat:[2,3,2,3,2,3,3]},alto:{sharp:[4,4,4,4,3,4,4],flat:[4,5,4,5,4,5,4]},grand:{sharp:[],flat:[]}};function At(h){const e=Q[h];if(!e)throw new Error(`Unknown key signature "${h}". Valid keys: ${Object.keys(Q).join(", ")}`);return e}function It(h,e,t,s){const r=At(t);if(r.count===0)return 0;const n=r.type==="sharp"?"ACCIDENTAL_SHARP":"ACCIDENTAL_FLAT",o=h.getLayerByName("staff");return e.getKeySignatureYPositions(r.type,r.count).forEach(a=>{a.forEach((c,l)=>{h.drawGlyph(n,o,{xOffset:s+l*j,yOffset:c})})}),r.count*j}const Tt={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}},_t=/^(?<name>[A-Ga-g])(?<accidental>##|bb|[#bn]?)(?<octave>\d)(?<duration>[whqeWHQE]?)$/,mt=/^[whqeWHQE]$/,F=["C","D","E","F","G","A","B"];function D(h){const e=h.match(_t);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:n}=e.groups;t=t.toUpperCase(),n=n.toLowerCase(),n||(n="w");const o={name:t,octave:parseInt(r),duration:n};return s&&(o.accidental=s),o}function H(h){const e=h.match(mt);if(!e)throw new Error(`Invalid note duration '${h}'. Use w | h | q | e.`);return e[0].toString().toLowerCase()}function B(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 J(h){let e=F.indexOf(h.name);return e+=h.octave*12,e}function N(h,e){return F.indexOf(h.name)-F.indexOf(e.name)+(h.octave-e.octave)*7}const P=48,tt=40+30/2,et=20,st=90;class rt{params;rendererRef;width=0;trebleStaffHeight=0;constructor(e,t){this.rendererRef=e;const s=y[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),this.trebleStaffHeight=s;let n=r,o=1;const i=B("treble"),a=B("bass");this.rendererRef.drawGlyph(i,t),this.rendererRef.drawGlyph(a,t,{yOffset:s+30}),n+=this.params.paddingBottom+1,o+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(n),this.rendererRef.addTotalRootSvgYOffset(o)};shouldNoteFlip(e){const t=Math.abs(e-st),s=Math.abs(e-et);return e===tt?!1:t<=s?!(e>=st):e<=et}getLedgerLinesX(e,t){const s=[],r=J(e);let n=e.duration==="w"?17:12.5;if(r===P)return s.push({x1:-2,x2:n,yPos:0}),s;if(t<this.params.topLineYPos){let o=this.params.topLineYPos-10;for(;o>=t;)s.push({x1:-2,x2:n,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:n,yPos:o-t}),o+=10}return s}calculateNoteYPos=e=>{let s=N(this.params.topLineNote,e)*(10/2);const r=J(e);return r<P?s+=10:r===P&&(s=tt),s};getKeySignatureYPositions(e,t){const s=K[e].slice(0,t),r=v.treble[e],n=v.bass[e],o=s.map((a,c)=>N(y.treble.topLineNote,{name:a,octave:r[c]})*(10/2)),i=s.map((a,c)=>N(y.bass.topLineNote,{name:a,octave:n[c]})*(10/2)+this.trebleStaffHeight+30);return[o,i]}}const Ct=20;class C{params;rendererRef;constructor(e,t){this.rendererRef=e;const s=y[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 i=0;i<5;i++)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,n=1;const o=B(this.params.staffType);this.rendererRef.drawGlyph(o,t),r+=this.params.paddingTop+this.params.paddingBottom,n+=this.params.paddingTop,this.rendererRef.addTotalRootSvgHeight(r),this.rendererRef.addTotalRootSvgYOffset(n)};shouldNoteFlip(e){return e<=Ct}getLedgerLinesX(e,t){const s=[];let r=e.duration==="w"?17:12.5;if(t<this.params.topLineYPos){let n=this.params.topLineYPos-10;for(;n>=t;)s.push({x1:-2,x2:r,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:r,yPos:n-t}),n+=10}return s}calculateNoteYPos=e=>N(this.params.topLineNote,e)*(10/2);getKeySignatureYPositions(e,t){const s=K[e].slice(0,t),r=v[this.params.staffType][e];return[s.map((o,i)=>this.calculateNoteYPos({name:o,octave:r[i]}))]}}class nt{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 n=0;n<e.length;n++){const o=e[n];if(o.noteObj.accidental&&r<3?(t+=-8,s=Math.min(s,t),r++):o.noteObj.accidental&&r<=3?(t=-8,r=1):(t=0,r=0),t!==0){const a=Array.from(o.noteGroup.getElementsByTagName("use")).find(c=>c.getAttribute("href")?.includes("ACCIDENTAL"));if(!a)continue;a.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 n=e[r];if(-N(t.noteObj,n.noteObj)===1){s=28/2,n.noteGroup.setAttribute("transform",`translate(${s}, ${n.noteYPos})`);const a=Array.from(n.noteGroup.getElementsByTagName("use")).find(c=>c.getAttribute("href")?.includes("ACCIDENTAL"));if(a){const c=a.getAttribute("transform")?.match(/([-]?\d+)/),l=c&&c[0];let d=-s;l&&(d+=Number(l)),a.setAttribute("transform",`translate(${d}, 0)`)}r++,t=e[r];continue}t=n}return s}renderNote(e){const t=this.svgRendererInstance.createGroup("note"),s=D(e),r=this.strategyInstance.calculateNoteYPos({name:s.name,octave:s.octave});let n=this.strategyInstance.shouldNoteFlip(r);switch(s.duration){case"h":this.svgRendererInstance.drawGlyph("NOTE_HEAD_HALF",t),this.drawStem(t,n);break;case"q":this.svgRendererInstance.drawGlyph("NOTE_HEAD_QUARTER",t),this.drawStem(t,n);break;case"e":n?this.svgRendererInstance.drawGlyph("EIGHTH_NOTE_FLIPPED",t):this.svgRendererInstance.drawGlyph("EIGHTH_NOTE",t);break;default:this.svgRendererInstance.drawGlyph("NOTE_HEAD_WHOLE",t)}let o=0;switch(s.accidental){case"#":this.svgRendererInstance.drawGlyph("ACCIDENTAL_SHARP",t),o-=-8;break;case"b":this.svgRendererInstance.drawGlyph("ACCIDENTAL_FLAT",t),o-=-8;break;case"n":this.svgRendererInstance.drawGlyph("ACCIDENTAL_NATURAL",t),o-=-8;break;case"##":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_SHARP",t),o-=-10;break;case"bb":this.svgRendererInstance.drawGlyph("ACCIDENTAL_DOUBLE_FLAT",t),o-=-14;break}return this.strategyInstance.getLedgerLinesX(s,r).forEach(a=>{this.svgRendererInstance.drawLine(a.x1,a.yPos,a.x2,a.yPos,t)}),{noteGroup:t,noteObj:s,noteYPos:r,accidentalOffset:o,cursorOffset:0}}renderChord(e){const t=this.svgRendererInstance.createGroup("chord"),s=[];for(const o of e){const i=this.renderNote(o);i.noteGroup.setAttribute("transform",`translate(0, ${i.noteYPos})`),t.appendChild(i.noteGroup),s.push({noteGroup:i.noteGroup,noteObj:i.noteObj,noteYPos:i.noteYPos,cursorOffset:0,accidentalOffset:0})}const r=this.chordOffsetConsecutiveAccidentals(s),n=this.chordOffsetCloseNotes(s);return{noteGroup:t,noteObj:s[0].noteObj,noteYPos:0,accidentalOffset:r,cursorOffset:n}}}const A="http://www.w3.org/2000/svg",St=.1,x=1200;class w{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>x&&(this.width=x,console.warn(`Width provided for the staff ${this.width} exceeds the limit ${x}. Please use this value to fix positioning issues.`)),this.svgElementRef=document.createElementNS(A,"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(A,"defs");Object.entries(Tt).filter(([r])=>e.includes(r)).forEach(([r,n])=>{const o=document.createElementNS(A,"path");o.setAttribute("id",`glyph-${r}`),o.setAttribute("d",n.path),o.setAttribute("fill","currentColor"),o.setAttribute("transform",`translate(${n.xOffset}, ${n.yOffset}) scale(${St})`),t.appendChild(o)}),this.rootSvgElement.appendChild(t)}addNamespacedClassesToElement(e,t){[e].flat().forEach(r=>t.classList.add(`vs-${r}`))}createGroup(e){const t=document.createElementNS(A,"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}setTotalRootSvgHeight(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,n){const o=document.createElementNS(A,"line");o.setAttribute("x1",e.toString()),o.setAttribute("y1",t.toString()),o.setAttribute("x2",s.toString()),o.setAttribute("y2",r.toString()),o.setAttribute("stroke","currentColor"),o.setAttribute("stroke-width","1"),n.appendChild(o)}drawRect(e,t,s,r){const n=document.createElementNS(A,"rect");return n.setAttribute("width",e.toString()),n.setAttribute("height",t.toString()),n.setAttribute("x",(r?.x??0).toString()),n.setAttribute("y",(r?.y??0).toString()),r?.fill?n.setAttribute("fill",r.fill):n.setAttribute("fill","currentColor"),r?.rx&&n.setAttribute("rx",r.rx.toString()),r?.classes&&this.addNamespacedClassesToElement(r.classes,n),s.appendChild(n),n}drawGlyph(e,t,s){s={xOffset:0,yOffset:0,...s};const r=document.createElementNS(A,"use");r.setAttribute("href",`#glyph-${e}`),(s.xOffset||s.yOffset)&&r.setAttribute("transform",`translate(${s.xOffset}, ${s.yOffset})`),t.appendChild(r)}drawCircle(e,t,s,r,n){const o=document.createElementNS(A,"circle");return o.setAttribute("cx",e.toString()),o.setAttribute("cy",t.toString()),o.setAttribute("r",s.toString()),n?.filled===!1?(o.setAttribute("fill","none"),o.setAttribute("stroke","currentColor"),o.setAttribute("stroke-width",(n?.strokeWidth??1.5).toString())):o.setAttribute("fill",n?.fill??"currentColor"),n?.classes&&this.addNamespacedClassesToElement(n.classes,o),r.appendChild(o),o}drawText(e,t,s,r,n){const o=document.createElementNS(A,"text");return o.setAttribute("x",t.toString()),o.setAttribute("y",s.toString()),o.setAttribute("text-anchor",n?.anchor??"middle"),o.setAttribute("fill",n?.fill??"currentColor"),n?.fontSize&&o.setAttribute("font-size",n.fontSize+"px"),n?.fontWeight&&o.setAttribute("font-weight",n.fontWeight),n?.classes&&this.addNamespacedClassesToElement(n.classes,o),o.textContent=e,r.appendChild(o),o}destroy(){this.rootElementRef&&this.svgElementRef&&this.rootElementRef.contains(this.svgElementRef)&&this.rootElementRef.removeChild(this.svgElementRef)}}const Nt=["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 Lt{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 w(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:Nt});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new rt(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new C(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new C(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new C(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 nt(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const n=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(n)}if(this.options.spaceBelow){let n=this.options.spaceBelow*10;this.options.staffType==="grand"&&(n-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(n)}let r=0;this.options.keySignature&&(r=this.createKeySignature(this.options.keySignature)),this.noteStartX=38+this.options.noteStartX+r,this.svgRendererInstance.getLayerByName("notes").setAttribute("transform",`translate(${this.noteStartX}, 0)`),this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}createKeySignature(e){return It(this.svgRendererInstance,this.strategyInstance,e,pt)}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.svgRendererInstance.getLayerByName("notes"),r=[];for(const n of t){let o;try{o=this.noteRendererInstance.renderNote(n)}catch(i){throw r.length>0&&this.svgRendererInstance.commitElementsToDOM(r,s),i}o.noteGroup.setAttribute("transform",`translate(${this.noteCursorX+o.accidentalOffset}, ${o.noteYPos})`),this.noteEntries.push({gElement:o.noteGroup,note:o.noteObj,xPos:this.noteCursorX+o.accidentalOffset,yPos:o.noteYPos,accidentalXOffset:o.accidentalOffset}),this.noteCursorX+=28+o.accidentalOffset,r.push(o.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:D(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-this.noteStartX,t=this.noteEntries.length;if(t<=0||e<=0)return;const s=Math.round(e/t);this.noteEntries.map((n,o)=>{const i=(o+.5)*s,a=n.gElement.getBBox(),c=i-a.width/2-a.x,l=Math.round(c*10)/10;return{entry:n,newX:l,isChord:n.gElement.classList.contains("chord")}}).forEach(n=>{const{entry:o,newX:i,isChord:a}=n;a?o.gElement.setAttribute("transform",`translate(${i}, 0)`):o.gElement.setAttribute("transform",`translate(${i}, ${o.yPos})`),o.xPos=i})}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),o=s.xPos-s.accidentalXOffset+r.accidentalOffset;r.noteGroup.setAttribute("transform",`translate(${o}, ${r.noteYPos})`),this.svgRendererInstance.getLayerByName("notes").replaceChild(r.noteGroup,s.gElement),this.noteEntries[t]={gElement:r.noteGroup,note:r.noteObj,xPos:o,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),o=s.xPos-s.accidentalXOffset+r.accidentalOffset;r.noteGroup.setAttribute("transform",`translate(${o}, 0)`),this.svgRendererInstance.getLayerByName("notes").replaceChild(r.noteGroup,s.gElement),this.noteEntries[t]={gElement:r.noteGroup,note:D(e[0]),xPos:o,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 T=30,ot=19,X=12,Rt=4,yt=6,it=1,U=38,wt=["TIME_4","TIME_3","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","REST_WHOLE","REST_HALF","REST_QUARTER","REST_EIGHTH"];class Ot{rendererInstance;options;barSpacing;quarterNoteSpacing;noteCursorX=0;noteEntries=[];maxBeatCount;currentBeatCount=0;currentBeatUICount=0;currentBeatUIElement=null;currentBeatUIXPos=U;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 w(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:wt});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 f=this.options.spaceAbove*10;this.rendererInstance.addTotalRootSvgYOffset(f)}if(this.options.spaceBelow){let f=this.options.spaceBelow*10;this.rendererInstance.addTotalRootSvgHeight(f)}const n=this.rendererInstance.getLayerByName("staff");this.rendererInstance.addTotalRootSvgHeight(T*2);const o=this.rendererInstance.createGroup("time-signature");n.appendChild(o);const i=T-ot;this.rendererInstance.drawGlyph(r,o),this.rendererInstance.drawGlyph("TIME_4",o,{yOffset:ot}),o.setAttribute("transform",`translate(0, ${i})`);let a=this.options.width-38;this.options.barsCount>1&&(a-=(this.options.barsCount-1)*X),a-=it,this.rendererInstance.drawLine(0,T,this.options.width-it,T,n),this.barSpacing=a/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=T/2,d=T+l;for(let f=0;f<this.options.barsCount-1;f++)this.rendererInstance.drawLine(c,l,c,d,n),c+=this.barSpacing;this.rendererInstance.getLayerByName("notes").setAttribute("transform",`translate(38, ${T})`),this.rendererInstance.applySizingToRootSvg(),this.rendererInstance.commitElementsToDOM(s)}createBeatUIElement(){const e=this.rendererInstance.getLayerByName("ui");this.currentBeatUIElement=this.rendererInstance.drawRect(this.quarterNoteSpacing/2,T*2,e,{x:U,fill:this.options.currentBeatUIColor})}handleNewBar(){this.noteCursorX+=X}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 n=0;s-I.h>=0?(this.rendererInstance.drawGlyph("REST_HALF",r),n=I.h):s-I.q>=0?(this.rendererInstance.drawGlyph("REST_QUARTER",r),n=I.q):(this.rendererInstance.drawGlyph("REST_EIGHTH",r),n=I.e),s-=n,this.currentBeatCount+=n,r.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=n*this.quarterNoteSpacing,t.push(r)}return t}renderBeamRect(e,t,s,r){this.rendererInstance.drawRect(e-t,Rt,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 n of t){let o="w";try{o=H(n)}catch(d){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),d}const i=I[o];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 a=this.checkAndFillBarWithRests(i);a&&a.forEach(d=>{r.push(d),this.noteEntries.push(d)});const c=this.rendererInstance.createGroup("note"),l=this.translateGroupByDuration(i,c);this.noteCursorX+=l,this.currentBeatCount+=i,this.renderNote(o,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 n of t){let o="w";try{o=H(n)}catch(d){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),d}const i=this.rendererInstance.createGroup("rest"),a=I[o],c=a*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(a);l&&l.forEach(d=>{r.push(d),this.noteEntries.push(d)}),this.renderRest(o,i),i.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=c,this.currentBeatCount+=a,r.push(i),this.noteEntries.push(i)}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=H(e),this.checkAndCreateNewBar();const r=this.rendererInstance.getLayerByName("notes"),n=I[s],o=n*this.quarterNoteSpacing,i=this.options.topNumber-this.currentBeatCount%this.options.topNumber,a=Math.min(t,i/n),c=this.rendererInstance.createGroup("beamed-note");c.setAttribute("transform",`translate(${this.noteCursorX}, 0)`);let l=0;for(let d=0;d<a;d++)this.rendererInstance.drawGlyph("NOTE_HEAD_QUARTER",c,{xOffset:l}),this.drawStem(c,l),l+=o,this.currentBeatCount+=n;this.renderBeamRect(l,o,c),e==="s"&&this.renderBeamRect(l,o,c,yt),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+=X),this.currentBeatUICount>1&&(this.currentBeatUIXPos+=this.quarterNoteSpacing),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString())}resetCurrentBeatUI(){this.currentBeatUICount=0,this.currentBeatUIXPos=U,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 bt=["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"],O=60,Gt=O;class vt{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 w(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:bt});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new rt(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new C(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new C(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new C(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 nt(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+Gt;for(;this.noteBuffer.length>0&&this.noteCursorX<e;)this.renderNextNote(),this.noteCursorX+=O;this.activeEntries.length>1&&(this.noteCursorX-=O)}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-=O,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=[]}}const Ft=/^[xX\da-zA-Z]+$/,Dt=/^[\d]+$/;function at(h,e){const t=[];for(let s=0;s<h.length;s++)t.push({fret:h[s],finger:e[s]});return t}function ct(h,e){const t=h.filter(n=>n.toLowerCase()!=="x"&&n!=="0").map(n=>parseInt(n,36));if(t.length===0)return 1;const s=Math.min(...t);return Math.max(...t)<=e?1:s}function Y(h){if(!Ft.test(h))throw new Error("Invalid frets string. Only 'x', 'X', and digits are allowed.");return h.split("")}function M(h){if(!Dt.test(h))throw new Error("Invalid fingers string. Only digits are allowed.");return h.split("")}class Ht{svgRendererInstance;options;chordEntries=[];cursorX=0;cursorY=0;diagramWidth;diagramHeight;gridTopY;rowHeight;constructor(e,t){if(this.options={stringCount:ht,fretCount:lt,stringLabels:[],inlineChordsAmount:2,scale:1,color:"black",backgroundColor:"transparent",...t},this.diagramWidth=(this.options.stringCount-1)*_,this.diagramHeight=this.options.fretCount*m,this.gridTopY=z+V,this.rowHeight=this.gridTopY+this.diagramHeight+W,t?.width?this.options.width=t.width:this.options.width=(this.diagramWidth+k)*this.options.inlineChordsAmount,this.options.stringLabels.length>=1&&(this.rowHeight+=ft+dt),this.diagramWidth>this.options.width)throw new Error(`The configured width (${this.options.width}) is too small to fit a single ${this.options.stringCount}-string diagram (needs at least ${this.diagramWidth}). Increase 'width'.`);this.svgRendererInstance=new w(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.color,staffBackgroundColor:this.options.backgroundColor,useGlyphs:[]});const s=this.svgRendererInstance.rootSvgElement;this.svgRendererInstance.setTotalRootSvgHeight(this.rowHeight),this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}getDotsToHide(e){const t=new Set;return e&&e.forEach(s=>{const r=s.fromString-1,n=s.toString-1;for(let o=r;o<=n;o++)t.add(`${o}-${s.fret}`)}),t}drawFretDots(e,t,s,r,n){const o=this.gridTopY-V/2;for(let i=0;i<this.options.stringCount;i++){const a=i*_,c=e[i].toLowerCase(),l=t[i];if(c==="x")this.svgRendererInstance.drawLine(a-E,o-E,a+E,o+E,n),this.svgRendererInstance.drawLine(a-E,o+E,a+E,o-E,n);else if(c==="0")this.svgRendererInstance.drawCircle(a,o,E,n,{filled:!1});else{const d=parseInt(c,36);if(r.has(`${i}-${d}`))continue;const f=d-s+1;if(f<1||f>this.options.fretCount)throw new Error(`Fret ${c} on string ${i+1} is outside the visible range (${s}-${s+this.options.fretCount-1}). Adjust 'startFret' or 'fretCount'.`);const L=this.gridTopY+(f-.5)*m;if(this.svgRendererInstance.drawCircle(a,L,u,n,{classes:"guitar-fret-dot"}),l!=="0"){const g=this.options.backgroundColor==="transparent"?"white":this.options.backgroundColor;this.svgRendererInstance.drawText(l,a,L+S/3,n,{fontSize:S,fill:g,classes:"guitar-text-small"})}}}}drawStringLabels(e,t){if(!t||t.length===0)return;const s=u,r=this.rowHeight-s-W;for(let n=0;n<this.options.stringCount;n++){const o=t[n];if(!o)continue;const i=n*_,a=r+s/2;this.svgRendererInstance.drawText(o,i,a,e,{fontSize:S,classes:"guitar-text-small"})}}drawBarre(e,t){const s=t.fret;if(t.fromIndex<0||t.toIndex>=this.options.stringCount||t.fromIndex>=t.toIndex)throw new Error(`Barre fret error: Invalid string range ${t.fromIndex+1}:${t.toIndex+1}.`);if(s<t.startingFret||s>t.startingFret+(this.options.fretCount-1))throw new Error(`Barre fret error: ${t.fret} is outside the visible range.`);const r=s-t.startingFret,n=t.fromIndex*_,o=t.toIndex*_,i=u*2,a=o-n+i,c=this.gridTopY+u/2+m*r,l=this.gridTopY+m*r+u*2;if(this.svgRendererInstance.drawRect(a,i,e,{x:n-u,y:c,rx:u,classes:"guitar-barre"}),t.finger){const d=this.options.backgroundColor==="transparent"?"white":this.options.backgroundColor;this.svgRendererInstance.drawText(t.finger.toString(),(n+o)/2,l,e,{fontSize:S,fill:d,classes:"guitar-text-small"})}}renderChordDiagram(e,t,s){const r=this.svgRendererInstance.createGroup("chord"),n=s?.startFret??1;s?.label&&this.svgRendererInstance.drawText(s.label,this.diagramWidth/2,z-5,r,{fontSize:q,fontWeight:"bold",classes:"guitar-text-base"});for(let i=0;i<=this.options.fretCount;i++){const a=this.gridTopY+i*m;i===0&&n===1?this.svgRendererInstance.drawRect(this.diagramWidth+Z*2,G,r,{x:-Z,y:a-G/2}):this.svgRendererInstance.drawLine(0,a,this.diagramWidth,a,r)}n>1&&this.svgRendererInstance.drawText(`${n}fr`,this.diagramWidth+u+gt,this.gridTopY+m/2+4,r,{anchor:"start",fontSize:S,fontWeight:"bold",classes:"guitar-text-small"});for(let i=0;i<this.options.stringCount;i++){const a=i*_;this.svgRendererInstance.drawLine(a,this.gridTopY,a,this.gridTopY+this.diagramHeight,r)}const o=this.getDotsToHide(s?.barres);return this.drawFretDots(e,t,n,o,r),this.options.stringLabels.length>=1&&this.drawStringLabels(r,this.options.stringLabels),s?.barres?.forEach(i=>{this.drawBarre(r,{fromIndex:i.fromString-1,toIndex:i.toString-1,fret:i.fret,finger:i.finger,startingFret:n})}),r}relayoutChords(){if(this.cursorX=u,this.cursorY=Et,this.chordEntries.length===1){const t=this.chordEntries[0];this.cursorX=this.options.width/2-this.diagramWidth/2,t.xPos=this.cursorX,t.yPos=this.cursorY,t.gElement.setAttribute("transform",`translate(${this.cursorX}, ${this.cursorY})`)}else this.chordEntries.forEach((t,s)=>{s>0&&this.cursorX+this.diagramWidth>this.options.width&&(this.cursorX=u,this.cursorY+=this.rowHeight+ut),t.xPos=this.cursorX,t.yPos=this.cursorY,t.gElement.setAttribute("transform",`translate(${this.cursorX}, ${this.cursorY})`),this.cursorX+=this.diagramWidth+k});const e=this.cursorY+this.rowHeight;this.svgRendererInstance.setTotalRootSvgHeight(e),this.svgRendererInstance.applySizingToRootSvg()}addChord(e,t,s){const r=Y(e),n=M(t);if(r.length!==this.options.stringCount)throw new Error("Invalid number of frets provided, entries should be equal to number of strings in diagram.");if(n.length!==this.options.stringCount)throw new Error("Invalid number of fingers provided, entries should be equal to number of strings in diagram.");const o=s?.startFret??ct(r,this.options.fretCount),i=s?.label,a=s?.barres,c={startFret:o,label:i,barres:a},l=this.renderChordDiagram(r,n,c),d=this.svgRendererInstance.getLayerByName("notes");return this.svgRendererInstance.commitElementsToDOM(l,d),this.chordEntries.push({gElement:l,strings:at(r,n),...c,xPos:0,yPos:0}),this.relayoutChords(),this.chordEntries.length-1}modifyChordByIndex(e,t,s,r){if(s>=this.chordEntries.length||s<0)throw new Error("Chord index was out of bounds.");const n=Y(e),o=M(t);if(n.length!==this.options.stringCount)throw new Error("Invalid number of frets provided, entries should be equal to number of strings in diagram.");if(o.length!==this.options.stringCount)throw new Error("Invalid number of fingers provided, entries should be equal to number of strings in diagram.");const i=this.chordEntries[s],a=r&&"label"in r?r.label===""?void 0:r.label:i.label,c=r?.startFret??ct(n,this.options.fretCount),l={...r,label:a,startFret:c},d=this.renderChordDiagram(n,o,l);this.svgRendererInstance.getLayerByName("notes").replaceChild(d,i.gElement),this.chordEntries[s]={gElement:d,strings:at(n,o),...l,xPos:i.xPos,yPos:i.yPos},this.relayoutChords()}removeChordByIndex(e){if(e>=this.chordEntries.length||e<0)throw new Error("Chord index was out of bounds.");this.chordEntries[e].gElement.remove(),this.chordEntries.splice(e,1),this.relayoutChords()}clearAllChords(){this.svgRendererInstance.getLayerByName("notes").replaceChildren(),this.chordEntries=[],this.cursorX=0,this.cursorY=0,this.svgRendererInstance.setTotalRootSvgHeight(this.rowHeight),this.svgRendererInstance.applySizingToRootSvg()}determineBarreOptions(e,t,s){const r=Y(e),n=M(t),o=[];return s.forEach(i=>{if(i===0)return;const a=[],c={};for(let g=0;g<r.length;g++){if(r[g].toLowerCase()==="x")continue;const b=parseInt(r[g],36),$=Number(n[g]);b===i&&(c[$]?c[$]+=1:c[$]=1,a.push(g+1))}a.sort();let l=0,d=0;for(const[g,b]of Object.entries(c))b>d&&(d=b,l=Number(g));const f=a[0],L=a.at(-1);a.length>1&&L&&o.push({fret:i,fromString:f,toString:L,finger:l})}),o}destroy(){this.chordEntries=[],this.svgRendererInstance.destroy()}}p.GuitarChord=Ht,p.MusicStaff=Lt,p.RhythmStaff=Ot,p.ScrollingStaff=vt,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vector-score",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -35,6 +35,7 @@
35
35
  "devDependencies": {
36
36
  "@types/node": "^25.0.0",
37
37
  "jsdom": "^27.3.0",
38
+ "render-scan": "^0.0.3",
38
39
  "typescript": "~5.9.3",
39
40
  "vite": "^7.2.4",
40
41
  "vite-plugin-dts": "^4.5.4",