UNPKG

@ozarkoc/chordpro-parser

Version:

A browser-friendly bundled version of chordproject-parser

1 lines 33.3 kB
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ChordProParser=e():t.ChordProParser=e()}(this,(()=>(()=>{"use strict";var t={d:(e,s)=>{for(var a in s)t.o(s,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:s[a]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Formatter:()=>u,Models:()=>s,Parsers:()=>a,Transposer:()=>I,default:()=>V});var s={};t.r(s),t.d(s,{Chord:()=>T,ChordDiagram:()=>N,ChordLyricsPair:()=>A,Key:()=>E,MusicAccidental:()=>n,MusicLetter:()=>i,MusicNote:()=>b,Song:()=>R,TimeSignature:()=>v});var a={};t.r(a),t.d(a,{ChordProParser:()=>k,ParserWarning:()=>L});var r,i,n,o,c,h,l,u={};t.r(u),t.d(u,{ChordProFormatter:()=>X,FormatterSettings:()=>j,HtmlFormatter:()=>Y,TextFormatter:()=>K}),function(t){t.Lyrics="lyrics",t.Comment="comment",t.Empty="empty",t.Custom="custom",t.Tabs="tabs",t.Unknown="unknown"}(r||(r={}));class d{_lineType=r.Unknown;get lineType(){return this._lineType}constructor(t){this._lineType=t}}class m extends d{clone(){return new m(this._comment)}get comment(){return this._comment}_comment;constructor(t){super(r.Comment),this._comment=t}}class p extends d{clone(){return new p}constructor(){super(r.Empty)}}class g extends d{clone(){let t=[];return this._pairs.forEach((e=>{t.push(e.clone())})),new g(t)}get pairs(){return this._pairs}_pairs=[];constructor(t=[]){super(r.Lyrics),this._pairs=t}addPair(t){this._pairs.push(t)}}class _ extends d{clone(){return new _(this.value)}get value(){return this._value}_value;constructor(t){super(r.Tabs),this._value=t}}class f extends d{clone(){return new f(this.name,this.value)}get name(){return this._name}get value(){return this._value}_name;_value;constructor(t,e){super(r.Custom),this._name=t,this._value=e}}class b{accidental;letter;toString(){return this.accidental===n.none?i[this.letter]:i[this.letter]+n[this.accidental]}constructor(t,e=n.none){this.letter=t,this.accidental=e}clone(){return new b(this.letter,this.accidental)}static parse(t){if(!t)return;const e=t.trim().match(/^(?<letter>[A-G])(?<symbol>(#{1,2}|b{1,2}|x))?$/);if(!e||!e.groups)return;const s=e.groups.letter,a=i[s];if(null==a)return;let r=e.groups.symbol;"x"==r&&(r="##");const o=n[r];return new b(a,o)}equals(t){return!!t&&t.toString()===this.toString()}}!function(t){t[t.A=0]="A",t[t.B=1]="B",t[t.C=2]="C",t[t.D=3]="D",t[t.E=4]="E",t[t.F=5]="F",t[t.G=6]="G"}(i||(i={})),function(t){t[t.b=0]="b",t[t.bb=1]="bb",t[t["#"]=2]="#",t[t["##"]=3]="##",t[t.none=4]="none"}(n||(n={}));class E{note;mode;constructor(t,e=o.Major){this.note=t,this.mode=e}clone(){return new E(this.note.clone(),this.mode)}static parse(t){if(!t)return;const e=t.trim().match(/^(?<note>[A-G](#{1,2}|b{1,2}|x)?)(?<mode>m?)$/);if(!e||!e.groups)return;const s=b.parse(e.groups.note);if(null==s)return;const a="m"===e.groups.mode?o.Minor:o.Major;return new E(s,a)}toString(){return this.note.toString()+(this.mode==o.Major?"":"m")}equals(t){return this.toString()==t.toString()}}!function(t){t[t.Major=0]="Major",t[t.Minor=1]="Minor"}(o||(o={}));class T{key;type;bass;constructor(t,e="",s=null){this.key=t,this.type=e,this.bass=s}clone(){return new T(this.key.clone(),this.type,this.bass?.clone())}static chordRegex=/^(?<note>[A-G](#{1,2}|b{1,2}|x)?(min|m(?!aj)|-)?)(?<type>(?!\/).*?)?(?:$|(?:\/(?<bass>[A-G](#{1,2}|b{1,2}|x)?)))$/;static parse(t){if(!t)return;const e=(t=t.trim()).match(T.chordRegex);if(!e||!e.groups)return;const s=e.groups.note,a=E.parse(s);if(null==a)return;const r=e.groups.type,i=e.groups.bass,n=b.parse(i);return new T(a,r,n)}toString(t=!0,e=!0){var s=this.key.toString();return t&&(s+=this.type),e&&this.bass&&(s+="/"+this.bass.toString()),s}toSimpleString(){return this.toString(!1,!1)}equals(t){return!!t&&t.toString()===this.toString()}}!function(t){t.Lyrics="lyrics",t.Tabs="tabs",t.None="none"}(c||(c={}));class S{get lines(){return this._lines}get sectionType(){return this._sectionType}_sectionType=c.None;_lines=[];constructor(t){this._sectionType=t}}!function(t){t.Chorus="chorus",t.Verse="verse",t.Bridge="bridge",t.Custom="custom",t.None="none"}(h||(h={}));class y extends S{get type(){return this._type}_type;constructor(t){super(c.Lyrics),this._type=t}addLine(t){this._lines.push(t)}}class M extends y{clone(){let t=new M(this.type,this._name,this._value);return this._lines.forEach((e=>{t.addLine(e.clone())})),t}_name;_value;get name(){return this._name}get value(){return this._value}constructor(t,e,s=null){super(t),this._name=e,this._value=s}}class C extends y{clone(){let t=new C;return this._lines.forEach((e=>{t.addLine(e.clone())})),t}constructor(){super(h.None)}}class O extends S{clone(){let t=new O(this._value);return this._lines.forEach((e=>{t.addLine(e.clone())})),t}get value(){return this._value}_value=null;constructor(t=null){super(c.Tabs),this._value=t}addLine(t){this.lines.push(t)}}class v{topNumber;bottomNumber;constructor(t,e){this.topNumber=t,this.bottomNumber=e}toString(){return`${this.topNumber.toString()}/${this.bottomNumber.toString()}`}}class R{title=null;subtitle=null;albums=[];artists=[];composers=[];arrangers=[];lyricists=[];year=null;copyright=null;key=null;capo=0;duration=null;time=null;tempo=null;customMetadatas=[];userDiagrams=[];rawContent="";sections=[];getLyrics(){let t=[];return this.sections.forEach((e=>{e instanceof y&&e.lines.forEach((e=>{let s="";e instanceof g&&e.pairs.forEach((t=>{t.lyrics&&(s+=t.lyrics)})),s=s.trim(),s&&t.push(s)}))})),t}getAllChords(){let t=[];return this.sections.forEach((e=>{e instanceof y&&e.lines.forEach((e=>{e instanceof g&&e.pairs.forEach((e=>{if(e.hasChord()){const s=e.chord;t.push(s)}}))}))})),t}getUniqueChords(){const t=this.getAllChords();let e=[];return t.forEach((t=>{e.find((e=>e.equals(t)))||e.push(t)})),e}getPossibleKey(){const t=this.getAllChords();if(0==t.length)return;const e=t[0].key,s=t[t.length-1].key;if(e.equals(s))return e.clone();let a=[];t.forEach((t=>{let e=a.find((e=>e.key.equals(t.key)));e?e.count++:a.push({count:0,key:t.key.clone()})})),a.sort(((t,e)=>e.count-t.count));let r=a[0],i=a.find((t=>t.key.equals(e))).count,n=a.find((t=>t.key.equals(s))).count;return r.count>i&&r.count>n?r.key.clone():i>n?e.clone():s.clone()}clone(){let t=new R;return t.albums=this.albums,t.arrangers=this.arrangers,t.artists=this.artists,t.capo=this.capo,t.composers=this.composers,t.copyright=this.copyright,t.customMetadatas=this.customMetadatas,t.duration=this.duration,t.lyricists=this.lyricists,t.rawContent=this.rawContent,t.subtitle=this.subtitle,t.tempo=this.tempo,t.title=this.title,t.year=this.year,this.time&&(t.time=new v(this.time.bottomNumber,this.time.topNumber)),this.key&&(t.key=this.key.clone()),this.userDiagrams.forEach((e=>{t.userDiagrams.push(e.clone())})),this.sections.forEach((e=>{t.sections.push(e.clone())})),t}}class N{_chord;get chord(){return this._chord}_frets;get frets(){return this._frets}_fingers;get fingers(){return this._fingers}_variation;get variation(){return this._variation}constructor(t,e,s=[],a=1){this._chord=t,this._frets=e,this._fingers=s,this._variation=a}clone(){return new N(this._chord.clone(),[...this._frets],[...this._fingers],this.variation)}static parse(t){const e=t.match(/^\{define: (?<chord>([A-G][#bx]{0,2})(.*?)(?: |(?:\/([A-G][#bx]{0,2})))) *base-fret (?<basefret>[1-9][0-9]?) *frets(?<frets>( [0-9xNn]){6})( *fingers(?<fingers>( [0-5]){6}))?\}$/);if(!e||e.length<1||!e.groups)return;const s=e.groups.chord,a=parseInt(e.groups.basefret,10),r=e.groups.fingers?.trim().split(" ").map(Number),i=e.groups.frets?.trim().split(" "),n=[];i.forEach((t=>{const e=parseInt(t,10);let s=isNaN(e)?-1:e;a>1&&s>0&&(s+=a-1),n.push(s)}));const o=T.parse(s);return o&&n&&!isNaN(a)?new N(o,n,r):void 0}hasBarre(){return this.barre()>0}barre(){const t=this.frets.filter((t=>0!=t)),e=this.fingers.filter((t=>1===t));return t.length<this.frets.length||e.length<=1?0:this.fretsRange()[0]}fretsRange(t=!0){const e=t?-1:0,s=this._frets.filter((t=>t>e));return[Math.min(...s),Math.max(...s)]}getRelativeFrets(){let t=this.fretsRange(!1),e=t[0],s=t[1];(e<1||s<4)&&(e=1);const a=-(e-1);return[e,this.tryMovingFrets(a)[1]]}tryMovingFrets(t){return 0===t?[!0,this._frets]:t>this.fretsRange()[0]?[!1,this._frets]:[!0,this._frets.map((e=>e<1?e:e+t))]}}class A{chord;lyrics;text;constructor(t,e=null,s=null){this.lyrics=t,this.chord=e,this.text=s}clone(){return new A(this.lyrics,this.chord?.clone(),this.text)}hasChord(){return null!==this.chord}hasText(){return null!==this.text}static parse(t){const e=t.match(/\[(?<value>.*?)\]/);if(!e||!e.groups)return[!0,new A(t)];const s=e.groups.value,a=t.substring(s.length+2,t.length);return this.createChordLyricsPair(a,s)}static parseLine(t){const e=[],s=/\[(?<value>.*?)\]/g;if(!s.test(t))return e.push([!0,new A(t)]),e;let a;s.lastIndex=0;let r=0,i=null;for(;a=s.exec(t);){const n=t.substring(r,a.index);n&&e.push(this.createChordLyricsPair(n,i)),i=a.groups.value,r=s.lastIndex}const n=t.substring(r,t.length);return n&&e.push(this.createChordLyricsPair(n,i)),e}static createChordLyricsPair(t,e){let s=null,a=null;e?.startsWith("*")?a=e.substring(1,e.length):s=e?T.parse(e):null;const r=new A(t,s,a),i=void 0!==s;return i||(r.text=e),[i,r]}}class L{_message;_lineNumber;constructor(t,e){this._message=t,this._lineNumber=e}toString(){return`Warning: ${this._message} on line ${this._lineNumber}`}}class w{static ALBUM="album";static ARRANGER="arranger";static ARTIST="artist";static CAPO="capo";static COMMENT="comment";static DEFINE="define";static COMPOSER="composer";static COPYRIGHT="copyright";static DURATION="duration";static END_OF_BRIDGE="end_of_bridge";static END_OF_CHORUS="end_of_chorus";static END_OF_TAB="end_of_tab";static END_OF_VERSE="end_of_verse";static KEY="key";static LYRICIST="lyricist";static START_OF_BRIDGE="start_of_bridge";static START_OF_CHORUS="start_of_chorus";static START_OF_TAB="start_of_tab";static START_OF_VERSE="start_of_verse";static SUBTITLE="subtitle";static TEMPO="tempo";static TIME="time";static TITLE="title";static YEAR="year";static TITLE_SHORT="t";static SUBTITLE_SHORT="st";static COMMENT_SHORT="c";static START_OF_CHORUS_SHORT="soc";static END_OF_CHORUS_SHORT="eoc";static START_OF_VERSE_SHORT="sov";static END_OF_VERSE_SHORT="eov";static START_OF_BRIDGE_SHORT="sob";static END_OF_BRIDGE_SHORT="eob";static START_OF_TAB_SHORT="sot";static END_OF_TAB_SHORT="eot";static META_TAGS=[w.ALBUM,w.ARRANGER,w.ARTIST,w.CAPO,w.COMPOSER,w.COPYRIGHT,w.DURATION,w.KEY,w.LYRICIST,w.TEMPO,w.TIME,w.TITLE,w.SUBTITLE,w.YEAR];static START_BLOCK_TAGS=[w.START_OF_BRIDGE,w.START_OF_CHORUS,w.START_OF_TAB,w.START_OF_VERSE];static END_BLOCK_TAGS=[w.END_OF_BRIDGE,w.END_OF_CHORUS,w.END_OF_TAB,w.END_OF_VERSE]}!function(t){t[t.Metadata=0]="Metadata",t[t.CustomMetadata=1]="CustomMetadata",t[t.StartOfBlock=2]="StartOfBlock",t[t.EndOfBlock=3]="EndOfBlock",t[t.Comment=4]="Comment",t[t.Define=5]="Define",t[t.Custom=6]="Custom",t[t.None=7]="None"}(l||(l={}));class F{static ALIASES=[{shortName:w.TITLE_SHORT,longName:w.TITLE},{shortName:w.SUBTITLE_SHORT,longName:w.SUBTITLE},{shortName:w.COMMENT_SHORT,longName:w.COMMENT},{shortName:w.START_OF_BRIDGE_SHORT,longName:w.START_OF_BRIDGE},{shortName:w.END_OF_BRIDGE_SHORT,longName:w.END_OF_BRIDGE},{shortName:w.START_OF_CHORUS_SHORT,longName:w.START_OF_CHORUS},{shortName:w.END_OF_CHORUS_SHORT,longName:w.END_OF_CHORUS},{shortName:w.START_OF_VERSE_SHORT,longName:w.START_OF_VERSE},{shortName:w.END_OF_VERSE_SHORT,longName:w.END_OF_VERSE},{shortName:w.START_OF_TAB_SHORT,longName:w.START_OF_TAB},{shortName:w.END_OF_TAB_SHORT,longName:w.END_OF_TAB}];constructor(){}static META_TAG_REGEX=/^meta:\s*(?<name>[^:\s]+)(\s*(?<value>.+))?$/;static TAG_REGEX=/^(?<name>[^:\s]+)(:?\s*(?<value>.+))?$/;static CUSTOM_META_TAG_REGEX=/^(?<name>x_[^:]+)(:?\s*(?<value>.+))?$/;_originalName="";_value=null;_type=l.None;get value(){return this._value}get type(){return this._type}get shortName(){return F.getShortName(this._originalName)}get longName(){return F.getLongName(this._originalName)}static getLongName(t){if(!t)return t;const e=this.ALIASES.find((e=>e.shortName===t));return e?e.longName:t}static getShortName(t){if(!t)return t;const e=this.ALIASES.find((e=>e.longName===t));return e?e.shortName:t}static parse(t){const e=t.trim();if(this.CUSTOM_META_TAG_REGEX.test(e)){let t=this.parseRegex(e,this.CUSTOM_META_TAG_REGEX);return t&&(t._type=l.Custom),t}if(this.META_TAG_REGEX.test(e)){let t=this.parseRegex(e,this.META_TAG_REGEX);return t&&(t._type=w.META_TAGS.find((e=>e===t.longName))?t._type=l.Metadata:t._type=l.CustomMetadata),t}if(this.TAG_REGEX.test(e)){let t=this.parseRegex(e,this.TAG_REGEX);if(t){if(w.META_TAGS.find((e=>e===t.longName)))t._type=l.Metadata;else if(t.longName.startsWith("start_of_"))t._type=l.StartOfBlock;else if(t.longName.startsWith("end_of_"))t._type=l.EndOfBlock;else if(t.longName===w.DEFINE)t._type=l.Define;else{if(t.longName!==w.COMMENT)return;t._type=l.Comment}return t}}}static parseRegex(t,e){let s=new F;const a=t.trim().match(e);if(a&&a.groups){if(!a.groups.name)return;return s._originalName=a.groups.name,a.groups.value&&(s._value=a.groups.value),s}}}class k{_currentSection;_song;_currentLineIndex=0;_currentSectionTagName;_warnings;get warnings(){return this._warnings}TAG_REGEX=/\{(?<value>.*)\}/;TAB_LINE_REGEX=/^[aA-zZ]\|[^ ]+$/;CHORD_REGEX=/\[(.*?)\]/g;SPLIT_CHORD_REGEX=/(?=\[.*?\])/g;constructor(){this._song=new R,this._currentSection=new C,this._currentSectionTagName=null,this._warnings=[]}parse(t){if(!t.trim())return this.addWarning("The song sheet is empty"),new R;this._song.rawContent=t;const e=t.split(/\r\n|\r|\n/);for(;!e[0].trim();)e.splice(0,1);return e.forEach((t=>{this.parseLine(t),this._currentLineIndex++})),this.completeCurrentSection(),this._song.key,this._song}parseLine(t){if(t=t.trim())if(this.TAG_REGEX.test(t))this.parseTag(t);else switch(this._currentSection.sectionType){case c.Tabs:this.parseTabLine(t);break;case c.Lyrics:this.parseLyricsLine(t)}else this.addLine(new p)}parseTabLine(t){this._currentSection instanceof O?(this.TAB_LINE_REGEX.test(t)||this.addWarning("This tabs line is invalid. It must starts with the string name and a pipe."),this.addLine(new _(t))):this.addWarning("Internal error: wrong section type")}parseLyricsLine(t){if(this._currentSection instanceof y){const e=t.replace(this.CHORD_REGEX,"");/[\[\]\{\}]/.test(e)&&this.addWarning("The lyrics line contains invalid characters or unclosed chords.");const s=t.split(this.SPLIT_CHORD_REGEX),a=[];s.forEach((t=>{const e=A.parse(t);e[0]||(e[1].lyrics.trim()?this.addWarning(`Cannot parse the chord '${e[1].text}' before the lyrics '${e[1].lyrics.trim()}'`):this.addWarning(`Cannot parse the chord '${e[1].text}'`)),a.push(e[1])}));const r=new g(a);this.addLine(r)}else this.addWarning("Internal error: wrong section type")}parseTag(t){const e=t.match(this.TAG_REGEX);if(!e||!e.groups||!e.groups.value)return void this.addWarning("Invalid tag.");const s=F.parse(e.groups.value.trim());if(s)switch(s.type){case l.Metadata:this.parseMetadataTag(s.longName,s.value);break;case l.Comment:this.parseCommentTag(s.value);break;case l.Define:this.parseDefineTag(s.value);break;case l.Custom:this.parseCustomTag(s.longName,s.value);break;case l.CustomMetadata:this.parseCustomMetadataTag(s.longName,s.value);case l.StartOfBlock:this.parseStartOfBlockTag(s.longName,s.value);break;case l.EndOfBlock:this.parseEndOfBlockTag(s.longName);break;default:this.addWarning("Unknown tag type.")}else this.addWarning("Unknown or mal-formatted tag.")}parseCommentTag(t){t?this.addLine(new m(t)):this.addWarning("The comment tag must have a value")}parseDefineTag(t){if(!t)return void this.addWarning("The define tag must have a value");const e=N.parse(t);e?this._song.userDiagrams.push(e):this.addWarning("The define tag is invalid")}parseCustomTag(t,e){this.addLine(new f(t,e))}parseStartOfBlockTag(t,e){null!==this._currentSectionTagName&&this.addWarning(`The section tag ${this._currentSectionTagName} must be closed before starting a new section`),this.completeCurrentSection();const s=t.replace("start_of_","");this._currentSectionTagName=s;const a=w.START_BLOCK_TAGS.find((e=>e===t));if(a)switch(a){case w.START_OF_BRIDGE:return void(this._currentSection=new M(h.Bridge,s,e));case w.START_OF_CHORUS:return void(this._currentSection=new M(h.Chorus,s,e));case w.START_OF_VERSE:return void(this._currentSection=new M(h.Verse,s,e));case w.START_OF_TAB:return void(this._currentSection=new O(e))}else this._currentSection=new M(h.Custom,s,e)}parseEndOfBlockTag(t){this._currentSectionTagName?(t.replace("end_of_","")!==this._currentSectionTagName&&this.addWarning("The end of section tag does not match the start of section tag."),this.completeCurrentSection()):this.addWarning("This end of section tag is useless and will be ignore.")}completeCurrentSection(){this._currentSection.lines.length>0&&this._song.sections.push(this._currentSection),this._currentSection=new C,this._currentSectionTagName=null}addLine(t){this._currentSection.sectionType!==c.Tabs||t instanceof _?this._currentSection.addLine(t):this.addWarning("Tabs section can only contains tabs lines")}parseMetadataTag(t,e){if(e&&e.trim())switch(t){case w.ALBUM:this._song.albums.push(e);break;case w.ARRANGER:this._song.arrangers.push(e);break;case w.ARTIST:this._song.artists.push(e);break;case w.CAPO:this.parseCapoMetadata(e);break;case w.COMPOSER:this._song.composers.push(e);break;case w.COPYRIGHT:this._song.copyright=e;break;case w.DURATION:this.parseDurationMetadata(e);break;case w.KEY:this.parseKeyMetadata(e);break;case w.LYRICIST:this._song.lyricists.push(e);break;case w.TEMPO:this.parseTempoMetadata(e);break;case w.TIME:this.parseTimeMetadata(e);break;case w.TITLE:this._song.title=e;break;case w.SUBTITLE:this._song.subtitle=e;break;case w.YEAR:this.parseYearMetadata(e);break;default:this.addWarning("Unknown metadata tag")}else this.addWarning("The metadata must have a value")}parseYearMetadata(t){const e=parseInt(t,10);isNaN(e)||4!=e.toString().length?this.addWarning("The year metadata must be a 4 digits number"):this._song.year=e}parseCapoMetadata(t){const e=parseInt(t,10);isNaN(e)?this.addWarning("The capo metadata must be a number"):this._song.capo=e}parseDurationMetadata(t){const e=t.match(/^((?<time>[0-9]+)|(?<minutes>[0-5]?[0-9]):(?<seconds>[0-5][0-9]))$/);if(!e||!e.groups)return void this.addWarning("The duration metadata is invalid. Must be a number or a time (eg: 5:30)");if(e.groups.time){const e=parseInt(t,10);this._song.duration=e}const s=e.groups.minutes,a=e.groups.seconds;s&&a?this._song.duration=60*parseInt(s,10)+parseInt(a):this.addWarning("The duration metadata time format is invalid")}parseTempoMetadata(t){const e=parseInt(t,10);isNaN(e)?this.addWarning("The tempo metadata must be a number"):this._song.tempo=e}parseKeyMetadata(t){const e=E.parse(t);e?this._song.key=e:this.addWarning("The key metadata is not a valid key")}parseTimeMetadata(t){const e=t.match(/^(?<top>[0-9]{1,2})\/(?<bottom>[0-9]{1,2})$/);if(!(e&&e.groups&&e.groups.top&&e.groups.bottom))return void this.addWarning("The time metadata is invalid. Must be number/number (eg: 6/8)");const s=parseInt(e.groups.top),a=parseInt(e.groups.bottom);this._song.time=new v(s,a)}parseCustomMetadataTag(t,e){this._song.customMetadatas.push([t,e])}addWarning(t){const e=new L(t,this._currentLineIndex+1);this._warnings.push(e)}}class G{static circleOfFifths=["C","G","D","A","E","B","F#","Db","Ab","Eb","Bb","F"];static pitchClassMap={C:0,"C#":1,D:2,Eb:3,E:4,F:5,"F#":6,G:7,Ab:8,A:9,Bb:10,B:11,Cb:11,"D#":3,"E#":5,Fb:4,"G#":8,"A#":10,"B#":0,Gb:6,Db:1};static reversePitchClassMap={0:"C",1:"C#",2:"D",3:"Eb",4:"E",5:"F",6:"F#",7:"G",8:"Ab",9:"A",10:"Bb",11:"B"};static getNextInCircle(t,e){const s=this.circleOfFifths.indexOf(t);return-1===s?t:this.circleOfFifths[(s+e+this.circleOfFifths.length)%this.circleOfFifths.length]}static normalizeKey(t){const e=t.replace("m","");return void 0!==this.pitchClassMap[e]?t.includes("m")?`${e}m`:e:t}static transposeKey(t,e,s){const a=t.replace("m",""),r=this.pitchClassMap[a],i=(this.circleOfFifths.indexOf(a)+e+this.circleOfFifths.length)%this.circleOfFifths.length,n=this.circleOfFifths[i],o=(r+s+12)%12,c=this.reversePitchClassMap[o];if(c!==n){const t=(this.circleOfFifths.indexOf(c)+e+this.circleOfFifths.length)%this.circleOfFifths.length;return this.circleOfFifths[t]}return c}static semiTonesBetween(t,e){const s=this.pitchClassMap[t],a=this.pitchClassMap[e];return void 0===s||void 0===a?0:(a-s+12)%12}static letterDiff(t,e){const s=this.circleOfFifths.indexOf(t),a=this.circleOfFifths.indexOf(e);return-1===s||-1===a?0:a-s}static getPreferredEnharmonic(t,e){const s=this.pitchClassMap[t];if(void 0===s)return t;return e&&e.includes("#")?["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"][s]:e&&e.includes("b")?["C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B"][s]:this.reversePitchClassMap[s]}}class I{static transpose(t,e){let s=t.clone(),a=s.key?s.key:s.getPossibleKey();if(!a)return t;const r=a.note,o=i[r.letter],h=n[r.accidental],l=o+("none"===h?"":h),u="up"===e?1:-1,d=G.pitchClassMap[l];if(void 0===d)return t;const m=(d+u+12)%12,p=G.getPreferredEnharmonic(G.reversePitchClassMap[m],l),_=b.parse(p);return _?(a.note=_,s.sections.forEach((t=>{t.sectionType==c.Lyrics&&t.lines.forEach((t=>{t instanceof g&&t.pairs.forEach((t=>{if(t.chord){const e=t.chord.key.note,s=i[e.letter],a=n[e.accidental],r=s+("none"===a?"":a),o=G.pitchClassMap[r];if(void 0!==o){const e=(o+u+12)%12,s=G.getPreferredEnharmonic(G.reversePitchClassMap[e],p),a=b.parse(s);a&&(t.chord.key.note=a)}if(t.chord.bass){const e=i[t.chord.bass.letter],s=n[t.chord.bass.accidental],a=e+("none"===s?"":s),r=G.pitchClassMap[a];if(void 0!==r){const e=(r+u+12)%12,s=G.getPreferredEnharmonic(G.reversePitchClassMap[e],p),a=b.parse(s);a&&(t.chord.bass=a)}}}}))}))})),s):t}}class D{static toMinutesSeconds(t){const e=Math.floor(t/60),s=t-60*e;return`${e.toLocaleString("en-US",{minimumIntegerDigits:2,useGrouping:!1})}:${s.toLocaleString("en-US",{minimumIntegerDigits:2,useGrouping:!1})}`}static toProperCase(t){return t.length<1?t:t.charAt(0).toUpperCase()+t.substring(1).toLocaleLowerCase()}}class H{useSimpleChord=!1;showChords=!0}class B{settings;constructor(t=new H){this.settings=t}writeMetadata(t,e){return e?`${D.toProperCase(t)}: ${e}`:D.toProperCase(t)}buildMetadataArray(t,e,s){const a=t.length>1?s:e,r=t.join(", ");return`${D.toProperCase(a)}: ${r}`}titleMetadata(t){return[t]}subtitleMetadata(t){return[t]}artistsMetadata(t){return[t.join(", ")]}composersMetadata(t){return[this.buildMetadataArray(t,"Composer","Composers")]}lyricistsMetadata(t){return[this.buildMetadataArray(t,"Lyricist","Lyricists")]}arrangersMetadata(t){return[this.buildMetadataArray(t,"Arranger","Arrangers")]}yearMetadata(t){return[this.writeMetadata("Year",t.toString())]}copyrightMetadata(t){return[this.writeMetadata("Copyright",t)]}timeMetadata(t){return[this.writeMetadata("Time",t)]}tempoMetadata(t){return[this.writeMetadata("Tempo",t.toString())]}durationMetadata(t){return[this.writeMetadata("Duration",D.toMinutesSeconds(t))]}capoMetadata(t){return[this.writeMetadata("Capo",t.toString())]}keyMetadata(t){return[this.writeMetadata("Key",t)]}customMetadatas(t){let e=[];return t.forEach((t=>{e.push(this.writeMetadata(t[0],t[1]))})),e}emptyLine(){return[""]}lyricsLine(t){let e="",s="",a=[];return t.pairs.forEach((t=>{let a=1;if(this.settings.showChords)if(t.chord){let s=this.settings.useSimpleChord?t.chord.toSimpleString():t.chord.toString();e+=s,a=t.lyrics.length-s.length}else t.text?(e+=t.text,a=t.lyrics.length-t.text.length):a=t.lyrics.length;a>0?(e+=" ".repeat(a),s+=t.lyrics):(e+=" ",s+=t.lyrics+" ".repeat(Math.abs(a)+1))})),e=e.trimEnd(),s=s.trimEnd(),e&&a.push(e),s&&a.push(s),a}commentLine(t){return["#"+t.comment]}tabLine(t){return[t.value]}customLine(t){return[]}sectionStart(t){return(t instanceof M||t instanceof O)&&t.value?[t.value]:[]}sectionEnd(t){return[]}metadataStart(){return["*".repeat(10)]}metadataEnd(){return["*".repeat(10)]}contentStart(){return[]}contentEnd(){return[]}}class x{settings;constructor(t=new H){this.settings=t}buildMetadata(t,e){return e?`{${t}: ${e}}`:`{${t}}`}buildMetadatas(t,e){let s=[];return e.forEach((e=>{s.push(this.buildMetadata(t,e))})),s}titleMetadata(t){return[this.buildMetadata("title",t)]}subtitleMetadata(t){return[this.buildMetadata("subtitle",t)]}artistsMetadata(t){return this.buildMetadatas("artist",t)}composersMetadata(t){return this.buildMetadatas("composer",t)}lyricistsMetadata(t){return this.buildMetadatas("lyricist",t)}arrangersMetadata(t){return this.buildMetadatas("arranger",t)}yearMetadata(t){return[this.buildMetadata("year",t.toString())]}copyrightMetadata(t){return[this.buildMetadata("copyright",t)]}timeMetadata(t){return[this.buildMetadata("time",t)]}tempoMetadata(t){return[this.buildMetadata("tempo",t.toString())]}durationMetadata(t){return[this.buildMetadata("duration",D.toMinutesSeconds(t))]}capoMetadata(t){return[this.buildMetadata("capo",t.toString())]}keyMetadata(t){return[this.buildMetadata("key",t)]}customMetadatas(t){let e=[];return t.forEach((t=>{e.push(this.buildMetadata(t[0].toLowerCase(),t[1]))})),e}emptyLine(){return[""]}lyricsLine(t){let e="";return t.pairs.forEach((t=>{if(this.settings.showChords)if(t.chord){let s=this.settings.useSimpleChord?t.chord.toSimpleString():t.chord.toString();e+=`[${s}]${t.lyrics}`}else t.text?e+=`[*${t.text}]${t.lyrics}`:e+=t.lyrics;else e+=t.lyrics})),[e.trim()]}commentLine(t){return[this.buildMetadata("comment",t.comment)]}tabLine(t){return[t.value]}customLine(t){return[this.buildMetadata(t.name,t.value)]}sectionStart(t){if(t instanceof M||t instanceof O){let e=t instanceof O?"tab":t.name;return[this.buildMetadata("start_of_"+e,t.value)]}return[]}sectionEnd(t){if(t instanceof M||t instanceof O){let e=t instanceof O?"tab":t.name;return[this.buildMetadata("end_of_"+e,null)]}return[]}metadataStart(){return[]}metadataEnd(){return[]}contentStart(){return[]}contentEnd(){return[]}}class P{value;constructor(t){this.value=t}toStringLines(){return[this.value]}}class ${tag;classNames=[];innerHtml=[];constructor(t,e,...s){this.tag=t,this.innerHtml=s,this.classNames=e}toStringLines(){const t=[];return t.push(`<${this.tag} class="${this.classNames.join(" ")}">`),this.innerHtml.forEach((e=>{t.push(...e.toStringLines())})),t.push(`</${this.tag}>`),t}addElement(...t){this.innerHtml.push(...t)}addString(t){this.innerHtml.push(new P(t))}}class W{settings;constructor(t=new H){this.settings=t}buildHtmlElement(t,e,s=[]){return`<${t} class="${s.join(" ")}">${e}</${t}>`}titleMetadata(t){return[this.buildHtmlElement("h1",t,["metadata","title-metadata"])]}subtitleMetadata(t){return[this.buildHtmlElement("h2",t,["metadata","subtitle-metadata"])]}artistsMetadata(t){return[this.buildHtmlElement("h3",t.join(", "),["metadata","artist-metadata"])]}composersMetadata(t){const e=t.length>1?"Composers":"Composer";return[this.buildHtmlElement("div",e+": "+t.join(", "),["metadata","composer-metadata"])]}lyricistsMetadata(t){const e=t.length>1?"Lyricists":"Lyricist";return[this.buildHtmlElement("div",e+": "+t.join(", "),["metadata","lyricist-metadata"])]}arrangersMetadata(t){const e=t.length>1?"Arrangers":"Arranger";return[this.buildHtmlElement("div",e+": "+t.join(", "),["metadata","arranger-metadata"])]}yearMetadata(t){return[this.buildHtmlElement("div","Year: "+t,["metadata","year-metadata"])]}copyrightMetadata(t){return[this.buildHtmlElement("div","Copyright: "+t,["metadata","copyright-metadata"])]}timeMetadata(t){return[this.buildHtmlElement("div","Time: "+t,["metadata","time-metadata"])]}tempoMetadata(t){return[this.buildHtmlElement("div","Tempo: "+t,["metadata","tempo-metadata"])]}durationMetadata(t){return[this.buildHtmlElement("div","Duration: "+D.toMinutesSeconds(t),["metadata","duration-metadata"])]}capoMetadata(t){return[this.buildHtmlElement("div","Capo: "+t,["metadata","capo-metadata"])]}keyMetadata(t){return[this.buildHtmlElement("div","Key: "+t,["metadata","key-metadata"])]}customMetadatas(t){let e=[];const s=["metadata","custom-metadata"];return t.forEach((t=>{e.push(this.buildHtmlElement("div",D.toProperCase(t[0])+": "+t[1],s))})),e}emptyLine(){return[this.buildHtmlElement("div","",["line","empty-line"])]}createWordElement(...t){return t.map((t=>t.toStringLines())).join("").trim()?new $("div",["word"],...t):new P("")}createChordElement(t,e){let s=["above-lyrics"];e?s.push("chord"):s.push("annotation");let a=new $("span",s);return a.addString(t),a}createLyricsElement(t){let e=new $("span",["lyrics"]);return e.addString(t),e}createChordLyricsElement(t,e,s){if(!this.settings.showChords&&"&nbsp;"==s)return new P("");let a=new $("div",["chord-lyrics"]);return this.settings.showChords&&a.addElement(this.createChordElement(t,e)),s&&a.addElement(this.createLyricsElement(s)),a}lyricsLine(t){let e=t.pairs.map((t=>t.lyrics)).join("").trim();if(!this.settings.showChords&&!e)return[];let s=new $("div",["lyrics-line"]),a=[];if(t.pairs.forEach(((r,i)=>{let n=null!=r.chord||null!=r.text,o=null!=r.chord,c="";r.chord?c=this.settings.useSimpleChord?r.chord.toSimpleString():r.chord.toString():r.text&&(c=r.text);let h=n?r.lyrics:r.lyrics.trimStart();h=h.replace(/ +/g," ");let l=h.split(" "),u=l.shift(),d=l.pop();if(""==u){if(a.length>0){let t=this.createWordElement(...a);s.addElement(t),a=[]}u="&nbsp;",l.length>0&&(u+=l.shift())}e||(u=void 0);var m=n?this.createChordLyricsElement(c,o,u):this.createLyricsElement(u);if(a.push(m),null==d&&i<t.pairs.length-1)return;let p=this.createWordElement(...a);s.addElement(p),a=[],l.forEach((t=>{let e=this.createLyricsElement(t),a=this.createWordElement(e);s.addElement(a)})),""!=d&&null!=d&&(a.push(this.createLyricsElement(d)),t.pairs.length)})),a.length>0){let t=this.createWordElement(...a);s.addElement(t),a=[]}return s.toStringLines()}commentLine(t){return[this.buildHtmlElement("div",t.comment,["line","comment-line"])]}tabLine(t){return[this.buildHtmlElement("div",t.value,["line","tab-line"])]}customLine(t){const e=["metadata","custom-metadata",t.name];return[this.buildHtmlElement("div",t.value?t.value:"",e)]}sectionStart(t){let e=[];if(t instanceof M||t instanceof O){let s="tab";if(t instanceof M)switch(t.type){case h.Chorus:s="chorus";break;case h.Verse:s="verse";break;case h.Bridge:s="bridge";break;case h.Custom:s="custom"}if(e.push(`<div class="section ${s}-section">`),t.value){const s=["section-title"];e.push(this.buildHtmlElement("div",t.value,s))}}return e}sectionEnd(t){return t instanceof M||t instanceof O?["</div>"]:[]}metadataStart(){return[`<div class=${["song-metadata"].join(" ")}>`]}metadataEnd(){return["</div>"]}contentStart(){return[`<div class="${["song-content"].join(" ")}">`]}contentEnd(){return["</div>"]}}class U{_builder;_lines=[];constructor(t){this._builder=t}format(t){return this._lines=[],this.settings.showMetadata&&this.formatMetadata(t),this._lines.push(...this._builder.contentStart()),t.sections.forEach((t=>{(this.settings.showTabs||t.sectionType!=c.Tabs)&&(this._lines.push(...this._builder.sectionStart(t)),t.lines.forEach((t=>{t instanceof p?this._lines.push(...this._builder.emptyLine()):t instanceof g?this._lines.push(...this._builder.lyricsLine(t)):t instanceof _?this._lines.push(...this._builder.tabLine(t)):t instanceof m&&this._lines.push(...this._builder.commentLine(t))})),this._lines.push(...this._builder.sectionEnd(t)))})),this._lines.push(...this._builder.contentEnd()),this._lines}formatMetadata(t){this._lines.push(...this._builder.metadataStart()),t.title?.trim()&&this._lines.push(...this._builder.titleMetadata(t.title)),t.subtitle?.trim()&&this._lines.push(...this._builder.subtitleMetadata(t.subtitle)),t.artists.length>0&&this._lines.push(...this._builder.artistsMetadata(t.artists)),t.composers.length>0&&this._lines.push(...this._builder.composersMetadata(t.composers)),t.lyricists.length>0&&this._lines.push(...this._builder.lyricistsMetadata(t.lyricists)),t.arrangers.length>0&&this._lines.push(...this._builder.arrangersMetadata(t.arrangers)),t.copyright?.trim()&&this._lines.push(...this._builder.copyrightMetadata(t.copyright)),t.time&&this._lines.push(...this._builder.timeMetadata(`${t.time.topNumber}/${t.time.bottomNumber}`)),t.tempo&&t.tempo>0&&this._lines.push(...this._builder.tempoMetadata(t.tempo)),t.year&&this._lines.push(...this._builder.yearMetadata(t.year)),t.duration&&t.duration>0&&this._lines.push(...this._builder.durationMetadata(t.duration)),t.key&&this._lines.push(...this._builder.keyMetadata(t.key.toString())),t.capo&&t.capo>0&&this._lines.push(...this._builder.capoMetadata(t.capo)),t.customMetadatas.length>0&&this._lines.push(...this._builder.customMetadatas(t.customMetadatas)),this._lines.push(...this._builder.metadataEnd())}}class j extends H{showMetadata=!0;showTabs=!0}class X extends U{settings;constructor(t=new j){super(new x(t)),this.settings=t}}class Y extends U{settings;constructor(t=new j){super(new W(t)),this.settings=t}}class K extends U{settings;constructor(t=new j){super(new B(t)),this.settings=t}}const V={Parsers:a,Transposer:I,Formatter:u,Models:s,TransposerClass:I};return e})()));