musicxml-io 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-TIFUKSTH.js → chunk-24XBPMRJ.js} +9 -9
- package/dist/{chunk-EFP2DAOK.mjs → chunk-AWYTZMJB.mjs} +25 -11
- package/dist/{chunk-CANSNTYK.js → chunk-LLFU3JZA.js} +47 -33
- package/dist/{chunk-ZDAN74FN.mjs → chunk-LYSKKBKA.mjs} +9 -9
- package/dist/{index-C1gu_fLF.d.ts → index-BWaC45uP.d.ts} +14 -14
- package/dist/{index-Dy4LmZRQ.d.mts → index-DFwIbWZu.d.mts} +14 -14
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +46 -46
- package/dist/index.mjs +11 -11
- package/dist/operations/index.d.mts +2 -2
- package/dist/operations/index.d.ts +2 -2
- package/dist/operations/index.js +3 -3
- package/dist/operations/index.mjs +2 -2
- package/dist/query/index.d.mts +7 -7
- package/dist/query/index.d.ts +7 -7
- package/dist/query/index.js +2 -2
- package/dist/query/index.mjs +1 -1
- package/dist/{types-D0G3_ykl.d.mts → types-BFmNsRNw.d.mts} +9 -9
- package/dist/{types-D0G3_ykl.d.ts → types-BFmNsRNw.d.ts} +9 -9
- package/package.json +1 -1
|
@@ -191,7 +191,7 @@ function groupByVoice(measure) {
|
|
|
191
191
|
for (const entry of measure.entries) {
|
|
192
192
|
if (entry.type !== "note") continue;
|
|
193
193
|
const staff = _nullishCoalesce(entry.staff, () => ( 1));
|
|
194
|
-
const voice = _nullishCoalesce(entry.voice, () => ( 1));
|
|
194
|
+
const voice = _nullishCoalesce(entry.voice, () => ( "1"));
|
|
195
195
|
const key = `${staff}-${voice}`;
|
|
196
196
|
if (!groups.has(key)) {
|
|
197
197
|
groups.set(key, { staff, voice, notes: [] });
|
|
@@ -200,7 +200,7 @@ function groupByVoice(measure) {
|
|
|
200
200
|
}
|
|
201
201
|
return Array.from(groups.values()).sort((a, b) => {
|
|
202
202
|
if (a.staff !== b.staff) return a.staff - b.staff;
|
|
203
|
-
return a.voice
|
|
203
|
+
return a.voice.localeCompare(b.voice, void 0, { numeric: true });
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
206
|
function groupByStaff(measure) {
|
|
@@ -285,10 +285,10 @@ function getVoices(measure) {
|
|
|
285
285
|
const voices = /* @__PURE__ */ new Set();
|
|
286
286
|
for (const entry of measure.entries) {
|
|
287
287
|
if (entry.type === "note") {
|
|
288
|
-
voices.add(_nullishCoalesce(entry.voice, () => ( 1)));
|
|
288
|
+
voices.add(_nullishCoalesce(entry.voice, () => ( "1")));
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
|
-
return Array.from(voices).sort((a, b) => a
|
|
291
|
+
return Array.from(voices).sort((a, b) => a.localeCompare(b, void 0, { numeric: true }));
|
|
292
292
|
}
|
|
293
293
|
function getStaves(measure) {
|
|
294
294
|
const staves = /* @__PURE__ */ new Set();
|
|
@@ -336,7 +336,7 @@ function buildVoiceToStaffMap(measure) {
|
|
|
336
336
|
const map = /* @__PURE__ */ new Map();
|
|
337
337
|
for (const entry of measure.entries) {
|
|
338
338
|
if (entry.type === "note" && entry.staff !== void 0) {
|
|
339
|
-
const voice = _nullishCoalesce(entry.voice, () => ( 1));
|
|
339
|
+
const voice = _nullishCoalesce(entry.voice, () => ( "1"));
|
|
340
340
|
const staff = entry.staff;
|
|
341
341
|
if (!map.has(voice)) {
|
|
342
342
|
map.set(voice, staff);
|
|
@@ -355,7 +355,7 @@ function buildVoiceToStaffMapForPart(part) {
|
|
|
355
355
|
for (const measure of part.measures) {
|
|
356
356
|
for (const entry of measure.entries) {
|
|
357
357
|
if (entry.type === "note" && entry.staff !== void 0) {
|
|
358
|
-
const voice = _nullishCoalesce(entry.voice, () => ( 1));
|
|
358
|
+
const voice = _nullishCoalesce(entry.voice, () => ( "1"));
|
|
359
359
|
const staff = entry.staff;
|
|
360
360
|
if (!map.has(voice)) {
|
|
361
361
|
map.set(voice, staff);
|
|
@@ -374,7 +374,7 @@ function inferStaff(entry, voiceToStaffMap) {
|
|
|
374
374
|
if (entry.staff !== void 0) {
|
|
375
375
|
return entry.staff;
|
|
376
376
|
}
|
|
377
|
-
const inferredStaff = voiceToStaffMap.get(_nullishCoalesce(entry.voice, () => ( 1)));
|
|
377
|
+
const inferredStaff = voiceToStaffMap.get(_nullishCoalesce(entry.voice, () => ( "1")));
|
|
378
378
|
if (inferredStaff !== void 0) {
|
|
379
379
|
return inferredStaff;
|
|
380
380
|
}
|
|
@@ -417,11 +417,11 @@ function getVoicesForStaff(measure, staff) {
|
|
|
417
417
|
if (entry.type === "note") {
|
|
418
418
|
const entryStaff = _nullishCoalesce(entry.staff, () => ( 1));
|
|
419
419
|
if (entryStaff === staff) {
|
|
420
|
-
voices.add(_nullishCoalesce(entry.voice, () => ( 1)));
|
|
420
|
+
voices.add(_nullishCoalesce(entry.voice, () => ( "1")));
|
|
421
421
|
}
|
|
422
422
|
}
|
|
423
423
|
}
|
|
424
|
-
return Array.from(voices).sort((a, b) => a
|
|
424
|
+
return Array.from(voices).sort((a, b) => a.localeCompare(b, void 0, { numeric: true }));
|
|
425
425
|
}
|
|
426
426
|
function getStaffRange(score, partIndex) {
|
|
427
427
|
const part = score.parts[partIndex];
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
getMeasureEndPosition,
|
|
9
9
|
pitchToSemitone,
|
|
10
10
|
semitoneToKeyAwarePitch
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-LYSKKBKA.mjs";
|
|
12
12
|
|
|
13
13
|
// src/id.ts
|
|
14
14
|
import { nanoid } from "nanoid";
|
|
@@ -176,7 +176,9 @@ function validateMeasureDuration(measure, divisions, time, location, tolerance =
|
|
|
176
176
|
const expectedDuration = beats / time.beatType * 4 * divisions;
|
|
177
177
|
const voiceDurations = calculateVoiceDurations(measure);
|
|
178
178
|
for (const [voiceKey, actualDuration] of voiceDurations.entries()) {
|
|
179
|
-
const
|
|
179
|
+
const dashIndex = voiceKey.indexOf("-");
|
|
180
|
+
const staff = Number(voiceKey.slice(0, dashIndex));
|
|
181
|
+
const voice = voiceKey.slice(dashIndex + 1);
|
|
180
182
|
const diff = actualDuration - expectedDuration;
|
|
181
183
|
if (Math.abs(diff) > tolerance) {
|
|
182
184
|
if (diff > 0) {
|
|
@@ -265,7 +267,7 @@ function validateMeasureFullness(measure, divisions, time, location) {
|
|
|
265
267
|
currentPosition -= entry.duration;
|
|
266
268
|
} else if (entry.type === "forward") {
|
|
267
269
|
const staff = entry.staff ?? 1;
|
|
268
|
-
const voice = entry.voice ?? 1;
|
|
270
|
+
const voice = entry.voice ?? "1";
|
|
269
271
|
const key = `${staff}-${voice}`;
|
|
270
272
|
if (!voiceCoverage.has(key)) {
|
|
271
273
|
voiceCoverage.set(key, { segments: [] });
|
|
@@ -278,7 +280,9 @@ function validateMeasureFullness(measure, divisions, time, location) {
|
|
|
278
280
|
}
|
|
279
281
|
}
|
|
280
282
|
for (const [voiceKey, { segments }] of voiceCoverage.entries()) {
|
|
281
|
-
const
|
|
283
|
+
const dashIndex = voiceKey.indexOf("-");
|
|
284
|
+
const staff = Number(voiceKey.slice(0, dashIndex));
|
|
285
|
+
const voice = voiceKey.slice(dashIndex + 1);
|
|
282
286
|
const sorted = [...segments].sort((a, b) => a.start - b.start);
|
|
283
287
|
let lastEnd = 0;
|
|
284
288
|
const gaps = [];
|
|
@@ -427,7 +431,9 @@ function validateBeams(measure, location) {
|
|
|
427
431
|
}
|
|
428
432
|
}
|
|
429
433
|
for (const [beamKey, { entryIndex: startIndex, staff }] of openBeams.entries()) {
|
|
430
|
-
const
|
|
434
|
+
const beamDashIndex = beamKey.indexOf("-");
|
|
435
|
+
const beamNumber = Number(beamKey.slice(0, beamDashIndex));
|
|
436
|
+
const voice = beamKey.slice(beamDashIndex + 1);
|
|
431
437
|
errors.push({
|
|
432
438
|
code: "BEAM_BEGIN_WITHOUT_END",
|
|
433
439
|
level: "error",
|
|
@@ -499,7 +505,11 @@ function validateTuplets(measure, location) {
|
|
|
499
505
|
}
|
|
500
506
|
}
|
|
501
507
|
for (const [tupletKey, startIndex] of openTuplets.entries()) {
|
|
502
|
-
const
|
|
508
|
+
const firstDash = tupletKey.indexOf("-");
|
|
509
|
+
const lastDash = tupletKey.lastIndexOf("-");
|
|
510
|
+
const tupletNumber = Number(tupletKey.slice(0, firstDash));
|
|
511
|
+
const voice = tupletKey.slice(firstDash + 1, lastDash);
|
|
512
|
+
const staff = Number(tupletKey.slice(lastDash + 1));
|
|
503
513
|
errors.push({
|
|
504
514
|
code: "TUPLET_START_WITHOUT_STOP",
|
|
505
515
|
level: "error",
|
|
@@ -550,11 +560,11 @@ function validateVoiceStaff(measure, staves, location) {
|
|
|
550
560
|
for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
|
|
551
561
|
const entry = measure.entries[entryIndex];
|
|
552
562
|
if (entry.type !== "note") continue;
|
|
553
|
-
if (entry.voice !== void 0 && entry.voice
|
|
563
|
+
if (entry.voice !== void 0 && entry.voice.trim() === "") {
|
|
554
564
|
errors.push({
|
|
555
565
|
code: "INVALID_VOICE_NUMBER",
|
|
556
566
|
level: "error",
|
|
557
|
-
message: `Invalid voice
|
|
567
|
+
message: `Invalid voice: empty string.`,
|
|
558
568
|
location: { ...location, entryIndex, voice: entry.voice }
|
|
559
569
|
});
|
|
560
570
|
}
|
|
@@ -1025,7 +1035,11 @@ function validateSlursAcrossMeasures(part) {
|
|
|
1025
1035
|
}
|
|
1026
1036
|
}
|
|
1027
1037
|
for (const [slurKey, { measureIndex, entryIndex }] of openSlurs.entries()) {
|
|
1028
|
-
const
|
|
1038
|
+
const firstDash = slurKey.indexOf("-");
|
|
1039
|
+
const lastDash = slurKey.lastIndexOf("-");
|
|
1040
|
+
const slurNumber = Number(slurKey.slice(0, firstDash));
|
|
1041
|
+
const voice = slurKey.slice(firstDash + 1, lastDash);
|
|
1042
|
+
const staff = Number(slurKey.slice(lastDash + 1));
|
|
1029
1043
|
const measure = part.measures[measureIndex];
|
|
1030
1044
|
errors.push({
|
|
1031
1045
|
code: "SLUR_START_WITHOUT_STOP",
|
|
@@ -1225,7 +1239,7 @@ function rebuildMeasureWithVoice(measure, voice, newEntries, measureDuration, st
|
|
|
1225
1239
|
_id: generateId(),
|
|
1226
1240
|
type: "forward",
|
|
1227
1241
|
duration: diff,
|
|
1228
|
-
voice: entry.type === "note" ? entry.voice : 1,
|
|
1242
|
+
voice: entry.type === "note" ? entry.voice : "1",
|
|
1229
1243
|
staff: entry.type === "note" ? entry.staff : void 0
|
|
1230
1244
|
});
|
|
1231
1245
|
currentPosition = targetPos;
|
|
@@ -2716,7 +2730,7 @@ function autoBeam(score, options) {
|
|
|
2716
2730
|
for (const entry of measure.entries) {
|
|
2717
2731
|
if (entry.type === "note") {
|
|
2718
2732
|
if (!entry.chord && !entry.rest) {
|
|
2719
|
-
const voice = entry.voice ?? 1;
|
|
2733
|
+
const voice = entry.voice ?? "1";
|
|
2720
2734
|
if (options.voice === void 0 || voice === options.voice) {
|
|
2721
2735
|
if (!notesByVoice.has(voice)) {
|
|
2722
2736
|
notesByVoice.set(voice, []);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunk24XBPMRJjs = require('./chunk-24XBPMRJ.js');
|
|
12
12
|
|
|
13
13
|
// src/id.ts
|
|
14
14
|
var _nanoid = require('nanoid');
|
|
@@ -176,7 +176,9 @@ function validateMeasureDuration(measure, divisions, time, location, tolerance =
|
|
|
176
176
|
const expectedDuration = beats / time.beatType * 4 * divisions;
|
|
177
177
|
const voiceDurations = calculateVoiceDurations(measure);
|
|
178
178
|
for (const [voiceKey, actualDuration] of voiceDurations.entries()) {
|
|
179
|
-
const
|
|
179
|
+
const dashIndex = voiceKey.indexOf("-");
|
|
180
|
+
const staff = Number(voiceKey.slice(0, dashIndex));
|
|
181
|
+
const voice = voiceKey.slice(dashIndex + 1);
|
|
180
182
|
const diff = actualDuration - expectedDuration;
|
|
181
183
|
if (Math.abs(diff) > tolerance) {
|
|
182
184
|
if (diff > 0) {
|
|
@@ -265,7 +267,7 @@ function validateMeasureFullness(measure, divisions, time, location) {
|
|
|
265
267
|
currentPosition -= entry.duration;
|
|
266
268
|
} else if (entry.type === "forward") {
|
|
267
269
|
const staff = _nullishCoalesce(entry.staff, () => ( 1));
|
|
268
|
-
const voice = _nullishCoalesce(entry.voice, () => ( 1));
|
|
270
|
+
const voice = _nullishCoalesce(entry.voice, () => ( "1"));
|
|
269
271
|
const key = `${staff}-${voice}`;
|
|
270
272
|
if (!voiceCoverage.has(key)) {
|
|
271
273
|
voiceCoverage.set(key, { segments: [] });
|
|
@@ -278,7 +280,9 @@ function validateMeasureFullness(measure, divisions, time, location) {
|
|
|
278
280
|
}
|
|
279
281
|
}
|
|
280
282
|
for (const [voiceKey, { segments }] of voiceCoverage.entries()) {
|
|
281
|
-
const
|
|
283
|
+
const dashIndex = voiceKey.indexOf("-");
|
|
284
|
+
const staff = Number(voiceKey.slice(0, dashIndex));
|
|
285
|
+
const voice = voiceKey.slice(dashIndex + 1);
|
|
282
286
|
const sorted = [...segments].sort((a, b) => a.start - b.start);
|
|
283
287
|
let lastEnd = 0;
|
|
284
288
|
const gaps = [];
|
|
@@ -427,7 +431,9 @@ function validateBeams(measure, location) {
|
|
|
427
431
|
}
|
|
428
432
|
}
|
|
429
433
|
for (const [beamKey, { entryIndex: startIndex, staff }] of openBeams.entries()) {
|
|
430
|
-
const
|
|
434
|
+
const beamDashIndex = beamKey.indexOf("-");
|
|
435
|
+
const beamNumber = Number(beamKey.slice(0, beamDashIndex));
|
|
436
|
+
const voice = beamKey.slice(beamDashIndex + 1);
|
|
431
437
|
errors.push({
|
|
432
438
|
code: "BEAM_BEGIN_WITHOUT_END",
|
|
433
439
|
level: "error",
|
|
@@ -499,7 +505,11 @@ function validateTuplets(measure, location) {
|
|
|
499
505
|
}
|
|
500
506
|
}
|
|
501
507
|
for (const [tupletKey, startIndex] of openTuplets.entries()) {
|
|
502
|
-
const
|
|
508
|
+
const firstDash = tupletKey.indexOf("-");
|
|
509
|
+
const lastDash = tupletKey.lastIndexOf("-");
|
|
510
|
+
const tupletNumber = Number(tupletKey.slice(0, firstDash));
|
|
511
|
+
const voice = tupletKey.slice(firstDash + 1, lastDash);
|
|
512
|
+
const staff = Number(tupletKey.slice(lastDash + 1));
|
|
503
513
|
errors.push({
|
|
504
514
|
code: "TUPLET_START_WITHOUT_STOP",
|
|
505
515
|
level: "error",
|
|
@@ -550,11 +560,11 @@ function validateVoiceStaff(measure, staves, location) {
|
|
|
550
560
|
for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
|
|
551
561
|
const entry = measure.entries[entryIndex];
|
|
552
562
|
if (entry.type !== "note") continue;
|
|
553
|
-
if (entry.voice !== void 0 && entry.voice
|
|
563
|
+
if (entry.voice !== void 0 && entry.voice.trim() === "") {
|
|
554
564
|
errors.push({
|
|
555
565
|
code: "INVALID_VOICE_NUMBER",
|
|
556
566
|
level: "error",
|
|
557
|
-
message: `Invalid voice
|
|
567
|
+
message: `Invalid voice: empty string.`,
|
|
558
568
|
location: { ...location, entryIndex, voice: entry.voice }
|
|
559
569
|
});
|
|
560
570
|
}
|
|
@@ -1025,7 +1035,11 @@ function validateSlursAcrossMeasures(part) {
|
|
|
1025
1035
|
}
|
|
1026
1036
|
}
|
|
1027
1037
|
for (const [slurKey, { measureIndex, entryIndex }] of openSlurs.entries()) {
|
|
1028
|
-
const
|
|
1038
|
+
const firstDash = slurKey.indexOf("-");
|
|
1039
|
+
const lastDash = slurKey.lastIndexOf("-");
|
|
1040
|
+
const slurNumber = Number(slurKey.slice(0, firstDash));
|
|
1041
|
+
const voice = slurKey.slice(firstDash + 1, lastDash);
|
|
1042
|
+
const staff = Number(slurKey.slice(lastDash + 1));
|
|
1029
1043
|
const measure = part.measures[measureIndex];
|
|
1030
1044
|
errors.push({
|
|
1031
1045
|
code: "SLUR_START_WITHOUT_STOP",
|
|
@@ -1225,7 +1239,7 @@ function rebuildMeasureWithVoice(measure, voice, newEntries, measureDuration, st
|
|
|
1225
1239
|
_id: generateId(),
|
|
1226
1240
|
type: "forward",
|
|
1227
1241
|
duration: diff,
|
|
1228
|
-
voice: entry.type === "note" ? entry.voice : 1,
|
|
1242
|
+
voice: entry.type === "note" ? entry.voice : "1",
|
|
1229
1243
|
staff: entry.type === "note" ? entry.staff : void 0
|
|
1230
1244
|
});
|
|
1231
1245
|
currentPosition = targetPos;
|
|
@@ -1546,18 +1560,18 @@ function setNotePitchBySemitone(score, options) {
|
|
|
1546
1560
|
const result = cloneScore(score);
|
|
1547
1561
|
const measure = result.parts[options.partIndex].measures[options.measureIndex];
|
|
1548
1562
|
const measureNumber = _nullishCoalesce(measure.number, () => ( String(options.measureIndex + 1)));
|
|
1549
|
-
const attrs =
|
|
1563
|
+
const attrs = _chunk24XBPMRJjs.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
|
|
1550
1564
|
const keySignature = _nullishCoalesce(attrs.key, () => ( { fifths: 0 }));
|
|
1551
1565
|
let noteCount = 0;
|
|
1552
1566
|
for (const entry of measure.entries) {
|
|
1553
1567
|
if (entry.type === "note" && !entry.rest) {
|
|
1554
1568
|
if (noteCount === options.noteIndex) {
|
|
1555
|
-
const notePosition =
|
|
1556
|
-
const accidentalsInMeasure =
|
|
1557
|
-
const newPitch =
|
|
1569
|
+
const notePosition = _chunk24XBPMRJjs.getAbsolutePositionForNote.call(void 0, entry, measure);
|
|
1570
|
+
const accidentalsInMeasure = _chunk24XBPMRJjs.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
|
|
1571
|
+
const newPitch = _chunk24XBPMRJjs.semitoneToKeyAwarePitch.call(void 0, options.semitone, keySignature, {
|
|
1558
1572
|
preferSharp: options.preferSharp
|
|
1559
1573
|
});
|
|
1560
|
-
const accidental =
|
|
1574
|
+
const accidental = _chunk24XBPMRJjs.determineAccidental.call(void 0, newPitch, keySignature, accidentalsInMeasure);
|
|
1561
1575
|
entry.pitch = newPitch;
|
|
1562
1576
|
if (accidental) {
|
|
1563
1577
|
entry.accidental = { value: accidental };
|
|
@@ -1591,7 +1605,7 @@ function shiftNotePitch(score, options) {
|
|
|
1591
1605
|
if (!entry.pitch) {
|
|
1592
1606
|
return failure([operationError("NOTE_NOT_FOUND", "Note has no pitch", { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
|
|
1593
1607
|
}
|
|
1594
|
-
currentSemitone =
|
|
1608
|
+
currentSemitone = _chunk24XBPMRJjs.pitchToSemitone.call(void 0, entry.pitch);
|
|
1595
1609
|
break;
|
|
1596
1610
|
}
|
|
1597
1611
|
noteCount++;
|
|
@@ -1619,7 +1633,7 @@ function raiseAccidental(score, options) {
|
|
|
1619
1633
|
const result = cloneScore(score);
|
|
1620
1634
|
const measure = result.parts[options.partIndex].measures[options.measureIndex];
|
|
1621
1635
|
const measureNumber = _nullishCoalesce(measure.number, () => ( String(options.measureIndex + 1)));
|
|
1622
|
-
const attrs =
|
|
1636
|
+
const attrs = _chunk24XBPMRJjs.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
|
|
1623
1637
|
const keySignature = _nullishCoalesce(attrs.key, () => ( { fifths: 0 }));
|
|
1624
1638
|
let noteCount = 0;
|
|
1625
1639
|
for (const entry of measure.entries) {
|
|
@@ -1634,9 +1648,9 @@ function raiseAccidental(score, options) {
|
|
|
1634
1648
|
return failure([operationError("ACCIDENTAL_OUT_OF_BOUNDS", `Cannot raise accidental beyond double-sharp (current: ${currentAlter})`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
|
|
1635
1649
|
}
|
|
1636
1650
|
entry.pitch.alter = newAlter === 0 ? void 0 : newAlter;
|
|
1637
|
-
const notePosition =
|
|
1638
|
-
const accidentalsInMeasure =
|
|
1639
|
-
const accidental =
|
|
1651
|
+
const notePosition = _chunk24XBPMRJjs.getAbsolutePositionForNote.call(void 0, entry, measure);
|
|
1652
|
+
const accidentalsInMeasure = _chunk24XBPMRJjs.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
|
|
1653
|
+
const accidental = _chunk24XBPMRJjs.determineAccidental.call(void 0, entry.pitch, keySignature, accidentalsInMeasure);
|
|
1640
1654
|
if (accidental) {
|
|
1641
1655
|
entry.accidental = { value: accidental };
|
|
1642
1656
|
} else {
|
|
@@ -1660,7 +1674,7 @@ function lowerAccidental(score, options) {
|
|
|
1660
1674
|
const result = cloneScore(score);
|
|
1661
1675
|
const measure = result.parts[options.partIndex].measures[options.measureIndex];
|
|
1662
1676
|
const measureNumber = _nullishCoalesce(measure.number, () => ( String(options.measureIndex + 1)));
|
|
1663
|
-
const attrs =
|
|
1677
|
+
const attrs = _chunk24XBPMRJjs.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
|
|
1664
1678
|
const keySignature = _nullishCoalesce(attrs.key, () => ( { fifths: 0 }));
|
|
1665
1679
|
let noteCount = 0;
|
|
1666
1680
|
for (const entry of measure.entries) {
|
|
@@ -1675,9 +1689,9 @@ function lowerAccidental(score, options) {
|
|
|
1675
1689
|
return failure([operationError("ACCIDENTAL_OUT_OF_BOUNDS", `Cannot lower accidental beyond double-flat (current: ${currentAlter})`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
|
|
1676
1690
|
}
|
|
1677
1691
|
entry.pitch.alter = newAlter === 0 ? void 0 : newAlter;
|
|
1678
|
-
const notePosition =
|
|
1679
|
-
const accidentalsInMeasure =
|
|
1680
|
-
const accidental =
|
|
1692
|
+
const notePosition = _chunk24XBPMRJjs.getAbsolutePositionForNote.call(void 0, entry, measure);
|
|
1693
|
+
const accidentalsInMeasure = _chunk24XBPMRJjs.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
|
|
1694
|
+
const accidental = _chunk24XBPMRJjs.determineAccidental.call(void 0, entry.pitch, keySignature, accidentalsInMeasure);
|
|
1681
1695
|
if (accidental) {
|
|
1682
1696
|
entry.accidental = { value: accidental };
|
|
1683
1697
|
} else {
|
|
@@ -1711,7 +1725,7 @@ function addVoice(score, options) {
|
|
|
1711
1725
|
const context = getMeasureContext(result, options.partIndex, options.measureIndex);
|
|
1712
1726
|
const measureDuration = context.time ? getMeasureDuration(context.divisions, context.time) : context.divisions * 4;
|
|
1713
1727
|
const rest = createRest(measureDuration, options.voice, options.staff);
|
|
1714
|
-
const currentEnd =
|
|
1728
|
+
const currentEnd = _chunk24XBPMRJjs.getMeasureEndPosition.call(void 0, measure);
|
|
1715
1729
|
if (currentEnd > 0) {
|
|
1716
1730
|
measure.entries.push({ _id: generateId(), type: "backup", duration: currentEnd });
|
|
1717
1731
|
}
|
|
@@ -1719,14 +1733,14 @@ function addVoice(score, options) {
|
|
|
1719
1733
|
return success(result);
|
|
1720
1734
|
}
|
|
1721
1735
|
function transposePitch(pitch, semitones) {
|
|
1722
|
-
const currentSemitone =
|
|
1736
|
+
const currentSemitone = _chunk24XBPMRJjs.STEP_SEMITONES[pitch.step] + (_nullishCoalesce(pitch.alter, () => ( 0))) + pitch.octave * 12;
|
|
1723
1737
|
const targetSemitone = currentSemitone + semitones;
|
|
1724
1738
|
const targetOctave = Math.floor(targetSemitone / 12);
|
|
1725
1739
|
const targetPitchClass = (targetSemitone % 12 + 12) % 12;
|
|
1726
1740
|
let bestStep = "C";
|
|
1727
1741
|
let bestAlter = 99;
|
|
1728
|
-
for (const step of
|
|
1729
|
-
const stepSemitone =
|
|
1742
|
+
for (const step of _chunk24XBPMRJjs.STEPS) {
|
|
1743
|
+
const stepSemitone = _chunk24XBPMRJjs.STEP_SEMITONES[step];
|
|
1730
1744
|
let diff = targetPitchClass - stepSemitone;
|
|
1731
1745
|
if (diff > 6) diff -= 12;
|
|
1732
1746
|
if (diff < -6) diff += 12;
|
|
@@ -2716,7 +2730,7 @@ function autoBeam(score, options) {
|
|
|
2716
2730
|
for (const entry of measure.entries) {
|
|
2717
2731
|
if (entry.type === "note") {
|
|
2718
2732
|
if (!entry.chord && !entry.rest) {
|
|
2719
|
-
const voice = _nullishCoalesce(entry.voice, () => ( 1));
|
|
2733
|
+
const voice = _nullishCoalesce(entry.voice, () => ( "1"));
|
|
2720
2734
|
if (options.voice === void 0 || voice === options.voice) {
|
|
2721
2735
|
if (!notesByVoice.has(voice)) {
|
|
2722
2736
|
notesByVoice.set(voice, []);
|
|
@@ -3788,7 +3802,7 @@ function addDaCapo(score, options) {
|
|
|
3788
3802
|
}
|
|
3789
3803
|
const result = cloneScore(score);
|
|
3790
3804
|
const measure = result.parts[partIndex].measures[measureIndex];
|
|
3791
|
-
const attrs =
|
|
3805
|
+
const attrs = _chunk24XBPMRJjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
|
|
3792
3806
|
const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
|
|
3793
3807
|
const insertPos = _nullishCoalesce(position, () => ( measureDuration));
|
|
3794
3808
|
const direction = {
|
|
@@ -3817,7 +3831,7 @@ function addDalSegno(score, options) {
|
|
|
3817
3831
|
}
|
|
3818
3832
|
const result = cloneScore(score);
|
|
3819
3833
|
const measure = result.parts[partIndex].measures[measureIndex];
|
|
3820
|
-
const attrs =
|
|
3834
|
+
const attrs = _chunk24XBPMRJjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
|
|
3821
3835
|
const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
|
|
3822
3836
|
const insertPos = _nullishCoalesce(position, () => ( measureDuration));
|
|
3823
3837
|
const direction = {
|
|
@@ -3846,7 +3860,7 @@ function addFine(score, options) {
|
|
|
3846
3860
|
}
|
|
3847
3861
|
const result = cloneScore(score);
|
|
3848
3862
|
const measure = result.parts[partIndex].measures[measureIndex];
|
|
3849
|
-
const attrs =
|
|
3863
|
+
const attrs = _chunk24XBPMRJjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
|
|
3850
3864
|
const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
|
|
3851
3865
|
const insertPos = _nullishCoalesce(position, () => ( measureDuration));
|
|
3852
3866
|
const direction = {
|
|
@@ -3875,7 +3889,7 @@ function addToCoda(score, options) {
|
|
|
3875
3889
|
}
|
|
3876
3890
|
const result = cloneScore(score);
|
|
3877
3891
|
const measure = result.parts[partIndex].measures[measureIndex];
|
|
3878
|
-
const attrs =
|
|
3892
|
+
const attrs = _chunk24XBPMRJjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
|
|
3879
3893
|
const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
|
|
3880
3894
|
const insertPos = _nullishCoalesce(position, () => ( measureDuration));
|
|
3881
3895
|
const direction = {
|
|
@@ -191,7 +191,7 @@ function groupByVoice(measure) {
|
|
|
191
191
|
for (const entry of measure.entries) {
|
|
192
192
|
if (entry.type !== "note") continue;
|
|
193
193
|
const staff = entry.staff ?? 1;
|
|
194
|
-
const voice = entry.voice ?? 1;
|
|
194
|
+
const voice = entry.voice ?? "1";
|
|
195
195
|
const key = `${staff}-${voice}`;
|
|
196
196
|
if (!groups.has(key)) {
|
|
197
197
|
groups.set(key, { staff, voice, notes: [] });
|
|
@@ -200,7 +200,7 @@ function groupByVoice(measure) {
|
|
|
200
200
|
}
|
|
201
201
|
return Array.from(groups.values()).sort((a, b) => {
|
|
202
202
|
if (a.staff !== b.staff) return a.staff - b.staff;
|
|
203
|
-
return a.voice
|
|
203
|
+
return a.voice.localeCompare(b.voice, void 0, { numeric: true });
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
206
|
function groupByStaff(measure) {
|
|
@@ -285,10 +285,10 @@ function getVoices(measure) {
|
|
|
285
285
|
const voices = /* @__PURE__ */ new Set();
|
|
286
286
|
for (const entry of measure.entries) {
|
|
287
287
|
if (entry.type === "note") {
|
|
288
|
-
voices.add(entry.voice ?? 1);
|
|
288
|
+
voices.add(entry.voice ?? "1");
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
|
-
return Array.from(voices).sort((a, b) => a
|
|
291
|
+
return Array.from(voices).sort((a, b) => a.localeCompare(b, void 0, { numeric: true }));
|
|
292
292
|
}
|
|
293
293
|
function getStaves(measure) {
|
|
294
294
|
const staves = /* @__PURE__ */ new Set();
|
|
@@ -336,7 +336,7 @@ function buildVoiceToStaffMap(measure) {
|
|
|
336
336
|
const map = /* @__PURE__ */ new Map();
|
|
337
337
|
for (const entry of measure.entries) {
|
|
338
338
|
if (entry.type === "note" && entry.staff !== void 0) {
|
|
339
|
-
const voice = entry.voice ?? 1;
|
|
339
|
+
const voice = entry.voice ?? "1";
|
|
340
340
|
const staff = entry.staff;
|
|
341
341
|
if (!map.has(voice)) {
|
|
342
342
|
map.set(voice, staff);
|
|
@@ -355,7 +355,7 @@ function buildVoiceToStaffMapForPart(part) {
|
|
|
355
355
|
for (const measure of part.measures) {
|
|
356
356
|
for (const entry of measure.entries) {
|
|
357
357
|
if (entry.type === "note" && entry.staff !== void 0) {
|
|
358
|
-
const voice = entry.voice ?? 1;
|
|
358
|
+
const voice = entry.voice ?? "1";
|
|
359
359
|
const staff = entry.staff;
|
|
360
360
|
if (!map.has(voice)) {
|
|
361
361
|
map.set(voice, staff);
|
|
@@ -374,7 +374,7 @@ function inferStaff(entry, voiceToStaffMap) {
|
|
|
374
374
|
if (entry.staff !== void 0) {
|
|
375
375
|
return entry.staff;
|
|
376
376
|
}
|
|
377
|
-
const inferredStaff = voiceToStaffMap.get(entry.voice ?? 1);
|
|
377
|
+
const inferredStaff = voiceToStaffMap.get(entry.voice ?? "1");
|
|
378
378
|
if (inferredStaff !== void 0) {
|
|
379
379
|
return inferredStaff;
|
|
380
380
|
}
|
|
@@ -417,11 +417,11 @@ function getVoicesForStaff(measure, staff) {
|
|
|
417
417
|
if (entry.type === "note") {
|
|
418
418
|
const entryStaff = entry.staff ?? 1;
|
|
419
419
|
if (entryStaff === staff) {
|
|
420
|
-
voices.add(entry.voice ?? 1);
|
|
420
|
+
voices.add(entry.voice ?? "1");
|
|
421
421
|
}
|
|
422
422
|
}
|
|
423
423
|
}
|
|
424
|
-
return Array.from(voices).sort((a, b) => a
|
|
424
|
+
return Array.from(voices).sort((a, b) => a.localeCompare(b, void 0, { numeric: true }));
|
|
425
425
|
}
|
|
426
426
|
function getStaffRange(score, partIndex) {
|
|
427
427
|
const part = score.parts[partIndex];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as Score, M as Measure, n as TimeSignature, f as Part, P as Pitch, N as NoteEntry, K as KeySignature, C as Clef, ac as ArticulationType, m as DynamicsValue, ad as OrnamentType, i as NoteType } from './types-
|
|
1
|
+
import { S as Score, M as Measure, n as TimeSignature, f as Part, P as Pitch, N as NoteEntry, K as KeySignature, C as Clef, ac as ArticulationType, m as DynamicsValue, ad as OrnamentType, i as NoteType } from './types-BFmNsRNw.js';
|
|
2
2
|
|
|
3
3
|
type ValidationErrorCode = 'MISSING_DIVISIONS' | 'INVALID_DIVISIONS' | 'MEASURE_DURATION_MISMATCH' | 'MEASURE_DURATION_OVERFLOW' | 'MEASURE_DURATION_UNDERFLOW' | 'VOICE_INCOMPLETE' | 'VOICE_GAP' | 'NEGATIVE_POSITION' | 'BACKUP_EXCEEDS_POSITION' | 'TIE_START_WITHOUT_STOP' | 'TIE_STOP_WITHOUT_START' | 'TIE_PITCH_MISMATCH' | 'BEAM_BEGIN_WITHOUT_END' | 'BEAM_END_WITHOUT_BEGIN' | 'SLUR_START_WITHOUT_STOP' | 'SLUR_STOP_WITHOUT_START' | 'TUPLET_START_WITHOUT_STOP' | 'TUPLET_STOP_WITHOUT_START' | 'PART_ID_NOT_IN_PART_LIST' | 'PART_LIST_ID_NOT_IN_PARTS' | 'PART_MEASURE_COUNT_MISMATCH' | 'PART_MEASURE_NUMBER_MISMATCH' | 'PART_GROUP_START_WITHOUT_STOP' | 'PART_GROUP_STOP_WITHOUT_START' | 'DUPLICATE_PART_ID' | 'INVALID_VOICE_NUMBER' | 'INVALID_STAFF_NUMBER' | 'STAFF_EXCEEDS_STAVES' | 'MISSING_STAVES_DECLARATION' | 'STAVES_DECLARATION_MISMATCH' | 'MISSING_CLEF_FOR_STAFF' | 'CLEF_STAFF_EXCEEDS_STAVES' | 'INVALID_DURATION' | 'EMPTY_MEASURE';
|
|
4
4
|
type ValidationLevel = 'error' | 'warning' | 'info';
|
|
@@ -8,7 +8,7 @@ interface ValidationLocation {
|
|
|
8
8
|
measureIndex?: number;
|
|
9
9
|
measureNumber?: string;
|
|
10
10
|
entryIndex?: number;
|
|
11
|
-
voice?:
|
|
11
|
+
voice?: string;
|
|
12
12
|
staff?: number;
|
|
13
13
|
}
|
|
14
14
|
interface ValidationError {
|
|
@@ -197,7 +197,7 @@ type OperationErrorCode = 'NOTE_CONFLICT' | 'EXCEEDS_MEASURE' | 'INVALID_POSITIO
|
|
|
197
197
|
interface InsertNoteOptions {
|
|
198
198
|
partIndex: number;
|
|
199
199
|
measureIndex: number;
|
|
200
|
-
voice:
|
|
200
|
+
voice: string;
|
|
201
201
|
staff?: number;
|
|
202
202
|
position: number;
|
|
203
203
|
pitch: Pitch;
|
|
@@ -310,7 +310,7 @@ declare function lowerAccidental(score: Score, options: LowerAccidentalOptions):
|
|
|
310
310
|
interface AddVoiceOptions {
|
|
311
311
|
partIndex: number;
|
|
312
312
|
measureIndex: number;
|
|
313
|
-
voice:
|
|
313
|
+
voice: string;
|
|
314
314
|
staff?: number;
|
|
315
315
|
}
|
|
316
316
|
/**
|
|
@@ -480,7 +480,7 @@ declare const addNote: (score: Score, options: {
|
|
|
480
480
|
partIndex: number;
|
|
481
481
|
measureIndex: number;
|
|
482
482
|
staff?: number;
|
|
483
|
-
voice:
|
|
483
|
+
voice: string;
|
|
484
484
|
position: number;
|
|
485
485
|
note: Omit<NoteEntry, "type" | "voice" | "staff">;
|
|
486
486
|
}) => Score;
|
|
@@ -518,7 +518,7 @@ declare const addNoteChecked: (score: Score, options: {
|
|
|
518
518
|
partIndex: number;
|
|
519
519
|
measureIndex: number;
|
|
520
520
|
staff?: number;
|
|
521
|
-
voice:
|
|
521
|
+
voice: string;
|
|
522
522
|
position: number;
|
|
523
523
|
note: Omit<NoteEntry, "type" | "voice" | "staff">;
|
|
524
524
|
}) => OperationResult<Score>;
|
|
@@ -618,7 +618,7 @@ interface AutoBeamOptions {
|
|
|
618
618
|
partIndex: number;
|
|
619
619
|
measureIndex: number;
|
|
620
620
|
/** Optional voice filter */
|
|
621
|
-
voice?:
|
|
621
|
+
voice?: string;
|
|
622
622
|
/** Group by beat (default: true) */
|
|
623
623
|
groupByBeat?: boolean;
|
|
624
624
|
}
|
|
@@ -637,7 +637,7 @@ interface NoteSelection {
|
|
|
637
637
|
measureIndex: number;
|
|
638
638
|
startPosition: number;
|
|
639
639
|
endPosition: number;
|
|
640
|
-
voice:
|
|
640
|
+
voice: string;
|
|
641
641
|
staff?: number;
|
|
642
642
|
};
|
|
643
643
|
/** Copied notes with their relative positions */
|
|
@@ -658,7 +658,7 @@ interface CopyNotesOptions {
|
|
|
658
658
|
/** End position in the measure (in divisions) */
|
|
659
659
|
endPosition: number;
|
|
660
660
|
/** Voice to copy from */
|
|
661
|
-
voice:
|
|
661
|
+
voice: string;
|
|
662
662
|
/** Staff to copy from (optional) */
|
|
663
663
|
staff?: number;
|
|
664
664
|
}
|
|
@@ -677,7 +677,7 @@ interface PasteNotesOptions {
|
|
|
677
677
|
/** Target position in the measure */
|
|
678
678
|
position: number;
|
|
679
679
|
/** Target voice (defaults to original voice) */
|
|
680
|
-
voice?:
|
|
680
|
+
voice?: string;
|
|
681
681
|
/** Target staff (defaults to original staff) */
|
|
682
682
|
staff?: number;
|
|
683
683
|
/** Clear existing notes in the paste range (default: true) */
|
|
@@ -704,7 +704,7 @@ interface CopyNotesMultiMeasureOptions {
|
|
|
704
704
|
/** Ending measure index (inclusive) */
|
|
705
705
|
endMeasureIndex: number;
|
|
706
706
|
/** Voice to copy from */
|
|
707
|
-
voice:
|
|
707
|
+
voice: string;
|
|
708
708
|
/** Staff to copy from (optional) */
|
|
709
709
|
staff?: number;
|
|
710
710
|
}
|
|
@@ -716,7 +716,7 @@ interface MultiMeasureSelection {
|
|
|
716
716
|
partIndex: number;
|
|
717
717
|
startMeasureIndex: number;
|
|
718
718
|
endMeasureIndex: number;
|
|
719
|
-
voice:
|
|
719
|
+
voice: string;
|
|
720
720
|
staff?: number;
|
|
721
721
|
};
|
|
722
722
|
/** Notes grouped by measure offset */
|
|
@@ -738,7 +738,7 @@ interface PasteNotesMultiMeasureOptions {
|
|
|
738
738
|
/** Target starting measure index */
|
|
739
739
|
startMeasureIndex: number;
|
|
740
740
|
/** Target voice (defaults to original voice) */
|
|
741
|
-
voice?:
|
|
741
|
+
voice?: string;
|
|
742
742
|
/** Target staff (defaults to original staff) */
|
|
743
743
|
staff?: number;
|
|
744
744
|
/** Clear existing notes in paste measures (default: true) */
|
|
@@ -1038,7 +1038,7 @@ interface AddGraceNoteOptions {
|
|
|
1038
1038
|
pitch: Pitch;
|
|
1039
1039
|
noteType?: NoteType;
|
|
1040
1040
|
slash?: boolean;
|
|
1041
|
-
voice?:
|
|
1041
|
+
voice?: string;
|
|
1042
1042
|
staff?: number;
|
|
1043
1043
|
}
|
|
1044
1044
|
/**
|