musicxml-io 0.12.0 → 0.12.2

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.
Files changed (98) hide show
  1. package/README.md +96 -8
  2. package/dist/abc-HXITSXCS.js +9 -0
  3. package/dist/abc-IAD53SFI.mjs +11 -0
  4. package/dist/abc-MTGVOYKS.js +11 -0
  5. package/dist/abc-R7DIJSHG.mjs +9 -0
  6. package/dist/abc.d.mts +67 -0
  7. package/dist/abc.d.ts +67 -0
  8. package/dist/abc.js +17 -0
  9. package/dist/abc.mjs +17 -0
  10. package/dist/accessors/index.d.mts +1 -1
  11. package/dist/accessors/index.d.ts +1 -1
  12. package/dist/browser.d.mts +11 -187
  13. package/dist/browser.d.ts +11 -187
  14. package/dist/browser.js +30 -6
  15. package/dist/browser.mjs +96 -72
  16. package/dist/chunk-2EH2MGBY.js +1799 -0
  17. package/dist/chunk-33IQXDOH.js +1 -0
  18. package/dist/chunk-5EK7K5X3.js +29 -0
  19. package/dist/chunk-5VF442RA.mjs +29 -0
  20. package/dist/chunk-626TXMVP.js +706 -0
  21. package/dist/chunk-63UT3IEY.mjs +2788 -0
  22. package/dist/chunk-6EKVRPFF.js +407 -0
  23. package/dist/chunk-776XPK66.js +45 -0
  24. package/dist/chunk-7D4MLQKO.js +69 -0
  25. package/dist/chunk-A2CGW2UF.js +25 -0
  26. package/dist/chunk-AOSK4RGV.mjs +45 -0
  27. package/dist/{chunk-FQ3NEYIV.js → chunk-ASPCIBWD.js} +127 -1249
  28. package/dist/chunk-BDHPMB7Q.mjs +61 -0
  29. package/dist/chunk-BHHOS2E6.mjs +407 -0
  30. package/dist/chunk-F2UCOAO6.mjs +155 -0
  31. package/dist/chunk-HP4DAUGT.js +2788 -0
  32. package/dist/chunk-JF5TM534.js +1065 -0
  33. package/dist/chunk-K6DSQPVF.mjs +706 -0
  34. package/dist/chunk-KJK2IGNN.mjs +0 -0
  35. package/dist/chunk-KYGLANYG.mjs +2354 -0
  36. package/dist/chunk-LFQXT7PV.mjs +69 -0
  37. package/dist/chunk-LS5SHP75.js +155 -0
  38. package/dist/chunk-MMIZQMIO.mjs +25 -0
  39. package/dist/chunk-NIUEAHPN.js +2354 -0
  40. package/dist/{chunk-EWLB5X64.js → chunk-PMPROVJW.js} +66 -770
  41. package/dist/chunk-QFYOH4DY.mjs +0 -0
  42. package/dist/chunk-QKUNJEVW.mjs +1401 -0
  43. package/dist/chunk-SBT2RMUW.mjs +1065 -0
  44. package/dist/chunk-TCXDBRRT.mjs +1799 -0
  45. package/dist/chunk-WNQIUYWY.js +61 -0
  46. package/dist/{chunk-I4X4GRMP.mjs → chunk-WS5LSW3S.mjs} +13 -1135
  47. package/dist/chunk-YKMNCYOD.js +1 -0
  48. package/dist/{chunk-UMEH3ENQ.mjs → chunk-ZRKJKEP7.mjs} +0 -704
  49. package/dist/chunk-ZSEJQPBO.js +1401 -0
  50. package/dist/core.d.mts +33 -0
  51. package/dist/core.d.ts +33 -0
  52. package/dist/core.js +524 -0
  53. package/dist/core.mjs +524 -0
  54. package/dist/file.d.mts +37 -0
  55. package/dist/file.d.ts +37 -0
  56. package/dist/file.js +14 -0
  57. package/dist/file.mjs +14 -0
  58. package/dist/index-C9lLZwol.d.mts +185 -0
  59. package/dist/index-DNA970t1.d.ts +185 -0
  60. package/dist/index.d.mts +12 -38
  61. package/dist/index.d.ts +12 -38
  62. package/dist/index.js +34 -49
  63. package/dist/index.mjs +101 -116
  64. package/dist/midi.d.mts +54 -0
  65. package/dist/midi.d.ts +54 -0
  66. package/dist/midi.js +10 -0
  67. package/dist/midi.mjs +10 -0
  68. package/dist/musicxml-DWPClEqa.d.ts +25 -0
  69. package/dist/musicxml-DzuFr2c3.d.mts +25 -0
  70. package/dist/musicxml-compressed-7NUEGLSF.mjs +8 -0
  71. package/dist/musicxml-compressed-7RL6QRF7.js +12 -0
  72. package/dist/musicxml-compressed-WPEIBOZ3.js +8 -0
  73. package/dist/musicxml-compressed-ZHZYFJ7H.mjs +12 -0
  74. package/dist/musicxml-compressed.d.mts +33 -0
  75. package/dist/musicxml-compressed.d.ts +33 -0
  76. package/dist/musicxml-compressed.js +18 -0
  77. package/dist/musicxml-compressed.mjs +18 -0
  78. package/dist/musicxml.d.mts +8 -0
  79. package/dist/musicxml.d.ts +8 -0
  80. package/dist/musicxml.js +14 -0
  81. package/dist/musicxml.mjs +14 -0
  82. package/dist/operations/index.d.mts +1234 -2
  83. package/dist/operations/index.d.ts +1234 -2
  84. package/dist/operations/index.js +7 -3
  85. package/dist/operations/index.mjs +6 -2
  86. package/dist/playback-timeline-CVRHsikj.d.mts +129 -0
  87. package/dist/playback-timeline-CmWA8YDy.d.ts +129 -0
  88. package/dist/query/index.d.mts +3 -128
  89. package/dist/query/index.d.ts +3 -128
  90. package/dist/query/index.js +4 -2
  91. package/dist/query/index.mjs +7 -5
  92. package/dist/{types-Cy0veafI.d.mts → types-B-RGHY0c.d.mts} +1 -1
  93. package/dist/{types-Cy0veafI.d.ts → types-B-RGHY0c.d.ts} +1 -1
  94. package/package.json +36 -2
  95. package/dist/chunk-T2USSS5E.mjs +0 -8939
  96. package/dist/chunk-UT7LQW6V.js +0 -8939
  97. package/dist/index-CbUtBHLD.d.ts +0 -1415
  98. package/dist/index-CuMPBK7U.d.mts +0 -1415
@@ -8,1117 +8,19 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkEWLB5X64js = require('./chunk-EWLB5X64.js');
12
-
13
- // src/id.ts
14
- var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
15
- var ID_LENGTH = 10;
16
- var POOL_SIZE = ID_LENGTH * 128;
17
- var pool;
18
- var poolOffset = 0;
19
- function randomBytes() {
20
- if (pool === void 0 || poolOffset + ID_LENGTH > POOL_SIZE) {
21
- if (pool === void 0) {
22
- pool = new Uint8Array(POOL_SIZE);
23
- }
24
- globalThis.crypto.getRandomValues(pool);
25
- poolOffset = 0;
26
- }
27
- const bytes = pool.subarray(poolOffset, poolOffset + ID_LENGTH);
28
- poolOffset += ID_LENGTH;
29
- return bytes;
30
- }
31
- function generateId() {
32
- const bytes = randomBytes();
33
- let id = "i";
34
- for (let i = 0; i < ID_LENGTH; i++) {
35
- id += ALPHABET[bytes[i] & 63];
36
- }
37
- return id;
38
- }
11
+ var _chunkPMPROVJWjs = require('./chunk-PMPROVJW.js');
39
12
 
40
- // src/beams.ts
41
- var BEAM_LEVELS = {
42
- eighth: 1,
43
- "16th": 2,
44
- "32nd": 3,
45
- "64th": 4,
46
- "128th": 5,
47
- "256th": 6,
48
- "512th": 7,
49
- "1024th": 8
50
- };
51
- function beamLevel(note) {
52
- return note.rest || !note.noteType ? 0 : _nullishCoalesce(BEAM_LEVELS[note.noteType], () => ( 0));
53
- }
54
- function applyBeamGroup(group) {
55
- const levels = group.map(beamLevel);
56
- const beams = group.map(() => []);
57
- const maxLevel = Math.max(...levels);
58
- for (let lv = 1; lv <= maxLevel; lv++) {
59
- for (let i = 0; i < group.length; ) {
60
- if (levels[i] < lv) {
61
- i++;
62
- continue;
63
- }
64
- let j = i;
65
- while (j + 1 < group.length && levels[j + 1] >= lv) j++;
66
- if (i === j) {
67
- beams[i].push({ number: lv, type: i === group.length - 1 ? "backward hook" : "forward hook" });
68
- } else {
69
- for (let k = i; k <= j; k++) {
70
- beams[k].push({ number: lv, type: k === i ? "begin" : k === j ? "end" : "continue" });
71
- }
72
- }
73
- i = j + 1;
74
- }
75
- }
76
- group.forEach((n, i) => {
77
- n.beam = beams[i];
78
- });
79
- }
80
13
 
81
- // src/validator/index.ts
82
- var DEFAULT_OPTIONS = {
83
- checkDivisions: true,
84
- checkMeasureDuration: true,
85
- checkMeasureFullness: false,
86
- // Piano Roll semantics - opt-in
87
- checkPosition: true,
88
- checkTies: true,
89
- checkBeams: true,
90
- checkSlurs: true,
91
- checkTuplets: true,
92
- checkPartReferences: true,
93
- checkPartStructure: true,
94
- checkVoiceStaff: true,
95
- checkStaffStructure: true,
96
- durationTolerance: 0
97
- };
98
- function validate(score, options = {}) {
99
- const opts = { ...DEFAULT_OPTIONS, ...options };
100
- const allErrors = [];
101
- if (opts.checkPartReferences) {
102
- allErrors.push(...validatePartReferences(score));
103
- }
104
- if (opts.checkPartStructure) {
105
- allErrors.push(...validatePartStructure(score));
106
- }
107
- if (opts.checkDivisions) {
108
- allErrors.push(...validateDivisions(score));
109
- }
110
- for (let partIndex = 0; partIndex < score.parts.length; partIndex++) {
111
- const part = score.parts[partIndex];
112
- let currentDivisions = 1;
113
- let currentTime;
114
- let currentStaves = 1;
115
- for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
116
- const measure = part.measures[measureIndex];
117
- const location = {
118
- partIndex,
119
- partId: part.id,
120
- measureIndex,
121
- measureNumber: measure.number
122
- };
123
- if (measure.attributes) {
124
- if (measure.attributes.divisions !== void 0) {
125
- currentDivisions = measure.attributes.divisions;
126
- }
127
- if (measure.attributes.time !== void 0) {
128
- currentTime = measure.attributes.time;
129
- }
130
- if (measure.attributes.staves !== void 0) {
131
- currentStaves = measure.attributes.staves;
132
- }
133
- }
134
- if (opts.checkMeasureDuration && currentTime) {
135
- allErrors.push(...validateMeasureDuration(
136
- measure,
137
- currentDivisions,
138
- currentTime,
139
- location,
140
- opts.durationTolerance
141
- ));
142
- }
143
- if (opts.checkMeasureFullness && currentTime) {
144
- allErrors.push(...validateMeasureFullness(
145
- measure,
146
- currentDivisions,
147
- currentTime,
148
- location
149
- ));
150
- }
151
- if (opts.checkPosition) {
152
- allErrors.push(...validateBackupForward(measure, location));
153
- }
154
- if (opts.checkTies) {
155
- allErrors.push(...validateTies(measure, location));
156
- }
157
- if (opts.checkBeams) {
158
- allErrors.push(...validateBeams(measure, location));
159
- }
160
- if (opts.checkSlurs) {
161
- allErrors.push(...validateSlurs(measure, location));
162
- }
163
- if (opts.checkTuplets) {
164
- allErrors.push(...validateTuplets(measure, location));
165
- }
166
- if (opts.checkVoiceStaff) {
167
- allErrors.push(...validateVoiceStaff(measure, currentStaves, location));
168
- }
169
- }
170
- if (opts.checkStaffStructure) {
171
- allErrors.push(...validateStaffStructure(part, partIndex));
172
- }
173
- }
174
- const errors = allErrors.filter((e) => e.level === "error");
175
- const warnings = allErrors.filter((e) => e.level === "warning");
176
- const infos = allErrors.filter((e) => e.level === "info");
177
- return {
178
- valid: errors.length === 0,
179
- errors,
180
- warnings,
181
- infos
182
- };
183
- }
184
- function validateDivisions(score) {
185
- const errors = [];
186
- for (let partIndex = 0; partIndex < score.parts.length; partIndex++) {
187
- const part = score.parts[partIndex];
188
- let hasDivisions = false;
189
- for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
190
- const measure = part.measures[measureIndex];
191
- if (_optionalChain([measure, 'access', _ => _.attributes, 'optionalAccess', _2 => _2.divisions]) !== void 0) {
192
- hasDivisions = true;
193
- if (measure.attributes.divisions <= 0) {
194
- errors.push({
195
- code: "INVALID_DIVISIONS",
196
- level: "error",
197
- message: `Invalid divisions value: ${measure.attributes.divisions}. Must be positive.`,
198
- location: {
199
- partIndex,
200
- partId: part.id,
201
- measureIndex,
202
- measureNumber: measure.number
203
- },
204
- details: { divisions: measure.attributes.divisions }
205
- });
206
- }
207
- }
208
- if (!hasDivisions) {
209
- const hasNotes = measure.entries.some((e) => e.type === "note");
210
- if (hasNotes) {
211
- errors.push({
212
- code: "MISSING_DIVISIONS",
213
- level: "error",
214
- message: "Notes found before divisions are defined",
215
- location: {
216
- partIndex,
217
- partId: part.id,
218
- measureIndex,
219
- measureNumber: measure.number
220
- }
221
- });
222
- hasDivisions = true;
223
- }
224
- }
225
- }
226
- }
227
- return errors;
228
- }
229
- function validateMeasureDuration(measure, divisions, time, location, tolerance = 0) {
230
- const errors = [];
231
- if (time.senzaMisura) {
232
- return errors;
233
- }
234
- const beats = parseInt(time.beats, 10);
235
- if (isNaN(beats)) {
236
- return errors;
237
- }
238
- const expectedDuration = beats / time.beatType * 4 * divisions;
239
- const voiceDurations = calculateVoiceDurations(measure);
240
- for (const [voiceKey, actualDuration] of voiceDurations.entries()) {
241
- const dashIndex = voiceKey.indexOf("-");
242
- const staff = Number(voiceKey.slice(0, dashIndex));
243
- const voice = voiceKey.slice(dashIndex + 1);
244
- const diff = actualDuration - expectedDuration;
245
- if (Math.abs(diff) > tolerance) {
246
- if (diff > 0) {
247
- errors.push({
248
- code: "MEASURE_DURATION_OVERFLOW",
249
- level: "error",
250
- message: `Voice ${voice} (staff ${staff}) duration ${actualDuration} exceeds expected ${expectedDuration}`,
251
- location: { ...location, voice, staff },
252
- details: {
253
- expected: expectedDuration,
254
- actual: actualDuration,
255
- difference: diff
256
- }
257
- });
258
- } else {
259
- errors.push({
260
- code: "MEASURE_DURATION_UNDERFLOW",
261
- level: "warning",
262
- message: `Voice ${voice} (staff ${staff}) duration ${actualDuration} is less than expected ${expectedDuration}`,
263
- location: { ...location, voice, staff },
264
- details: {
265
- expected: expectedDuration,
266
- actual: actualDuration,
267
- difference: diff
268
- }
269
- });
270
- }
271
- }
272
- }
273
- return errors;
274
- }
275
- function calculateVoiceDurations(measure) {
276
- const voiceDurations = /* @__PURE__ */ new Map();
277
- let currentPosition = 0;
278
- const voiceMaxPositions = /* @__PURE__ */ new Map();
279
- for (const entry of measure.entries) {
280
- if (entry.type === "note") {
281
- const staff = _nullishCoalesce(entry.staff, () => ( 1));
282
- const voice = entry.voice;
283
- const key = `${staff}-${voice}`;
284
- if (!entry.chord) {
285
- const endPosition = currentPosition + entry.duration;
286
- const currentMax = _nullishCoalesce(voiceMaxPositions.get(key), () => ( 0));
287
- voiceMaxPositions.set(key, Math.max(currentMax, endPosition));
288
- currentPosition = endPosition;
289
- }
290
- } else if (entry.type === "backup") {
291
- currentPosition -= entry.duration;
292
- } else if (entry.type === "forward") {
293
- currentPosition += entry.duration;
294
- }
295
- }
296
- for (const [key, maxPos] of voiceMaxPositions.entries()) {
297
- voiceDurations.set(key, maxPos);
298
- }
299
- return voiceDurations;
300
- }
301
- function validateMeasureFullness(measure, divisions, time, location) {
302
- const errors = [];
303
- if (time.senzaMisura) {
304
- return errors;
305
- }
306
- const beats = parseInt(time.beats, 10);
307
- if (isNaN(beats)) {
308
- return errors;
309
- }
310
- const expectedDuration = beats / time.beatType * 4 * divisions;
311
- const voiceCoverage = /* @__PURE__ */ new Map();
312
- let currentPosition = 0;
313
- for (const entry of measure.entries) {
314
- if (entry.type === "note") {
315
- const staff = _nullishCoalesce(entry.staff, () => ( 1));
316
- const voice = entry.voice;
317
- const key = `${staff}-${voice}`;
318
- if (!entry.chord) {
319
- if (!voiceCoverage.has(key)) {
320
- voiceCoverage.set(key, { segments: [] });
321
- }
322
- voiceCoverage.get(key).segments.push({
323
- start: currentPosition,
324
- end: currentPosition + entry.duration
325
- });
326
- currentPosition += entry.duration;
327
- }
328
- } else if (entry.type === "backup") {
329
- currentPosition -= entry.duration;
330
- } else if (entry.type === "forward") {
331
- const staff = _nullishCoalesce(entry.staff, () => ( 1));
332
- const voice = _nullishCoalesce(entry.voice, () => ( "1"));
333
- const key = `${staff}-${voice}`;
334
- if (!voiceCoverage.has(key)) {
335
- voiceCoverage.set(key, { segments: [] });
336
- }
337
- voiceCoverage.get(key).segments.push({
338
- start: currentPosition,
339
- end: currentPosition + entry.duration
340
- });
341
- currentPosition += entry.duration;
342
- }
343
- }
344
- for (const [voiceKey, { segments }] of voiceCoverage.entries()) {
345
- const dashIndex = voiceKey.indexOf("-");
346
- const staff = Number(voiceKey.slice(0, dashIndex));
347
- const voice = voiceKey.slice(dashIndex + 1);
348
- const sorted = [...segments].sort((a, b) => a.start - b.start);
349
- let lastEnd = 0;
350
- const gaps = [];
351
- for (const seg of sorted) {
352
- if (seg.start > lastEnd) {
353
- gaps.push({ start: lastEnd, end: seg.start });
354
- }
355
- lastEnd = Math.max(lastEnd, seg.end);
356
- }
357
- if (lastEnd < expectedDuration) {
358
- gaps.push({ start: lastEnd, end: expectedDuration });
359
- }
360
- for (const gap of gaps) {
361
- errors.push({
362
- code: "VOICE_GAP",
363
- level: "warning",
364
- message: `Voice ${voice} (staff ${staff}) has gap from position ${gap.start} to ${gap.end}`,
365
- location: { ...location, voice, staff },
366
- details: {
367
- gapStart: gap.start,
368
- gapEnd: gap.end,
369
- gapDuration: gap.end - gap.start
370
- }
371
- });
372
- }
373
- if (lastEnd < expectedDuration) {
374
- errors.push({
375
- code: "VOICE_INCOMPLETE",
376
- level: "warning",
377
- message: `Voice ${voice} (staff ${staff}) ends at ${lastEnd}, expected ${expectedDuration}`,
378
- location: { ...location, voice, staff },
379
- details: {
380
- actualEnd: lastEnd,
381
- expectedDuration,
382
- missing: expectedDuration - lastEnd
383
- }
384
- });
385
- }
386
- }
387
- return errors;
388
- }
389
- function validateBackupForward(measure, location) {
390
- const errors = [];
391
- let position = 0;
392
- let minPosition = 0;
393
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
394
- const entry = measure.entries[entryIndex];
395
- if (entry.type === "note") {
396
- if (!entry.chord) {
397
- position += entry.duration;
398
- }
399
- } else if (entry.type === "backup") {
400
- const newPosition = position - entry.duration;
401
- if (newPosition < 0) {
402
- errors.push({
403
- code: "BACKUP_EXCEEDS_POSITION",
404
- level: "error",
405
- message: `Backup of ${entry.duration} at position ${position} results in negative position ${newPosition}`,
406
- location: { ...location, entryIndex },
407
- details: {
408
- backupDuration: entry.duration,
409
- positionBefore: position,
410
- positionAfter: newPosition
411
- }
412
- });
413
- }
414
- position = newPosition;
415
- minPosition = Math.min(minPosition, position);
416
- } else if (entry.type === "forward") {
417
- position += entry.duration;
418
- }
419
- }
420
- if (minPosition < 0) {
421
- errors.push({
422
- code: "NEGATIVE_POSITION",
423
- level: "error",
424
- message: `Position went negative (min: ${minPosition}) in measure`,
425
- location,
426
- details: { minPosition }
427
- });
428
- }
429
- return errors;
430
- }
431
- function validateTies(measure, location) {
432
- const errors = [];
433
- const openTies = /* @__PURE__ */ new Map();
434
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
435
- const entry = measure.entries[entryIndex];
436
- if (entry.type !== "note" || !entry.pitch) continue;
437
- const pitchKey = `${entry.pitch.step}${entry.pitch.octave}${_nullishCoalesce(entry.pitch.alter, () => ( 0))}-${entry.voice}-${_nullishCoalesce(entry.staff, () => ( 1))}`;
438
- const ties = _nullishCoalesce(entry.ties, () => ( (entry.tie ? [entry.tie] : [])));
439
- for (const tie of ties) {
440
- if (tie.type === "start") {
441
- if (openTies.has(pitchKey)) {
442
- }
443
- openTies.set(pitchKey, { entryIndex, pitch: entry.pitch });
444
- } else if (tie.type === "stop") {
445
- if (!openTies.has(pitchKey)) {
446
- errors.push({
447
- code: "TIE_STOP_WITHOUT_START",
448
- level: "warning",
449
- message: `Tie stop without matching start for ${entry.pitch.step}${entry.pitch.octave}`,
450
- location: { ...location, entryIndex, voice: entry.voice, staff: _nullishCoalesce(entry.staff, () => ( 1)) },
451
- details: { pitch: entry.pitch }
452
- });
453
- } else {
454
- openTies.delete(pitchKey);
455
- }
456
- }
457
- }
458
- }
459
- return errors;
460
- }
461
- function validateBeams(measure, location) {
462
- const errors = [];
463
- const openBeams = /* @__PURE__ */ new Map();
464
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
465
- const entry = measure.entries[entryIndex];
466
- if (entry.type !== "note" || !entry.beam) continue;
467
- for (const beam of entry.beam) {
468
- const beamKey = `${beam.number}-${entry.voice}`;
469
- if (beam.type === "begin") {
470
- if (openBeams.has(beamKey)) {
471
- errors.push({
472
- code: "BEAM_BEGIN_WITHOUT_END",
473
- level: "error",
474
- message: `Beam ${beam.number} started again before previous beam ended`,
475
- location: { ...location, entryIndex, voice: entry.voice, staff: _nullishCoalesce(entry.staff, () => ( 1)) },
476
- details: { beamNumber: beam.number }
477
- });
478
- }
479
- openBeams.set(beamKey, { entryIndex, staff: _nullishCoalesce(entry.staff, () => ( 1)) });
480
- } else if (beam.type === "end") {
481
- if (!openBeams.has(beamKey)) {
482
- errors.push({
483
- code: "BEAM_END_WITHOUT_BEGIN",
484
- level: "error",
485
- message: `Beam ${beam.number} end without matching begin`,
486
- location: { ...location, entryIndex, voice: entry.voice, staff: _nullishCoalesce(entry.staff, () => ( 1)) },
487
- details: { beamNumber: beam.number }
488
- });
489
- } else {
490
- openBeams.delete(beamKey);
491
- }
492
- }
493
- }
494
- }
495
- for (const [beamKey, { entryIndex: startIndex, staff }] of openBeams.entries()) {
496
- const beamDashIndex = beamKey.indexOf("-");
497
- const beamNumber = Number(beamKey.slice(0, beamDashIndex));
498
- const voice = beamKey.slice(beamDashIndex + 1);
499
- errors.push({
500
- code: "BEAM_BEGIN_WITHOUT_END",
501
- level: "error",
502
- message: `Beam ${beamNumber} started but never ended in measure`,
503
- location: { ...location, entryIndex: startIndex, voice, staff },
504
- details: { beamNumber }
505
- });
506
- }
507
- return errors;
508
- }
509
- function validateSlurs(measure, _location) {
510
- const errors = [];
511
- const openSlurs = /* @__PURE__ */ new Map();
512
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
513
- const entry = measure.entries[entryIndex];
514
- if (entry.type !== "note" || !entry.notations) continue;
515
- for (const notation of entry.notations) {
516
- if (notation.type !== "slur") continue;
517
- const slurNumber = _nullishCoalesce(notation.number, () => ( 1));
518
- const slurKey = `${slurNumber}-${entry.voice}-${_nullishCoalesce(entry.staff, () => ( 1))}`;
519
- if (notation.slurType === "start") {
520
- if (openSlurs.has(slurKey)) {
521
- }
522
- openSlurs.set(slurKey, entryIndex);
523
- } else if (notation.slurType === "stop") {
524
- if (!openSlurs.has(slurKey)) {
525
- } else {
526
- openSlurs.delete(slurKey);
527
- }
528
- }
529
- }
530
- }
531
- return errors;
532
- }
533
- function validateTuplets(measure, location) {
534
- const errors = [];
535
- const openTuplets = /* @__PURE__ */ new Map();
536
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
537
- const entry = measure.entries[entryIndex];
538
- if (entry.type !== "note" || !entry.notations) continue;
539
- for (const notation of entry.notations) {
540
- if (notation.type !== "tuplet") continue;
541
- const tupletNumber = _nullishCoalesce(notation.number, () => ( 1));
542
- const tupletKey = `${tupletNumber}-${entry.voice}-${_nullishCoalesce(entry.staff, () => ( 1))}`;
543
- if (notation.tupletType === "start") {
544
- if (openTuplets.has(tupletKey)) {
545
- errors.push({
546
- code: "TUPLET_START_WITHOUT_STOP",
547
- level: "error",
548
- message: `Tuplet ${tupletNumber} started again before previous tuplet ended`,
549
- location: { ...location, entryIndex, voice: entry.voice, staff: _nullishCoalesce(entry.staff, () => ( 1)) },
550
- details: { tupletNumber }
551
- });
552
- }
553
- openTuplets.set(tupletKey, entryIndex);
554
- } else if (notation.tupletType === "stop") {
555
- if (!openTuplets.has(tupletKey)) {
556
- errors.push({
557
- code: "TUPLET_STOP_WITHOUT_START",
558
- level: "error",
559
- message: `Tuplet ${tupletNumber} stop without matching start`,
560
- location: { ...location, entryIndex, voice: entry.voice, staff: _nullishCoalesce(entry.staff, () => ( 1)) },
561
- details: { tupletNumber }
562
- });
563
- } else {
564
- openTuplets.delete(tupletKey);
565
- }
566
- }
567
- }
568
- }
569
- for (const [tupletKey, startIndex] of openTuplets.entries()) {
570
- const firstDash = tupletKey.indexOf("-");
571
- const lastDash = tupletKey.lastIndexOf("-");
572
- const tupletNumber = Number(tupletKey.slice(0, firstDash));
573
- const voice = tupletKey.slice(firstDash + 1, lastDash);
574
- const staff = Number(tupletKey.slice(lastDash + 1));
575
- errors.push({
576
- code: "TUPLET_START_WITHOUT_STOP",
577
- level: "error",
578
- message: `Tuplet ${tupletNumber} started but never ended in measure`,
579
- location: { ...location, entryIndex: startIndex, voice, staff },
580
- details: { tupletNumber }
581
- });
582
- }
583
- return errors;
584
- }
585
- function validatePartReferences(score) {
586
- const errors = [];
587
- const partListIds = /* @__PURE__ */ new Set();
588
- for (const entry of score.partList) {
589
- if (entry.type === "score-part") {
590
- partListIds.add(entry.id);
591
- }
592
- }
593
- const partIds = /* @__PURE__ */ new Set();
594
- for (const part of score.parts) {
595
- partIds.add(part.id);
596
- }
597
- for (let partIndex = 0; partIndex < score.parts.length; partIndex++) {
598
- const part = score.parts[partIndex];
599
- if (!partListIds.has(part.id)) {
600
- errors.push({
601
- code: "PART_ID_NOT_IN_PART_LIST",
602
- level: "error",
603
- message: `Part "${part.id}" is not defined in partList`,
604
- location: { partIndex, partId: part.id }
605
- });
606
- }
607
- }
608
- for (const entry of score.partList) {
609
- if (entry.type === "score-part" && !partIds.has(entry.id)) {
610
- errors.push({
611
- code: "PART_LIST_ID_NOT_IN_PARTS",
612
- level: "error",
613
- message: `PartList entry "${entry.id}" has no corresponding part`,
614
- location: { partId: entry.id }
615
- });
616
- }
617
- }
618
- return errors;
619
- }
620
- function validateVoiceStaff(measure, staves, location) {
621
- const errors = [];
622
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
623
- const entry = measure.entries[entryIndex];
624
- if (entry.type !== "note") continue;
625
- if (entry.voice !== void 0 && entry.voice.trim() === "") {
626
- errors.push({
627
- code: "INVALID_VOICE_NUMBER",
628
- level: "error",
629
- message: `Invalid voice: empty string.`,
630
- location: { ...location, entryIndex, voice: entry.voice }
631
- });
632
- }
633
- const staff = _nullishCoalesce(entry.staff, () => ( 1));
634
- if (staff <= 0) {
635
- errors.push({
636
- code: "INVALID_STAFF_NUMBER",
637
- level: "error",
638
- message: `Invalid staff number: ${staff}. Must be positive.`,
639
- location: { ...location, entryIndex, staff }
640
- });
641
- } else if (staff > staves) {
642
- errors.push({
643
- code: "STAFF_EXCEEDS_STAVES",
644
- level: "error",
645
- message: `Staff number ${staff} exceeds declared staves count ${staves}`,
646
- location: { ...location, entryIndex, staff },
647
- details: { declaredStaves: staves }
648
- });
649
- }
650
- if (entry.duration < 0) {
651
- errors.push({
652
- code: "INVALID_DURATION",
653
- level: "error",
654
- message: `Invalid duration: ${entry.duration}. Must be non-negative.`,
655
- location: { ...location, entryIndex },
656
- details: { duration: entry.duration }
657
- });
658
- }
659
- }
660
- return errors;
661
- }
662
- function validatePartStructure(score) {
663
- const errors = [];
664
- if (score.parts.length === 0) {
665
- return errors;
666
- }
667
- const partIds = /* @__PURE__ */ new Map();
668
- for (let partIndex = 0; partIndex < score.parts.length; partIndex++) {
669
- const part = score.parts[partIndex];
670
- if (partIds.has(part.id)) {
671
- errors.push({
672
- code: "DUPLICATE_PART_ID",
673
- level: "error",
674
- message: `Duplicate part ID "${part.id}" found at index ${partIndex} (first at index ${partIds.get(part.id)})`,
675
- location: { partIndex, partId: part.id },
676
- details: { firstIndex: partIds.get(part.id) }
677
- });
678
- } else {
679
- partIds.set(part.id, partIndex);
680
- }
681
- }
682
- const referencePart = score.parts[0];
683
- const referenceMeasureCount = referencePart.measures.length;
684
- for (let partIndex = 1; partIndex < score.parts.length; partIndex++) {
685
- const part = score.parts[partIndex];
686
- if (part.measures.length !== referenceMeasureCount) {
687
- errors.push({
688
- code: "PART_MEASURE_COUNT_MISMATCH",
689
- level: "error",
690
- message: `Part "${part.id}" has ${part.measures.length} measures, expected ${referenceMeasureCount} (same as first part)`,
691
- location: { partIndex, partId: part.id },
692
- details: {
693
- expected: referenceMeasureCount,
694
- actual: part.measures.length
695
- }
696
- });
697
- }
698
- const minLength = Math.min(part.measures.length, referenceMeasureCount);
699
- for (let measureIndex = 0; measureIndex < minLength; measureIndex++) {
700
- const refMeasure = referencePart.measures[measureIndex];
701
- const partMeasure = part.measures[measureIndex];
702
- if (refMeasure.number !== partMeasure.number) {
703
- errors.push({
704
- code: "PART_MEASURE_NUMBER_MISMATCH",
705
- level: "warning",
706
- message: `Part "${part.id}" measure at index ${measureIndex} has number "${partMeasure.number}", expected "${refMeasure.number}"`,
707
- location: {
708
- partIndex,
709
- partId: part.id,
710
- measureIndex,
711
- measureNumber: partMeasure.number
712
- },
713
- details: {
714
- expected: refMeasure.number,
715
- actual: partMeasure.number
716
- }
717
- });
718
- }
719
- }
720
- }
721
- const openGroups = /* @__PURE__ */ new Map();
722
- for (let i = 0; i < score.partList.length; i++) {
723
- const entry = score.partList[i];
724
- if (entry.type !== "part-group") continue;
725
- const groupNumber = _nullishCoalesce(entry.number, () => ( 1));
726
- if (entry.groupType === "start") {
727
- if (openGroups.has(groupNumber)) {
728
- errors.push({
729
- code: "PART_GROUP_START_WITHOUT_STOP",
730
- level: "error",
731
- message: `Part group ${groupNumber} started again at index ${i} before previous group ended`,
732
- location: {},
733
- details: { groupNumber, partListIndex: i }
734
- });
735
- }
736
- openGroups.set(groupNumber, i);
737
- } else if (entry.groupType === "stop") {
738
- if (!openGroups.has(groupNumber)) {
739
- errors.push({
740
- code: "PART_GROUP_STOP_WITHOUT_START",
741
- level: "error",
742
- message: `Part group ${groupNumber} stop at index ${i} without matching start`,
743
- location: {},
744
- details: { groupNumber, partListIndex: i }
745
- });
746
- } else {
747
- openGroups.delete(groupNumber);
748
- }
749
- }
750
- }
751
- for (const [groupNumber, startIndex] of openGroups.entries()) {
752
- errors.push({
753
- code: "PART_GROUP_START_WITHOUT_STOP",
754
- level: "error",
755
- message: `Part group ${groupNumber} started at index ${startIndex} but never stopped`,
756
- location: {},
757
- details: { groupNumber, partListIndex: startIndex }
758
- });
759
- }
760
- return errors;
761
- }
762
- function validateStaffStructure(part, partIndex) {
763
- const errors = [];
764
- let currentStaves = void 0;
765
- let stavesDeclarationMeasure = void 0;
766
- const clefsDeclaredForStaves = /* @__PURE__ */ new Set();
767
- for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
768
- const measure = part.measures[measureIndex];
769
- const location = {
770
- partIndex,
771
- partId: part.id,
772
- measureIndex,
773
- measureNumber: measure.number
774
- };
775
- if (_optionalChain([measure, 'access', _3 => _3.attributes, 'optionalAccess', _4 => _4.staves]) !== void 0) {
776
- const newStaves = measure.attributes.staves;
777
- if (currentStaves !== void 0 && newStaves !== currentStaves) {
778
- errors.push({
779
- code: "STAVES_DECLARATION_MISMATCH",
780
- level: "info",
781
- message: `Staves count changed from ${currentStaves} to ${newStaves}`,
782
- location,
783
- details: {
784
- previous: currentStaves,
785
- new: newStaves,
786
- previousMeasure: stavesDeclarationMeasure
787
- }
788
- });
789
- clefsDeclaredForStaves.clear();
790
- }
791
- currentStaves = newStaves;
792
- stavesDeclarationMeasure = measure.number;
793
- }
794
- if (_optionalChain([measure, 'access', _5 => _5.attributes, 'optionalAccess', _6 => _6.clef])) {
795
- for (const clef of measure.attributes.clef) {
796
- const staffNum = _nullishCoalesce(clef.staff, () => ( 1));
797
- clefsDeclaredForStaves.add(staffNum);
798
- if (currentStaves !== void 0 && staffNum > currentStaves) {
799
- errors.push({
800
- code: "CLEF_STAFF_EXCEEDS_STAVES",
801
- level: "error",
802
- message: `Clef declared for staff ${staffNum}, but only ${currentStaves} staves declared`,
803
- location,
804
- details: {
805
- clefStaff: staffNum,
806
- declaredStaves: currentStaves
807
- }
808
- });
809
- }
810
- }
811
- }
812
- if (currentStaves !== void 0) {
813
- const usedStaves = /* @__PURE__ */ new Set();
814
- for (const entry of measure.entries) {
815
- if (entry.type === "note") {
816
- usedStaves.add(_nullishCoalesce(entry.staff, () => ( 1)));
817
- } else if (entry.type === "forward" && entry.staff) {
818
- usedStaves.add(entry.staff);
819
- }
820
- }
821
- for (const usedStaff of usedStaves) {
822
- if (usedStaff > currentStaves) {
823
- }
824
- }
825
- }
826
- }
827
- if (currentStaves !== void 0 && currentStaves > 1) {
828
- for (let staff = 1; staff <= currentStaves; staff++) {
829
- if (!clefsDeclaredForStaves.has(staff)) {
830
- errors.push({
831
- code: "MISSING_CLEF_FOR_STAFF",
832
- level: "warning",
833
- message: `No clef declared for staff ${staff} in part "${part.id}"`,
834
- location: { partIndex, partId: part.id },
835
- details: { staff, totalStaves: currentStaves }
836
- });
837
- }
838
- }
839
- }
840
- const allUsedStaves = /* @__PURE__ */ new Set();
841
- for (const measure of part.measures) {
842
- for (const entry of measure.entries) {
843
- if (entry.type === "note" && entry.staff !== void 0) {
844
- allUsedStaves.add(entry.staff);
845
- }
846
- }
847
- }
848
- if (allUsedStaves.size > 1 && currentStaves === void 0) {
849
- errors.push({
850
- code: "MISSING_STAVES_DECLARATION",
851
- level: "warning",
852
- message: `Part "${part.id}" uses staff numbers ${Array.from(allUsedStaves).sort().join(", ")} but has no staves declaration`,
853
- location: { partIndex, partId: part.id },
854
- details: { usedStaves: Array.from(allUsedStaves).sort() }
855
- });
856
- }
857
- return errors;
858
- }
859
- var DEFAULT_LOCAL_OPTIONS = {
860
- checkMeasureDuration: true,
861
- checkMeasureFullness: false,
862
- // Piano Roll semantics - opt-in
863
- checkPosition: true,
864
- checkBeams: true,
865
- checkTuplets: true,
866
- checkVoiceStaff: true,
867
- durationTolerance: 0
868
- };
869
- function validateMeasureLocal(measure, context, options = {}) {
870
- const opts = { ...DEFAULT_LOCAL_OPTIONS, ...options };
871
- const errors = [];
872
- const location = {
873
- partIndex: context.partIndex,
874
- partId: context.partId,
875
- measureIndex: context.measureIndex,
876
- measureNumber: measure.number
877
- };
878
- if (opts.checkMeasureDuration && context.time) {
879
- errors.push(...validateMeasureDuration(
880
- measure,
881
- context.divisions,
882
- context.time,
883
- location,
884
- opts.durationTolerance
885
- ));
886
- }
887
- if (opts.checkMeasureFullness && context.time) {
888
- errors.push(...validateMeasureFullness(
889
- measure,
890
- context.divisions,
891
- context.time,
892
- location
893
- ));
894
- }
895
- if (opts.checkPosition) {
896
- errors.push(...validateBackupForward(measure, location));
897
- }
898
- if (opts.checkBeams) {
899
- errors.push(...validateBeams(measure, location));
900
- }
901
- if (opts.checkTuplets) {
902
- errors.push(...validateTuplets(measure, location));
903
- }
904
- if (opts.checkVoiceStaff) {
905
- errors.push(...validateVoiceStaff(measure, context.staves, location));
906
- }
907
- return errors;
908
- }
909
- function getMeasureContext(score, partIndex, measureIndex) {
910
- const part = score.parts[partIndex];
911
- if (!part) {
912
- throw new Error(`Part index ${partIndex} out of bounds`);
913
- }
914
- let divisions = 1;
915
- let time;
916
- let staves = 1;
917
- for (let i = 0; i <= measureIndex && i < part.measures.length; i++) {
918
- const measure = part.measures[i];
919
- if (measure.attributes) {
920
- if (measure.attributes.divisions !== void 0) {
921
- divisions = measure.attributes.divisions;
922
- }
923
- if (measure.attributes.time !== void 0) {
924
- time = measure.attributes.time;
925
- }
926
- if (measure.attributes.staves !== void 0) {
927
- staves = measure.attributes.staves;
928
- }
929
- }
930
- for (const entry of measure.entries) {
931
- if (entry.type === "attributes") {
932
- if (entry.attributes.divisions !== void 0) {
933
- divisions = entry.attributes.divisions;
934
- }
935
- if (entry.attributes.time !== void 0) {
936
- time = entry.attributes.time;
937
- }
938
- if (entry.attributes.staves !== void 0) {
939
- staves = entry.attributes.staves;
940
- }
941
- }
942
- }
943
- }
944
- return {
945
- divisions,
946
- time,
947
- staves,
948
- partIndex,
949
- partId: part.id,
950
- measureIndex
951
- };
952
- }
953
- function assertMeasureValid(score, partIndex, measureIndex, options) {
954
- const part = score.parts[partIndex];
955
- if (!part) {
956
- throw new Error(`Part index ${partIndex} out of bounds`);
957
- }
958
- const measure = part.measures[measureIndex];
959
- if (!measure) {
960
- throw new Error(`Measure index ${measureIndex} out of bounds`);
961
- }
962
- const context = getMeasureContext(score, partIndex, measureIndex);
963
- const errors = validateMeasureLocal(measure, context, options);
964
- const criticalErrors = errors.filter((e) => e.level === "error");
965
- if (criticalErrors.length > 0) {
966
- const errorMessages = criticalErrors.map((e) => `[${e.code}] ${e.message}`).join("\n");
967
- throw new ValidationException(criticalErrors, errorMessages);
968
- }
969
- }
970
- function isValid(score, options) {
971
- return validate(score, options).valid;
972
- }
973
- function assertValid(score, options) {
974
- const result = validate(score, options);
975
- if (!result.valid) {
976
- const errorMessages = result.errors.map(
977
- (e) => `[${e.code}] ${e.message} at ${formatLocation(e.location)}`
978
- ).join("\n");
979
- throw new ValidationException(result.errors, errorMessages);
980
- }
981
- }
982
- function formatLocation(location) {
983
- const parts = [];
984
- if (location.partId !== void 0) {
985
- parts.push(`part=${location.partId}`);
986
- } else if (location.partIndex !== void 0) {
987
- parts.push(`part[${location.partIndex}]`);
988
- }
989
- if (location.measureNumber !== void 0) {
990
- parts.push(`measure=${location.measureNumber}`);
991
- } else if (location.measureIndex !== void 0) {
992
- parts.push(`measure[${location.measureIndex}]`);
993
- }
994
- if (location.entryIndex !== void 0) {
995
- parts.push(`entry[${location.entryIndex}]`);
996
- }
997
- if (location.voice !== void 0) {
998
- parts.push(`voice=${location.voice}`);
999
- }
1000
- if (location.staff !== void 0) {
1001
- parts.push(`staff=${location.staff}`);
1002
- }
1003
- return parts.join(", ");
1004
- }
1005
- var ValidationException = class extends Error {
1006
- constructor(errors, message) {
1007
- super(message);
1008
- this.errors = errors;
1009
- this.name = "ValidationException";
1010
- }
1011
- };
1012
- function validateTiesAcrossMeasures(part) {
1013
- const errors = [];
1014
- const openTies = /* @__PURE__ */ new Map();
1015
- for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
1016
- const measure = part.measures[measureIndex];
1017
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
1018
- const entry = measure.entries[entryIndex];
1019
- if (entry.type !== "note" || !entry.pitch) continue;
1020
- const pitchKey = `${entry.pitch.step}${entry.pitch.octave}${_nullishCoalesce(entry.pitch.alter, () => ( 0))}-${entry.voice}-${_nullishCoalesce(entry.staff, () => ( 1))}`;
1021
- const ties = _nullishCoalesce(entry.ties, () => ( (entry.tie ? [entry.tie] : [])));
1022
- for (const tie of ties) {
1023
- if (tie.type === "start") {
1024
- openTies.set(pitchKey, { measureIndex, entryIndex, pitch: entry.pitch });
1025
- } else if (tie.type === "stop") {
1026
- if (!openTies.has(pitchKey)) {
1027
- errors.push({
1028
- code: "TIE_STOP_WITHOUT_START",
1029
- level: "error",
1030
- message: `Tie stop without matching start for ${entry.pitch.step}${entry.pitch.octave}`,
1031
- location: {
1032
- measureIndex,
1033
- measureNumber: measure.number,
1034
- entryIndex,
1035
- voice: entry.voice,
1036
- staff: _nullishCoalesce(entry.staff, () => ( 1))
1037
- },
1038
- details: { pitch: entry.pitch }
1039
- });
1040
- } else {
1041
- openTies.delete(pitchKey);
1042
- }
1043
- }
1044
- }
1045
- }
1046
- }
1047
- for (const [, { measureIndex, entryIndex, pitch }] of openTies.entries()) {
1048
- const measure = part.measures[measureIndex];
1049
- errors.push({
1050
- code: "TIE_START_WITHOUT_STOP",
1051
- level: "warning",
1052
- message: `Tie started for ${pitch.step}${pitch.octave} but never stopped`,
1053
- location: {
1054
- measureIndex,
1055
- measureNumber: measure.number,
1056
- entryIndex
1057
- },
1058
- details: { pitch }
1059
- });
1060
- }
1061
- return errors;
1062
- }
1063
- function validateSlursAcrossMeasures(part) {
1064
- const errors = [];
1065
- const openSlurs = /* @__PURE__ */ new Map();
1066
- for (let measureIndex = 0; measureIndex < part.measures.length; measureIndex++) {
1067
- const measure = part.measures[measureIndex];
1068
- for (let entryIndex = 0; entryIndex < measure.entries.length; entryIndex++) {
1069
- const entry = measure.entries[entryIndex];
1070
- if (entry.type !== "note" || !entry.notations) continue;
1071
- for (const notation of entry.notations) {
1072
- if (notation.type !== "slur") continue;
1073
- const slurNumber = _nullishCoalesce(notation.number, () => ( 1));
1074
- const slurKey = `${slurNumber}-${entry.voice}-${_nullishCoalesce(entry.staff, () => ( 1))}`;
1075
- if (notation.slurType === "start") {
1076
- openSlurs.set(slurKey, { measureIndex, entryIndex });
1077
- } else if (notation.slurType === "stop") {
1078
- if (!openSlurs.has(slurKey)) {
1079
- errors.push({
1080
- code: "SLUR_STOP_WITHOUT_START",
1081
- level: "error",
1082
- message: `Slur ${slurNumber} stop without matching start`,
1083
- location: {
1084
- measureIndex,
1085
- measureNumber: measure.number,
1086
- entryIndex,
1087
- voice: entry.voice,
1088
- staff: _nullishCoalesce(entry.staff, () => ( 1))
1089
- },
1090
- details: { slurNumber }
1091
- });
1092
- } else {
1093
- openSlurs.delete(slurKey);
1094
- }
1095
- }
1096
- }
1097
- }
1098
- }
1099
- for (const [slurKey, { measureIndex, entryIndex }] of openSlurs.entries()) {
1100
- const firstDash = slurKey.indexOf("-");
1101
- const lastDash = slurKey.lastIndexOf("-");
1102
- const slurNumber = Number(slurKey.slice(0, firstDash));
1103
- const voice = slurKey.slice(firstDash + 1, lastDash);
1104
- const staff = Number(slurKey.slice(lastDash + 1));
1105
- const measure = part.measures[measureIndex];
1106
- errors.push({
1107
- code: "SLUR_START_WITHOUT_STOP",
1108
- level: "warning",
1109
- message: `Slur ${slurNumber} started but never stopped`,
1110
- location: {
1111
- measureIndex,
1112
- measureNumber: measure.number,
1113
- entryIndex,
1114
- voice,
1115
- staff
1116
- },
1117
- details: { slurNumber }
1118
- });
1119
- }
1120
- return errors;
1121
- }
14
+
15
+ var _chunk776XPK66js = require('./chunk-776XPK66.js');
16
+
17
+
18
+
19
+
20
+ var _chunkJF5TM534js = require('./chunk-JF5TM534.js');
21
+
22
+
23
+ var _chunk5EK7K5X3js = require('./chunk-5EK7K5X3.js');
1122
24
 
1123
25
  // src/operations/index.ts
1124
26
  function success(data, warnings) {
@@ -1167,29 +69,29 @@ function cloneScoreAt(score, partIndex, ...measureIndices) {
1167
69
  }
1168
70
  function cloneNoteWithNewId(note) {
1169
71
  const cloned = deepClone(note);
1170
- cloned._id = generateId();
72
+ cloned._id = _chunk5EK7K5X3js.generateId.call(void 0, );
1171
73
  return cloned;
1172
74
  }
1173
75
  function cloneEntryWithNewId(entry) {
1174
76
  const cloned = deepClone(entry);
1175
- cloned._id = generateId();
77
+ cloned._id = _chunk5EK7K5X3js.generateId.call(void 0, );
1176
78
  return cloned;
1177
79
  }
1178
80
  function cloneMeasureWithNewIds(measure) {
1179
81
  const cloned = deepClone(measure);
1180
- cloned._id = generateId();
82
+ cloned._id = _chunk5EK7K5X3js.generateId.call(void 0, );
1181
83
  cloned.entries = cloned.entries.map((entry) => cloneEntryWithNewId(entry));
1182
84
  if (cloned.barlines) {
1183
85
  cloned.barlines = cloned.barlines.map((barline) => ({
1184
86
  ...barline,
1185
- _id: generateId()
87
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, )
1186
88
  }));
1187
89
  }
1188
90
  return cloned;
1189
91
  }
1190
92
  function clonePartWithNewIds(part) {
1191
93
  const cloned = deepClone(part);
1192
- cloned._id = generateId();
94
+ cloned._id = _chunk5EK7K5X3js.generateId.call(void 0, );
1193
95
  cloned.measures = cloned.measures.map((measure) => cloneMeasureWithNewIds(measure));
1194
96
  return cloned;
1195
97
  }
@@ -1255,7 +157,7 @@ function hasNotesInRange(voiceEntries, startPos, endPos) {
1255
157
  }
1256
158
  function createRest(duration, voice, staff) {
1257
159
  const note = {
1258
- _id: generateId(),
160
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
1259
161
  type: "note",
1260
162
  rest: { displayStep: void 0, displayOctave: void 0 },
1261
163
  duration,
@@ -1320,11 +222,11 @@ function rebuildMeasureWithVoice(measure, voice, newEntries, measureDuration, st
1320
222
  for (const { position: targetPos, entry } of allEntries) {
1321
223
  const diff = targetPos - currentPosition;
1322
224
  if (diff < 0) {
1323
- result.push({ _id: generateId(), type: "backup", duration: -diff });
225
+ result.push({ _id: _chunk5EK7K5X3js.generateId.call(void 0, ), type: "backup", duration: -diff });
1324
226
  currentPosition = targetPos;
1325
227
  } else if (diff > 0) {
1326
228
  result.push({
1327
- _id: generateId(),
229
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
1328
230
  type: "forward",
1329
231
  duration: diff,
1330
232
  voice: entry.type === "note" ? entry.voice : "1",
@@ -1357,7 +259,7 @@ function insertNote(score, options) {
1357
259
  }
1358
260
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
1359
261
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
1360
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
262
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
1361
263
  const measureDuration = context.time ? getMeasureDuration(context.divisions, context.time) : context.divisions * 4;
1362
264
  const noteEnd = options.position + options.duration;
1363
265
  if (noteEnd > measureDuration) {
@@ -1379,7 +281,7 @@ function insertNote(score, options) {
1379
281
  )]);
1380
282
  }
1381
283
  const newNote = {
1382
- _id: generateId(),
284
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
1383
285
  type: "note",
1384
286
  pitch: options.pitch,
1385
287
  duration: options.duration,
@@ -1404,7 +306,7 @@ function insertNote(score, options) {
1404
306
  measureDuration,
1405
307
  options.staff
1406
308
  );
1407
- const errors = validateMeasureLocal(measure, context, {
309
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, {
1408
310
  checkMeasureDuration: true,
1409
311
  checkPosition: true,
1410
312
  checkVoiceStaff: true
@@ -1486,7 +388,7 @@ function addChord(score, options) {
1486
388
  return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} not found`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
1487
389
  }
1488
390
  const chordNote = {
1489
- _id: generateId(),
391
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
1490
392
  type: "note",
1491
393
  pitch: options.pitch,
1492
394
  duration: targetEntry.duration,
@@ -1521,7 +423,7 @@ function changeNoteDuration(score, options) {
1521
423
  }
1522
424
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
1523
425
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
1524
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
426
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
1525
427
  const measureDuration = context.time ? getMeasureDuration(context.divisions, context.time) : context.divisions * 4;
1526
428
  let noteCount = 0;
1527
429
  let targetEntry = null;
@@ -1604,7 +506,7 @@ function changeNoteDuration(score, options) {
1604
506
  measureDuration,
1605
507
  targetEntry.staff
1606
508
  );
1607
- const errors = validateMeasureLocal(measure, context, {
509
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, {
1608
510
  checkMeasureDuration: true,
1609
511
  checkPosition: true,
1610
512
  checkVoiceStaff: true
@@ -1648,18 +550,18 @@ function setNotePitchBySemitone(score, options) {
1648
550
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
1649
551
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
1650
552
  const measureNumber = _nullishCoalesce(measure.number, () => ( String(options.measureIndex + 1)));
1651
- const attrs = _chunkEWLB5X64js.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
553
+ const attrs = _chunkPMPROVJWjs.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
1652
554
  const keySignature = _nullishCoalesce(attrs.key, () => ( { fifths: 0 }));
1653
555
  let noteCount = 0;
1654
556
  for (const entry of measure.entries) {
1655
557
  if (entry.type === "note" && !entry.rest) {
1656
558
  if (noteCount === options.noteIndex) {
1657
- const notePosition = _chunkEWLB5X64js.getAbsolutePositionForNote.call(void 0, entry, measure);
1658
- const accidentalsInMeasure = _chunkEWLB5X64js.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
1659
- const newPitch = _chunkEWLB5X64js.semitoneToKeyAwarePitch.call(void 0, options.semitone, keySignature, {
559
+ const notePosition = _chunkPMPROVJWjs.getAbsolutePositionForNote.call(void 0, entry, measure);
560
+ const accidentalsInMeasure = _chunkPMPROVJWjs.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
561
+ const newPitch = _chunkPMPROVJWjs.semitoneToKeyAwarePitch.call(void 0, options.semitone, keySignature, {
1660
562
  preferSharp: options.preferSharp
1661
563
  });
1662
- const accidental = _chunkEWLB5X64js.determineAccidental.call(void 0, newPitch, keySignature, accidentalsInMeasure);
564
+ const accidental = _chunkPMPROVJWjs.determineAccidental.call(void 0, newPitch, keySignature, accidentalsInMeasure);
1663
565
  entry.pitch = newPitch;
1664
566
  if (accidental) {
1665
567
  entry.accidental = { value: accidental };
@@ -1693,7 +595,7 @@ function shiftNotePitch(score, options) {
1693
595
  if (!entry.pitch) {
1694
596
  return failure([operationError("NOTE_NOT_FOUND", "Note has no pitch", { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
1695
597
  }
1696
- currentSemitone = _chunkEWLB5X64js.pitchToSemitone.call(void 0, entry.pitch);
598
+ currentSemitone = _chunkPMPROVJWjs.pitchToSemitone.call(void 0, entry.pitch);
1697
599
  break;
1698
600
  }
1699
601
  noteCount++;
@@ -1721,7 +623,7 @@ function raiseAccidental(score, options) {
1721
623
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
1722
624
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
1723
625
  const measureNumber = _nullishCoalesce(measure.number, () => ( String(options.measureIndex + 1)));
1724
- const attrs = _chunkEWLB5X64js.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
626
+ const attrs = _chunkPMPROVJWjs.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
1725
627
  const keySignature = _nullishCoalesce(attrs.key, () => ( { fifths: 0 }));
1726
628
  let noteCount = 0;
1727
629
  for (const entry of measure.entries) {
@@ -1736,9 +638,9 @@ function raiseAccidental(score, options) {
1736
638
  return failure([operationError("ACCIDENTAL_OUT_OF_BOUNDS", `Cannot raise accidental beyond double-sharp (current: ${currentAlter})`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
1737
639
  }
1738
640
  entry.pitch.alter = newAlter === 0 ? void 0 : newAlter;
1739
- const notePosition = _chunkEWLB5X64js.getAbsolutePositionForNote.call(void 0, entry, measure);
1740
- const accidentalsInMeasure = _chunkEWLB5X64js.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
1741
- const accidental = _chunkEWLB5X64js.determineAccidental.call(void 0, entry.pitch, keySignature, accidentalsInMeasure);
641
+ const notePosition = _chunkPMPROVJWjs.getAbsolutePositionForNote.call(void 0, entry, measure);
642
+ const accidentalsInMeasure = _chunkPMPROVJWjs.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
643
+ const accidental = _chunkPMPROVJWjs.determineAccidental.call(void 0, entry.pitch, keySignature, accidentalsInMeasure);
1742
644
  if (accidental) {
1743
645
  entry.accidental = { value: accidental };
1744
646
  } else {
@@ -1762,7 +664,7 @@ function lowerAccidental(score, options) {
1762
664
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
1763
665
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
1764
666
  const measureNumber = _nullishCoalesce(measure.number, () => ( String(options.measureIndex + 1)));
1765
- const attrs = _chunkEWLB5X64js.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
667
+ const attrs = _chunkPMPROVJWjs.getAttributesAtMeasure.call(void 0, result, { part: options.partIndex, measure: measureNumber });
1766
668
  const keySignature = _nullishCoalesce(attrs.key, () => ( { fifths: 0 }));
1767
669
  let noteCount = 0;
1768
670
  for (const entry of measure.entries) {
@@ -1777,9 +679,9 @@ function lowerAccidental(score, options) {
1777
679
  return failure([operationError("ACCIDENTAL_OUT_OF_BOUNDS", `Cannot lower accidental beyond double-flat (current: ${currentAlter})`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
1778
680
  }
1779
681
  entry.pitch.alter = newAlter === 0 ? void 0 : newAlter;
1780
- const notePosition = _chunkEWLB5X64js.getAbsolutePositionForNote.call(void 0, entry, measure);
1781
- const accidentalsInMeasure = _chunkEWLB5X64js.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
1782
- const accidental = _chunkEWLB5X64js.determineAccidental.call(void 0, entry.pitch, keySignature, accidentalsInMeasure);
682
+ const notePosition = _chunkPMPROVJWjs.getAbsolutePositionForNote.call(void 0, entry, measure);
683
+ const accidentalsInMeasure = _chunkPMPROVJWjs.getAccidentalsInMeasure.call(void 0, measure, notePosition, entry.voice);
684
+ const accidental = _chunkPMPROVJWjs.determineAccidental.call(void 0, entry.pitch, keySignature, accidentalsInMeasure);
1783
685
  if (accidental) {
1784
686
  entry.accidental = { value: accidental };
1785
687
  } else {
@@ -1810,25 +712,25 @@ function addVoice(score, options) {
1810
712
  { partIndex: options.partIndex, measureIndex: options.measureIndex, voice: options.voice }
1811
713
  )]);
1812
714
  }
1813
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
715
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
1814
716
  const measureDuration = context.time ? getMeasureDuration(context.divisions, context.time) : context.divisions * 4;
1815
717
  const rest = createRest(measureDuration, options.voice, options.staff);
1816
- const currentEnd = _chunkEWLB5X64js.getMeasureEndPosition.call(void 0, measure);
718
+ const currentEnd = _chunkPMPROVJWjs.getMeasureEndPosition.call(void 0, measure);
1817
719
  if (currentEnd > 0) {
1818
- measure.entries.push({ _id: generateId(), type: "backup", duration: currentEnd });
720
+ measure.entries.push({ _id: _chunk5EK7K5X3js.generateId.call(void 0, ), type: "backup", duration: currentEnd });
1819
721
  }
1820
722
  measure.entries.push(rest);
1821
723
  return success(result);
1822
724
  }
1823
725
  function transposePitch(pitch, semitones) {
1824
- const currentSemitone = _chunkEWLB5X64js.STEP_SEMITONES[pitch.step] + (_nullishCoalesce(pitch.alter, () => ( 0))) + pitch.octave * 12;
726
+ const currentSemitone = _chunkPMPROVJWjs.STEP_SEMITONES[pitch.step] + (_nullishCoalesce(pitch.alter, () => ( 0))) + pitch.octave * 12;
1825
727
  const targetSemitone = currentSemitone + semitones;
1826
728
  const targetOctave = Math.floor(targetSemitone / 12);
1827
729
  const targetPitchClass = (targetSemitone % 12 + 12) % 12;
1828
730
  let bestStep = "C";
1829
731
  let bestAlter = 99;
1830
- for (const step of _chunkEWLB5X64js.STEPS) {
1831
- const stepSemitone = _chunkEWLB5X64js.STEP_SEMITONES[step];
732
+ for (const step of _chunkPMPROVJWjs.STEPS) {
733
+ const stepSemitone = _chunkPMPROVJWjs.STEP_SEMITONES[step];
1832
734
  let diff = targetPitchClass - stepSemitone;
1833
735
  if (diff > 6) diff -= 12;
1834
736
  if (diff < -6) diff += 12;
@@ -1866,7 +768,7 @@ function addPart(score, options) {
1866
768
  const result = cloneScore(score);
1867
769
  const insertIndex = _nullishCoalesce(options.insertIndex, () => ( result.parts.length));
1868
770
  const partInfo = {
1869
- _id: generateId(),
771
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
1870
772
  type: "score-part",
1871
773
  id: options.id,
1872
774
  name: options.name,
@@ -1885,13 +787,13 @@ function addPart(score, options) {
1885
787
  }
1886
788
  result.partList.splice(partListInsertIndex, 0, partInfo);
1887
789
  const measureCount = result.parts.length > 0 ? result.parts[0].measures.length : 1;
1888
- const newPart = { _id: generateId(), id: options.id, measures: [] };
790
+ const newPart = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ), id: options.id, measures: [] };
1889
791
  for (let i = 0; i < measureCount; i++) {
1890
- const measureNumber = result.parts.length > 0 ? _nullishCoalesce(_optionalChain([result, 'access', _7 => _7.parts, 'access', _8 => _8[0], 'access', _9 => _9.measures, 'access', _10 => _10[i], 'optionalAccess', _11 => _11.number]), () => ( String(i + 1))) : String(i + 1);
1891
- const measure = { _id: generateId(), number: measureNumber, entries: [] };
792
+ const measureNumber = result.parts.length > 0 ? _nullishCoalesce(_optionalChain([result, 'access', _ => _.parts, 'access', _2 => _2[0], 'access', _3 => _3.measures, 'access', _4 => _4[i], 'optionalAccess', _5 => _5.number]), () => ( String(i + 1))) : String(i + 1);
793
+ const measure = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ), number: measureNumber, entries: [] };
1892
794
  if (i === 0) {
1893
795
  measure.attributes = {
1894
- _id: generateId(),
796
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
1895
797
  divisions: _nullishCoalesce(options.divisions, () => ( 4)),
1896
798
  time: _nullishCoalesce(options.time, () => ( { beats: "4", beatType: 4 })),
1897
799
  key: _nullishCoalesce(options.key, () => ( { fifths: 0 })),
@@ -1901,7 +803,7 @@ function addPart(score, options) {
1901
803
  newPart.measures.push(measure);
1902
804
  }
1903
805
  result.parts.splice(insertIndex, 0, newPart);
1904
- const validationResult = validate(result, { checkPartReferences: true, checkPartStructure: true });
806
+ const validationResult = _chunkJF5TM534js.validate.call(void 0, result, { checkPartReferences: true, checkPartStructure: true });
1905
807
  if (!validationResult.valid) {
1906
808
  return failure(validationResult.errors);
1907
809
  }
@@ -1937,11 +839,11 @@ function duplicatePart(score, options) {
1937
839
  newPart.id = options.newPartId;
1938
840
  const sourcePartInfo = result.partList.find((e) => e.type === "score-part" && e.id === options.sourcePartId);
1939
841
  const newPartInfo = {
1940
- _id: generateId(),
842
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
1941
843
  type: "score-part",
1942
844
  id: options.newPartId,
1943
- name: _nullishCoalesce(options.newPartName, () => ( _optionalChain([sourcePartInfo, 'optionalAccess', _12 => _12.name]))),
1944
- abbreviation: _optionalChain([sourcePartInfo, 'optionalAccess', _13 => _13.abbreviation])
845
+ name: _nullishCoalesce(options.newPartName, () => ( _optionalChain([sourcePartInfo, 'optionalAccess', _6 => _6.name]))),
846
+ abbreviation: _optionalChain([sourcePartInfo, 'optionalAccess', _7 => _7.abbreviation])
1945
847
  };
1946
848
  result.parts.splice(sourceIndex + 1, 0, newPart);
1947
849
  const partListSourceIndex = result.partList.findIndex((e) => e.type === "score-part" && e.id === options.sourcePartId);
@@ -1967,7 +869,7 @@ function setStaves(score, options) {
1967
869
  return failure([operationError("MEASURE_NOT_FOUND", `Measure index ${fromMeasureIndex} out of bounds`, { partIndex: options.partIndex, measureIndex: fromMeasureIndex })]);
1968
870
  }
1969
871
  if (!measure.attributes) {
1970
- measure.attributes = { _id: generateId() };
872
+ measure.attributes = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ) };
1971
873
  }
1972
874
  measure.attributes.staves = options.staves;
1973
875
  if (options.clefs) {
@@ -1980,7 +882,7 @@ function setStaves(score, options) {
1980
882
  }
1981
883
  measure.attributes.clef = newClefs;
1982
884
  }
1983
- const validationResult = validate(result, { checkVoiceStaff: true, checkStaffStructure: true });
885
+ const validationResult = _chunkJF5TM534js.validate.call(void 0, result, { checkVoiceStaff: true, checkStaffStructure: true });
1984
886
  if (!validationResult.valid) {
1985
887
  return failure(validationResult.errors);
1986
888
  }
@@ -2004,8 +906,8 @@ function moveNoteToStaff(score, options) {
2004
906
  if (entry.type === "note" && !entry.rest) {
2005
907
  if (noteCount === options.noteIndex) {
2006
908
  entry.staff = options.targetStaff;
2007
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
2008
- const errors = validateMeasureLocal(measure, context, { checkVoiceStaff: true });
909
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
910
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, { checkVoiceStaff: true });
2009
911
  const criticalErrors = errors.filter((e) => e.level === "error");
2010
912
  if (criticalErrors.length > 0) {
2011
913
  return failure(criticalErrors);
@@ -2023,7 +925,7 @@ function changeKey(score, key, options) {
2023
925
  for (const part of result.parts) {
2024
926
  for (const measure of part.measures) {
2025
927
  if (measure.number === targetMeasure) {
2026
- if (!measure.attributes) measure.attributes = { _id: generateId() };
928
+ if (!measure.attributes) measure.attributes = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ) };
2027
929
  measure.attributes.key = key;
2028
930
  }
2029
931
  }
@@ -2036,7 +938,7 @@ function changeTime(score, time, options) {
2036
938
  for (const part of result.parts) {
2037
939
  for (const measure of part.measures) {
2038
940
  if (measure.number === targetMeasure) {
2039
- if (!measure.attributes) measure.attributes = { _id: generateId() };
941
+ if (!measure.attributes) measure.attributes = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ) };
2040
942
  measure.attributes.time = time;
2041
943
  }
2042
944
  }
@@ -2051,9 +953,9 @@ function insertMeasure(score, options) {
2051
953
  if (insertIndex === -1) continue;
2052
954
  const numericPart = parseInt(targetMeasure, 10);
2053
955
  const newMeasureNumber = String(isNaN(numericPart) ? insertIndex + 2 : numericPart + 1);
2054
- const newMeasure = { _id: generateId(), number: newMeasureNumber, entries: [] };
956
+ const newMeasure = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ), number: newMeasureNumber, entries: [] };
2055
957
  if (options.copyAttributes && part.measures[insertIndex].attributes) {
2056
- newMeasure.attributes = { ...part.measures[insertIndex].attributes, _id: generateId() };
958
+ newMeasure.attributes = { ...part.measures[insertIndex].attributes, _id: _chunk5EK7K5X3js.generateId.call(void 0, ) };
2057
959
  }
2058
960
  part.measures.splice(insertIndex + 1, 0, newMeasure);
2059
961
  for (let i = insertIndex + 2; i < part.measures.length; i++) {
@@ -2127,7 +1029,7 @@ function addTie(score, options) {
2127
1029
  if (!pitchesEqual(startNote.pitch, endNote.pitch)) {
2128
1030
  return failure([operationError("TIE_PITCH_MISMATCH", "Tied notes must have the same pitch", { partIndex: options.partIndex }, { startPitch: startNote.pitch, endPitch: endNote.pitch })]);
2129
1031
  }
2130
- if (_optionalChain([startNote, 'access', _14 => _14.tie, 'optionalAccess', _15 => _15.type]) === "start" || _optionalChain([startNote, 'access', _16 => _16.tie, 'optionalAccess', _17 => _17.type]) === "continue") {
1032
+ if (_optionalChain([startNote, 'access', _8 => _8.tie, 'optionalAccess', _9 => _9.type]) === "start" || _optionalChain([startNote, 'access', _10 => _10.tie, 'optionalAccess', _11 => _11.type]) === "continue") {
2131
1033
  return failure([operationError("TIE_ALREADY_EXISTS", "Start note already has a tie start", { partIndex: options.partIndex, measureIndex: options.startMeasureIndex })]);
2132
1034
  }
2133
1035
  startNote.tie = { type: "start" };
@@ -2136,7 +1038,7 @@ function addTie(score, options) {
2136
1038
  endNote.tie = { type: "stop" };
2137
1039
  if (!endNote.notations) endNote.notations = [];
2138
1040
  endNote.notations.push({ type: "tied", tiedType: "stop" });
2139
- const validationResult = validate(result, { checkTies: true });
1041
+ const validationResult = _chunkJF5TM534js.validate.call(void 0, result, { checkTies: true });
2140
1042
  const criticalErrors = validationResult.errors.filter((e) => e.level === "error");
2141
1043
  if (criticalErrors.length > 0) {
2142
1044
  return failure(criticalErrors);
@@ -2196,7 +1098,7 @@ function addSlur(score, options) {
2196
1098
  const startNote = startResult.note;
2197
1099
  const endNote = endResult.note;
2198
1100
  const slurNumber = _nullishCoalesce(options.number, () => ( 1));
2199
- if (_optionalChain([startNote, 'access', _18 => _18.notations, 'optionalAccess', _19 => _19.some, 'call', _20 => _20((n) => n.type === "slur" && n.slurType === "start" && (_nullishCoalesce(n.number, () => ( 1))) === slurNumber)])) {
1101
+ if (_optionalChain([startNote, 'access', _12 => _12.notations, 'optionalAccess', _13 => _13.some, 'call', _14 => _14((n) => n.type === "slur" && n.slurType === "start" && (_nullishCoalesce(n.number, () => ( 1))) === slurNumber)])) {
2200
1102
  return failure([operationError("SLUR_ALREADY_EXISTS", `Slur ${slurNumber} already starts on this note`, { partIndex: options.partIndex, measureIndex: options.startMeasureIndex })]);
2201
1103
  }
2202
1104
  if (!startNote.notations) startNote.notations = [];
@@ -2212,7 +1114,7 @@ function addSlur(score, options) {
2212
1114
  slurType: "stop",
2213
1115
  number: slurNumber
2214
1116
  });
2215
- const validationResult = validate(result, { checkSlurs: true });
1117
+ const validationResult = _chunkJF5TM534js.validate.call(void 0, result, { checkSlurs: true });
2216
1118
  const criticalErrors = validationResult.errors.filter((e) => e.level === "error");
2217
1119
  if (criticalErrors.length > 0) {
2218
1120
  return failure(criticalErrors);
@@ -2235,7 +1137,7 @@ function removeSlur(score, options) {
2235
1137
  }
2236
1138
  const note = noteResult.note;
2237
1139
  const slurNumber = _nullishCoalesce(options.number, () => ( 1));
2238
- if (!_optionalChain([note, 'access', _21 => _21.notations, 'optionalAccess', _22 => _22.some, 'call', _23 => _23((n) => n.type === "slur" && (_nullishCoalesce(n.number, () => ( 1))) === slurNumber)])) {
1140
+ if (!_optionalChain([note, 'access', _15 => _15.notations, 'optionalAccess', _16 => _16.some, 'call', _17 => _17((n) => n.type === "slur" && (_nullishCoalesce(n.number, () => ( 1))) === slurNumber)])) {
2239
1141
  return failure([operationError("SLUR_NOT_FOUND", `Slur ${slurNumber} not found on this note`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
2240
1142
  }
2241
1143
  note.notations = note.notations.filter((n) => !(n.type === "slur" && (_nullishCoalesce(n.number, () => ( 1))) === slurNumber));
@@ -2259,7 +1161,7 @@ function addArticulation(score, options) {
2259
1161
  return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} not found`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
2260
1162
  }
2261
1163
  const note = noteResult.note;
2262
- if (_optionalChain([note, 'access', _24 => _24.notations, 'optionalAccess', _25 => _25.some, 'call', _26 => _26((n) => n.type === "articulation" && n.articulation === options.articulation)])) {
1164
+ if (_optionalChain([note, 'access', _18 => _18.notations, 'optionalAccess', _19 => _19.some, 'call', _20 => _20((n) => n.type === "articulation" && n.articulation === options.articulation)])) {
2263
1165
  return failure([operationError("ARTICULATION_ALREADY_EXISTS", `Articulation ${options.articulation} already exists on this note`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
2264
1166
  }
2265
1167
  if (!note.notations) note.notations = [];
@@ -2285,7 +1187,7 @@ function removeArticulation(score, options) {
2285
1187
  return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} not found`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
2286
1188
  }
2287
1189
  const note = noteResult.note;
2288
- if (!_optionalChain([note, 'access', _27 => _27.notations, 'optionalAccess', _28 => _28.some, 'call', _29 => _29((n) => n.type === "articulation" && n.articulation === options.articulation)])) {
1190
+ if (!_optionalChain([note, 'access', _21 => _21.notations, 'optionalAccess', _22 => _22.some, 'call', _23 => _23((n) => n.type === "articulation" && n.articulation === options.articulation)])) {
2289
1191
  return failure([operationError("ARTICULATION_NOT_FOUND", `Articulation ${options.articulation} not found on this note`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
2290
1192
  }
2291
1193
  note.notations = note.notations.filter((n) => !(n.type === "articulation" && n.articulation === options.articulation));
@@ -2327,7 +1229,7 @@ function addDynamics(score, options) {
2327
1229
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
2328
1230
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
2329
1231
  const directionEntry = {
2330
- _id: generateId(),
1232
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
2331
1233
  type: "direction",
2332
1234
  directionTypes: [{
2333
1235
  kind: "dynamics",
@@ -2428,7 +1330,7 @@ function insertClefChange(score, options) {
2428
1330
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
2429
1331
  if (options.position === 0) {
2430
1332
  if (!measure.attributes) {
2431
- measure.attributes = { _id: generateId() };
1333
+ measure.attributes = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ) };
2432
1334
  }
2433
1335
  const staff = _nullishCoalesce(options.clef.staff, () => ( 1));
2434
1336
  if (!measure.attributes.clef) {
@@ -2442,7 +1344,7 @@ function insertClefChange(score, options) {
2442
1344
  }
2443
1345
  } else {
2444
1346
  const attributesEntry = {
2445
- _id: generateId(),
1347
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
2446
1348
  type: "attributes",
2447
1349
  attributes: {
2448
1350
  clef: [options.clef]
@@ -2451,7 +1353,7 @@ function insertClefChange(score, options) {
2451
1353
  const insertIndex = getInsertPositionForDirection(measure, options.position);
2452
1354
  measure.entries.splice(insertIndex, 0, attributesEntry);
2453
1355
  }
2454
- const validationResult = validate(result, { checkStaffStructure: true });
1356
+ const validationResult = _chunkJF5TM534js.validate.call(void 0, result, { checkStaffStructure: true });
2455
1357
  const criticalErrors = validationResult.errors.filter((e) => e.level === "error");
2456
1358
  if (criticalErrors.length > 0) {
2457
1359
  return failure(criticalErrors);
@@ -2574,8 +1476,8 @@ function createTuplet(score, options) {
2574
1476
  });
2575
1477
  }
2576
1478
  }
2577
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
2578
- const errors = validateMeasureLocal(measure, context, {
1479
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
1480
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, {
2579
1481
  checkTuplets: true,
2580
1482
  checkMeasureDuration: true
2581
1483
  });
@@ -2625,11 +1527,11 @@ function removeTuplet(score, options) {
2625
1527
  for (const entry of measure.entries) {
2626
1528
  if (entry.type !== "note" || entry.rest) continue;
2627
1529
  if (entry.voice !== voice || entry.staff !== staff) continue;
2628
- const hasSameTimeModification = _optionalChain([entry, 'access', _30 => _30.timeModification, 'optionalAccess', _31 => _31.actualNotes]) === actualNotes && _optionalChain([entry, 'access', _32 => _32.timeModification, 'optionalAccess', _33 => _33.normalNotes]) === normalNotes;
2629
- const tupletStart = _optionalChain([entry, 'access', _34 => _34.notations, 'optionalAccess', _35 => _35.find, 'call', _36 => _36(
1530
+ const hasSameTimeModification = _optionalChain([entry, 'access', _24 => _24.timeModification, 'optionalAccess', _25 => _25.actualNotes]) === actualNotes && _optionalChain([entry, 'access', _26 => _26.timeModification, 'optionalAccess', _27 => _27.normalNotes]) === normalNotes;
1531
+ const tupletStart = _optionalChain([entry, 'access', _28 => _28.notations, 'optionalAccess', _29 => _29.find, 'call', _30 => _30(
2630
1532
  (n) => n.type === "tuplet" && n.tupletType === "start"
2631
1533
  )]);
2632
- const tupletStop = _optionalChain([entry, 'access', _37 => _37.notations, 'optionalAccess', _38 => _38.find, 'call', _39 => _39(
1534
+ const tupletStop = _optionalChain([entry, 'access', _31 => _31.notations, 'optionalAccess', _32 => _32.find, 'call', _33 => _33(
2633
1535
  (n) => n.type === "tuplet" && n.tupletType === "stop" && (currentTupletNumber === void 0 || n.number === currentTupletNumber)
2634
1536
  )]);
2635
1537
  if (tupletStart && tupletStart.type === "tuplet") {
@@ -2713,8 +1615,8 @@ function addBeam(score, options) {
2713
1615
  type: beamType
2714
1616
  });
2715
1617
  }
2716
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
2717
- const errors = validateMeasureLocal(measure, context, { checkBeams: true });
1618
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
1619
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, { checkBeams: true });
2718
1620
  const criticalErrors = errors.filter((e) => e.level === "error");
2719
1621
  if (criticalErrors.length > 0) {
2720
1622
  return failure(criticalErrors);
@@ -2752,11 +1654,11 @@ function removeBeam(score, options) {
2752
1654
  const staff = targetNote.staff;
2753
1655
  const beamNotes = [];
2754
1656
  let inBeam = false;
2755
- const targetBeamLevel = _nullishCoalesce(_nullishCoalesce(options.beamLevel, () => ( _optionalChain([targetNote, 'access', _40 => _40.beam, 'access', _41 => _41[0], 'optionalAccess', _42 => _42.number]))), () => ( 1));
1657
+ const targetBeamLevel = _nullishCoalesce(_nullishCoalesce(options.beamLevel, () => ( _optionalChain([targetNote, 'access', _34 => _34.beam, 'access', _35 => _35[0], 'optionalAccess', _36 => _36.number]))), () => ( 1));
2756
1658
  for (const entry of measure.entries) {
2757
1659
  if (entry.type !== "note" || entry.rest) continue;
2758
1660
  if (entry.voice !== voice || entry.staff !== staff) continue;
2759
- const beamInfo = _optionalChain([entry, 'access', _43 => _43.beam, 'optionalAccess', _44 => _44.find, 'call', _45 => _45((b) => b.number === targetBeamLevel)]);
1661
+ const beamInfo = _optionalChain([entry, 'access', _37 => _37.beam, 'optionalAccess', _38 => _38.find, 'call', _39 => _39((b) => b.number === targetBeamLevel)]);
2760
1662
  if (!beamInfo) {
2761
1663
  if (inBeam) {
2762
1664
  break;
@@ -2805,7 +1707,7 @@ function autoBeam(score, options) {
2805
1707
  }
2806
1708
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
2807
1709
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
2808
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
1710
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
2809
1711
  const divisions = context.divisions;
2810
1712
  const time = _nullishCoalesce(context.time, () => ( { beats: "4", beatType: 4 }));
2811
1713
  const beatDuration = 4 / time.beatType * divisions;
@@ -2841,7 +1743,7 @@ function autoBeam(score, options) {
2841
1743
  let currentBeat = -1;
2842
1744
  let currentGroup = [];
2843
1745
  for (const { note, position: notePos } of notes) {
2844
- const beamable = note.noteType ? beamLevel(note) > 0 : note.duration < beatDuration;
1746
+ const beamable = note.noteType ? _chunk776XPK66js.beamLevel.call(void 0, note) > 0 : note.duration < beatDuration;
2845
1747
  if (!beamable || note.grace) {
2846
1748
  if (currentGroup.length >= 2) {
2847
1749
  beatGroups.push(currentGroup);
@@ -2866,7 +1768,7 @@ function autoBeam(score, options) {
2866
1768
  }
2867
1769
  for (const group of beatGroups) {
2868
1770
  if (group.every(({ note }) => note.noteType)) {
2869
- applyBeamGroup(group.map(({ note }) => note));
1771
+ _chunk776XPK66js.applyBeamGroup.call(void 0, group.map(({ note }) => note));
2870
1772
  } else {
2871
1773
  group.forEach(({ note }, i) => {
2872
1774
  note.beam = [{ number: 1, type: i === 0 ? "begin" : i === group.length - 1 ? "end" : "continue" }];
@@ -2874,7 +1776,7 @@ function autoBeam(score, options) {
2874
1776
  }
2875
1777
  }
2876
1778
  }
2877
- const errors = validateMeasureLocal(measure, context, { checkBeams: true });
1779
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, { checkBeams: true });
2878
1780
  const criticalErrors = errors.filter((e) => e.level === "error");
2879
1781
  if (criticalErrors.length > 0) {
2880
1782
  return failure(criticalErrors);
@@ -2961,7 +1863,7 @@ function pasteNotes(score, options) {
2961
1863
  }
2962
1864
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
2963
1865
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
2964
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
1866
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
2965
1867
  const measureDuration = context.time ? getMeasureDuration(context.divisions, context.time) : context.divisions * 4;
2966
1868
  const targetVoice = _nullishCoalesce(options.voice, () => ( options.selection.source.voice));
2967
1869
  const targetStaff = _nullishCoalesce(options.staff, () => ( options.selection.source.staff));
@@ -3048,7 +1950,7 @@ function pasteNotes(score, options) {
3048
1950
  targetStaff
3049
1951
  );
3050
1952
  }
3051
- const errors = validateMeasureLocal(measure, context, {
1953
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, {
3052
1954
  checkMeasureDuration: true,
3053
1955
  checkPosition: true,
3054
1956
  checkVoiceStaff: true
@@ -3067,7 +1969,7 @@ function cutNotes(score, options) {
3067
1969
  const selection = copyResult.data;
3068
1970
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
3069
1971
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
3070
- const context = getMeasureContext(result, options.partIndex, options.measureIndex);
1972
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, options.measureIndex);
3071
1973
  const measureDuration = context.time ? getMeasureDuration(context.divisions, context.time) : context.divisions * 4;
3072
1974
  const voiceEntries = getVoiceEntries(measure, options.voice, options.staff);
3073
1975
  const entriesToKeep = voiceEntries.filter((e) => {
@@ -3089,7 +1991,7 @@ function cutNotes(score, options) {
3089
1991
  measureDuration,
3090
1992
  options.staff
3091
1993
  );
3092
- const errors = validateMeasureLocal(measure, context, {
1994
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, {
3093
1995
  checkMeasureDuration: true,
3094
1996
  checkPosition: true,
3095
1997
  checkVoiceStaff: true
@@ -3184,7 +2086,7 @@ function pasteNotesMultiMeasure(score, options) {
3184
2086
  for (const measureData of options.selection.measures) {
3185
2087
  const measureIndex = options.startMeasureIndex + measureData.measureOffset;
3186
2088
  const measure = result.parts[options.partIndex].measures[measureIndex];
3187
- const context = getMeasureContext(result, options.partIndex, measureIndex);
2089
+ const context = _chunkJF5TM534js.getMeasureContext.call(void 0, result, options.partIndex, measureIndex);
3188
2090
  const measureDuration = context.time ? getMeasureDuration(context.divisions, context.time) : context.divisions * 4;
3189
2091
  const voiceEntries = getVoiceEntries(measure, targetVoice, targetStaff);
3190
2092
  let entriesToKeep;
@@ -3216,7 +2118,7 @@ function pasteNotesMultiMeasure(score, options) {
3216
2118
  measureDuration,
3217
2119
  targetStaff
3218
2120
  );
3219
- const errors = validateMeasureLocal(measure, context, {
2121
+ const errors = _chunkJF5TM534js.validateMeasureLocal.call(void 0, measure, context, {
3220
2122
  checkMeasureDuration: true,
3221
2123
  checkPosition: true,
3222
2124
  checkVoiceStaff: true
@@ -3256,7 +2158,7 @@ function addTempo(score, options) {
3256
2158
  });
3257
2159
  }
3258
2160
  const direction = {
3259
- _id: generateId(),
2161
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3260
2162
  type: "direction",
3261
2163
  directionTypes,
3262
2164
  placement: _nullishCoalesce(options.placement, () => ( "above")),
@@ -3369,7 +2271,7 @@ function addWedge(score, options) {
3369
2271
  const result = cloneScore(score);
3370
2272
  const startMeasure = result.parts[options.partIndex].measures[options.startMeasureIndex];
3371
2273
  const startDirection = {
3372
- _id: generateId(),
2274
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3373
2275
  type: "direction",
3374
2276
  directionTypes: [{
3375
2277
  kind: "wedge",
@@ -3381,7 +2283,7 @@ function addWedge(score, options) {
3381
2283
  insertDirectionAtPosition(startMeasure, startDirection, options.startPosition);
3382
2284
  const endMeasure = result.parts[options.partIndex].measures[options.endMeasureIndex];
3383
2285
  const endDirection = {
3384
- _id: generateId(),
2286
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3385
2287
  type: "direction",
3386
2288
  directionTypes: [{
3387
2289
  kind: "wedge",
@@ -3456,7 +2358,7 @@ function addFermata(score, options) {
3456
2358
  return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} out of bounds`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3457
2359
  }
3458
2360
  const note = notes[options.noteIndex];
3459
- if (_optionalChain([note, 'access', _46 => _46.notations, 'optionalAccess', _47 => _47.some, 'call', _48 => _48((n) => n.type === "fermata")])) {
2361
+ if (_optionalChain([note, 'access', _40 => _40.notations, 'optionalAccess', _41 => _41.some, 'call', _42 => _42((n) => n.type === "fermata")])) {
3460
2362
  return failure([operationError("FERMATA_ALREADY_EXISTS", "Note already has a fermata", { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3461
2363
  }
3462
2364
  if (!note.notations) {
@@ -3486,7 +2388,7 @@ function removeFermata(score, options) {
3486
2388
  return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} out of bounds`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3487
2389
  }
3488
2390
  const note = notes[options.noteIndex];
3489
- const fermataIndex = _optionalChain([note, 'access', _49 => _49.notations, 'optionalAccess', _50 => _50.findIndex, 'call', _51 => _51((n) => n.type === "fermata")]);
2391
+ const fermataIndex = _optionalChain([note, 'access', _43 => _43.notations, 'optionalAccess', _44 => _44.findIndex, 'call', _45 => _45((n) => n.type === "fermata")]);
3490
2392
  if (fermataIndex === void 0 || fermataIndex === -1) {
3491
2393
  return failure([operationError("FERMATA_NOT_FOUND", "Note does not have a fermata", { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3492
2394
  }
@@ -3511,7 +2413,7 @@ function addOrnament(score, options) {
3511
2413
  return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} out of bounds`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3512
2414
  }
3513
2415
  const note = notes[options.noteIndex];
3514
- if (_optionalChain([note, 'access', _52 => _52.notations, 'optionalAccess', _53 => _53.some, 'call', _54 => _54((n) => n.type === "ornament" && n.ornament === options.ornament)])) {
2416
+ if (_optionalChain([note, 'access', _46 => _46.notations, 'optionalAccess', _47 => _47.some, 'call', _48 => _48((n) => n.type === "ornament" && n.ornament === options.ornament)])) {
3515
2417
  return failure([operationError("ORNAMENT_ALREADY_EXISTS", `Note already has ornament: ${options.ornament}`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3516
2418
  }
3517
2419
  if (!note.notations) {
@@ -3541,7 +2443,7 @@ function removeOrnament(score, options) {
3541
2443
  return failure([operationError("NOTE_NOT_FOUND", `Note index ${options.noteIndex} out of bounds`, { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3542
2444
  }
3543
2445
  const note = notes[options.noteIndex];
3544
- const ornamentIndex = options.ornament ? _optionalChain([note, 'access', _55 => _55.notations, 'optionalAccess', _56 => _56.findIndex, 'call', _57 => _57((n) => n.type === "ornament" && n.ornament === options.ornament)]) : _optionalChain([note, 'access', _58 => _58.notations, 'optionalAccess', _59 => _59.findIndex, 'call', _60 => _60((n) => n.type === "ornament")]);
2446
+ const ornamentIndex = options.ornament ? _optionalChain([note, 'access', _49 => _49.notations, 'optionalAccess', _50 => _50.findIndex, 'call', _51 => _51((n) => n.type === "ornament" && n.ornament === options.ornament)]) : _optionalChain([note, 'access', _52 => _52.notations, 'optionalAccess', _53 => _53.findIndex, 'call', _54 => _54((n) => n.type === "ornament")]);
3545
2447
  if (ornamentIndex === void 0 || ornamentIndex === -1) {
3546
2448
  return failure([operationError("ORNAMENT_NOT_FOUND", "Note does not have the specified ornament", { partIndex: options.partIndex, measureIndex: options.measureIndex })]);
3547
2449
  }
@@ -3562,7 +2464,7 @@ function addPedal(score, options) {
3562
2464
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
3563
2465
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
3564
2466
  const direction = {
3565
- _id: generateId(),
2467
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3566
2468
  type: "direction",
3567
2469
  directionTypes: [{
3568
2470
  kind: "pedal",
@@ -3615,7 +2517,7 @@ function addTextDirection(score, options) {
3615
2517
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
3616
2518
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
3617
2519
  const direction = {
3618
- _id: generateId(),
2520
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3619
2521
  type: "direction",
3620
2522
  directionTypes: [{
3621
2523
  kind: "words",
@@ -3639,7 +2541,7 @@ function addRehearsalMark(score, options) {
3639
2541
  const result = cloneScoreAt(score, options.partIndex, options.measureIndex);
3640
2542
  const measure = result.parts[options.partIndex].measures[options.measureIndex];
3641
2543
  const direction = {
3642
- _id: generateId(),
2544
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3643
2545
  type: "direction",
3644
2546
  directionTypes: [{
3645
2547
  kind: "rehearsal",
@@ -3698,7 +2600,7 @@ function addRepeatBarline(score, options) {
3698
2600
  measure.barlines.splice(nonRepeatIndex, 1);
3699
2601
  }
3700
2602
  measure.barlines.push({
3701
- _id: generateId(),
2603
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3702
2604
  location,
3703
2605
  barStyle,
3704
2606
  repeat: {
@@ -3761,7 +2663,7 @@ function addEnding(score, options) {
3761
2663
  }
3762
2664
  let barline = measure.barlines.find((b) => b.location === location);
3763
2665
  if (!barline) {
3764
- barline = { _id: generateId(), location };
2666
+ barline = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ), location };
3765
2667
  measure.barlines.push(barline);
3766
2668
  }
3767
2669
  if (barline.ending) {
@@ -3781,7 +2683,7 @@ function removeEnding(score, options) {
3781
2683
  return failure([operationError("MEASURE_NOT_FOUND", `Measure index ${measureIndex} out of bounds`, { partIndex, measureIndex })]);
3782
2684
  }
3783
2685
  const measure = part.measures[measureIndex];
3784
- const barline = _optionalChain([measure, 'access', _61 => _61.barlines, 'optionalAccess', _62 => _62.find, 'call', _63 => _63((b) => b.location === location && b.ending)]);
2686
+ const barline = _optionalChain([measure, 'access', _55 => _55.barlines, 'optionalAccess', _56 => _56.find, 'call', _57 => _57((b) => b.location === location && b.ending)]);
3785
2687
  if (!barline) {
3786
2688
  return failure([operationError("ENDING_NOT_FOUND", `No ending found at ${location} of measure ${measureIndex}`, { partIndex, measureIndex })]);
3787
2689
  }
@@ -3823,7 +2725,7 @@ function changeBarline(score, options) {
3823
2725
  }
3824
2726
  let barline = measure.barlines.find((b) => b.location === location);
3825
2727
  if (!barline) {
3826
- barline = { _id: generateId(), location };
2728
+ barline = { _id: _chunk5EK7K5X3js.generateId.call(void 0, ), location };
3827
2729
  measure.barlines.push(barline);
3828
2730
  }
3829
2731
  barline.barStyle = barStyle;
@@ -3842,7 +2744,7 @@ function addSegno(score, options) {
3842
2744
  const result = cloneScoreAt(score, partIndex, measureIndex);
3843
2745
  const measure = result.parts[partIndex].measures[measureIndex];
3844
2746
  const direction = {
3845
- _id: generateId(),
2747
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3846
2748
  type: "direction",
3847
2749
  directionTypes: [{ kind: "segno" }],
3848
2750
  placement: "above"
@@ -3862,7 +2764,7 @@ function addCoda(score, options) {
3862
2764
  const result = cloneScoreAt(score, partIndex, measureIndex);
3863
2765
  const measure = result.parts[partIndex].measures[measureIndex];
3864
2766
  const direction = {
3865
- _id: generateId(),
2767
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3866
2768
  type: "direction",
3867
2769
  directionTypes: [{ kind: "coda" }],
3868
2770
  placement: "above"
@@ -3881,18 +2783,18 @@ function addDaCapo(score, options) {
3881
2783
  }
3882
2784
  const result = cloneScoreAt(score, partIndex, measureIndex);
3883
2785
  const measure = result.parts[partIndex].measures[measureIndex];
3884
- const attrs = _chunkEWLB5X64js.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
2786
+ const attrs = _chunkPMPROVJWjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
3885
2787
  const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
3886
2788
  const insertPos = _nullishCoalesce(position, () => ( measureDuration));
3887
2789
  const direction = {
3888
- _id: generateId(),
2790
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3889
2791
  type: "direction",
3890
2792
  directionTypes: [{ kind: "words", text: "D.C." }],
3891
2793
  placement: "above"
3892
2794
  };
3893
2795
  insertDirectionAtPosition(measure, direction, insertPos);
3894
2796
  const sound = {
3895
- _id: generateId(),
2797
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3896
2798
  type: "sound",
3897
2799
  dacapo: true
3898
2800
  };
@@ -3910,18 +2812,18 @@ function addDalSegno(score, options) {
3910
2812
  }
3911
2813
  const result = cloneScoreAt(score, partIndex, measureIndex);
3912
2814
  const measure = result.parts[partIndex].measures[measureIndex];
3913
- const attrs = _chunkEWLB5X64js.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
2815
+ const attrs = _chunkPMPROVJWjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
3914
2816
  const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
3915
2817
  const insertPos = _nullishCoalesce(position, () => ( measureDuration));
3916
2818
  const direction = {
3917
- _id: generateId(),
2819
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3918
2820
  type: "direction",
3919
2821
  directionTypes: [{ kind: "words", text: "D.S." }],
3920
2822
  placement: "above"
3921
2823
  };
3922
2824
  insertDirectionAtPosition(measure, direction, insertPos);
3923
2825
  const sound = {
3924
- _id: generateId(),
2826
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3925
2827
  type: "sound",
3926
2828
  dalsegno: "segno"
3927
2829
  };
@@ -3939,18 +2841,18 @@ function addFine(score, options) {
3939
2841
  }
3940
2842
  const result = cloneScoreAt(score, partIndex, measureIndex);
3941
2843
  const measure = result.parts[partIndex].measures[measureIndex];
3942
- const attrs = _chunkEWLB5X64js.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
2844
+ const attrs = _chunkPMPROVJWjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
3943
2845
  const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
3944
2846
  const insertPos = _nullishCoalesce(position, () => ( measureDuration));
3945
2847
  const direction = {
3946
- _id: generateId(),
2848
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3947
2849
  type: "direction",
3948
2850
  directionTypes: [{ kind: "words", text: "Fine" }],
3949
2851
  placement: "above"
3950
2852
  };
3951
2853
  insertDirectionAtPosition(measure, direction, insertPos);
3952
2854
  const sound = {
3953
- _id: generateId(),
2855
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3954
2856
  type: "sound",
3955
2857
  fine: true
3956
2858
  };
@@ -3968,18 +2870,18 @@ function addToCoda(score, options) {
3968
2870
  }
3969
2871
  const result = cloneScoreAt(score, partIndex, measureIndex);
3970
2872
  const measure = result.parts[partIndex].measures[measureIndex];
3971
- const attrs = _chunkEWLB5X64js.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
2873
+ const attrs = _chunkPMPROVJWjs.getAttributesAtMeasure.call(void 0, result, { part: partIndex, measure: measureIndex });
3972
2874
  const measureDuration = getMeasureDuration(_nullishCoalesce(attrs.divisions, () => ( 1)), _nullishCoalesce(attrs.time, () => ( { beats: "4", beatType: 4 })));
3973
2875
  const insertPos = _nullishCoalesce(position, () => ( measureDuration));
3974
2876
  const direction = {
3975
- _id: generateId(),
2877
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3976
2878
  type: "direction",
3977
2879
  directionTypes: [{ kind: "words", text: "To Coda" }],
3978
2880
  placement: "above"
3979
2881
  };
3980
2882
  insertDirectionAtPosition(measure, direction, insertPos);
3981
2883
  const sound = {
3982
- _id: generateId(),
2884
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
3983
2885
  type: "sound",
3984
2886
  tocoda: "coda"
3985
2887
  };
@@ -4016,7 +2918,7 @@ function addGraceNote(score, options) {
4016
2918
  const result = cloneScoreAt(score, partIndex, measureIndex);
4017
2919
  const resultMeasure = result.parts[partIndex].measures[measureIndex];
4018
2920
  const graceNote = {
4019
- _id: generateId(),
2921
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
4020
2922
  type: "note",
4021
2923
  pitch,
4022
2924
  duration: 0,
@@ -4127,7 +3029,7 @@ function addLyric(score, options) {
4127
3029
  if (targetEntry.type !== "note") {
4128
3030
  return failure([operationError("NOTE_NOT_FOUND", `Entry is not a note`, { partIndex, measureIndex })]);
4129
3031
  }
4130
- if (_optionalChain([targetEntry, 'access', _64 => _64.lyrics, 'optionalAccess', _65 => _65.some, 'call', _66 => _66((l) => l.number === verse)])) {
3032
+ if (_optionalChain([targetEntry, 'access', _58 => _58.lyrics, 'optionalAccess', _59 => _59.some, 'call', _60 => _60((l) => l.number === verse)])) {
4131
3033
  return failure([operationError("LYRIC_ALREADY_EXISTS", `Lyric for verse ${verse} already exists on this note`, { partIndex, measureIndex })]);
4132
3034
  }
4133
3035
  const result = cloneScoreAt(score, partIndex, measureIndex);
@@ -4257,7 +3159,7 @@ function addHarmony(score, options) {
4257
3159
  const result = cloneScoreAt(score, partIndex, measureIndex);
4258
3160
  const measure = result.parts[partIndex].measures[measureIndex];
4259
3161
  const harmony = {
4260
- _id: generateId(),
3162
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
4261
3163
  type: "harmony",
4262
3164
  root: {
4263
3165
  rootStep: root.step.toUpperCase(),
@@ -4269,7 +3171,7 @@ function addHarmony(score, options) {
4269
3171
  bassStep: bass.step.toUpperCase(),
4270
3172
  bassAlter: bass.alter
4271
3173
  } : void 0,
4272
- degrees: _optionalChain([degrees, 'optionalAccess', _67 => _67.map, 'call', _68 => _68((d) => ({
3174
+ degrees: _optionalChain([degrees, 'optionalAccess', _61 => _61.map, 'call', _62 => _62((d) => ({
4273
3175
  degreeValue: d.value,
4274
3176
  degreeAlter: d.alter,
4275
3177
  degreeType: d.type
@@ -4656,7 +3558,7 @@ function addOctaveShift(score, options) {
4656
3558
  const result = cloneScoreAt(score, partIndex, measureIndex);
4657
3559
  const measure = result.parts[partIndex].measures[measureIndex];
4658
3560
  const direction = {
4659
- _id: generateId(),
3561
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
4660
3562
  type: "direction",
4661
3563
  directionTypes: [{
4662
3564
  kind: "octave-shift",
@@ -4680,7 +3582,7 @@ function stopOctaveShift(score, options) {
4680
3582
  const result = cloneScoreAt(score, partIndex, measureIndex);
4681
3583
  const measure = result.parts[partIndex].measures[measureIndex];
4682
3584
  const direction = {
4683
- _id: generateId(),
3585
+ _id: _chunk5EK7K5X3js.generateId.call(void 0, ),
4684
3586
  type: "direction",
4685
3587
  directionTypes: [{
4686
3588
  kind: "octave-shift",
@@ -5167,28 +4069,4 @@ var removeRepeat = removeRepeatBarline;
5167
4069
 
5168
4070
 
5169
4071
 
5170
-
5171
-
5172
-
5173
-
5174
-
5175
-
5176
-
5177
-
5178
-
5179
-
5180
-
5181
-
5182
-
5183
-
5184
-
5185
-
5186
-
5187
-
5188
-
5189
-
5190
-
5191
-
5192
-
5193
-
5194
- exports.generateId = generateId; exports.beamLevel = beamLevel; exports.applyBeamGroup = applyBeamGroup; exports.validate = validate; exports.validateDivisions = validateDivisions; exports.validateMeasureDuration = validateMeasureDuration; exports.validateBackupForward = validateBackupForward; exports.validateTies = validateTies; exports.validateBeams = validateBeams; exports.validateSlurs = validateSlurs; exports.validateTuplets = validateTuplets; exports.validatePartReferences = validatePartReferences; exports.validateVoiceStaff = validateVoiceStaff; exports.validatePartStructure = validatePartStructure; exports.validateStaffStructure = validateStaffStructure; exports.validateMeasureLocal = validateMeasureLocal; exports.getMeasureContext = getMeasureContext; exports.assertMeasureValid = assertMeasureValid; exports.isValid = isValid; exports.assertValid = assertValid; exports.formatLocation = formatLocation; exports.ValidationException = ValidationException; exports.validateTiesAcrossMeasures = validateTiesAcrossMeasures; exports.validateSlursAcrossMeasures = validateSlursAcrossMeasures; exports.insertNote = insertNote; exports.removeNote = removeNote; exports.addChord = addChord; exports.changeNoteDuration = changeNoteDuration; exports.setNotePitch = setNotePitch; exports.setNotePitchBySemitone = setNotePitchBySemitone; exports.shiftNotePitch = shiftNotePitch; exports.raiseAccidental = raiseAccidental; exports.lowerAccidental = lowerAccidental; exports.addVoice = addVoice; exports.transpose = transpose; exports.addPart = addPart; exports.removePart = removePart; exports.duplicatePart = duplicatePart; exports.setStaves = setStaves; exports.moveNoteToStaff = moveNoteToStaff; exports.changeKey = changeKey; exports.changeTime = changeTime; exports.insertMeasure = insertMeasure; exports.deleteMeasure = deleteMeasure; exports.addTie = addTie; exports.removeTie = removeTie; exports.addSlur = addSlur; exports.removeSlur = removeSlur; exports.addArticulation = addArticulation; exports.removeArticulation = removeArticulation; exports.addDynamics = addDynamics; exports.removeDynamics = removeDynamics; exports.modifyDynamics = modifyDynamics; exports.insertClefChange = insertClefChange; exports.addNote = addNote; exports.deleteNote = deleteNote; exports.addChordNote = addChordNote; exports.modifyNotePitch = modifyNotePitch; exports.modifyNoteDuration = modifyNoteDuration; exports.addNoteChecked = addNoteChecked; exports.deleteNoteChecked = deleteNoteChecked; exports.addChordNoteChecked = addChordNoteChecked; exports.modifyNotePitchChecked = modifyNotePitchChecked; exports.modifyNoteDurationChecked = modifyNoteDurationChecked; exports.transposeChecked = transposeChecked; exports.createTuplet = createTuplet; exports.removeTuplet = removeTuplet; exports.addBeam = addBeam; exports.removeBeam = removeBeam; exports.autoBeam = autoBeam; exports.copyNotes = copyNotes; exports.pasteNotes = pasteNotes; exports.cutNotes = cutNotes; exports.copyNotesMultiMeasure = copyNotesMultiMeasure; exports.pasteNotesMultiMeasure = pasteNotesMultiMeasure; exports.addTempo = addTempo; exports.removeTempo = removeTempo; exports.modifyTempo = modifyTempo; exports.addWedge = addWedge; exports.removeWedge = removeWedge; exports.addFermata = addFermata; exports.removeFermata = removeFermata; exports.addOrnament = addOrnament; exports.removeOrnament = removeOrnament; exports.addPedal = addPedal; exports.removePedal = removePedal; exports.addTextDirection = addTextDirection; exports.addRehearsalMark = addRehearsalMark; exports.addRepeatBarline = addRepeatBarline; exports.removeRepeatBarline = removeRepeatBarline; exports.addEnding = addEnding; exports.removeEnding = removeEnding; exports.changeBarline = changeBarline; exports.addSegno = addSegno; exports.addCoda = addCoda; exports.addDaCapo = addDaCapo; exports.addDalSegno = addDalSegno; exports.addFine = addFine; exports.addToCoda = addToCoda; exports.addGraceNote = addGraceNote; exports.removeGraceNote = removeGraceNote; exports.convertToGrace = convertToGrace; exports.addLyric = addLyric; exports.removeLyric = removeLyric; exports.updateLyric = updateLyric; exports.addHarmony = addHarmony; exports.removeHarmony = removeHarmony; exports.updateHarmony = updateHarmony; exports.addFingering = addFingering; exports.removeFingering = removeFingering; exports.addBowing = addBowing; exports.removeBowing = removeBowing; exports.addStringNumber = addStringNumber; exports.removeStringNumber = removeStringNumber; exports.addOctaveShift = addOctaveShift; exports.stopOctaveShift = stopOctaveShift; exports.removeOctaveShift = removeOctaveShift; exports.addBreathMark = addBreathMark; exports.removeBreathMark = removeBreathMark; exports.addCaesura = addCaesura; exports.removeCaesura = removeCaesura; exports.ALL_COLOR_TARGETS = ALL_COLOR_TARGETS; exports.setColor = setColor; exports.clearColors = clearColors; exports.addText = addText; exports.setBeaming = setBeaming; exports.addChordSymbol = addChordSymbol; exports.removeChordSymbol = removeChordSymbol; exports.updateChordSymbol = updateChordSymbol; exports.changeClef = changeClef; exports.setBarline = setBarline; exports.addRepeat = addRepeat; exports.removeRepeat = removeRepeat;
4072
+ exports.insertNote = insertNote; exports.removeNote = removeNote; exports.addChord = addChord; exports.changeNoteDuration = changeNoteDuration; exports.setNotePitch = setNotePitch; exports.setNotePitchBySemitone = setNotePitchBySemitone; exports.shiftNotePitch = shiftNotePitch; exports.raiseAccidental = raiseAccidental; exports.lowerAccidental = lowerAccidental; exports.addVoice = addVoice; exports.transpose = transpose; exports.addPart = addPart; exports.removePart = removePart; exports.duplicatePart = duplicatePart; exports.setStaves = setStaves; exports.moveNoteToStaff = moveNoteToStaff; exports.changeKey = changeKey; exports.changeTime = changeTime; exports.insertMeasure = insertMeasure; exports.deleteMeasure = deleteMeasure; exports.addTie = addTie; exports.removeTie = removeTie; exports.addSlur = addSlur; exports.removeSlur = removeSlur; exports.addArticulation = addArticulation; exports.removeArticulation = removeArticulation; exports.addDynamics = addDynamics; exports.removeDynamics = removeDynamics; exports.modifyDynamics = modifyDynamics; exports.insertClefChange = insertClefChange; exports.addNote = addNote; exports.deleteNote = deleteNote; exports.addChordNote = addChordNote; exports.modifyNotePitch = modifyNotePitch; exports.modifyNoteDuration = modifyNoteDuration; exports.addNoteChecked = addNoteChecked; exports.deleteNoteChecked = deleteNoteChecked; exports.addChordNoteChecked = addChordNoteChecked; exports.modifyNotePitchChecked = modifyNotePitchChecked; exports.modifyNoteDurationChecked = modifyNoteDurationChecked; exports.transposeChecked = transposeChecked; exports.createTuplet = createTuplet; exports.removeTuplet = removeTuplet; exports.addBeam = addBeam; exports.removeBeam = removeBeam; exports.autoBeam = autoBeam; exports.copyNotes = copyNotes; exports.pasteNotes = pasteNotes; exports.cutNotes = cutNotes; exports.copyNotesMultiMeasure = copyNotesMultiMeasure; exports.pasteNotesMultiMeasure = pasteNotesMultiMeasure; exports.addTempo = addTempo; exports.removeTempo = removeTempo; exports.modifyTempo = modifyTempo; exports.addWedge = addWedge; exports.removeWedge = removeWedge; exports.addFermata = addFermata; exports.removeFermata = removeFermata; exports.addOrnament = addOrnament; exports.removeOrnament = removeOrnament; exports.addPedal = addPedal; exports.removePedal = removePedal; exports.addTextDirection = addTextDirection; exports.addRehearsalMark = addRehearsalMark; exports.addRepeatBarline = addRepeatBarline; exports.removeRepeatBarline = removeRepeatBarline; exports.addEnding = addEnding; exports.removeEnding = removeEnding; exports.changeBarline = changeBarline; exports.addSegno = addSegno; exports.addCoda = addCoda; exports.addDaCapo = addDaCapo; exports.addDalSegno = addDalSegno; exports.addFine = addFine; exports.addToCoda = addToCoda; exports.addGraceNote = addGraceNote; exports.removeGraceNote = removeGraceNote; exports.convertToGrace = convertToGrace; exports.addLyric = addLyric; exports.removeLyric = removeLyric; exports.updateLyric = updateLyric; exports.addHarmony = addHarmony; exports.removeHarmony = removeHarmony; exports.updateHarmony = updateHarmony; exports.addFingering = addFingering; exports.removeFingering = removeFingering; exports.addBowing = addBowing; exports.removeBowing = removeBowing; exports.addStringNumber = addStringNumber; exports.removeStringNumber = removeStringNumber; exports.addOctaveShift = addOctaveShift; exports.stopOctaveShift = stopOctaveShift; exports.removeOctaveShift = removeOctaveShift; exports.addBreathMark = addBreathMark; exports.removeBreathMark = removeBreathMark; exports.addCaesura = addCaesura; exports.removeCaesura = removeCaesura; exports.ALL_COLOR_TARGETS = ALL_COLOR_TARGETS; exports.setColor = setColor; exports.clearColors = clearColors; exports.addText = addText; exports.setBeaming = setBeaming; exports.addChordSymbol = addChordSymbol; exports.removeChordSymbol = removeChordSymbol; exports.updateChordSymbol = updateChordSymbol; exports.changeClef = changeClef; exports.setBarline = setBarline; exports.addRepeat = addRepeat; exports.removeRepeat = removeRepeat;