musicxml-io 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -171,6 +171,344 @@ function getMeasureEndPosition(measure) {
171
171
  return state.position;
172
172
  }
173
173
 
174
+ // src/query/playback-sequence.ts
175
+ function parseEndingNumbers(numberStr) {
176
+ const numbers = [];
177
+ const parts = numberStr.split(/[,\s]+/);
178
+ for (const part of parts) {
179
+ if (part.includes("-")) {
180
+ const [start, end] = part.split("-").map((s) => parseInt(s.trim(), 10));
181
+ if (!isNaN(start) && !isNaN(end)) {
182
+ for (let i = start; i <= end; i++) {
183
+ numbers.push(i);
184
+ }
185
+ }
186
+ } else {
187
+ const num = parseInt(part.trim(), 10);
188
+ if (!isNaN(num)) {
189
+ numbers.push(num);
190
+ }
191
+ }
192
+ }
193
+ return numbers.length > 0 ? numbers : [1];
194
+ }
195
+ function parseJumpText(text) {
196
+ const t = text.toLowerCase().replace(/\s+/g, " ").trim();
197
+ if (t.includes("d.c. al coda") || t.includes("da capo al coda")) return "dc_al_coda";
198
+ if (t.includes("d.c. al fine") || t.includes("da capo al fine")) return "dc_al_fine";
199
+ if (t.includes("d.c.") || t.includes("da capo")) return "dc";
200
+ if (t.includes("d.s. al coda") || t.includes("dal segno al coda")) return "ds_al_coda";
201
+ if (t.includes("d.s. al fine") || t.includes("dal segno al fine")) return "ds_al_fine";
202
+ if (t.includes("d.s.") || t.includes("dal segno")) return "ds";
203
+ if (t === "fine") return "fine";
204
+ if (t.includes("to coda") || t.includes("al coda")) return "to_coda";
205
+ if (t === "coda" || t === "\u{1D14C}") return "coda";
206
+ if (t === "segno" || t === "\u{1D10B}") return "segno";
207
+ return null;
208
+ }
209
+ function getFirstWordsText(entry) {
210
+ for (const dt of entry.directionTypes) {
211
+ if (dt.kind === "words" && dt.text) return dt.text;
212
+ }
213
+ return void 0;
214
+ }
215
+ function hasDirectionKind(entry, kind) {
216
+ return entry.directionTypes.some((dt) => dt.kind === kind);
217
+ }
218
+ function extractPlaybackControls(part) {
219
+ const controls = {
220
+ repeatStarts: [],
221
+ repeatEnds: [],
222
+ voltas: [],
223
+ jumps: [],
224
+ segnoIndex: null,
225
+ codaIndex: null,
226
+ fineIndex: null,
227
+ toCodaIndex: null
228
+ };
229
+ const soundJumps = [];
230
+ for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
231
+ const measure = part.measures[measureIndex];
232
+ if (measure.barlines) {
233
+ for (const barline of measure.barlines) {
234
+ if (barline.repeat) {
235
+ if (barline.repeat.direction === "forward") {
236
+ controls.repeatStarts.push(measureIndex);
237
+ } else if (barline.repeat.direction === "backward") {
238
+ controls.repeatEnds.push({
239
+ measureIndex,
240
+ times: _nullishCoalesce(barline.repeat.times, () => ( 2))
241
+ });
242
+ }
243
+ }
244
+ if (barline.ending) {
245
+ const numbers = parseEndingNumbers(barline.ending.number);
246
+ controls.voltas.push({
247
+ measureIndex,
248
+ numbers,
249
+ type: barline.ending.type
250
+ });
251
+ }
252
+ }
253
+ }
254
+ for (const entry of measure.entries) {
255
+ if (entry.type === "direction") {
256
+ const dir = entry;
257
+ if (hasDirectionKind(dir, "segno") && controls.segnoIndex === null) {
258
+ controls.segnoIndex = measureIndex;
259
+ }
260
+ if (hasDirectionKind(dir, "coda") && controls.codaIndex === null) {
261
+ controls.codaIndex = measureIndex;
262
+ }
263
+ const words = getFirstWordsText(dir);
264
+ if (words) {
265
+ const jt = parseJumpText(words);
266
+ if (jt === "fine") {
267
+ if (controls.fineIndex === null) controls.fineIndex = measureIndex;
268
+ } else if (jt === "to_coda") {
269
+ if (controls.toCodaIndex === null) controls.toCodaIndex = measureIndex;
270
+ } else if (jt === "coda") {
271
+ if (controls.codaIndex === null) controls.codaIndex = measureIndex;
272
+ } else if (jt === "segno") {
273
+ if (controls.segnoIndex === null) controls.segnoIndex = measureIndex;
274
+ } else if (jt) {
275
+ controls.jumps.push({ measureIndex, type: jt });
276
+ }
277
+ }
278
+ } else if (entry.type === "sound") {
279
+ const sound = entry;
280
+ if (sound.segno && controls.segnoIndex === null) controls.segnoIndex = measureIndex;
281
+ if (sound.coda && controls.codaIndex === null) controls.codaIndex = measureIndex;
282
+ if (sound.tocoda && controls.toCodaIndex === null) controls.toCodaIndex = measureIndex;
283
+ if (sound.fine && controls.fineIndex === null) controls.fineIndex = measureIndex;
284
+ if (sound.dacapo) soundJumps.push({ measureIndex, base: "dc" });
285
+ if (sound.dalsegno) soundJumps.push({ measureIndex, base: "ds" });
286
+ }
287
+ }
288
+ }
289
+ for (const sj of soundJumps) {
290
+ if (controls.jumps.some((j) => j.measureIndex === sj.measureIndex)) continue;
291
+ let type;
292
+ if (controls.fineIndex !== null) {
293
+ type = sj.base === "dc" ? "dc_al_fine" : "ds_al_fine";
294
+ } else if (controls.toCodaIndex !== null || controls.codaIndex !== null) {
295
+ type = sj.base === "dc" ? "dc_al_coda" : "ds_al_coda";
296
+ } else {
297
+ type = sj.base;
298
+ }
299
+ controls.jumps.push({ measureIndex: sj.measureIndex, type });
300
+ }
301
+ return controls;
302
+ }
303
+ function buildVoltaRanges(voltas, measureCount) {
304
+ const voltaRanges = /* @__PURE__ */ new Map();
305
+ let currentVoltaStart = null;
306
+ let currentVoltaNumbers = [];
307
+ for (const volta of voltas) {
308
+ if (volta.type === "start") {
309
+ currentVoltaStart = volta.measureIndex;
310
+ currentVoltaNumbers = volta.numbers;
311
+ } else if ((volta.type === "stop" || volta.type === "discontinue") && currentVoltaStart !== null) {
312
+ for (let i = currentVoltaStart; i <= volta.measureIndex; i++) {
313
+ voltaRanges.set(i, currentVoltaNumbers);
314
+ }
315
+ currentVoltaStart = null;
316
+ }
317
+ }
318
+ if (currentVoltaStart !== null) {
319
+ for (let i = currentVoltaStart; i < measureCount; i++) {
320
+ voltaRanges.set(i, currentVoltaNumbers);
321
+ }
322
+ }
323
+ return voltaRanges;
324
+ }
325
+ function generatePlaybackSequence(score, options) {
326
+ const partIndex = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.partIndex]), () => ( 0));
327
+ const part = score.parts[partIndex];
328
+ if (!part) return [];
329
+ const measureCount = part.measures.length;
330
+ const sequence = [];
331
+ if (measureCount === 0) return sequence;
332
+ const controls = extractPlaybackControls(part);
333
+ if (controls.repeatStarts.length === 0 && controls.repeatEnds.length === 0 && controls.voltas.length === 0 && controls.jumps.length === 0) {
334
+ for (let i = 0; i < measureCount; i++) {
335
+ sequence.push({ measureIndex: i, repeatIteration: 0 });
336
+ }
337
+ return sequence;
338
+ }
339
+ const voltaRanges = buildVoltaRanges(controls.voltas, measureCount);
340
+ const sortedRepeatStarts = [...controls.repeatStarts].sort((a, b) => a - b);
341
+ const sortedRepeatEnds = [...controls.repeatEnds].sort((a, b) => a.measureIndex - b.measureIndex);
342
+ const repeatSections = /* @__PURE__ */ new Map();
343
+ const voltaToRepeatEnd = /* @__PURE__ */ new Map();
344
+ const usedRepeatStarts = /* @__PURE__ */ new Set();
345
+ let lastRepeatEndMeasure = -1;
346
+ for (const repeatEnd of sortedRepeatEnds) {
347
+ let startIndex = null;
348
+ for (const startMeasure of sortedRepeatStarts) {
349
+ if (startMeasure <= repeatEnd.measureIndex && startMeasure > lastRepeatEndMeasure && !usedRepeatStarts.has(startMeasure)) {
350
+ startIndex = startMeasure;
351
+ } else if (startMeasure > repeatEnd.measureIndex) {
352
+ break;
353
+ }
354
+ }
355
+ if (startIndex === null) {
356
+ startIndex = lastRepeatEndMeasure + 1;
357
+ } else {
358
+ usedRepeatStarts.add(startIndex);
359
+ }
360
+ repeatSections.set(repeatEnd.measureIndex, {
361
+ startIndex,
362
+ times: repeatEnd.times
363
+ });
364
+ lastRepeatEndMeasure = repeatEnd.measureIndex;
365
+ voltaRanges.forEach((_iterations, voltaMeasure) => {
366
+ const isInsideRepeat = voltaMeasure >= startIndex && voltaMeasure <= repeatEnd.measureIndex;
367
+ const isImmediatelyAfter = voltaMeasure > repeatEnd.measureIndex && !voltaToRepeatEnd.has(voltaMeasure);
368
+ if (isInsideRepeat) {
369
+ voltaToRepeatEnd.set(voltaMeasure, repeatEnd.measureIndex);
370
+ } else if (isImmediatelyAfter) {
371
+ let belongsToLaterRepeat = false;
372
+ for (const otherEnd of sortedRepeatEnds) {
373
+ if (otherEnd.measureIndex > repeatEnd.measureIndex) {
374
+ const otherSection = repeatSections.get(otherEnd.measureIndex);
375
+ if (otherSection && voltaMeasure >= otherSection.startIndex && voltaMeasure <= otherEnd.measureIndex) {
376
+ belongsToLaterRepeat = true;
377
+ break;
378
+ }
379
+ }
380
+ }
381
+ if (!belongsToLaterRepeat) {
382
+ voltaToRepeatEnd.set(voltaMeasure, repeatEnd.measureIndex);
383
+ }
384
+ }
385
+ });
386
+ }
387
+ let currentMeasure = 0;
388
+ const repeatCounts = /* @__PURE__ */ new Map();
389
+ let lastRepeatEndIndex = null;
390
+ let lastRepeatIteration = 0;
391
+ let inRepeatJump = false;
392
+ let stopAtFine = false;
393
+ let jumpToCoda = false;
394
+ const maxIterations = measureCount * 10 + 10;
395
+ let iterations = 0;
396
+ while (currentMeasure < measureCount && iterations < maxIterations) {
397
+ iterations++;
398
+ const voltaIterations = voltaRanges.get(currentMeasure);
399
+ let repeatIteration = 0;
400
+ let inRepeatSection = false;
401
+ let currentRepeatEndIndex = null;
402
+ for (const [endIndex, section] of repeatSections) {
403
+ if (currentMeasure >= section.startIndex && currentMeasure <= endIndex) {
404
+ inRepeatSection = true;
405
+ currentRepeatEndIndex = endIndex;
406
+ repeatIteration = repeatCounts.get(endIndex) || 1;
407
+ break;
408
+ }
409
+ }
410
+ if (inRepeatSection && currentRepeatEndIndex !== null) {
411
+ lastRepeatEndIndex = currentRepeatEndIndex;
412
+ lastRepeatIteration = repeatIteration;
413
+ }
414
+ if (voltaIterations) {
415
+ let effectiveIteration = repeatIteration;
416
+ if (!inRepeatSection) {
417
+ const associatedRepeatEnd = voltaToRepeatEnd.get(currentMeasure);
418
+ if (associatedRepeatEnd !== void 0) {
419
+ effectiveIteration = repeatCounts.get(associatedRepeatEnd) || 1;
420
+ } else if (lastRepeatEndIndex !== null) {
421
+ effectiveIteration = lastRepeatIteration;
422
+ }
423
+ }
424
+ if (!voltaIterations.includes(effectiveIteration)) {
425
+ currentMeasure++;
426
+ continue;
427
+ }
428
+ }
429
+ sequence.push({
430
+ measureIndex: currentMeasure,
431
+ repeatIteration: inRepeatSection ? repeatIteration : 0
432
+ });
433
+ if (stopAtFine && controls.fineIndex === currentMeasure) {
434
+ break;
435
+ }
436
+ if (jumpToCoda && controls.toCodaIndex === currentMeasure && controls.codaIndex !== null) {
437
+ currentMeasure = controls.codaIndex;
438
+ jumpToCoda = false;
439
+ continue;
440
+ }
441
+ const repeatSection = repeatSections.get(currentMeasure);
442
+ if (repeatSection) {
443
+ const currentCount = repeatCounts.get(currentMeasure) || 1;
444
+ if (currentCount < repeatSection.times) {
445
+ repeatCounts.set(currentMeasure, currentCount + 1);
446
+ currentMeasure = repeatSection.startIndex;
447
+ continue;
448
+ }
449
+ }
450
+ if (voltaIterations && !inRepeatSection) {
451
+ const associatedRepeatEnd = voltaToRepeatEnd.get(currentMeasure);
452
+ if (associatedRepeatEnd !== void 0) {
453
+ const repeatSectionForVolta = repeatSections.get(associatedRepeatEnd);
454
+ if (repeatSectionForVolta) {
455
+ const currentCount = repeatCounts.get(associatedRepeatEnd) || 1;
456
+ if (currentCount < repeatSectionForVolta.times) {
457
+ repeatCounts.set(associatedRepeatEnd, currentCount + 1);
458
+ currentMeasure = repeatSectionForVolta.startIndex;
459
+ continue;
460
+ }
461
+ }
462
+ }
463
+ }
464
+ const jumpAtMeasure = controls.jumps.find((j) => j.measureIndex === currentMeasure);
465
+ if (jumpAtMeasure && !inRepeatJump) {
466
+ inRepeatJump = true;
467
+ switch (jumpAtMeasure.type) {
468
+ case "dc":
469
+ currentMeasure = 0;
470
+ continue;
471
+ case "dc_al_fine":
472
+ currentMeasure = 0;
473
+ stopAtFine = true;
474
+ continue;
475
+ case "dc_al_coda":
476
+ currentMeasure = 0;
477
+ jumpToCoda = true;
478
+ continue;
479
+ case "ds":
480
+ if (controls.segnoIndex !== null) {
481
+ currentMeasure = controls.segnoIndex;
482
+ continue;
483
+ }
484
+ break;
485
+ case "ds_al_fine":
486
+ if (controls.segnoIndex !== null) {
487
+ currentMeasure = controls.segnoIndex;
488
+ stopAtFine = true;
489
+ continue;
490
+ }
491
+ break;
492
+ case "ds_al_coda":
493
+ if (controls.segnoIndex !== null) {
494
+ currentMeasure = controls.segnoIndex;
495
+ jumpToCoda = true;
496
+ continue;
497
+ }
498
+ break;
499
+ }
500
+ }
501
+ currentMeasure++;
502
+ }
503
+ return sequence;
504
+ }
505
+ function hasPlaybackControls(score, options) {
506
+ const part = score.parts[_nullishCoalesce(_optionalChain([options, 'optionalAccess', _4 => _4.partIndex]), () => ( 0))];
507
+ if (!part) return false;
508
+ const controls = extractPlaybackControls(part);
509
+ return controls.repeatStarts.length > 0 || controls.repeatEnds.length > 0 || controls.voltas.length > 0 || controls.jumps.length > 0 || controls.segnoIndex !== null || controls.codaIndex !== null;
510
+ }
511
+
174
512
  // src/query/index.ts
175
513
  function getNotesForVoice(measure, filter) {
176
514
  return measure.entries.filter((entry) => {
@@ -308,7 +646,7 @@ function isRestMeasure(measure) {
308
646
  }
309
647
  function getNormalizedPosition(note, measure, options) {
310
648
  const absolutePosition = getAbsolutePosition(note, measure);
311
- const currentDivisions = _nullishCoalesce(_nullishCoalesce(options.currentDivisions, () => ( _optionalChain([measure, 'access', _3 => _3.attributes, 'optionalAccess', _4 => _4.divisions]))), () => ( 1));
649
+ const currentDivisions = _nullishCoalesce(_nullishCoalesce(options.currentDivisions, () => ( _optionalChain([measure, 'access', _5 => _5.attributes, 'optionalAccess', _6 => _6.divisions]))), () => ( 1));
312
650
  return absolutePosition * options.baseDivisions / currentDivisions;
313
651
  }
314
652
  function getNormalizedDuration(note, options) {
@@ -401,7 +739,7 @@ function getClefForStaff(score, options) {
401
739
  }
402
740
  }
403
741
  }
404
- if (_optionalChain([measure, 'access', _5 => _5.attributes, 'optionalAccess', _6 => _6.clef])) {
742
+ if (_optionalChain([measure, 'access', _7 => _7.attributes, 'optionalAccess', _8 => _8.clef])) {
405
743
  for (const clef of measure.attributes.clef) {
406
744
  if ((_nullishCoalesce(clef.staff, () => ( 1))) === options.staff) {
407
745
  return clef;
@@ -429,7 +767,7 @@ function getStaffRange(score, partIndex) {
429
767
  let min = 1;
430
768
  let max = 1;
431
769
  for (const measure of part.measures) {
432
- if (_optionalChain([measure, 'access', _7 => _7.attributes, 'optionalAccess', _8 => _8.staves]) !== void 0) {
770
+ if (_optionalChain([measure, 'access', _9 => _9.attributes, 'optionalAccess', _10 => _10.staves]) !== void 0) {
433
771
  max = Math.max(max, measure.attributes.staves);
434
772
  }
435
773
  for (const entry of measure.entries) {
@@ -447,15 +785,15 @@ function getEntriesAtPosition(measure, position, options) {
447
785
  const currentPosition = entry.type === "note" && entry.chord ? state.lastNonChordPosition : state.position;
448
786
  if (currentPosition === position) {
449
787
  if (entry.type === "note") {
450
- if (_optionalChain([options, 'optionalAccess', _9 => _9.staff]) !== void 0 && (_nullishCoalesce(entry.staff, () => ( 1))) !== options.staff) {
788
+ if (_optionalChain([options, 'optionalAccess', _11 => _11.staff]) !== void 0 && (_nullishCoalesce(entry.staff, () => ( 1))) !== options.staff) {
451
789
  updatePositionForEntry(state, entry);
452
790
  continue;
453
791
  }
454
- if (_optionalChain([options, 'optionalAccess', _10 => _10.voice]) !== void 0 && entry.voice !== options.voice) {
792
+ if (_optionalChain([options, 'optionalAccess', _12 => _12.voice]) !== void 0 && entry.voice !== options.voice) {
455
793
  updatePositionForEntry(state, entry);
456
794
  continue;
457
795
  }
458
- if (_optionalChain([options, 'optionalAccess', _11 => _11.includeChordNotes]) === false && entry.chord) {
796
+ if (_optionalChain([options, 'optionalAccess', _13 => _13.includeChordNotes]) === false && entry.chord) {
459
797
  updatePositionForEntry(state, entry);
460
798
  continue;
461
799
  }
@@ -478,15 +816,15 @@ function getEntriesInRange(measure, range, options) {
478
816
  const currentPosition = entry.type === "note" && entry.chord ? state.lastNonChordPosition : state.position;
479
817
  if (currentPosition >= range.start && currentPosition < range.end) {
480
818
  if (entry.type === "note") {
481
- if (_optionalChain([options, 'optionalAccess', _12 => _12.staff]) !== void 0 && (_nullishCoalesce(entry.staff, () => ( 1))) !== options.staff) {
819
+ if (_optionalChain([options, 'optionalAccess', _14 => _14.staff]) !== void 0 && (_nullishCoalesce(entry.staff, () => ( 1))) !== options.staff) {
482
820
  updatePositionForEntry(state, entry);
483
821
  continue;
484
822
  }
485
- if (_optionalChain([options, 'optionalAccess', _13 => _13.voice]) !== void 0 && entry.voice !== options.voice) {
823
+ if (_optionalChain([options, 'optionalAccess', _15 => _15.voice]) !== void 0 && entry.voice !== options.voice) {
486
824
  updatePositionForEntry(state, entry);
487
825
  continue;
488
826
  }
489
- if (_optionalChain([options, 'optionalAccess', _14 => _14.includeChordNotes]) === false && entry.chord) {
827
+ if (_optionalChain([options, 'optionalAccess', _16 => _16.includeChordNotes]) === false && entry.chord) {
490
828
  updatePositionForEntry(state, entry);
491
829
  continue;
492
830
  }
@@ -692,13 +1030,13 @@ function getAdjacentNotes(score, context) {
692
1030
  }
693
1031
  function getDirections(score, options) {
694
1032
  const results = [];
695
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _15 => _15.partIndex]), () => ( 0));
696
- const endPart = _optionalChain([options, 'optionalAccess', _16 => _16.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1033
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _17 => _17.partIndex]), () => ( 0));
1034
+ const endPart = _optionalChain([options, 'optionalAccess', _18 => _18.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
697
1035
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
698
1036
  const part = score.parts[partIndex];
699
1037
  if (!part) continue;
700
- const startMeasure = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _17 => _17.measureIndex]), () => ( 0));
701
- const endMeasure = _optionalChain([options, 'optionalAccess', _18 => _18.measureIndex]) !== void 0 ? options.measureIndex + 1 : part.measures.length;
1038
+ const startMeasure = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _19 => _19.measureIndex]), () => ( 0));
1039
+ const endMeasure = _optionalChain([options, 'optionalAccess', _20 => _20.measureIndex]) !== void 0 ? options.measureIndex + 1 : part.measures.length;
702
1040
  for (let measureIndex = startMeasure; measureIndex < endMeasure; measureIndex++) {
703
1041
  const measure = part.measures[measureIndex];
704
1042
  if (!measure) continue;
@@ -739,8 +1077,8 @@ function findDirectionsByType(score, kind) {
739
1077
  }
740
1078
  function getDynamics(score, options) {
741
1079
  const results = [];
742
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _19 => _19.partIndex]), () => ( 0));
743
- const endPart = _optionalChain([options, 'optionalAccess', _20 => _20.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1080
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _21 => _21.partIndex]), () => ( 0));
1081
+ const endPart = _optionalChain([options, 'optionalAccess', _22 => _22.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
744
1082
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
745
1083
  const part = score.parts[partIndex];
746
1084
  if (!part) continue;
@@ -801,8 +1139,8 @@ function getTempoMarkings(score) {
801
1139
  }
802
1140
  function getPedalMarkings(score, options) {
803
1141
  const results = [];
804
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _21 => _21.partIndex]), () => ( 0));
805
- const endPart = _optionalChain([options, 'optionalAccess', _22 => _22.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1142
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _23 => _23.partIndex]), () => ( 0));
1143
+ const endPart = _optionalChain([options, 'optionalAccess', _24 => _24.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
806
1144
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
807
1145
  const part = score.parts[partIndex];
808
1146
  if (!part) continue;
@@ -831,8 +1169,8 @@ function getPedalMarkings(score, options) {
831
1169
  }
832
1170
  function getWedges(score, options) {
833
1171
  const results = [];
834
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _23 => _23.partIndex]), () => ( 0));
835
- const endPart = _optionalChain([options, 'optionalAccess', _24 => _24.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1172
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _25 => _25.partIndex]), () => ( 0));
1173
+ const endPart = _optionalChain([options, 'optionalAccess', _26 => _26.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
836
1174
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
837
1175
  const part = score.parts[partIndex];
838
1176
  if (!part) continue;
@@ -861,8 +1199,8 @@ function getWedges(score, options) {
861
1199
  }
862
1200
  function getOctaveShifts(score, options) {
863
1201
  const results = [];
864
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _25 => _25.partIndex]), () => ( 0));
865
- const endPart = _optionalChain([options, 'optionalAccess', _26 => _26.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1202
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _27 => _27.partIndex]), () => ( 0));
1203
+ const endPart = _optionalChain([options, 'optionalAccess', _28 => _28.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
866
1204
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
867
1205
  const part = score.parts[partIndex];
868
1206
  if (!part) continue;
@@ -892,8 +1230,8 @@ function getOctaveShifts(score, options) {
892
1230
  }
893
1231
  function getTiedNoteGroups(score, options) {
894
1232
  const results = [];
895
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _27 => _27.partIndex]), () => ( 0));
896
- const endPart = _optionalChain([options, 'optionalAccess', _28 => _28.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1233
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _29 => _29.partIndex]), () => ( 0));
1234
+ const endPart = _optionalChain([options, 'optionalAccess', _30 => _30.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
897
1235
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
898
1236
  const part = score.parts[partIndex];
899
1237
  if (!part) continue;
@@ -913,8 +1251,8 @@ function getTiedNoteGroups(score, options) {
913
1251
  measureIndex,
914
1252
  position
915
1253
  };
916
- const hasTieStart = _optionalChain([entry, 'access', _29 => _29.tie, 'optionalAccess', _30 => _30.type]) === "start" || _optionalChain([entry, 'access', _31 => _31.ties, 'optionalAccess', _32 => _32.some, 'call', _33 => _33((t) => t.type === "start")]) || _optionalChain([entry, 'access', _34 => _34.notations, 'optionalAccess', _35 => _35.some, 'call', _36 => _36((n) => n.type === "tied" && n.tiedType === "start")]);
917
- const hasTieStop = _optionalChain([entry, 'access', _37 => _37.tie, 'optionalAccess', _38 => _38.type]) === "stop" || _optionalChain([entry, 'access', _39 => _39.ties, 'optionalAccess', _40 => _40.some, 'call', _41 => _41((t) => t.type === "stop")]) || _optionalChain([entry, 'access', _42 => _42.notations, 'optionalAccess', _43 => _43.some, 'call', _44 => _44((n) => n.type === "tied" && n.tiedType === "stop")]);
1254
+ const hasTieStart = _optionalChain([entry, 'access', _31 => _31.tie, 'optionalAccess', _32 => _32.type]) === "start" || _optionalChain([entry, 'access', _33 => _33.ties, 'optionalAccess', _34 => _34.some, 'call', _35 => _35((t) => t.type === "start")]) || _optionalChain([entry, 'access', _36 => _36.notations, 'optionalAccess', _37 => _37.some, 'call', _38 => _38((n) => n.type === "tied" && n.tiedType === "start")]);
1255
+ const hasTieStop = _optionalChain([entry, 'access', _39 => _39.tie, 'optionalAccess', _40 => _40.type]) === "stop" || _optionalChain([entry, 'access', _41 => _41.ties, 'optionalAccess', _42 => _42.some, 'call', _43 => _43((t) => t.type === "stop")]) || _optionalChain([entry, 'access', _44 => _44.notations, 'optionalAccess', _45 => _45.some, 'call', _46 => _46((n) => n.type === "tied" && n.tiedType === "stop")]);
918
1256
  if (hasTieStop && pendingTies.has(pitchKey)) {
919
1257
  const group = pendingTies.get(pitchKey);
920
1258
  group.push(context);
@@ -935,8 +1273,8 @@ function getTiedNoteGroups(score, options) {
935
1273
  }
936
1274
  function getSlurSpans(score, options) {
937
1275
  const results = [];
938
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _45 => _45.partIndex]), () => ( 0));
939
- const endPart = _optionalChain([options, 'optionalAccess', _46 => _46.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1276
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _47 => _47.partIndex]), () => ( 0));
1277
+ const endPart = _optionalChain([options, 'optionalAccess', _48 => _48.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
940
1278
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
941
1279
  const part = score.parts[partIndex];
942
1280
  if (!part) continue;
@@ -992,8 +1330,8 @@ function getSlurSpans(score, options) {
992
1330
  }
993
1331
  function getTupletGroups(score, options) {
994
1332
  const results = [];
995
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _47 => _47.partIndex]), () => ( 0));
996
- const endPart = _optionalChain([options, 'optionalAccess', _48 => _48.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1333
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _49 => _49.partIndex]), () => ( 0));
1334
+ const endPart = _optionalChain([options, 'optionalAccess', _50 => _50.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
997
1335
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
998
1336
  const part = score.parts[partIndex];
999
1337
  if (!part) continue;
@@ -1017,8 +1355,8 @@ function getTupletGroups(score, options) {
1017
1355
  if (notation.type === "tuplet") {
1018
1356
  const tupletNumber = _nullishCoalesce(notation.number, () => ( 1));
1019
1357
  if (notation.tupletType === "start") {
1020
- const actualNotes = _nullishCoalesce(_optionalChain([entry, 'access', _49 => _49.timeModification, 'optionalAccess', _50 => _50.actualNotes]), () => ( 3));
1021
- const normalNotes = _nullishCoalesce(_optionalChain([entry, 'access', _51 => _51.timeModification, 'optionalAccess', _52 => _52.normalNotes]), () => ( 2));
1358
+ const actualNotes = _nullishCoalesce(_optionalChain([entry, 'access', _51 => _51.timeModification, 'optionalAccess', _52 => _52.actualNotes]), () => ( 3));
1359
+ const normalNotes = _nullishCoalesce(_optionalChain([entry, 'access', _53 => _53.timeModification, 'optionalAccess', _54 => _54.normalNotes]), () => ( 2));
1022
1360
  pendingTuplets.set(tupletNumber, {
1023
1361
  notes: [context],
1024
1362
  actualNotes,
@@ -1038,7 +1376,7 @@ function getTupletGroups(score, options) {
1038
1376
  }
1039
1377
  }
1040
1378
  }
1041
- if (entry.timeModification && !_optionalChain([entry, 'access', _53 => _53.notations, 'optionalAccess', _54 => _54.some, 'call', _55 => _55((n) => n.type === "tuplet")])) {
1379
+ if (entry.timeModification && !_optionalChain([entry, 'access', _55 => _55.notations, 'optionalAccess', _56 => _56.some, 'call', _57 => _57((n) => n.type === "tuplet")])) {
1042
1380
  for (const [, pending] of pendingTuplets) {
1043
1381
  if (entry.timeModification.actualNotes === pending.actualNotes && entry.timeModification.normalNotes === pending.normalNotes) {
1044
1382
  pending.notes.push(context);
@@ -1091,8 +1429,8 @@ function getBeamGroups(measure) {
1091
1429
  }
1092
1430
  function findNotesWithNotation(score, notationType, options) {
1093
1431
  const results = [];
1094
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _56 => _56.partIndex]), () => ( 0));
1095
- const endPart = _optionalChain([options, 'optionalAccess', _57 => _57.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1432
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _58 => _58.partIndex]), () => ( 0));
1433
+ const endPart = _optionalChain([options, 'optionalAccess', _59 => _59.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1096
1434
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1097
1435
  const part = score.parts[partIndex];
1098
1436
  if (!part) continue;
@@ -1102,7 +1440,7 @@ function findNotesWithNotation(score, notationType, options) {
1102
1440
  for (const entry of measure.entries) {
1103
1441
  if (entry.type === "note") {
1104
1442
  const position = entry.chord ? state.lastNonChordPosition : state.position;
1105
- if (_optionalChain([entry, 'access', _58 => _58.notations, 'optionalAccess', _59 => _59.some, 'call', _60 => _60((n) => n.type === notationType)])) {
1443
+ if (_optionalChain([entry, 'access', _60 => _60.notations, 'optionalAccess', _61 => _61.some, 'call', _62 => _62((n) => n.type === notationType)])) {
1106
1444
  results.push({
1107
1445
  note: entry,
1108
1446
  part,
@@ -1121,8 +1459,8 @@ function findNotesWithNotation(score, notationType, options) {
1121
1459
  }
1122
1460
  function getHarmonies(score, options) {
1123
1461
  const results = [];
1124
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _61 => _61.partIndex]), () => ( 0));
1125
- const endPart = _optionalChain([options, 'optionalAccess', _62 => _62.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1462
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.partIndex]), () => ( 0));
1463
+ const endPart = _optionalChain([options, 'optionalAccess', _64 => _64.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1126
1464
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1127
1465
  const part = score.parts[partIndex];
1128
1466
  if (!part) continue;
@@ -1185,8 +1523,8 @@ function getChordProgression(score, options) {
1185
1523
  }
1186
1524
  function getLyrics(score, options) {
1187
1525
  const results = [];
1188
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.partIndex]), () => ( 0));
1189
- const endPart = _optionalChain([options, 'optionalAccess', _64 => _64.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1526
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _65 => _65.partIndex]), () => ( 0));
1527
+ const endPart = _optionalChain([options, 'optionalAccess', _66 => _66.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1190
1528
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1191
1529
  const part = score.parts[partIndex];
1192
1530
  if (!part) continue;
@@ -1198,7 +1536,7 @@ function getLyrics(score, options) {
1198
1536
  const position = entry.chord ? state.lastNonChordPosition : state.position;
1199
1537
  for (const lyric of entry.lyrics) {
1200
1538
  const verse = _nullishCoalesce(lyric.number, () => ( 1));
1201
- if (_optionalChain([options, 'optionalAccess', _65 => _65.verse]) !== void 0 && verse !== options.verse) {
1539
+ if (_optionalChain([options, 'optionalAccess', _67 => _67.verse]) !== void 0 && verse !== options.verse) {
1202
1540
  continue;
1203
1541
  }
1204
1542
  results.push({
@@ -1258,8 +1596,8 @@ function getLyricText(score, options) {
1258
1596
  }
1259
1597
  function getVerseCount(score, options) {
1260
1598
  const verses = /* @__PURE__ */ new Set();
1261
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _66 => _66.partIndex]), () => ( 0));
1262
- const endPart = _optionalChain([options, 'optionalAccess', _67 => _67.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1599
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _68 => _68.partIndex]), () => ( 0));
1600
+ const endPart = _optionalChain([options, 'optionalAccess', _69 => _69.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1263
1601
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1264
1602
  const part = score.parts[partIndex];
1265
1603
  if (!part) continue;
@@ -1277,7 +1615,7 @@ function getVerseCount(score, options) {
1277
1615
  }
1278
1616
  function getRepeatStructure(score, options) {
1279
1617
  const results = [];
1280
- const partIndex = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _68 => _68.partIndex]), () => ( 0));
1618
+ const partIndex = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _70 => _70.partIndex]), () => ( 0));
1281
1619
  const part = score.parts[partIndex];
1282
1620
  if (!part) return results;
1283
1621
  for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
@@ -1300,8 +1638,8 @@ function getRepeatStructure(score, options) {
1300
1638
  }
1301
1639
  function findBarlines(score, options) {
1302
1640
  const results = [];
1303
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _69 => _69.partIndex]), () => ( 0));
1304
- const endPart = _optionalChain([options, 'optionalAccess', _70 => _70.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1641
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _71 => _71.partIndex]), () => ( 0));
1642
+ const endPart = _optionalChain([options, 'optionalAccess', _72 => _72.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1305
1643
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1306
1644
  const part = score.parts[partIndex];
1307
1645
  if (!part) continue;
@@ -1310,10 +1648,10 @@ function findBarlines(score, options) {
1310
1648
  const measureNumber = _nullishCoalesce(measure.number, () => ( String(measureIndex + 1)));
1311
1649
  if (measure.barlines) {
1312
1650
  for (const barline of measure.barlines) {
1313
- if (_optionalChain([options, 'optionalAccess', _71 => _71.style]) !== void 0 && barline.barStyle !== options.style) {
1651
+ if (_optionalChain([options, 'optionalAccess', _73 => _73.style]) !== void 0 && barline.barStyle !== options.style) {
1314
1652
  continue;
1315
1653
  }
1316
- if (_optionalChain([options, 'optionalAccess', _72 => _72.repeat]) !== void 0) {
1654
+ if (_optionalChain([options, 'optionalAccess', _74 => _74.repeat]) !== void 0) {
1317
1655
  const hasRepeat = barline.repeat !== void 0;
1318
1656
  if (hasRepeat !== options.repeat) {
1319
1657
  continue;
@@ -1333,8 +1671,8 @@ function findBarlines(score, options) {
1333
1671
  }
1334
1672
  function getEndings(score, options) {
1335
1673
  const results = [];
1336
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _73 => _73.partIndex]), () => ( 0));
1337
- const endPart = _optionalChain([options, 'optionalAccess', _74 => _74.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1674
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _75 => _75.partIndex]), () => ( 0));
1675
+ const endPart = _optionalChain([options, 'optionalAccess', _76 => _76.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1338
1676
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1339
1677
  const part = score.parts[partIndex];
1340
1678
  if (!part) continue;
@@ -1360,8 +1698,8 @@ function getEndings(score, options) {
1360
1698
  }
1361
1699
  function getKeyChanges(score, options) {
1362
1700
  const results = [];
1363
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _75 => _75.partIndex]), () => ( 0));
1364
- const endPart = _optionalChain([options, 'optionalAccess', _76 => _76.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1701
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _77 => _77.partIndex]), () => ( 0));
1702
+ const endPart = _optionalChain([options, 'optionalAccess', _78 => _78.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1365
1703
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1366
1704
  const part = score.parts[partIndex];
1367
1705
  if (!part) continue;
@@ -1370,7 +1708,7 @@ function getKeyChanges(score, options) {
1370
1708
  const measure = part.measures[measureIndex];
1371
1709
  const measureNumber = _nullishCoalesce(measure.number, () => ( String(measureIndex + 1)));
1372
1710
  const state = createPositionState();
1373
- if (_optionalChain([measure, 'access', _77 => _77.attributes, 'optionalAccess', _78 => _78.key])) {
1711
+ if (_optionalChain([measure, 'access', _79 => _79.attributes, 'optionalAccess', _80 => _80.key])) {
1374
1712
  const key = measure.attributes.key;
1375
1713
  if (!lastKey || lastKey.fifths !== key.fifths || lastKey.mode !== key.mode) {
1376
1714
  results.push({
@@ -1405,8 +1743,8 @@ function getKeyChanges(score, options) {
1405
1743
  }
1406
1744
  function getTimeChanges(score, options) {
1407
1745
  const results = [];
1408
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _79 => _79.partIndex]), () => ( 0));
1409
- const endPart = _optionalChain([options, 'optionalAccess', _80 => _80.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1746
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _81 => _81.partIndex]), () => ( 0));
1747
+ const endPart = _optionalChain([options, 'optionalAccess', _82 => _82.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1410
1748
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1411
1749
  const part = score.parts[partIndex];
1412
1750
  if (!part) continue;
@@ -1414,7 +1752,7 @@ function getTimeChanges(score, options) {
1414
1752
  for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
1415
1753
  const measure = part.measures[measureIndex];
1416
1754
  const measureNumber = _nullishCoalesce(measure.number, () => ( String(measureIndex + 1)));
1417
- if (_optionalChain([measure, 'access', _81 => _81.attributes, 'optionalAccess', _82 => _82.time])) {
1755
+ if (_optionalChain([measure, 'access', _83 => _83.attributes, 'optionalAccess', _84 => _84.time])) {
1418
1756
  const time = measure.attributes.time;
1419
1757
  if (!lastTime || lastTime.beats !== time.beats || lastTime.beatType !== time.beatType) {
1420
1758
  results.push({
@@ -1446,8 +1784,8 @@ function getTimeChanges(score, options) {
1446
1784
  }
1447
1785
  function getClefChanges(score, options) {
1448
1786
  const results = [];
1449
- const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _83 => _83.partIndex]), () => ( 0));
1450
- const endPart = _optionalChain([options, 'optionalAccess', _84 => _84.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1787
+ const startPart = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _85 => _85.partIndex]), () => ( 0));
1788
+ const endPart = _optionalChain([options, 'optionalAccess', _86 => _86.partIndex]) !== void 0 ? options.partIndex + 1 : score.parts.length;
1451
1789
  for (let partIndex = startPart; partIndex < endPart; partIndex++) {
1452
1790
  const part = score.parts[partIndex];
1453
1791
  if (!part) continue;
@@ -1456,10 +1794,10 @@ function getClefChanges(score, options) {
1456
1794
  const measure = part.measures[measureIndex];
1457
1795
  const measureNumber = _nullishCoalesce(measure.number, () => ( String(measureIndex + 1)));
1458
1796
  const state = createPositionState();
1459
- if (_optionalChain([measure, 'access', _85 => _85.attributes, 'optionalAccess', _86 => _86.clef])) {
1797
+ if (_optionalChain([measure, 'access', _87 => _87.attributes, 'optionalAccess', _88 => _88.clef])) {
1460
1798
  for (const clef of measure.attributes.clef) {
1461
1799
  const staff = _nullishCoalesce(clef.staff, () => ( 1));
1462
- if (_optionalChain([options, 'optionalAccess', _87 => _87.staff]) !== void 0 && staff !== options.staff) {
1800
+ if (_optionalChain([options, 'optionalAccess', _89 => _89.staff]) !== void 0 && staff !== options.staff) {
1463
1801
  continue;
1464
1802
  }
1465
1803
  const lastClef = lastClefs.get(staff);
@@ -1480,7 +1818,7 @@ function getClefChanges(score, options) {
1480
1818
  if (entry.type === "attributes" && entry.attributes.clef) {
1481
1819
  for (const clef of entry.attributes.clef) {
1482
1820
  const staff = _nullishCoalesce(clef.staff, () => ( 1));
1483
- if (_optionalChain([options, 'optionalAccess', _88 => _88.staff]) !== void 0 && staff !== options.staff) {
1821
+ if (_optionalChain([options, 'optionalAccess', _90 => _90.staff]) !== void 0 && staff !== options.staff) {
1484
1822
  continue;
1485
1823
  }
1486
1824
  const lastClef = lastClefs.get(staff);
@@ -1543,14 +1881,14 @@ function getDivisions(score, options) {
1543
1881
  const m = part.measures[i];
1544
1882
  const mNum = parseInt(m.number, 10);
1545
1883
  if (!isNaN(mNum) && mNum > targetMeasure) break;
1546
- if (_optionalChain([m, 'access', _89 => _89.attributes, 'optionalAccess', _90 => _90.divisions]) !== void 0) {
1884
+ if (_optionalChain([m, 'access', _91 => _91.attributes, 'optionalAccess', _92 => _92.divisions]) !== void 0) {
1547
1885
  }
1548
1886
  }
1549
1887
  let divisions = 1;
1550
1888
  for (const m of part.measures) {
1551
1889
  const mNum = parseInt(m.number, 10);
1552
1890
  if (!isNaN(mNum) && mNum > targetMeasure) break;
1553
- if (_optionalChain([m, 'access', _91 => _91.attributes, 'optionalAccess', _92 => _92.divisions]) !== void 0) {
1891
+ if (_optionalChain([m, 'access', _93 => _93.attributes, 'optionalAccess', _94 => _94.divisions]) !== void 0) {
1554
1892
  divisions = m.attributes.divisions;
1555
1893
  }
1556
1894
  }
@@ -1611,7 +1949,7 @@ function getDuration(score) {
1611
1949
  let totalDuration = 0;
1612
1950
  let divisions = 1;
1613
1951
  for (const measure of part.measures) {
1614
- if (_optionalChain([measure, 'access', _93 => _93.attributes, 'optionalAccess', _94 => _94.divisions]) !== void 0) {
1952
+ if (_optionalChain([measure, 'access', _95 => _95.attributes, 'optionalAccess', _96 => _96.divisions]) !== void 0) {
1615
1953
  divisions = measure.attributes.divisions;
1616
1954
  }
1617
1955
  let measureDuration = 0;
@@ -1640,7 +1978,7 @@ function hasMultipleStaves(score, partIndex = 0) {
1640
1978
  const part = score.parts[partIndex];
1641
1979
  if (!part) return false;
1642
1980
  for (const measure of part.measures) {
1643
- if (_optionalChain([measure, 'access', _95 => _95.attributes, 'optionalAccess', _96 => _96.staves]) !== void 0 && measure.attributes.staves > 1) {
1981
+ if (_optionalChain([measure, 'access', _97 => _97.attributes, 'optionalAccess', _98 => _98.staves]) !== void 0 && measure.attributes.staves > 1) {
1644
1982
  return true;
1645
1983
  }
1646
1984
  }
@@ -1650,7 +1988,7 @@ function getStaveCount(score, partIndex = 0) {
1650
1988
  const part = score.parts[partIndex];
1651
1989
  if (!part) return 1;
1652
1990
  for (const measure of part.measures) {
1653
- if (_optionalChain([measure, 'access', _97 => _97.attributes, 'optionalAccess', _98 => _98.staves]) !== void 0) {
1991
+ if (_optionalChain([measure, 'access', _99 => _99.attributes, 'optionalAccess', _100 => _100.staves]) !== void 0) {
1654
1992
  return measure.attributes.staves;
1655
1993
  }
1656
1994
  }
@@ -1806,4 +2144,7 @@ function pitchesEqual(a, b) {
1806
2144
 
1807
2145
 
1808
2146
 
1809
- exports.STEPS = STEPS; exports.STEP_SEMITONES = STEP_SEMITONES; exports.pitchToSemitone = pitchToSemitone; exports.getAccidentalsInMeasure = getAccidentalsInMeasure; exports.semitoneToKeyAwarePitch = semitoneToKeyAwarePitch; exports.determineAccidental = determineAccidental; exports.getAbsolutePositionForNote = getAbsolutePositionForNote; exports.getMeasureEndPosition = getMeasureEndPosition; exports.getNotesForVoice = getNotesForVoice; exports.getNotesForStaff = getNotesForStaff; exports.groupByVoice = groupByVoice; exports.groupByStaff = groupByStaff; exports.getAbsolutePosition = getAbsolutePosition; exports.withAbsolutePositions = withAbsolutePositions; exports.getChords = getChords; exports.iterateNotes = iterateNotes; exports.getAllNotes = getAllNotes; exports.getVoices = getVoices; exports.getStaves = getStaves; exports.hasNotes = hasNotes; exports.isRestMeasure = isRestMeasure; exports.getNormalizedPosition = getNormalizedPosition; exports.getNormalizedDuration = getNormalizedDuration; exports.getEntriesForStaff = getEntriesForStaff; exports.buildVoiceToStaffMap = buildVoiceToStaffMap; exports.buildVoiceToStaffMapForPart = buildVoiceToStaffMapForPart; exports.inferStaff = inferStaff; exports.getEffectiveStaff = getEffectiveStaff; exports.getClefForStaff = getClefForStaff; exports.getVoicesForStaff = getVoicesForStaff; exports.getStaffRange = getStaffRange; exports.getEntriesAtPosition = getEntriesAtPosition; exports.getNotesAtPosition = getNotesAtPosition; exports.getEntriesInRange = getEntriesInRange; exports.getNotesInRange = getNotesInRange; exports.getVerticalSlice = getVerticalSlice; exports.getVoiceLine = getVoiceLine; exports.getVoiceLineInRange = getVoiceLineInRange; exports.iterateEntries = iterateEntries; exports.getNextNote = getNextNote; exports.getPrevNote = getPrevNote; exports.getAdjacentNotes = getAdjacentNotes; exports.getDirections = getDirections; exports.getDirectionsAtPosition = getDirectionsAtPosition; exports.findDirectionsByType = findDirectionsByType; exports.getDynamics = getDynamics; exports.getTempoMarkings = getTempoMarkings; exports.getPedalMarkings = getPedalMarkings; exports.getWedges = getWedges; exports.getOctaveShifts = getOctaveShifts; exports.getTiedNoteGroups = getTiedNoteGroups; exports.getSlurSpans = getSlurSpans; exports.getTupletGroups = getTupletGroups; exports.getBeamGroups = getBeamGroups; exports.findNotesWithNotation = findNotesWithNotation; exports.getHarmonies = getHarmonies; exports.getHarmonyAtPosition = getHarmonyAtPosition; exports.getChordProgression = getChordProgression; exports.getLyrics = getLyrics; exports.getLyricText = getLyricText; exports.getVerseCount = getVerseCount; exports.getRepeatStructure = getRepeatStructure; exports.findBarlines = findBarlines; exports.getEndings = getEndings; exports.getKeyChanges = getKeyChanges; exports.getTimeChanges = getTimeChanges; exports.getClefChanges = getClefChanges; exports.getStructuralChanges = getStructuralChanges; exports.getPartByIndex = getPartByIndex; exports.getPartCount = getPartCount; exports.getPartIds = getPartIds; exports.getMeasure = getMeasure; exports.getMeasureByIndex = getMeasureByIndex; exports.getMeasureCount = getMeasureCount; exports.getDivisions = getDivisions; exports.getAttributesAtMeasure = getAttributesAtMeasure; exports.findNotes = findNotes; exports.getDuration = getDuration; exports.getPartById = getPartById; exports.getPartIndex = getPartIndex; exports.hasMultipleStaves = hasMultipleStaves; exports.getStaveCount = getStaveCount; exports.measureRoundtrip = measureRoundtrip; exports.countNotes = countNotes; exports.scoresEqual = scoresEqual;
2147
+
2148
+
2149
+
2150
+ exports.extractPlaybackControls = extractPlaybackControls; exports.generatePlaybackSequence = generatePlaybackSequence; exports.hasPlaybackControls = hasPlaybackControls; exports.STEPS = STEPS; exports.STEP_SEMITONES = STEP_SEMITONES; exports.pitchToSemitone = pitchToSemitone; exports.getAccidentalsInMeasure = getAccidentalsInMeasure; exports.semitoneToKeyAwarePitch = semitoneToKeyAwarePitch; exports.determineAccidental = determineAccidental; exports.getAbsolutePositionForNote = getAbsolutePositionForNote; exports.getMeasureEndPosition = getMeasureEndPosition; exports.getNotesForVoice = getNotesForVoice; exports.getNotesForStaff = getNotesForStaff; exports.groupByVoice = groupByVoice; exports.groupByStaff = groupByStaff; exports.getAbsolutePosition = getAbsolutePosition; exports.withAbsolutePositions = withAbsolutePositions; exports.getChords = getChords; exports.iterateNotes = iterateNotes; exports.getAllNotes = getAllNotes; exports.getVoices = getVoices; exports.getStaves = getStaves; exports.hasNotes = hasNotes; exports.isRestMeasure = isRestMeasure; exports.getNormalizedPosition = getNormalizedPosition; exports.getNormalizedDuration = getNormalizedDuration; exports.getEntriesForStaff = getEntriesForStaff; exports.buildVoiceToStaffMap = buildVoiceToStaffMap; exports.buildVoiceToStaffMapForPart = buildVoiceToStaffMapForPart; exports.inferStaff = inferStaff; exports.getEffectiveStaff = getEffectiveStaff; exports.getClefForStaff = getClefForStaff; exports.getVoicesForStaff = getVoicesForStaff; exports.getStaffRange = getStaffRange; exports.getEntriesAtPosition = getEntriesAtPosition; exports.getNotesAtPosition = getNotesAtPosition; exports.getEntriesInRange = getEntriesInRange; exports.getNotesInRange = getNotesInRange; exports.getVerticalSlice = getVerticalSlice; exports.getVoiceLine = getVoiceLine; exports.getVoiceLineInRange = getVoiceLineInRange; exports.iterateEntries = iterateEntries; exports.getNextNote = getNextNote; exports.getPrevNote = getPrevNote; exports.getAdjacentNotes = getAdjacentNotes; exports.getDirections = getDirections; exports.getDirectionsAtPosition = getDirectionsAtPosition; exports.findDirectionsByType = findDirectionsByType; exports.getDynamics = getDynamics; exports.getTempoMarkings = getTempoMarkings; exports.getPedalMarkings = getPedalMarkings; exports.getWedges = getWedges; exports.getOctaveShifts = getOctaveShifts; exports.getTiedNoteGroups = getTiedNoteGroups; exports.getSlurSpans = getSlurSpans; exports.getTupletGroups = getTupletGroups; exports.getBeamGroups = getBeamGroups; exports.findNotesWithNotation = findNotesWithNotation; exports.getHarmonies = getHarmonies; exports.getHarmonyAtPosition = getHarmonyAtPosition; exports.getChordProgression = getChordProgression; exports.getLyrics = getLyrics; exports.getLyricText = getLyricText; exports.getVerseCount = getVerseCount; exports.getRepeatStructure = getRepeatStructure; exports.findBarlines = findBarlines; exports.getEndings = getEndings; exports.getKeyChanges = getKeyChanges; exports.getTimeChanges = getTimeChanges; exports.getClefChanges = getClefChanges; exports.getStructuralChanges = getStructuralChanges; exports.getPartByIndex = getPartByIndex; exports.getPartCount = getPartCount; exports.getPartIds = getPartIds; exports.getMeasure = getMeasure; exports.getMeasureByIndex = getMeasureByIndex; exports.getMeasureCount = getMeasureCount; exports.getDivisions = getDivisions; exports.getAttributesAtMeasure = getAttributesAtMeasure; exports.findNotes = findNotes; exports.getDuration = getDuration; exports.getPartById = getPartById; exports.getPartIndex = getPartIndex; exports.hasMultipleStaves = hasMultipleStaves; exports.getStaveCount = getStaveCount; exports.measureRoundtrip = measureRoundtrip; exports.countNotes = countNotes; exports.scoresEqual = scoresEqual;