← Files Drum Notation ImporterARCHIVED FILE
skills/import-drum-score/scripts/validate-drum-notation.mjs
36.6 KB · Oct 3, 2026 · 06:32 UTC
#!/usr/bin/env node
import{readFile as Dn,stat as Rn}from"node:fs/promises";import{stdin as yn,stdout as xn}from"node:process";function M(e){return e.toLowerCase().replace(/[^a-z0-9]/g,"")}var gt=[{id:"crash",label:"Crash",aliases:["cr","crash","cc","crash cymbal"],notationVoice:"upper",vexKey:"a/5/X",midi:49,color:"#d97706",playback:"crash"},{id:"splash",label:"Splash",aliases:["sp","splash","splash cymbal"],notationVoice:"upper",vexKey:"b/5/X",midi:55,color:"#f59e0b",playback:"splash"},{id:"china",label:"China",aliases:["chna","china","china cymbal"],notationVoice:"upper",vexKey:"c/6/X",midi:52,color:"#ea580c",playback:"china"},{id:"stack",label:"Stack",aliases:["st","stack","stack cymbal"],notationVoice:"upper",vexKey:"d/6/X",midi:52,color:"#c2410c",playback:"stack"},{id:"ride",label:"Ride",aliases:["rd","ride","rc"],notationVoice:"upper",vexKey:"f/5/X",midi:51,color:"#b45309",playback:"ride"},{id:"ride-bell",label:"Ride bell",aliases:["rb","bell","ridebell","ride bell"],notationVoice:"upper",vexKey:"f/5/d2",midi:53,color:"#92400e",playback:"rideBell"},{id:"open-hat",label:"Open hat",aliases:["oh","openhat","open-hat","open hh"],notationVoice:"upper",vexKey:"g/5/X",midi:46,color:"#ca8a04",playback:"hatOpen"},{id:"half-open-hat",label:"Half-open hat",aliases:["ho","hho","halfopenhat","half-openhat","half open hat","half-open hat","half open hi-hat","half-open hi-hat"],notationVoice:"upper",vexKey:"g/5/X",midi:46,color:"#d4a017",playback:"hatHalfOpen"},{id:"closed-hat",label:"Hi-hat",aliases:["hh","ch","close","closed","hat","hihat","hi-hat","closedhat","closed-hat"],notationVoice:"upper",vexKey:"g/5/X",midi:42,color:"#eab308",playback:"hatClosed"},{id:"hi-hat-foot",label:"Hi-hat foot",aliases:["hf","hhf","fh","foot hat","hat foot","hi-hat foot","hihat foot"],notationVoice:"lower",vexKey:"d/4/X",midi:44,color:"#a16207",playback:"hatFoot"},{id:"hi-hat-foot-splash",label:"Hi-hat foot splash",aliases:["hfs","hhfs","foot splash","hat foot splash","hi-hat foot splash","hihat foot splash","hi-hat splash","hihat splash"],notationVoice:"lower",vexKey:"d/4/X",midi:44,color:"#854d0e",playback:"hatFootSplash"},{id:"snare",label:"Snare",aliases:["sd","sn","snare"],notationVoice:"upper",vexKey:"c/5",midi:38,color:"#2563eb",playback:"snare"},{id:"rim",label:"Rim",aliases:["rs","rim","rimshot","xstick","cross","crossstick","cross-stick"],notationVoice:"upper",vexKey:"c/5/X",midi:37,color:"#0891b2",playback:"click"},{id:"high-tom",label:"High rack tom",aliases:["ht","rt","rt1","t1","tom1","rack","rack tom","high tom","high rack tom"],notationVoice:"upper",vexKey:"e/5",midi:50,color:"#16a34a",playback:"tomHigh"},{id:"mid-tom",label:"Mid rack tom",aliases:["mt","rt2","t2","tom2","mid tom","mid rack tom"],notationVoice:"upper",vexKey:"d/5",midi:47,color:"#15803d",playback:"tomMid"},{id:"low-tom",label:"Low rack tom",aliases:["lt","rt3","t3","tom3","low tom","low rack tom"],notationVoice:"upper",vexKey:"a/4",midi:45,color:"#166534",playback:"tomLow"},{id:"floor-tom",label:"Floor tom",aliases:["ft","floor","floor tom"],notationVoice:"upper",vexKey:"g/4",midi:41,color:"#14532d",playback:"tomLow"},{id:"low-floor-tom",label:"Low floor tom",aliases:["lft","ft2","low floor","low floor tom"],notationVoice:"upper",vexKey:"e/4",midi:43,color:"#052e16",playback:"tomLow"},{id:"kick",label:"Kick",aliases:["bd","kd","kick","bass","bass drum"],notationVoice:"lower",vexKey:"f/4",midi:36,color:"#dc2626",playback:"kick"},{id:"second-kick",label:"Second kick",aliases:["bd2","kd2","kick2","bass2","bass drum 2","second kick","second bass","second bass drum"],notationVoice:"lower",vexKey:"d/4",midi:36,color:"#ef4444",playback:"kick"},{id:"cowbell",label:"Cowbell",aliases:["cb","cowbell"],notationVoice:"upper",vexKey:"e/5/X",midi:56,color:"#7c3aed",playback:"cowbell"}];function ft(){let e=[];for(let t of gt){e.push([M(t.label),t]);for(let n of t.aliases)e.push([M(n),t])}return e}var pe=new Map(ft());var Ee={z:"buzz",Z:"buzz",O:"accent",X:"accent","!":"accent","#":"accent",">":"accent",g:"ghost",f:"flam",r:"drag",d:"diddle",c:"choke"},ht={normal:.75,accent:1,ghost:.2,flam:.75,drag:.75,diddle:.75,buzz:.68,choke:.9},bt=new Set(["-",".","_"," "]);function te(e){return Ee[e]??"normal"}function St(e){return e==="x"||e==="o"?"normal":Ee[e]??null}function Me(e){return X(e)||St(e)!==null}function ve(e){return ht[te(e)]}function X(e){return bt.has(e)}function Dt(e){return e.vexKey.includes("/X")||e.id==="ride-bell"}function Rt(e,t){let n=Dt(e);switch(t){case"accent":return n?"X":"O";case"ghost":return"g";case"flam":return"f";case"drag":return"r";case"diddle":return"d";case"buzz":return"z";case"choke":return"c";case"normal":default:return n?"x":"o"}}function yt(e,t){return X(t)?"-":Rt(e,te(t))}function Te(e,t){return Array.from(t,n=>yt(e,n)).join("")}var U="single";function Ae(e,t=16){let n=/^(\d+)\/(\d+)$/.exec(e);if(!n)return 16;let r=Number.parseInt(n[1],10),i=Number.parseInt(n[2],10),a=r*(t/i);return Math.max(1,Math.round(a))}var xt=/^(\d+)(?:([/@])(\d+))?\(/,Pe=/\d+(?:[/@]\d+)?\(/,_e=new Set([2,4,8,16,32]),It=128;function Ne(e,t,n){let r=Ge(t,n),i=$e(t),a=kt(t),s=[],o=[],u="",l="",f=0,d=0,g=0,D=()=>{for(;l.length>0;){let p=Math.min(r,l.length),h=p*(4/n);s.push({kind:"plain",startPosition:d,positionCount:p,startQuarter:f,durationQuarter:h,spanWrittenBeats:h/i,subdivisionCount:p}),u+=l.slice(0,p),l=l.slice(p),d+=p,f+=h}};for(;g<e.length;){let p=e.slice(g),h=xt.exec(p);if(!h){l+=e[g],g+=1,l.length===r&&D();continue}D();let P=Number.parseInt(h[1],10),b=h[2],_=h[3]===void 0?void 0:Number.parseInt(h[3],10),w=b!=="@",E=b==="@"?_:void 0,N=Et(E),A=b==="/"?P:1,c=b==="/"?_??P:P,k=w?A*i:4/(E??1),S=w?A:k/i,B=g+h[0].length,C=e.indexOf(")",B),R=Math.floor(f/i)+1;if(C<0){o.push({code:"malformed-tuplet",message:`Tuplet at beat ${R} is missing its closing parenthesis.`,beat:R});break}let O=e.slice(B,C),F=Math.abs(f/i-Math.round(f/i))<1e-8,me=E===void 0||N!==null?wt(c,k):null;c<3||c>12?o.push({code:"malformed-tuplet",message:`Tuplet at beat ${R} uses ${c} subdivisions; supported values are 3\u201312.`,beat:R}):b==="/"&&A<1?o.push({code:"malformed-tuplet",message:`Tuplet at beat ${R} must span at least one written beat.`,beat:R}):b==="/"&&A===c?o.push({code:"malformed-tuplet",message:`Tuplet ${A}/${c}(...) at beat ${R} is an ordinary subdivision; use plain-grid notation instead.`,beat:R}):E!==void 0&&!_e.has(E)?o.push({code:"unsupported-tuplet-duration",message:`Tuplet ${c}@${E}(...) at beat ${R} uses an unsupported duration; supported denominators are 2, 4, 8, 16, and 32.`,beat:R}):me===null?o.push({code:E===void 0?"unsupported-tuplet-span":"unsupported-tuplet-duration",message:E===void 0?`Tuplet ${A}/${c}(...) at beat ${R} cannot be engraved with supported note values through 128th notes.`:`Tuplet ${c}@${E}(...) at beat ${R} cannot be engraved with supported note values through 128th notes.`,beat:R}):w&&!F?o.push({code:"malformed-tuplet",message:`Tuplet at beat ${R} must begin on a written-beat boundary unless it declares an explicit @ duration.`,beat:R}):O.includes("(")||O.includes(")")?o.push({code:"malformed-tuplet",message:`Tuplet at beat ${R} contains nested parentheses, which are not supported.`,beat:R}):Array.from(O).length!==c?o.push({code:"malformed-tuplet",message:`Tuplet at beat ${R} declares ${c} subdivisions but contains ${Array.from(O).length} positions.`,beat:R}):f+k>a+Number.EPSILON?o.push({code:"malformed-tuplet",message:`Tuplet at beat ${R} extends beyond the ${t} bar.`,beat:R}):(s.push({kind:"tuplet",startPosition:d,positionCount:c,startQuarter:f,durationQuarter:k,spanWrittenBeats:S,subdivisionCount:c,tupletSpan:w?{kind:"written-beats",beats:A}:{kind:"note-value",denominator:N??4}}),u+=O,d+=c,f+=k),g=C+1}return D(),{decodedPattern:u,regions:s,containsTupletSyntax:Pe.test(e),issues:o}}function Be(e,t,n){let r=Ge(t,n),i=$e(t),a=[],s=0,o=0;for(;s<e;){let u=Math.min(r,e-s),l=u*(4/n);a.push({kind:"plain",startPosition:s,positionCount:u,startQuarter:o,durationQuarter:l,spanWrittenBeats:l/i,subdivisionCount:u}),s+=u,o+=l}return a}function de(e){return e.replace(/\d+(?:[/@]\d+)?\(/g,"").replace(/[()]/g,"")}function Ce(e){return Pe.test(e)}function ge(e){return e.map(t=>[t.kind,t.positionCount,ne(t.startQuarter),ne(t.durationQuarter),ne(t.spanWrittenBeats),t.tupletSpan?.kind??"plain",t.tupletSpan?.kind==="written-beats"?ne(t.tupletSpan.beats):t.tupletSpan?.denominator??""].join(":")).join("|")}function $e(e){return 4/Ue(e)}function kt(e){let t=/^(\d+)\/(\d+)$/.exec(e),n=Math.max(1,Number.parseInt(t?.[1]??"4",10)),r=Math.max(1,Number.parseInt(t?.[2]??"4",10));return n*(4/r)}function Le(e){return e.startQuarter+e.durationQuarter}function wt(e,t){let n=[];for(let r=1;r<=It;r*=2){let i=t*r/4,a=Math.round(i);a<1||Math.abs(i-a)>1e-8||n.push({tickableDenominator:r,notesOccupied:a})}return n.sort((r,i)=>{let a=Math.abs(r.notesOccupied-e)-Math.abs(i.notesOccupied-e);if(a!==0)return a;let s=r.notesOccupied<e?0:1,o=i.notesOccupied<e?0:1;return s-o||r.tickableDenominator-i.tickableDenominator})[0]??null}function Oe(e){return Math.round(4/e.durationQuarter)}function ne(e){return String(Math.round(e*1e9)/1e9)}function Et(e){return e===void 0||!_e.has(e)?null:e===2||e===4||e===8||e===16||e===32?e:null}function Ge(e,t){return Math.max(1,Math.round(t/Ue(e)))}function Ue(e){let t=/^\d+\/(\d+)$/.exec(e);return Math.max(1,Number.parseInt(t?.[1]??"4",10))}var Qe=new Set(["st","stick","sticking","hands"]),vt=new Set(["title","author","comment","tempo","bpm","time","timesignature","meter","grouping","voicing","count","repeat","repeats","cursor","playbackcursor","highlight","notehighlight","playbackhighlight","rests","legend","instrumentlegend","kitlegend","colorlegend","grid","subdivision","resolution"]),Tt=new Set(["tempo","bpm","time","timesignature","meter","grouping","voicing","repeat","repeats","cursor","playbackcursor","highlight","notehighlight","playbackhighlight","rests","legend","instrumentlegend","kitlegend","colorlegend","grid","subdivision","resolution"]),At=new Set(["engraving"]),Fe=new Set(["on","true","yes","y","1","show","visible"]),We=new Set(["off","false","no","n","0","hide","hidden"]),Xe=new Set(["on","true","yes","y","1","show","visible","used","current","present"]),je=new Set(["all","full","kit","complete","supported","everything"]),Ye=new Set(["off","false","no","n","0","hide","hidden","none"]);function Re(e){return Pt(e,!0)}function Pt(e,t){let n=[],r=[],i=[],a=[],s=[],o=[],u=[],l=[],f=[],d=!1,g=[],D,p=[],h,P=[],b=100,_=1,w=!1,E=!0,N=!0,A=U,c="off",k=16,S=($,L,x,y)=>{t&&r.push({code:L,message:x,line:$,...y!==void 0?{column:y}:{}})},B=_t(e,S),C=B[0]??{timeSignature:"4/4"},R=0,O=()=>{if(g.length===0&&!D){h=void 0,p=[];return}let $=[...g,...D?[D]:[]].filter(T=>T.sectionRepeatIssue||(T.sectionRepeatStarts?.length??0)>0||(T.sectionRepeatEnds?.length??0)>0);$.forEach(T=>{T.sectionRepeatIssue&&(d=!0,S(T.lineNumber,"invalid-section-repeat",T.sectionRepeatIssue))});let L=$.filter(T=>!T.sectionRepeatIssue),x=L[0];if(x){let T=Ke(x),W=L.find(G=>Ke(G)!==T);if(W)d=!0,S(W.lineNumber,"section-repeat-mismatch","Section repeat markers on this system do not align across rows; rendering and playback will remain linear.");else{let G=P.length;l.push(...(x.sectionRepeatStarts??[]).map(m=>({...m,barIndex:G+m.barIndex}))),f.push(...(x.sectionRepeatEnds??[]).map(m=>({...m,barIndex:G+m.barIndex})))}}ot(g,D,p),i.push(g),a.push(D),s.push(p),o.push(h);let y=B[R]??C;u.push(qe(y)),P.push(...at(g,D,y.timeSignature)),g=[],D=void 0,p=[],h=void 0};e.split(/\r?\n/).forEach(($,L)=>{let x=$.trim(),y=L+1;if(x.length===0)return;if(Ze(x)){O(),R++;return}let T=Bt(x);if(T!==null){T.length>0&&(h=T);return}let W=Ct(x);if(W){S(y,"removed-setting",`${W.originalKey}: is preserved as metadata but no longer affects rendering.`),n.push(x);return}let G=$t(x);if(G){S(y,"invalid-setting",`${G.originalKey}: has no value and is preserved as metadata.`),n.push(x);return}let m=Je(x);if(m){if(m.key==="tempo"||m.key==="bpm"){let I=Number.parseInt(m.value,10),v=rn(I);Number.isFinite(I)?I!==v&&S(y,"clamped-setting",`${m.originalKey}: ${I} is outside the supported 30\u2013260 BPM range; using ${v} BPM.`):S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a valid tempo; using ${v} BPM.`),b=v}else if(!(m.key==="time"||m.key==="timesignature"||m.key==="meter"||m.key==="grouping"))if(m.key==="repeat"||m.key==="repeats"){let I=st(m.value),v=en(m.value);I===null?S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a valid repeat count; using ${v}.`):I!==v&&S(y,"clamped-setting",`${m.originalKey}: ${I} is outside the supported 1\u201364 range; using ${v}.`),_=v}else if(m.key==="cursor"||m.key==="playbackcursor")he(m.value)||S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a recognized on/off value; using ${"off"}.`),w=be(m.value,!1);else if(m.key==="highlight"||m.key==="notehighlight"||m.key==="playbackhighlight")he(m.value)||S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a recognized on/off value; using ${"on"}.`),E=be(m.value,!0);else if(m.key==="rests")he(m.value)||S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a recognized on/off value; using ${"on"}.`),N=be(m.value,!0);else if(m.key==="voicing"){let I=M(m.value);I!=="single"&&I!=="split"?(S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a recognized voicing mode; using ${U}.`),A=U):A=I}else if(m.key==="legend"||m.key==="instrumentlegend"||m.key==="kitlegend"||m.key==="colorlegend")tn(m.value)||S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a recognized legend mode; using ${"off"}.`),c=nn(m.value);else if(m.key==="grid"||m.key==="subdivision"||m.key==="resolution"){let I=ut(m.value),v=He(m.value);I===null?S(y,"invalid-setting",`${m.originalKey}: "${m.value}" is not a valid grid value; using Grid ${v}.`):I!==16&&I!==32&&S(y,"invalid-setting",`${m.originalKey}: ${I} is unsupported; using Grid ${v}.`),k=He(m.value)}else n.push(`${m.originalKey}: ${m.value}`);return}let Ie=/[\[\]]/.test(x)?Se(x.replace(/[\[\]]/g,"").trim()):null;Ie&&(d=!0,S(y,"invalid-section-repeat","Section repeat markers cannot be attached directly to a standalone measure repeat; the measure repeat remains playable without section navigation."));let ke=Se(x)??Ie;if(ke){let I=B[R]??C,v=Qt(g,D,p,P,ke,I.timeSignature);v.status==="missing"?(S(y,"repeat-without-previous-bar","Repeat notation needs a previous bar; this line is preserved as metadata."),n.push(x)):v.status==="meter-mismatch"?(S(y,"repeat-meter-mismatch",`Repeat notation cannot copy the previous ${v.previousTimeSignature} bar into a ${I.timeSignature} system; this line is preserved as metadata.`),n.push(x)):D=v.sticking;return}let we=tt(x);if(we){Ut(x,y,S);let I=Ve(we,y);D=p.length>0?Wt(g,D,p.length,I):I;return}let ce=et(x);if(ce){Gt(x,ce.label,y,S);let I=Ve(ce,y);p.length>0?Ft(g,D,p.length,I):g.push(I)}else Ot(x,y,S),n.push(x)}),O();let F=Vt(i,a,u,k,S);zt(i,a,u,k,S,F.tupletSourceSegments);let ee=u[0]??C,me=Lt(l,f,P.length,d,S),dt=Nt({tempo:b,timeSignature:ee.timeSignature,...ee.beamGrouping?{beamGrouping:[...ee.beamGrouping]}:{},repeatCount:_,showCursor:w,showHighlight:E,showRests:N,voicing:A,legendMode:c,gridResolution:k,metadata:n},i,s,a,o,F.rhythmSections,F.containsTupletSyntax,u,me);return r.sort(($,L)=>$.line-L.line||($.column??0)-(L.column??0)),{block:dt,warnings:r}}function _t(e,t){let n=[{timeDeclarations:[],groupingDeclarations:[]}],r=0,i=!1;e.split(/\r?\n/).forEach((s,o)=>{let u=s.trim();if(u.length===0)return;if(Ze(u)){r++,n[r]={timeDeclarations:[],groupingDeclarations:[]},i=!1;return}let l=Je(u);if(l&&(l.key==="time"||l.key==="timesignature"||l.key==="meter"||l.key==="grouping")){let f={value:l.value,line:o+1,originalKey:l.originalKey};i&&t(f.line,"late-system-setting",`${l.originalKey}: applies to this entire system and following systems; place it immediately after Bar for clarity.`),l.key==="grouping"?n[r].groupingDeclarations.push(f):n[r].timeDeclarations.push(f);return}(Se(u)||tt(u)||et(u))&&(i=!0)});let a={timeSignature:"4/4"};return n.map((s,o)=>{let u=a.timeSignature,l=a.beamGrouping?[...a.beamGrouping]:void 0,f=!1;s.timeDeclarations.forEach(g=>{if(!Zt(g.value)){t(g.line,"invalid-setting",`${g.originalKey}: "${g.value}" is not a valid time signature; keeping ${u}.`);return}u=Jt(g.value),l=void 0,f=!0});let d=s.groupingDeclarations[s.groupingDeclarations.length-1];if(d)if(M(d.value)==="auto")l=void 0;else{let g=De(d.value,u);g.error?(t(d.line,"invalid-setting",`${d.originalKey}: ${g.error}`),l=void 0):l=g.grouping}else f&&(l=void 0);return l&&De(l.join("+"),u).error&&(l=void 0),a={timeSignature:u,...l?{beamGrouping:[...l]}:{}},{...qe(a),sourceSectionIndex:o}})}function qe(e){return{timeSignature:e.timeSignature,...e.beamGrouping?{beamGrouping:[...e.beamGrouping]}:{}}}function Nt(e,t,n=[],r=[],i=[],a=[],s=!1,o=[],u=[]){let l=Ht(e,t,n,r,i,a,o),f=[],d=[],g=[];for(let D of l)for(let p of D.bars)f.push(p),d.push(...p.rows),g.push(...p.slots);return{...e,systems:l,bars:f,rows:d,slots:g,containsTupletSyntax:s,sectionRepeats:u.map(D=>({...D}))}}function Ze(e){return/^(new\s+)?(bar|measure)\b(\s+\d+)?\s*:?.*$/i.test(e)}function Bt(e){let t=/^subtitle\s*:\s*(.*)$/i.exec(e);return t?t[1].trim():null}function Se(e){let t=/^%(?:\s*x\s*(\d+))?$/i.exec(e);if(t)return{type:1,count:ze(t[1])};let n=/^repeat(?:\s+(?:bar|measure|previous\s+(?:bar|measure)|1(?:[-\s]*(?:bar|measure))?|one(?:[-\s]*(?:bar|measure))?))?(?:\s*x\s*(\d+))?$/i.exec(e);return n?{type:1,count:ze(n[1])}:null}function Je(e){let t=/^([A-Za-z][A-Za-z\s-]*):\s*(.+)$/.exec(e);if(!t)return null;let n=t[1].trim(),r=M(n),i=t[2].trim();return vt.has(r)?{key:r,originalKey:n,value:i}:null}function Ct(e){let t=/^([A-Za-z][A-Za-z\s-]*):\s*(.*)$/.exec(e);if(!t)return null;let n=t[1].trim();return At.has(M(n))?{originalKey:n,value:t[2].trim()}:null}function $t(e){let t=/^([A-Za-z][A-Za-z\s-]*):\s*$/.exec(e);if(!t)return null;let n=t[1].trim();return Tt.has(M(n))?{originalKey:n}:null}function et(e){let t=ye(e);if(!t)return null;let n=pe.get(M(t.label));return!n||t.patterns.length===0?null:{label:t.label,patterns:t.patterns,instrument:n,sectionRepeatStarts:t.sectionRepeatStarts.map(r=>({barIndex:r,lineNumber:0})),sectionRepeatEnds:t.sectionRepeatEnds.map(r=>({barIndex:r,lineNumber:0})),...t.sectionRepeatIssue?{sectionRepeatIssue:t.sectionRepeatIssue}:{}}}function tt(e){let t=ye(e);return!t||!Qe.has(M(t.label))||t.patterns.length===0?null:{label:t.label,patterns:t.patterns,sectionRepeatStarts:t.sectionRepeatStarts.map(n=>({barIndex:n,lineNumber:0})),sectionRepeatEnds:t.sectionRepeatEnds.map(n=>({barIndex:n,lineNumber:0})),...t.sectionRepeatIssue?{sectionRepeatIssue:t.sectionRepeatIssue}:{}}}function ye(e){let t=e.search(/[|\[\]]/);if(t<=0)return null;let n=e.slice(0,t).trim();if(!n)return null;let r=[],i=[],a=[],s,o=t,u=0;for(;o<e.length;){let l=e[o],f=e.slice(o+1).search(/[|\[\]]/),d=f<0?e.length:o+1+f,g=e.slice(o+1,d).replace(/\s+/g,"").trim();l==="]"&&(r.length===0?s??="A section repeat end marker must follow at least one bar; rendering and playback will remain linear.":a.push(r.length-1),u=Math.max(0,u-1)),g.length>0?(l==="["&&(u>0&&(s??="Nested or overlapping section repeats are not supported; rendering and playback will remain linear."),u++,i.push(r.length)),r.push(g)):l==="["?s??="A section repeat start marker must be followed by a bar on the same row; rendering and playback will remain linear.":d<e.length&&(s??="Adjacent section repeat separators are not supported; rendering and playback will remain linear."),o=d}return{label:n,patterns:r,sectionRepeatStarts:i,sectionRepeatEnds:a,...s?{sectionRepeatIssue:s}:{}}}function Ve(e,t){let n=e;return{...n,lineNumber:t,sectionRepeatStarts:n.sectionRepeatStarts?.map(r=>({...r,lineNumber:t})),sectionRepeatEnds:n.sectionRepeatEnds?.map(r=>({...r,lineNumber:t}))}}function Ke(e){let t=(e.sectionRepeatStarts??[]).map(r=>r.barIndex).join(","),n=(e.sectionRepeatEnds??[]).map(r=>r.barIndex).join(",");return`${t}|${n}`}function Lt(e,t,n,r,i){if(r||e.length===0&&t.length===0)return[];let a=[...e.map(l=>({...l,kind:"start"})),...t.map(l=>({...l,kind:"end"}))].sort((l,f)=>l.barIndex-f.barIndex||(l.kind===f.kind?0:l.kind==="end"?-1:1)),s=[],o=null,u=!1;for(let l of a){if(l.barIndex<0||l.barIndex>=n){u=!0,i(l.lineNumber,"invalid-section-repeat","Section repeat marker does not resolve to a playable bar; rendering and playback will remain linear.");continue}if(l.kind==="start"){if(o){u=!0,i(l.lineNumber,"invalid-section-repeat","Nested or overlapping section repeats are not supported; rendering and playback will remain linear.");continue}let f=s[s.length-1];if(f&&f.endBarIndex+1===l.barIndex){u=!0,i(l.lineNumber,"invalid-section-repeat","Adjacent section repeats sharing one boundary are not supported yet; rendering and playback will remain linear.");continue}o=l;continue}if(!o){u=!0,i(l.lineNumber,"invalid-section-repeat","Section repeat end marker has no matching start marker; rendering and playback will remain linear.");continue}if(l.barIndex<o.barIndex){u=!0,i(l.lineNumber,"invalid-section-repeat","Section repeat end marker precedes its start marker; rendering and playback will remain linear."),o=null;continue}s.push({startBarIndex:o.barIndex,endBarIndex:l.barIndex}),o=null}return o&&(u=!0,i(o.lineNumber,"invalid-section-repeat","Section repeat start marker has no matching end marker; rendering and playback will remain linear.")),u?[]:s}function Ot(e,t,n){let r=e.search(/[|\[\]]/);if(r<=0)return;let i=e.slice(0,r).trim();if(!i||i.includes(":"))return;let a=M(i),s=pe.has(a),o=Qe.has(a),u=ye(e)?.patterns??[];if((s||o)&&u.length===0){n(t,"empty-row",`${i} row has no usable pattern and is preserved as metadata.`,r+1);return}!s&&!o&&n(t,"unknown-row-label",`Unrecognized instrument row "${i}" is preserved as metadata.`,1)}function Gt(e,t,n,r){nt(e,n,i=>!Me(i),(i,a)=>{r(n,"unsupported-pattern-character",`${t} row contains unsupported character "${i}"; it will play as a normal hit.`,a)})}function Ut(e,t,n){nt(e,t,Kt,(r,i)=>{n(t,"unsupported-sticking-character",`Sticking row contains unsupported character "${r}"; it will be treated as a rest.`,i)})}function nt(e,t,n,r){let i=e.search(/[|\[\]]/);if(i<0)return;let a=new Set,s=Ce(e.slice(i+1));for(let o=i+1;o<e.length;o++){let u=e[o];s&&/[0-9()/@]/.test(u)||u==="|"||u==="["||u==="]"||/\s/.test(u)||a.has(u)||!n(u)||(a.add(u),r(u,o+1))}}function Vt(e,t,n,r,i){let a=[],s=[],o=!1;return e.forEach((u,l)=>{let f=n[l]?.timeSignature??"4/4",d=t[l],g=Math.max(0,...u.map(h=>h.patterns.length),d?.patterns.length??0),D=[],p=new Set;for(let h=0;h<g;h++){let b=[...u.filter(c=>c.patterns[h]!==void 0).map(c=>({kind:"row",pattern:c.patterns[h],line:c.segmentLineNumbers?.get(h)??c.lineNumber,assign:k=>{c.patterns[h]=k}})),...d?.patterns[h]!==void 0?[{kind:"sticking",pattern:d.patterns[h],line:d.segmentLineNumbers?.get(h)??d.lineNumber,assign:c=>{d.patterns[h]=c}}]:[]].map(c=>({entry:c,analysis:Ne(c.pattern,f,r)}));if(!b.some(({analysis:c})=>c.containsTupletSyntax)){b.forEach(({entry:c})=>{c.kind==="sticking"&&c.assign(fe(c.pattern))});continue}o=!0,p.add(h),b.forEach(({entry:c,analysis:k})=>{k.issues.forEach(S=>{i(c.line,S.code,`${c.kind==="sticking"?"Sticking row":"Row"} bar ${h+1}: ${S.message}`)})});let w=b.filter(({analysis:c})=>c.issues.length===0),E=w[0]?ge(w[0].analysis.regions):null,N=E===null?[]:w.filter(({analysis:c})=>ge(c.regions)!==E);if(N.forEach(({entry:c})=>{i(c.line,"tuplet-mismatch",`${c.kind==="sticking"?"Sticking row":"Row"} bar ${h+1} does not match the tuplet structure or duration form declared by the other rows; use the same written-beat or @ duration syntax across rows. Using plain-grid fallback for this bar.`)}),w.length!==b.length||N.length>0){b.forEach(({entry:c})=>{let k=de(c.pattern);c.assign(c.kind==="sticking"?fe(k):k)});continue}b.forEach(({entry:c,analysis:k})=>{c.assign(c.kind==="sticking"?fe(k.decodedPattern):k.decodedPattern)}),D[h]=w[0].analysis.regions.map(c=>({...c}))}a[l]=D,s[l]=p}),{rhythmSections:a,tupletSourceSegments:s,containsTupletSyntax:o}}function Kt(e){return!X(e)&&!["R","r","L","l","B","b"].includes(e)}function zt(e,t,n,r,i,a=[]){e.forEach((s,o)=>{let u=n[o]?.timeSignature??"4/4",l=Ae(u,r),f=Math.floor(l*.75),d=t[o],g=s.map(p=>({label:p.label,patterns:p.patterns,lineNumber:p.lineNumber,kind:"row",generatedSegments:p.generatedSegments,segmentLineNumbers:p.segmentLineNumbers}));d&&g.push({label:d.label,patterns:d.patterns,lineNumber:d.lineNumber,kind:"sticking",generatedSegments:d.generatedSegments,segmentLineNumbers:d.segmentLineNumbers});let D=Math.max(0,...g.map(p=>p.patterns.length));for(let p=0;p<D;p++){if(a[o]?.has(p))continue;let h=g.map(b=>{let _=b.patterns[p];return _===void 0||b.generatedSegments?.has(p)?null:{...b,pattern:_,length:_.length}}).filter(b=>b!==null),P=h.some(b=>b.length===l);h.forEach(b=>{if(b.length===l||b.length<f&&!P)return;let _=b.length>l?"Extra slots extend the bar and can change playback feel.":"Missing slots are treated as rests when another row sets the bar length.",w=b.kind==="sticking"?"Sticking row":`${b.label} row`;i(b.segmentLineNumbers?.get(p)??b.lineNumber,"row-length-mismatch",`${w} bar ${p+1} has ${b.length} slots; Time ${u} + Grid ${r} expects ${l}. ${_}`)})}})}function Ht(e,t,n,r,i,a,s){let o=0,u=0;return t.map((l,f)=>{let d=s[f]??e,g=d.timeSignature,D=d.beamGrouping&&!De(d.beamGrouping.join("+"),g).error?[...d.beamGrouping]:void 0,p=r[f],h=Math.max(1,J(l,p)),P=Array.from({length:h},(_,w)=>{let E=jt(l,w),N=p?.patterns[w],A=Math.max(0,...E.map(R=>R.pattern.length),N?.length??0),c=a[f]?.[w]?.map(R=>({...R}))??Be(A,g,e.gridResolution),k=c.length>0?Math.max(...c.map(Le)):0,S=Yt(E,o,u,c,N),B=n[f]?.[w],C={timeSignature:g,rows:E,slots:S,startSlot:o,startQuarter:u,durationQuarter:k,rhythmRegions:c,...N!==void 0?{stickingPattern:N}:{},...B?{measureRepeat:B.type}:{},...B&&B.count>1?{measureRepeatCount:B.count}:{}};return o+=S.length,u+=k,C}),b=i[f]?.trim();return{timeSignature:g,...D?{beamGrouping:D}:{},bars:P,...b?{subtitle:b}:{}}})}function Qt(e,t,n,r,i,a){ot(e,t,n);let s=[...r,...at(e,t,a)],o=s[s.length-1];if(!o)return{status:"missing"};if(o.timeSignature!==a)return{status:"meter-mismatch",previousTimeSignature:o.timeSignature};let u=t;for(let l=0;l<i.count;l++)u=Xt(e,u,o),n.push({type:i.type,count:l===0?i.count:1});return{status:"ok",sticking:u}}function Ft(e,t,n,r){let i=se(e,t),a=e.find(s=>s.instrument.id===r.instrument.id);for(a||(a={label:r.label,patterns:[],instrument:r.instrument,lineNumber:r.lineNumber},e.push(a));a.patterns.length<n;){let s=a.patterns.length,o=ie(e,t,s);a.patterns.push(o?oe(o):"-".repeat(i[s]??re(r.patterns[0]??""))),z(a,a.patterns.length-1)}r.patterns.forEach(s=>{let o=a.patterns.length;a.patterns.push(s),it(a,o,r.lineNumber)}),rt(a,r,n)}function Wt(e,t,n,r){let i=se(e,t),a=t??{label:r.label,patterns:[],lineNumber:r.lineNumber};for(;a.patterns.length<n;){let s=a.patterns.length,o=ie(e,t,s);a.patterns.push(o?oe(o):"-".repeat(i[s]??re(r.patterns[0]??""))),z(a,a.patterns.length-1)}return r.patterns.forEach(s=>{let o=a.patterns.length;a.patterns.push(s),it(a,o,r.lineNumber)}),rt(a,r,n),a}function rt(e,t,n){e.sectionRepeatStarts=[...e.sectionRepeatStarts??[],...(t.sectionRepeatStarts??[]).map(r=>({...r,barIndex:r.barIndex+n}))],e.sectionRepeatEnds=[...e.sectionRepeatEnds??[],...(t.sectionRepeatEnds??[]).map(r=>({...r,barIndex:r.barIndex+n}))],e.sectionRepeatIssue??=t.sectionRepeatIssue}function Xt(e,t,n){let r=J(e,t),i=se(e,t);if(n.rows.forEach(a=>{let s=e.find(o=>o.instrument.id===a.instrument.id);for(s||(s={label:a.label,patterns:[],instrument:a.instrument,lineNumber:0},e.push(s));s.patterns.length<r;){let o=s.patterns.length,u=ie(e,t,o);s.patterns.push(u?oe(u):"-".repeat(i[o]??n.width)),z(s,s.patterns.length-1)}s.patterns.push(a.pattern),z(s,s.patterns.length-1)}),n.stickingPattern!==void 0){let a=t??{label:"ST",patterns:[],lineNumber:0};for(;a.patterns.length<r;){let s=a.patterns.length,o=ie(e,a,s);a.patterns.push(o?oe(o):"-".repeat(i[s]??n.width)),z(a,a.patterns.length-1)}return a.patterns.push(n.stickingPattern),z(a,a.patterns.length-1),a}return t}function z(e,t){let n=e,r=n.generatedSegments??new Set;r.add(t),n.generatedSegments=r}function it(e,t,n){let r=new Map(e.segmentLineNumbers??[]);r.set(t,n),e.segmentLineNumbers=r}function ot(e,t,n){let r=J(e,t);for(;n.length<r;)n.push(void 0)}function ze(e){let t=e?Number.parseInt(e,10):1;return Number.isFinite(t)?Math.min(99,Math.max(1,t)):1}function at(e,t,n){let r=J(e,t),i=se(e,t);return Array.from({length:r},(a,s)=>({rows:e.map(o=>{let u=o.patterns[s];return u?{label:o.label,instrument:o.instrument,pattern:u}:null}).filter(o=>o!==null),...t?.patterns[s]!==void 0?{stickingPattern:t.patterns[s]}:{},width:i[s]??0,timeSignature:n}))}function J(e,t){return Math.max(0,...e.map(n=>n.patterns.length),t?.patterns.length??0)}function se(e,t){let n=J(e,t);return Array.from({length:n},(r,i)=>Math.max(0,...e.map(a=>re(a.patterns[i]??"")),re(t?.patterns[i]??"")))}function re(e){return Array.from(de(e)).length}function ie(e,t,n){return e.find(r=>r.patterns[n]!==void 0)?.patterns[n]??t?.patterns[n]}function oe(e){return Array.from(e).map(t=>/[0-9()/]/.test(t)?t:"-").join("")}function jt(e,t){return e.map(n=>{let r=n.patterns[t];return r?{label:n.label,pattern:r,instrument:n.instrument}:null}).filter(n=>n!==null)}function Yt(e,t,n,r,i){let a=Math.max(0,...e.map(s=>s.pattern.length),i?.length??0);return Array.from({length:a},(s,o)=>{let u=e.map(p=>{let h=p.pattern[o]??"-";return X(h)?null:{instrument:p.instrument,articulation:te(h),velocity:ve(h)}}).filter(p=>p!==null),l=qt(i?.[o]??"-"),f=r.findIndex(p=>o>=p.startPosition&&o<p.startPosition+p.positionCount),d=r[Math.max(0,f)],g=d?o-d.startPosition:0,D=d&&d.positionCount>0?d.durationQuarter/d.positionCount:4/16;return{index:t+o,hits:u,startQuarter:n+(d?.startQuarter??o*D)+g*D,durationQuarter:D,regionIndex:Math.max(0,f),...l?{sticking:l}:{}}})}function fe(e){return Array.from(e).map(t=>t==="R"||t==="r"?"R":t==="L"||t==="l"?"L":t==="B"||t==="b"?"B":"-").join("")}function qt(e){if(e==="R")return"right";if(e==="L")return"left";if(e==="B")return"both"}function Zt(e){return/^(\d{1,2})\s*\/\s*(\d{1,2})$/.test(e)}function Jt(e){let t=/^(\d{1,2})\s*\/\s*(\d{1,2})$/.exec(e);return t?`${t[1]}/${t[2]}`:"4/4"}function De(e,t){if(!/^\d+(?:\s*\+\s*\d+)*$/.test(e))return{error:`"${e}" must contain positive whole numbers joined with +, such as 2+2+3; using normal meter grouping.`};let n=e.split("+").map(o=>Number.parseInt(o.trim(),10));if(n.some(o=>o<=0))return{error:`"${e}" must contain only positive group sizes; using normal meter grouping.`};let r=/^(\d+)\/(\d+)$/.exec(t),i=r?Number.parseInt(r[1],10):4,a=r?Number.parseInt(r[2],10):4;if(a!==8&&a!==16)return{error:`is supported only for /8 and /16 meters; Time ${t} uses /${a}. Using normal meter grouping.`};let s=n.reduce((o,u)=>o+u,0);return s!==i?{error:`"${e}" totals ${s}, but Time ${t} requires ${i}; using normal meter grouping.`}:{grouping:n}}function st(e){let t=/(\d+)/.exec(e);return t?Number.parseInt(t[1],10):null}function en(e){let t=st(e);return t===null?1:Math.min(64,Math.max(1,t))}function he(e){let t=M(e);return Fe.has(t)||We.has(t)}function be(e,t){let n=M(e);return Fe.has(n)?!0:We.has(n)?!1:t}function tn(e){let t=M(e);return Xe.has(t)||je.has(t)||Ye.has(t)}function nn(e){let t=M(e);return Xe.has(t)?"used":je.has(t)?"all":Ye.has(t)?"off":"off"}function ut(e){let t=/(\d+)/.exec(e);return t?Number.parseInt(t[1],10):null}function He(e){let t=ut(e);return t===null?16:t===32?32:16}function rn(e){return Number.isFinite(e)?Math.min(260,Math.max(30,e)):100}function xe(e,t={}){return t.mode==="authoring"?an(e):on(e)}function on(e){return[...mt(e),...lt(e)].join(`
`)}function lt(e){let t=[],n=new Map(e.bars.map((r,i)=>[r,i]));return e.systems.forEach((r,i)=>{if(i>0){t.push("Bar");let a=e.systems[i-1],s=r.timeSignature!==a.timeSignature;s&&t.push(`Time: ${r.timeSignature}`);let o=s?void 0:a.beamGrouping;sn(r.beamGrouping,o)||t.push(r.beamGrouping?`Grouping: ${r.beamGrouping.join("+")}`:"Grouping: auto")}r.subtitle&&t.push(`Subtitle: ${r.subtitle}`),t.push(...mn(r,e.sectionRepeats,n))}),t}function mt(e){let t=[...e.metadata];return e.tempo!==100&&t.push(`Tempo: ${e.tempo}`),e.timeSignature!=="4/4"&&t.push(`Time: ${e.timeSignature}`),e.beamGrouping&&t.push(`Grouping: ${e.beamGrouping.join("+")}`),e.repeatCount!==1&&t.push(`Repeat: ${e.repeatCount}`),e.gridResolution!==16&&t.push(`Grid: ${e.gridResolution}`),e.legendMode!=="off"&&t.push(`Legend: ${e.legendMode}`),e.showCursor!==!1&&t.push(`Cursor: ${e.showCursor?"on":"off"}`),e.showHighlight!==!0&&t.push(`Highlight: ${e.showHighlight?"on":"off"}`),e.showRests!==!0&&t.push(`Rests: ${e.showRests?"on":"off"}`),e.voicing!==U&&t.push(`Voicing: ${e.voicing}`),t}function an(e){let t=[`Title: ${un(e)}`,`Tempo: ${e.tempo}`,`Time: ${e.timeSignature}`,...e.beamGrouping?[`Grouping: ${e.beamGrouping.join("+")}`]:[],...e.voicing!==U?[`Voicing: ${e.voicing}`]:[],`Grid: ${e.gridResolution}`];e.repeatCount!==1&&t.push(`Repeat: ${e.repeatCount}`),e.legendMode!=="off"&&t.push(`Legend: ${e.legendMode}`);let n=mt(e).filter(i=>i.trim().length>0).filter(i=>!ln(i)),r=lt(e);return[...t,...n,...r].join(`
`)}function sn(e,t){return!e||!t?e===t:e.length===t.length&&e.every((n,r)=>n===t[r])}function un(e){let t=e.metadata.find(n=>M(n.split(":")[0]??"")==="title");return t&&t.slice(t.indexOf(":")+1).trim()||"Drum notation"}function ln(e){let t=e.indexOf(":");return t<=0?!1:new Set(["title","tempo","bpm","time","timesignature","meter","grouping","voicing","repeat","repeats","grid","subdivision","resolution","legend","instrumentlegend","kitlegend","colorlegend"]).has(M(e.slice(0,t)))}function mn(e,t,n){let r=[],i=[],a=()=>{i.length!==0&&(r.push(...dn(i,t,n)),i=[])};for(let s=0;s<e.bars.length;s++){let o=e.bars[s];if(o.measureRepeat){a();let u=Math.max(1,Math.min(o.measureRepeatCount??1,cn(e.bars,s)));r.push(pn(u)),s+=u-1;continue}i.push(o)}return a(),r}function cn(e,t){let n=0;for(let r=t;r<e.length&&e[r].measureRepeat;r++)n++;return n}function pn(e){return e>1?`%x${e}`:"%"}function dn(e,t,n){let r=[],i=hn(e);i&&r.push(i);for(let u of bn(e))r.push(u);let a=0;for(let u of r)a=Math.max(a,u.label.length);let s=[],o=e.map(u=>n.get(u)??-1);for(let u of r)s.push(`${gn(u.label,a)} ${fn(u.patterns,o,t)}`);return s}function gn(e,t){let n=e;for(;n.length<t;)n+=" ";return n}function fn(e,t,n){let r="",i=new Set(n.map(o=>o.startBarIndex)),a=new Set(n.map(o=>o.endBarIndex));for(let o=0;o<e.length;o++){let u=t[o]??-1,l=t[o-1]??-1,f=o>0&&a.has(l)?"]":i.has(u)?"[":"|";r+=`${o>0?" ":""}${f} ${e[o]}`}let s=t[e.length-1]??-1;return a.has(s)&&(r+=" ]"),r}function hn(e){return e.some(t=>t.stickingPattern!==void 0)?{label:"ST",patterns:e.map(t=>ct(t,Sn(t.stickingPattern??"-".repeat(t.slots.length))))}:null}function bn(e){let t=[],n=new Map,r=new Map;for(let i of e)for(let a of i.rows){let s=a.instrument.id;r.has(s)||(t.push(a.instrument),n.set(s,a.label),r.set(s,[])),r.get(s).push(ct(i,Te(a.instrument,a.pattern)))}return t.map(i=>({label:n.get(i.id),instrument:i,patterns:r.get(i.id)}))}function ct(e,t){if(!e.rhythmRegions.some(i=>i.kind==="tuplet"))return t;let n="",r=0;for(let i of e.rhythmRegions){i.startPosition>r&&(n+=t.slice(r,i.startPosition));let a=i.startPosition+i.positionCount,s=t.slice(i.startPosition,a),o=s+"-".repeat(Math.max(0,i.positionCount-s.length));if(i.kind==="tuplet"){let u=i.tupletSpan;if(u?.kind==="written-beats"){let l=u.beats===1?String(i.subdivisionCount):`${u.beats}/${i.subdivisionCount}`;n+=`${l}(${o})`}else{let l=u?.kind==="note-value"?u.denominator:Oe(i);n+=`${i.subdivisionCount}@${l}(${o})`}}else n+=o;r=a}return n+t.slice(r)}function Sn(e){return Array.from(e).map(t=>t==="R"||t==="r"?"R":t==="L"||t==="l"?"L":t==="B"||t==="b"?"B":"-").join("")}function pt(e){try{let t=Re(e),n=xe(t.block),r=[];if(t.block.rows.length===0&&r.push("No supported drum rows were parsed."),n.length>0){let i=Re(n);xe(i.block)!==n&&r.push("Normalized notation is not serializer-idempotent.")}return{status:r.length>0?"invalid":t.warnings.length>0?"warnings":"clean",normalized:n,warnings:t.warnings,errors:r}}catch(t){return{status:"invalid",normalized:"",warnings:[],errors:[t instanceof Error?t.message:String(t)]}}}var Q=128*1024,ue={importerVersion:"0.2.1",notationCoreVersion:"1.6.0",notationCoreDigest:"3920b0e9d89585623dac697f7cabef47f5592536e9dbd86fbe621c113b70fd26",validatorBuildDigest:"a7b0f99695abcc589ffc3efbe669f7d35957683f2125a6ebf564037051ea6073"};function le(e){xn.write(`${JSON.stringify(e)}
`)}async function In(){let e=[],t=0;for await(let n of yn){let r=Buffer.isBuffer(n)?n:Buffer.from(n);if(e.push(r),t+=r.length,t>Q)throw new Error(`Input exceeds ${Q} bytes.`)}return Buffer.concat(e).toString("utf8")}async function kn(){let e=process.argv.slice(2);if(e.length===1&&e[0]==="--version"){le({schemaVersion:1,...ue});return}if(e.length>1||e[0]?.startsWith("--")){le({schemaVersion:1,status:"invalid",...ue,normalized:"",warnings:[],errors:["Usage: validate-drum-notation.mjs [file]"]}),process.exitCode=1;return}if(e[0]&&(await Rn(e[0])).size>Q)throw new Error(`Input exceeds ${Q} bytes.`);let t=e[0]?await Dn(e[0],"utf8"):await In();if(Buffer.byteLength(t,"utf8")>Q)throw new Error(`Input exceeds ${Q} bytes.`);let n=pt(t);le({schemaVersion:1,...ue,...n}),process.exitCode=n.status==="invalid"?1:n.status==="warnings"?2:0}kn().catch(e=>{le({schemaVersion:1,status:"invalid",...ue,normalized:"",warnings:[],errors:[e instanceof Error?e.message:String(e)]}),process.exitCode=1});
SHA-256: 5082aea1871da665f3a9664e06fcd576f6e7fdd2813629cd6db46d7dedc8c34d