vector-score 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- (function(u,S){typeof exports=="object"&&typeof module<"u"?S(exports):typeof define=="function"&&define.amd?define(["exports"],S):(u=typeof globalThis<"u"?globalThis:u||self,S(u.VectorScore={}))})(this,(function(u){"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}},A={w:4,h:2,q:1,e:.5,s:.25},nt=6,ot=5,_=22,m=30,f=10,E=6,it=4,at=f*2,ct=40,ht=16,Y=1,w=4,M=1,$=E*2+w+4,O=16,L=14,lt=14,k=O,dt=f+2,W=8,ft=40,Z={sharp:["F","C","G","D","A","E","B"],flat:["B","E","A","D","G","C","F"]},V={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}},b={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 Et(h){const e=V[h];if(!e)throw new Error(`Unknown key signature "${h}". Valid keys: ${Object.keys(V).join(", ")}`);return e}function ut(h,e,t,s){const r=Et(t);if(r.count===0)return 0;const o=r.type==="sharp"?"ACCIDENTAL_SHARP":"ACCIDENTAL_FLAT",n=h.getLayerByName("staff");return e.getKeySignatureYPositions(r.type,r.count).forEach(a=>{a.forEach((c,l)=>{h.drawGlyph(o,n,{xOffset:s+l*W,yOffset:c})})}),r.count*W}const gt={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}},pt=/^(?<name>[A-Ga-g])(?<accidental>##|bb|[#bn]?)(?<octave>\d)(?<duration>[whqeWHQE]?)$/,At=/^[whqeWHQE]$/,v=["C","D","E","F","G","A","B"];function G(h){const e=h.match(pt);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;t=t.toUpperCase(),o=o.toLowerCase(),o||(o="w");const n={name:t,octave:parseInt(r),duration:o};return s&&(n.accidental=s),n}function F(h){const e=h.match(At);if(!e)throw new Error(`Invalid note duration '${h}'. Use w | h | q | e.`);return e[0].toString().toLowerCase()}function D(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 q(h){let e=v.indexOf(h.name);return e+=h.octave*12,e}function C(h,e){return v.indexOf(h.name)-v.indexOf(e.name)+(h.octave-e.octave)*7}const B=48,z=40+30/2,j=20,K=90;class Q{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 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 o=r,n=1;const i=D("treble"),a=D("bass");this.rendererRef.drawGlyph(i,t),this.rendererRef.drawGlyph(a,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-K),s=Math.abs(e-j);return e===z?!1:t<=s?!(e>=K):e<=j}getLedgerLinesX(e,t){const s=[],r=q(e);let o=e.duration==="w"?17:12.5;if(r===B)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=C(this.params.topLineNote,e)*(10/2);const r=q(e);return r<B?s+=10:r===B&&(s=z),s};getKeySignatureYPositions(e,t){const s=Z[e].slice(0,t),r=b.treble[e],o=b.bass[e],n=s.map((a,c)=>C(N.treble.topLineNote,{name:a,octave:r[c]})*(10/2)),i=s.map((a,c)=>C(N.bass.topLineNote,{name:a,octave:o[c]})*(10/2)+this.trebleStaffHeight+30);return[n,i]}}const It=20;class T{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 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,o=1;const n=D(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<=It}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=>C(this.params.topLineNote,e)*(10/2);getKeySignatureYPositions(e,t){const s=Z[e].slice(0,t),r=b[this.params.staffType][e];return[s.map((n,i)=>this.calculateNoteYPos({name:n,octave:r[i]}))]}}class J{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 a=Array.from(n.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 o=e[r];if(-C(t.noteObj,o.noteObj)===1){s=28/2,o.noteGroup.setAttribute("transform",`translate(${s}, ${o.noteYPos})`);const a=Array.from(o.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=o}return s}renderNote(e){const t=this.svgRendererInstance.createGroup("note"),s=G(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(a=>{this.svgRendererInstance.drawLine(a.x1,a.yPos,a.x2,a.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 i=this.renderNote(n);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),o=this.chordOffsetCloseNotes(s);return{noteGroup:t,noteObj:s[0].noteObj,noteYPos:0,accidentalOffset:r,cursorOffset:o}}}const g="http://www.w3.org/2000/svg",_t=.1,H=1200;class R{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>H&&(this.width=H,console.warn(`Width provided for the staff ${this.width} exceeds the limit ${H}. Please use this value to fix positioning issues.`)),this.svgElementRef=document.createElementNS(g,"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(g,"defs");Object.entries(gt).filter(([r])=>e.includes(r)).forEach(([r,o])=>{const n=document.createElementNS(g,"path");n.setAttribute("id",`glyph-${r}`),n.setAttribute("d",o.path),n.setAttribute("fill","currentColor"),n.setAttribute("transform",`translate(${o.xOffset}, ${o.yOffset}) scale(${_t})`),t.appendChild(n)}),this.rootSvgElement.appendChild(t)}createGroup(e){const t=document.createElementNS(g,"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,o){const n=document.createElementNS(g,"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(g,"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"),r?.rx&&o.setAttribute("rx",r.rx.toString()),s.appendChild(o),o}drawGlyph(e,t,s){s={xOffset:0,yOffset:0,...s};const r=document.createElementNS(g,"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,o){const n=document.createElementNS(g,"circle");return n.setAttribute("cx",e.toString()),n.setAttribute("cy",t.toString()),n.setAttribute("r",s.toString()),o?.filled===!1?(n.setAttribute("fill","none"),n.setAttribute("stroke","currentColor"),n.setAttribute("stroke-width",(o?.strokeWidth??1.5).toString())):n.setAttribute("fill",o?.fill??"currentColor"),r.appendChild(n),n}drawText(e,t,s,r,o){const n=document.createElementNS(g,"text");return n.setAttribute("x",t.toString()),n.setAttribute("y",s.toString()),n.setAttribute("text-anchor",o?.anchor??"middle"),n.setAttribute("font-size",(o?.fontSize??10).toString()),n.setAttribute("fill",o?.fill??"currentColor"),o?.fontWeight&&n.setAttribute("font-weight",o.fontWeight),n.textContent=e,r.appendChild(n),n}destroy(){this.rootElementRef&&this.svgElementRef&&this.rootElementRef.contains(this.svgElementRef)&&this.rootElementRef.removeChild(this.svgElementRef)}}const Tt=["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 mt{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 R(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:Tt});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new Q(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new T(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new T(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new T(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 J(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const o=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(o)}if(this.options.spaceBelow){let o=this.options.spaceBelow*10;this.options.staffType==="grand"&&(o-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(o)}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 ut(this.svgRendererInstance,this.strategyInstance,e,ft)}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(i){throw r.length>0&&this.svgRendererInstance.commitElementsToDOM(r,s),i}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:G(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((o,n)=>{const i=(n+.5)*s,a=o.gElement.getBBox(),c=i-a.width/2-a.x,l=Math.round(c*10)/10;return{entry:o,newX:l,isChord:o.gElement.classList.contains("chord")}}).forEach(o=>{const{entry:n,newX:i,isChord:a}=o;a?n.gElement.setAttribute("transform",`translate(${i}, 0)`):n.gElement.setAttribute("transform",`translate(${i}, ${n.yPos})`),n.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),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:G(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 I=30,tt=19,P=12,Ct=4,St=6,et=1,x=38,Nt=["TIME_4","TIME_3","NOTE_HEAD_WHOLE","NOTE_HEAD_HALF","NOTE_HEAD_QUARTER","EIGHTH_NOTE","REST_WHOLE","REST_HALF","REST_QUARTER","REST_EIGHTH"];class Lt{rendererInstance;options;barSpacing;quarterNoteSpacing;noteCursorX=0;noteEntries=[];maxBeatCount;currentBeatCount=0;currentBeatUICount=0;currentBeatUIElement=null;currentBeatUIXPos=x;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 R(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:Nt});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 p=this.options.spaceAbove*10;this.rendererInstance.addTotalRootSvgYOffset(p)}if(this.options.spaceBelow){let p=this.options.spaceBelow*10;this.rendererInstance.addTotalRootSvgHeight(p)}const o=this.rendererInstance.getLayerByName("staff");this.rendererInstance.addTotalRootSvgHeight(I*2);const n=this.rendererInstance.createGroup("time-signature");o.appendChild(n);const i=I-tt;this.rendererInstance.drawGlyph(r,n),this.rendererInstance.drawGlyph("TIME_4",n,{yOffset:tt}),n.setAttribute("transform",`translate(0, ${i})`);let a=this.options.width-38;this.options.barsCount>1&&(a-=(this.options.barsCount-1)*P),a-=et,this.rendererInstance.drawLine(0,I,this.options.width-et,I,o),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=I/2,d=I+l;for(let p=0;p<this.options.barsCount-1;p++)this.rendererInstance.drawLine(c,l,c,d,o),c+=this.barSpacing;this.rendererInstance.getLayerByName("notes").setAttribute("transform",`translate(38, ${I})`),this.rendererInstance.applySizingToRootSvg(),this.rendererInstance.commitElementsToDOM(s)}createBeatUIElement(){const e=this.rendererInstance.getLayerByName("ui");this.currentBeatUIElement=this.rendererInstance.drawRect(this.quarterNoteSpacing/2,I*2,e,{x,fill:this.options.currentBeatUIColor})}handleNewBar(){this.noteCursorX+=P}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-A.h>=0?(this.rendererInstance.drawGlyph("REST_HALF",r),o=A.h):s-A.q>=0?(this.rendererInstance.drawGlyph("REST_QUARTER",r),o=A.q):(this.rendererInstance.drawGlyph("REST_EIGHTH",r),o=A.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,Ct,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=F(o)}catch(d){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),d}const i=A[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 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(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=F(o)}catch(d){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),d}const i=this.rendererInstance.createGroup("rest"),a=A[n],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(n,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=F(e),this.checkAndCreateNewBar();const r=this.rendererInstance.getLayerByName("notes"),o=A[s],n=o*this.quarterNoteSpacing,i=this.options.topNumber-this.currentBeatCount%this.options.topNumber,a=Math.min(t,i/o),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+=n,this.currentBeatCount+=o;this.renderBeamRect(l,n,c),e==="s"&&this.renderBeamRect(l,n,c,St),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+=P),this.currentBeatUICount>1&&(this.currentBeatUIXPos+=this.quarterNoteSpacing),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString())}resetCurrentBeatUI(){this.currentBeatUICount=0,this.currentBeatUIXPos=x,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 Rt=["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"],y=60,yt=y;class wt{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 R(e,{width:this.options.width,height:100,scale:this.options.scale,staffColor:this.options.staffColor,staffBackgroundColor:this.options.staffBackgroundColor,useGlyphs:Rt});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new Q(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new T(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new T(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new T(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 J(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+yt;for(;this.noteBuffer.length>0&&this.noteCursorX<e;)this.renderNextNote(),this.noteCursorX+=y;this.activeEntries.length>1&&(this.noteCursorX-=y)}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-=y,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 Ot=/^[xX\da-zA-Z]+$/,bt=/^[\d]+$/;function st(h,e){const t=[];for(let s=0;s<h.length;s++)t.push({fret:h[s],finger:e[s]});return t}function rt(h,e){const t=h.filter(o=>o.toLowerCase()!=="x"&&o!=="0").map(o=>parseInt(o,36));if(t.length===0)return 1;const s=Math.min(...t);return Math.max(...t)<=e?1:s}function X(h){if(!Ot.test(h))throw new Error("Invalid frets string. Only 'x', 'X', and digits are allowed.");return h.split("")}function U(h){if(!bt.test(h))throw new Error("Invalid fingers string. Only digits are allowed.");return h.split("")}class vt{svgRendererInstance;options;chordEntries=[];cursorX=0;cursorY=0;diagramWidth;diagramHeight;gridTopY;rowHeight;constructor(e,t){if(this.options={width:300,scale:1,stringCount:nt,fretCount:ot,stringLabels:[],color:"black",backgroundColor:"transparent",...t},this.diagramWidth=(this.options.stringCount-1)*_,this.diagramHeight=this.options.fretCount*m,this.gridTopY=k+$,this.rowHeight=this.gridTopY+this.diagramHeight+Y,this.options.stringLabels.length>=1&&(this.rowHeight+=at+it),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 R(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)}drawStringDots(e,t,s,r){const o=this.gridTopY-$/2;for(let n=0;n<this.options.stringCount;n++){const i=n*_,a=e[n].toLowerCase(),c=t[n];if(a==="x")this.svgRendererInstance.drawLine(i-E,o-E,i+E,o+E,r),this.svgRendererInstance.drawLine(i-E,o+E,i+E,o-E,r);else if(a==="0")this.svgRendererInstance.drawCircle(i,o,E,r,{filled:!1});else{const l=parseInt(a,36)-s+1;if(l<1||l>this.options.fretCount)throw new Error(`Fret ${a} on string ${n+1} is outside the visible range (${s}-${s+this.options.fretCount-1}). Adjust 'startFret' or 'fretCount'.`);const d=this.gridTopY+(l-.5)*m;if(this.svgRendererInstance.drawCircle(i,d,f,r),c!=="0"){const p=this.options.backgroundColor==="transparent"?"white":this.options.backgroundColor;this.svgRendererInstance.drawText(c,i,d+L/3,r,{fontSize:L,fill:p})}}}}drawStringLabels(e,t){if(!t||t.length===0)return;const s=f-1,r=this.rowHeight-s-Y;for(let o=0;o<this.options.stringCount;o++){const n=t[o];if(!n)continue;const i=o*_,a=r+s/2;this.svgRendererInstance.drawCircle(i,r,s,e,{filled:!1}),this.svgRendererInstance.drawText(n,i,a,e,{fontSize:O})}}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,o=t.fromIndex*_,n=t.toIndex*_,i=f*2,a=n-o+i,c=this.gridTopY+f/2+m*r;if(this.svgRendererInstance.drawRect(a,i,e,{x:o-f,y:c,rx:f}),t.finger){const l=this.options.backgroundColor==="transparent"?"white":this.options.backgroundColor;this.svgRendererInstance.drawText(t.finger.toString(),(o+n)/2,c+L,e,{fontSize:L,fill:l})}}renderChordDiagram(e,t,s){const r=this.svgRendererInstance.createGroup("chord"),o=s?.startFret??1;s?.label&&this.svgRendererInstance.drawText(s.label,this.diagramWidth/2,k-5,r,{fontSize:O,fontWeight:"bold"});for(let n=0;n<=this.options.fretCount;n++){const i=this.gridTopY+n*m;n===0&&o===1?this.svgRendererInstance.drawRect(this.diagramWidth+M*2,w,r,{x:-M,y:i-w/2}):this.svgRendererInstance.drawLine(0,i,this.diagramWidth,i,r)}o>1&&this.svgRendererInstance.drawText(`${o}fr`,this.diagramWidth+dt,this.gridTopY+m/2+4,r,{anchor:"start",fontSize:lt,fontWeight:"bold"});for(let n=0;n<this.options.stringCount;n++){const i=n*_;this.svgRendererInstance.drawLine(i,this.gridTopY,i,this.gridTopY+this.diagramHeight,r)}return this.drawStringDots(e,t,o,r),this.options.stringLabels.length>=1&&this.drawStringLabels(r,this.options.stringLabels),s?.barres?.forEach(n=>{this.drawBarre(r,{fromIndex:n.fromString-1,toIndex:n.toString-1,fret:n.fret,finger:n.finger,startingFret:o})}),r}relayoutChords(){if(this.cursorX=f,this.cursorY=0,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=f,this.cursorY+=this.rowHeight+ht),t.xPos=this.cursorX,t.yPos=this.cursorY,t.gElement.setAttribute("transform",`translate(${this.cursorX}, ${this.cursorY})`),this.cursorX+=this.diagramWidth+ct});const e=this.cursorY+this.rowHeight;this.svgRendererInstance.setTotalRootSvgHeight(e),this.svgRendererInstance.applySizingToRootSvg()}addChord(e,t,s){const r=X(e),o=U(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(o.length!==this.options.stringCount)throw new Error("Invalid number of fingers provided, entries should be equal to number of strings in diagram.");const n=s?.startFret??rt(r,this.options.fretCount),i=s?.label,a=s?.barres,c={startFret:n,label:i,barres:a},l=this.renderChordDiagram(r,o,c),d=this.svgRendererInstance.getLayerByName("notes");return this.svgRendererInstance.commitElementsToDOM(l,d),this.chordEntries.push({gElement:l,strings:st(r,o),...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 o=X(e),n=U(t);if(o.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 i=this.chordEntries[s],a=r&&"label"in r?r.label===""?void 0:r.label:i.label,c=r?.startFret??rt(o,this.options.fretCount),l={...r,label:a,startFret:c},d=this.renderChordDiagram(o,n,l);this.svgRendererInstance.getLayerByName("notes").replaceChild(d,i.gElement),this.chordEntries[s]={gElement:d,strings:st(o,n),...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=X(e),o=U(t),n=[];return s.forEach(i=>{const a={};for(let c=0;c<r.length;c++){if(r[c].toLowerCase()==="x")continue;if(parseInt(r[c],36)===i&&o[c]!=="0"){const d=o[c];a[d]||(a[d]=[]),a[d].push(c)}}for(const[c,l]of Object.entries(a))l.length>1&&n.push({fret:i,fromString:Math.min(...l)+1,toString:Math.max(...l)+1,finger:Number(c)})}),n}destroy(){this.chordEntries=[],this.svgRendererInstance.destroy()}}u.GuitarChord=vt,u.MusicStaff=mt,u.RhythmStaff=Lt,u.ScrollingStaff=wt,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(I,L){typeof exports=="object"&&typeof module<"u"?L(exports):typeof define=="function"&&define.amd?define(["exports"],L):(I=typeof globalThis<"u"?globalThis:I||self,L(I.VectorScore={}))})(this,(function(I){"use strict";const R={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}},T={w:4,h:2,q:1,e:.5,s:.25},ct=6,ht=5,S=22,C=30,E=10,g=6,lt=4,dt=E*2,w=51,ft=12,ut=4,k=1,G=4,Et=1,Z=g*2+G+8,V=16,y=12,z=V,gt=2,q=8,pt=40,j={sharp:["F","C","G","D","A","E","B"],flat:["B","E","A","D","G","C","F"]},K={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}},F={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(l){const e=K[l];if(!e)throw new Error(`Unknown key signature "${l}". Valid keys: ${Object.keys(K).join(", ")}`);return e}function It(l,e,t,s){const r=At(t);if(r.count===0)return 0;const n=r.type==="sharp"?"ACCIDENTAL_SHARP":"ACCIDENTAL_FLAT",o=l.getLayer("staff");if(!o)throw new Error("Staff Init Error: Failed to retrieve staff layer for key signature renderering.");return e.getKeySignatureYPositions(r.type,r.count).forEach(a=>{a.forEach((h,d)=>{l.drawGlyph(n,o,{xOffset:s+d*q,yOffset:h})})}),r.count*q}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]?)$/,St=/^[whqeWHQE]$/,D=["C","D","E","F","G","A","B"];function H(l){const e=l.match(_t);if(!e||!e.groups)throw new Error(`Invalid note string format: ${l}. 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 P(l){const e=l.match(St);if(!e)throw new Error(`Invalid note duration '${l}'. Use w | h | q | e.`);return e[0].toString().toLowerCase()}function B(l){let e;switch(l){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: ${l}. Valid clef types are: treble, bass, alto.`);return e}function Q(l){let e=D.indexOf(l.name);return e+=l.octave*12,e}function N(l,e){return D.indexOf(l.name)-D.indexOf(e.name)+(l.octave-e.octave)*7}const x=48,J=40+30/2,tt=20,et=90;class st{params;rendererRef;width=0;trebleStaffHeight=0;constructor(e,t){this.rendererRef=e;const s=R[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.createLayer("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-et),s=Math.abs(e-tt);return e===J?!1:t<=s?!(e>=et):e<=tt}getLedgerLinesX(e,t){const s=[],r=Q(e);let n=e.duration==="w"?17:12.5;if(r===x)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=Q(e);return r<x?s+=10:r===x&&(s=J),s};getKeySignatureYPositions(e,t){const s=j[e].slice(0,t),r=F.treble[e],n=F.bass[e],o=s.map((a,h)=>N(R.treble.topLineNote,{name:a,octave:r[h]})*(10/2)),i=s.map((a,h)=>N(R.bass.topLineNote,{name:a,octave:n[h]})*(10/2)+this.trebleStaffHeight+30);return[o,i]}}const mt=20;class m{params;rendererRef;constructor(e,t){this.rendererRef=e;const s=R[t];if(!s)throw new Error(`Staff type ${t} is not supported`);this.params=s}drawStaff=e=>{const t=this.rendererRef.createLayer("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<=mt}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=j[e].slice(0,t),r=F[this.params.staffType][e];return[s.map((o,i)=>this.calculateNoteYPos({name:o,octave:r[i]}))]}}class rt{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(h=>h.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(h=>h.getAttribute("href")?.includes("ACCIDENTAL"));if(a){const h=a.getAttribute("transform")?.match(/([-]?\d+)/),d=h&&h[0];let c=-s;d&&(c+=Number(d)),a.setAttribute("transform",`translate(${c}, 0)`)}r++,t=e[r];continue}t=n}return s}renderNote(e){const t=this.svgRendererInstance.createGroup("note"),s=H(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 p="http://www.w3.org/2000/svg",Ct=.1,X=2;class O{rootElementRef;svgElementRef;parentGroupContainer;layers={};width;scale;totalYOffset=0;totalHeight=0;constructor(e,t){this.rootElementRef=e,this.width=t.width,this.scale=t.scale,this.svgElementRef=document.createElementNS(p,"svg"),this.svgElementRef.classList.add("vs-svg-renderer-root"),t.svgAutoFill&&(this.svgElementRef.style.maxWidth="100%",this.svgElementRef.style.height="auto"),this.makeGlyphDefs(t.useGlyphs),this.parentGroupContainer=this.createGroup("svg-renderer-parent"),this.svgElementRef.appendChild(this.parentGroupContainer)}makeGlyphDefs(e){const t=document.createElementNS(p,"defs");Object.entries(Tt).filter(([r])=>e.includes(r)).forEach(([r,n])=>{const o=document.createElementNS(p,"path");o.setAttribute("id",`glyph-${r}`),o.setAttribute("d",n.path),o.setAttribute("fill","currentColor"),o.setAttribute("transform",`translate(${n.xOffset}, ${n.yOffset}) scale(${Ct})`),t.appendChild(o)}),this.rootSvgElement.appendChild(t)}addNamespacedClassesToElement(e,t){[e].flat().forEach(r=>t.classList.add(`vs-${r}`))}createLayer(e){const t=document.createElementNS(p,"g");return t.classList.add(`vs-${e}-layer`),this.layers[e]=t,this.parentGroupContainer.appendChild(this.layers[e]),t}getLayer(e){return this.layers[e]??null}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)}addTotalRootSvgHeight(e){this.totalHeight+=e}setTotalRootSvgHeight(e){this.totalHeight=e}addTotalRootSvgYOffset(e){this.totalYOffset+=e}applySizingToRootSvg(){this.parentGroupContainer.setAttribute("transform",`translate(${X/2}, ${this.totalYOffset})`);let e=Math.round(this.width*this.scale);const t=(this.totalHeight+this.totalYOffset)*this.scale;e+=X,this.svgElementRef.setAttribute("width",e.toString()),this.svgElementRef.setAttribute("height",t.toString()),this.svgElementRef.setAttribute("viewBox",`0 0 ${this.width+X} ${this.totalHeight+this.totalYOffset}`)}get rootSvgElement(){return this.svgElementRef}get parentGroupElement(){return this.parentGroupContainer}drawLine(e,t,s,r,n,o){const i=o?.strokeWidth??1,a=document.createElementNS(p,"line");a.setAttribute("x1",e.toString()),a.setAttribute("y1",t.toString()),a.setAttribute("x2",s.toString()),a.setAttribute("y2",r.toString()),a.setAttribute("stroke","currentColor"),a.setAttribute("stroke-width",i.toString()),o?.classes&&this.addNamespacedClassesToElement(o.classes,n),n.appendChild(a)}drawRect(e,t,s,r){const n=document.createElementNS(p,"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(p,"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(p,"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(p,"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?.baseline&&o.setAttribute("dominant-baseline",n.baseline),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,svgAutoFill:!0,...t},this.svgRendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,useGlyphs:Nt,svgAutoFill:this.options.svgAutoFill});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new st(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new m(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new m(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new m(this.svgRendererInstance,"alto");break;default:throw new Error(`The staff type ${this.options.staffType} is not supported. Please use "treble", "bass", "alto", or "grand".`)}this.strategyInstance.drawStaff(this.options.width);const r=this.svgRendererInstance.createLayer("notes");if(this.noteRendererInstance=new rt(this.svgRendererInstance,this.strategyInstance),this.options.spaceAbove){const o=this.options.spaceAbove*10;this.svgRendererInstance.addTotalRootSvgYOffset(o)}if(this.options.spaceBelow){let o=this.options.spaceBelow*10;this.options.staffType==="grand"&&(o-=10/2),this.svgRendererInstance.addTotalRootSvgHeight(o)}let n=0;this.options.keySignature&&(n=this.createKeySignature(this.options.keySignature)),this.noteStartX=38+this.options.noteStartX+n,r.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.getLayer("notes");if(!s)throw new Error("DrawNote Error: Failed to retrieve notesLayer to append notes.");const 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.getLayer("notes");if(!t)throw new Error("DrawChord Error: Failed to retrieve notesLayer to append chord.");const s=this.noteRendererInstance.renderChord(e);s.noteGroup.setAttribute("transform",`translate(${this.noteCursorX+s.accidentalOffset}, 0)`),this.noteEntries.push({gElement:s.noteGroup,note:H(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(),h=i-a.width/2-a.x,d=Math.round(h*10)/10;return{entry:n,newX:d,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.getLayer("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;if(r.noteGroup.setAttribute("transform",`translate(${o}, ${r.noteYPos})`),!this.svgRendererInstance.getLayer("notes"))throw new Error("ChangeNoteByIndex Error: Failed to retrieve notesLayer to append notes.");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)`);const i=this.svgRendererInstance.getLayer("notes");if(!i)throw new Error("DrawNote Error: Failed to retrieve notesLayer to append notes.");i.replaceChild(r.noteGroup,s.gElement),this.noteEntries[t]={gElement:r.noteGroup,note:H(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 _=30,nt=19,U=12,Rt=4,wt=6,ot=1,M=38,yt=["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=M;constructor(e,t){this.options={width:300,scale:1,topNumber:4,barsCount:2,spaceAbove:0,spaceBelow:0,svgAutoFill:!0,...t},this.rendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,useGlyphs:yt,svgAutoFill:this.options.svgAutoFill});const s=this.rendererInstance.rootSvgElement,r=this.rendererInstance.createLayer("staff"),n=this.rendererInstance.createLayer("notes");this.rendererInstance.createLayer("ui");let o="TIME_4";switch(this.options.topNumber){case 3:o="TIME_3";break;case 4:o="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 u=this.options.spaceAbove*10;this.rendererInstance.addTotalRootSvgYOffset(u)}if(this.options.spaceBelow){let u=this.options.spaceBelow*10;this.rendererInstance.addTotalRootSvgHeight(u)}this.rendererInstance.addTotalRootSvgHeight(_*2);const i=this.rendererInstance.createGroup("time-signature");r.appendChild(i);const a=_-nt;this.rendererInstance.drawGlyph(o,i),this.rendererInstance.drawGlyph("TIME_4",i,{yOffset:nt}),i.setAttribute("transform",`translate(0, ${a})`);let h=this.options.width-38;this.options.barsCount>1&&(h-=(this.options.barsCount-1)*U),h-=ot,this.rendererInstance.drawLine(0,_,this.options.width-ot,_,r),this.barSpacing=h/this.options.barsCount,this.quarterNoteSpacing=Math.round(this.barSpacing/this.options.topNumber),this.maxBeatCount=this.options.barsCount*this.options.topNumber;let d=this.barSpacing+38;const c=_/2,f=_+c;for(let u=0;u<this.options.barsCount-1;u++)this.rendererInstance.drawLine(d,c,d,f,r),d+=this.barSpacing;n.setAttribute("transform",`translate(38, ${_})`),this.rendererInstance.applySizingToRootSvg(),this.rendererInstance.commitElementsToDOM(s)}createBeatUIElement(){const e=this.rendererInstance.getLayer("ui");if(!e)throw new Error("BeatUI Error: Failed to retrieve ui layer");this.currentBeatUIElement=this.rendererInstance.drawRect(this.quarterNoteSpacing/2,_*2,e,{x:M,fill:"rgba(0,255,40,0.4)",classes:"rhythm-current-beat"})}handleNewBar(){this.noteCursorX+=U}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-T.h>=0?(this.rendererInstance.drawGlyph("REST_HALF",r),n=T.h):s-T.q>=0?(this.rendererInstance.drawGlyph("REST_QUARTER",r),n=T.q):(this.rendererInstance.drawGlyph("REST_EIGHTH",r),n=T.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)})}drawNote(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayer("notes");if(!s)throw new Error("DrawNote Error: Failed to retrieve notes layer");const r=[];for(const n of t){let o="w";try{o=P(n)}catch(c){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),c}const i=T[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(c=>{r.push(c),this.noteEntries.push(c)});const h=this.rendererInstance.createGroup("note"),d=this.translateGroupByDuration(i,h);this.noteCursorX+=d,this.currentBeatCount+=i,this.renderNote(o,h),r.push(h),this.noteEntries.push(h)}this.rendererInstance.commitElementsToDOM(r,s)}drawRest(e){const t=Array.isArray(e)?e:[e],s=this.rendererInstance.getLayer("notes");if(!s)throw new Error("DrawRest Error: Failed to retrieve notes layer");const r=[];for(const n of t){let o="w";try{o=P(n)}catch(c){throw r.length>0&&this.rendererInstance.commitElementsToDOM(r,s),c}const i=this.rendererInstance.createGroup("rest"),a=T[o],h=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 d=this.checkAndFillBarWithRests(a);d&&d.forEach(c=>{r.push(c),this.noteEntries.push(c)}),this.renderRest(o,i),i.setAttribute("transform",`translate(${this.noteCursorX}, 0)`),this.noteCursorX+=h,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=P(e),this.checkAndCreateNewBar();const r=this.rendererInstance.getLayer("notes");if(!r)throw new Error("drawBeamedNotes Error: Failed to retrieve notes layer");const n=T[s],o=n*this.quarterNoteSpacing,i=this.options.topNumber-this.currentBeatCount%this.options.topNumber,a=Math.min(t,i/n),h=this.rendererInstance.createGroup("beamed-note");h.setAttribute("transform",`translate(${this.noteCursorX}, 0)`);let d=0;for(let c=0;c<a;c++)this.rendererInstance.drawGlyph("NOTE_HEAD_QUARTER",h,{xOffset:d}),this.drawStem(h,d),d+=o,this.currentBeatCount+=n;this.renderBeamRect(d,o,h),e==="s"&&this.renderBeamRect(d,o,h,wt),this.noteCursorX+=d,this.noteEntries.push(h),this.rendererInstance.commitElementsToDOM(h,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+=U),this.currentBeatUICount>1&&(this.currentBeatUIXPos+=this.quarterNoteSpacing),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString())}resetCurrentBeatUI(){this.currentBeatUICount=0,this.currentBeatUIXPos=M,this.currentBeatUIElement&&(this.currentBeatUIElement.setAttribute("display","none"),this.currentBeatUIElement.setAttribute("x",this.currentBeatUIXPos.toString()))}clearAllNotes(){this.noteCursorX=0,this.currentBeatCount=0,this.rendererInstance.getLayer("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"],b=60,vt=b;class Gt{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,svgAutoFill:!0,...t},this.svgRendererInstance=new O(e,{width:this.options.width,height:100,scale:this.options.scale,useGlyphs:bt,svgAutoFill:this.options.svgAutoFill});const s=this.svgRendererInstance.rootSvgElement;switch(this.options.staffType){case"grand":this.strategyInstance=new st(this.svgRendererInstance,"grand");break;case"bass":this.strategyInstance=new m(this.svgRendererInstance,"bass");break;case"treble":this.strategyInstance=new m(this.svgRendererInstance,"treble");break;case"alto":this.strategyInstance=new m(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 rt(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)}const r=this.svgRendererInstance.createLayer("notes");this.notesLayer=r,r.classList.add("vs-scrolling-notes-layer"),this.noteStartX=38+this.options.noteStartX,r.setAttribute("transform",`translate(${this.noteStartX}, 0)`),this.svgRendererInstance.applySizingToRootSvg(),this.svgRendererInstance.commitElementsToDOM(s)}renderFirstNoteGroups(){const e=this.options.width-this.options.noteStartX+vt;for(;this.noteBuffer.length>0&&this.noteCursorX<e;)this.renderNextNote(),this.noteCursorX+=b;this.activeEntries.length>1&&(this.noteCursorX-=b)}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-=b,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 it(l,e){const t=[];for(let s=0;s<l.length;s++)t.push({fret:l[s],finger:e[s]});return t}function at(l,e){const t=l.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(l){if(!Ft.test(l))throw new Error("Invalid frets string. Only 'x', 'X', and digits are allowed.");return l.split("")}function $(l){if(!Dt.test(l))throw new Error("Invalid fingers string. Only digits are allowed.");return l.split("")}class Ht{svgRendererInstance;options;chordEntries=[];cursorX=0;cursorY=0;diagramWidth;diagramHeight;gridTopY;rowHeight;constructor(e,t){if(this.options={stringCount:ct,fretCount:ht,stringLabels:[],inlineChordsAmount:2,centerChords:!0,scale:1,svgAutoFill:!0,...t},this.diagramWidth=(this.options.stringCount-1)*S,this.diagramHeight=this.options.fretCount*C,this.gridTopY=z+Z,this.rowHeight=this.gridTopY+this.diagramHeight+k,t?.width?this.options.width=t.width:this.options.width=(this.diagramWidth+w)*this.options.inlineChordsAmount,this.options.stringLabels.length>=1&&(this.rowHeight+=dt+lt),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 O(e,{width:this.options.width,height:100,scale:this.options.scale,useGlyphs:[],svgAutoFill:this.options.svgAutoFill});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-Z/2;for(let i=0;i<this.options.stringCount;i++){const a=i*S,h=e[i].toLowerCase(),d=t[i],c=this.svgRendererInstance.createGroup("");if(h==="x")c.classList.add("vs-guitar-fret-muted"),c.setAttribute("transform",`translate(${a}, ${o})`),this.svgRendererInstance.drawLine(-g,-g,g,g,c,{strokeWidth:1.5}),this.svgRendererInstance.drawLine(-g,g,g,-g,c,{strokeWidth:1.5});else if(h==="0")c.classList.add("vs-guitar-fret-open"),c.setAttribute("transform",`translate(${a}, ${o})`),this.svgRendererInstance.drawCircle(0,0,g,c,{filled:!1});else{const f=parseInt(h,36);if(r.has(`${i}-${f}`))continue;c.classList.add("vs-guitar-fret-dot");const u=f-s+1;if(u<1||u>this.options.fretCount)throw new Error(`Fret ${h} on string ${i+1} is outside the visible range (${s}-${s+this.options.fretCount-1}). Adjust 'startFret' or 'fretCount'.`);const A=this.gridTopY+(u-.5)*C;c.setAttribute("transform",`translate(${a}, ${A})`),this.svgRendererInstance.drawCircle(0,0,E,c,{classes:"guitar-fret-circle"}),d!=="0"&&this.svgRendererInstance.drawText(d,0,-1,c,{fontSize:y,baseline:"central",classes:["guitar-text","guitar-fret-text"]})}n.appendChild(c)}}drawStringLabels(e,t){if(!t||t.length===0)return;const s=E,r=this.rowHeight-s-k;for(let n=0;n<this.options.stringCount;n++){const o=t[n];if(!o)continue;const i=n*S;this.svgRendererInstance.drawText(o,i,r,e,{fontSize:y,baseline:"central",classes:"guitar-text"})}}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=this.svgRendererInstance.createGroup("guitar-group-barre"),n=s-t.startingFret,o=t.fromIndex*S,i=t.toIndex*S,a=E*2,h=i-o+a,d=this.gridTopY+C*n;r.setAttribute("transform",`translate(0, ${d})`),this.svgRendererInstance.drawRect(h,a,r,{x:o-E,y:E/2,rx:E,classes:"guitar-barre"}),t.finger&&this.svgRendererInstance.drawText(t.finger.toString(),(o+i)/2,E*1.5-1,r,{fontSize:y,baseline:"central",classes:["guitar-text","guitar-fret-text"]}),e.appendChild(r)}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:V,fontWeight:"bold",classes:["guitar-text","guitar-diagram-label"]}),n>1&&this.svgRendererInstance.drawText(`${n}fr`,this.diagramWidth+E+gt,this.gridTopY+C/2+4,r,{anchor:"start",fontSize:y,fontWeight:"bold",classes:["guitar-text","guitar-fret-label"]});const o=this.svgRendererInstance.createGroup("guitar-group-fret-lines");for(let c=0;c<=this.options.fretCount;c++){const f=this.gridTopY+c*C;c===0&&n===1?this.svgRendererInstance.drawRect(this.diagramWidth+Et,G,o,{x:-.5,y:f-G/2}):this.svgRendererInstance.drawLine(0,f,this.diagramWidth,f,o)}r.appendChild(o);const i=this.svgRendererInstance.createGroup("guitar-group-string-lines");for(let c=0;c<this.options.stringCount;c++){const f=c*S;this.svgRendererInstance.drawLine(f,this.gridTopY,f,this.gridTopY+this.diagramHeight,i)}r.appendChild(i);const a=this.svgRendererInstance.createGroup("guitar-group-fret-dots"),h=this.getDotsToHide(s?.barres);this.drawFretDots(e,t,n,h,a),s?.barres?.forEach(c=>{this.drawBarre(a,{fromIndex:c.fromString-1,toIndex:c.toString-1,fret:c.fret,finger:c.finger,startingFret:n})}),r.appendChild(a);const d=this.svgRendererInstance.createGroup("guitar-group-string-labels");return this.options.stringLabels.length>=1&&this.drawStringLabels(d,this.options.stringLabels),r.appendChild(d),r}relayoutChords(){if(this.chordEntries.length===0){this.svgRendererInstance.setTotalRootSvgHeight(0),this.svgRendererInstance.applySizingToRootSvg();return}const e=[];let t=[],s=E;this.chordEntries.forEach((n,o)=>{o>0&&s+this.diagramWidth>this.options.width&&(e.push(t),t=[],s=E),t.push(n),s+=this.diagramWidth+w}),t.length>0&&e.push(t),this.cursorY=ut,e.forEach((n,o)=>{if(o>0&&(this.cursorY+=this.rowHeight+ft),this.options.centerChords){const i=n.length*this.diagramWidth+(n.length-1)*w;this.cursorX=this.options.width/2-i/2}else this.cursorX=E;n.forEach(i=>{i.xPos=this.cursorX,i.yPos=this.cursorY,i.gElement.setAttribute("transform",`translate(${this.cursorX}, ${this.cursorY})`),this.cursorX+=this.diagramWidth+w})});const r=this.cursorY+this.rowHeight;this.svgRendererInstance.setTotalRootSvgHeight(r),this.svgRendererInstance.applySizingToRootSvg()}addChord(e,t,s){const r=Y(e),n=$(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??at(r,this.options.fretCount),i=s?.label,a=s?.barres,h={startFret:o,label:i,barres:a},d=this.renderChordDiagram(r,n,h),c=this.svgRendererInstance.parentGroupElement;return this.svgRendererInstance.commitElementsToDOM(d,c),this.chordEntries.push({gElement:d,strings:it(r,n),...h,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=$(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,h=r?.startFret??at(n,this.options.fretCount),d={...r,label:a,startFret:h},c=this.renderChordDiagram(n,o,d);this.svgRendererInstance.parentGroupElement.replaceChild(c,i.gElement),this.chordEntries[s]={gElement:c,strings:it(n,o),...d,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.parentGroupElement.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=$(t),o=[];return s.forEach(i=>{if(i===0)return;const a=[],h={};for(let A=0;A<r.length;A++){if(r[A].toLowerCase()==="x")continue;const v=parseInt(r[A],36),W=Number(n[A]);v===i&&(h[W]?h[W]+=1:h[W]=1,a.push(A+1))}a.sort();let d=0,c=0;for(const[A,v]of Object.entries(h))v>c&&(c=v,d=Number(A));const f=a[0],u=a.at(-1);a.length>1&&u&&o.push({fret:i,fromString:f,toString:u,finger:d})}),o}destroy(){this.chordEntries=[],this.svgRendererInstance.destroy()}}I.GuitarChord=Ht,I.MusicStaff=Lt,I.RhythmStaff=Ot,I.ScrollingStaff=Gt,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vector-score",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "keywords": [