@tspro/web-music-score 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +18 -9
  3. package/dist/audio/index.d.mts +40 -1
  4. package/dist/audio/index.d.ts +40 -1
  5. package/dist/audio/index.js +1 -1
  6. package/dist/audio/index.mjs +2 -2
  7. package/dist/audio-cg/index.d.mts +3 -0
  8. package/dist/audio-cg/index.d.ts +3 -0
  9. package/dist/audio-cg/index.js +1 -1
  10. package/dist/audio-cg/index.mjs +2 -2
  11. package/dist/{chunk-D643HZHM.mjs → chunk-MHNTJ6FU.mjs} +2 -2
  12. package/dist/core/index.d.mts +12 -0
  13. package/dist/core/index.d.ts +12 -0
  14. package/dist/core/index.js +3 -2
  15. package/dist/core/index.mjs +4 -3
  16. package/dist/guitar-CaZJDA05.d.ts +35 -0
  17. package/dist/guitar-DdexKdN6.d.mts +35 -0
  18. package/dist/iife/index.global.js +11 -11
  19. package/dist/{interface-XoKiryoV.d.mts → music-objects-DIaqNPjs.d.mts} +616 -114
  20. package/dist/{interface-7k8qGG44.d.ts → music-objects-xJJNlFwK.d.ts} +616 -114
  21. package/dist/note-eA2xPPiG.d.mts +294 -0
  22. package/dist/note-eA2xPPiG.d.ts +294 -0
  23. package/dist/pieces/index.d.mts +22 -3
  24. package/dist/pieces/index.d.ts +22 -3
  25. package/dist/pieces/index.js +5 -2
  26. package/dist/pieces/index.mjs +6 -3
  27. package/dist/react-ui/index.d.mts +166 -17
  28. package/dist/react-ui/index.d.ts +166 -17
  29. package/dist/react-ui/index.js +78 -1
  30. package/dist/react-ui/index.mjs +79 -2
  31. package/dist/scale-DQNA-YLD.d.ts +230 -0
  32. package/dist/scale-bnD0WnMV.d.mts +230 -0
  33. package/dist/score/index.d.mts +315 -47
  34. package/dist/score/index.d.ts +315 -47
  35. package/dist/score/index.js +684 -173
  36. package/dist/score/index.mjs +683 -174
  37. package/dist/tempo-Bp1UzsrZ.d.ts +399 -0
  38. package/dist/tempo-S85Q7uJA.d.mts +399 -0
  39. package/dist/theory/index.d.mts +29 -13
  40. package/dist/theory/index.d.ts +29 -13
  41. package/dist/theory/index.js +433 -42
  42. package/dist/theory/index.mjs +432 -43
  43. package/package.json +3 -2
  44. package/dist/guitar-DggbM2UL.d.mts +0 -17
  45. package/dist/guitar-cNmE-EvH.d.ts +0 -17
  46. package/dist/note-BFa43I86.d.mts +0 -85
  47. package/dist/note-CcVdUFqS.d.ts +0 -85
  48. package/dist/scale-C2pCNxdE.d.mts +0 -75
  49. package/dist/scale-CvPbJvfN.d.ts +0 -75
  50. package/dist/tempo-BAYoZ_Li.d.mts +0 -187
  51. package/dist/tempo-r2sb6Ku2.d.ts +0 -187
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v4.0.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -24,6 +24,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
24
24
  var theory_exports = {};
25
25
  __export(theory_exports, {
26
26
  AccidentalType: () => AccidentalType,
27
+ BeamGrouping: () => BeamGrouping,
27
28
  Chord: () => Chord,
28
29
  DefaultGuitarNoteLabel: () => DefaultGuitarNoteLabel,
29
30
  DefaultHandedness: () => DefaultHandedness,
@@ -46,6 +47,7 @@ __export(theory_exports, {
46
47
  ScaleType: () => ScaleType,
47
48
  SymbolSet: () => SymbolSet,
48
49
  TimeSignature: () => TimeSignature,
50
+ TimeSignatures: () => TimeSignatures,
49
51
  TuningNameList: () => TuningNameList,
50
52
  Tuplet: () => Tuplet,
51
53
  alterTempoSpeed: () => alterTempoSpeed,
@@ -132,8 +134,11 @@ var DiatonicToChromaticMap = [0, 2, 4, 5, 7, 9, 11];
132
134
  var NoteNameRegex = /^([A-G])((?:bb|𝄫|♭|b|#|♯|x|𝄪)?)?(-?\d+)?$/;
133
135
  var _Note = class _Note {
134
136
  constructor(arg, accidental, octave) {
137
+ /** Diatonic class */
135
138
  __publicField(this, "diatonicClass");
139
+ /** Accidental. */
136
140
  __publicField(this, "accidental");
141
+ /** Octave. */
137
142
  __publicField(this, "octave");
138
143
  if (typeof arg === "number" && typeof accidental === "number" && octave === void 0) {
139
144
  _Note.validateDiatonicId(arg);
@@ -152,21 +157,32 @@ var _Note = class _Note {
152
157
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid args: ${arg}, ${accidental}, ${octave}`);
153
158
  }
154
159
  }
160
+ /** Diatonic id getter. */
155
161
  get diatonicId() {
156
162
  return _Note.getDiatonicIdInOctave(this.diatonicClass, this.octave);
157
163
  }
164
+ /** Chromatic id getter. */
158
165
  get chromaticId() {
159
166
  return _Note.getChromaticIdInOctave(DiatonicToChromaticMap[this.diatonicClass] + this.accidental, this.octave);
160
167
  }
168
+ /** Midi number getter (implemented same as chromatic id). */
161
169
  get midiNumber() {
162
170
  return this.chromaticId;
163
171
  }
172
+ /** Chromatic class getter. */
164
173
  get chromaticClass() {
165
174
  return _Note.getChromaticClass(DiatonicToChromaticMap[this.diatonicClass] + this.accidental);
166
175
  }
176
+ /** Note letter getter. */
167
177
  get noteLetter() {
168
178
  return NoteLetters[this.diatonicClass];
169
179
  }
180
+ /**
181
+ * Format note to string presentation.
182
+ * @param pitchNotation - Pitchy notation.
183
+ * @param symbolSet - Symbol set.
184
+ * @returns - String presentation of note.
185
+ */
170
186
  format(pitchNotation, symbolSet) {
171
187
  let { noteLetter, octave } = this;
172
188
  let accidentalSymbol = _Note.getAccidentalSymbol(this.accidental, symbolSet);
@@ -180,11 +196,21 @@ var _Note = class _Note {
180
196
  return noteLetter + accidentalSymbol + octave;
181
197
  }
182
198
  }
199
+ /**
200
+ * Format note to string presentation without octave number.
201
+ * @param symbolSet - Symbol set.
202
+ * @returns - String presentation of note without octave number.
203
+ */
183
204
  formatOmitOctave(symbolSet) {
184
205
  let noteLetter = NoteLetters[this.diatonicClass];
185
206
  let accidental = _Note.getAccidentalSymbol(this.accidental, symbolSet);
186
207
  return noteLetter + accidental;
187
208
  }
209
+ /**
210
+ * Get note.
211
+ * @param noteName - Note name (e.g. "C4").
212
+ * @returns - Note.
213
+ */
188
214
  static getNote(noteName) {
189
215
  let note = this.noteByNameCache.get(noteName);
190
216
  if (note === void 0) {
@@ -200,6 +226,11 @@ var _Note = class _Note {
200
226
  }
201
227
  return note;
202
228
  }
229
+ /**
230
+ * Get chromatic note. There are number of alternatives, this function uses simple logic to choose one.
231
+ * @param chromaticId - Chromatic id.
232
+ * @returns - Note.
233
+ */
203
234
  static getChromaticNote(chromaticId) {
204
235
  let note = this.chromaticNoteCache.get(chromaticId);
205
236
  if (note === void 0) {
@@ -226,21 +257,54 @@ var _Note = class _Note {
226
257
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid arg: ${arg}`);
227
258
  }
228
259
  }
260
+ /**
261
+ * Get octave from diatonic id.
262
+ * @param diatonicId - Diatonic id.
263
+ * @returns - Octave.
264
+ */
229
265
  static getOctaveFromDiatonicId(diatonicId) {
230
266
  return Math.floor((diatonicId - C0_diatonicId) / 7);
231
267
  }
268
+ /**
269
+ * Get diatonic id in given octave (transposes diatonic id to given octave).
270
+ * @param diatonicId - Original diatonic id.
271
+ * @param octave - Octave.
272
+ * @returns - Transposed diatonic id.
273
+ */
232
274
  static getDiatonicIdInOctave(diatonicId, octave) {
233
275
  return _Note.getDiatonicClass(diatonicId) + octave * 7 + C0_diatonicId;
234
276
  }
277
+ /**
278
+ * Get chromatic class from chromatic id.
279
+ * @param chromaticId - Chromatic id.
280
+ * @returns - Chromatic class.
281
+ */
235
282
  static getChromaticClass(chromaticId) {
236
283
  return mod(chromaticId, 12);
237
284
  }
285
+ /**
286
+ * Get octave from chromatic id.
287
+ * @param chromaticId - Chromatic id.
288
+ * @returns - Octave.
289
+ */
238
290
  static getOctaveFromChromaticId(chromaticId) {
239
291
  return Math.floor((chromaticId - C0_chromaticId) / 12);
240
292
  }
293
+ /**
294
+ * Get chromatic id in given octave (transposes chromatic id to given octave).
295
+ * @param chromaticId - Original chromatic id.
296
+ * @param octave - Octave.
297
+ * @returns - Transpose chromatic id.
298
+ */
241
299
  static getChromaticIdInOctave(chromaticId, octave) {
242
300
  return _Note.getChromaticClass(chromaticId) + octave * 12 + C0_chromaticId;
243
301
  }
302
+ /**
303
+ * Test if given two notes are equal.
304
+ * @param a - Note a.
305
+ * @param b - Note b.
306
+ * @returns - True/false.
307
+ */
244
308
  static equals(a, b) {
245
309
  if (a == null && b == null) {
246
310
  return true;
@@ -250,6 +314,12 @@ var _Note = class _Note {
250
314
  return a === b || a.diatonicId === b.diatonicId && a.accidental === b.accidental;
251
315
  }
252
316
  }
317
+ /**
318
+ * Replace accidental symbols in given string to givn symbol set (ascii/unicode).
319
+ * @param str - String to replace.
320
+ * @param symbolSet - Symbol set.
321
+ * @returns - String with updated accidental symbols.
322
+ */
253
323
  static replaceAccidentalSymbols(str, symbolSet) {
254
324
  if (symbolSet === 1 /* Unicode */) {
255
325
  return str.replace("bb", "\u{1D12B}").replace("b", "\u266D").replace("#", "\u266F").replace("x", "\u{1D12A}");
@@ -257,9 +327,19 @@ var _Note = class _Note {
257
327
  return str.replace("\u{1D12B}", "bb").replace("\u266D", "b").replace("\u266F", "#").replace("\u{1D12A}", "x");
258
328
  }
259
329
  }
330
+ /**
331
+ * Test if given string is valid note name.
332
+ * @param noteName - Note name to validate.
333
+ * @returns - True/false.
334
+ */
260
335
  static isValidNoteName(noteName) {
261
336
  return NoteNameRegex.test(noteName);
262
337
  }
338
+ /**
339
+ * Parse note name string to note props.
340
+ * @param noteName - Note name to parse.
341
+ * @returns - Parsed note props or undefined if parsing error.
342
+ */
263
343
  static parseNote(noteName) {
264
344
  var _a;
265
345
  let m = NoteNameRegex.exec(noteName);
@@ -273,6 +353,12 @@ var _Note = class _Note {
273
353
  let octave = octaveStr ? _Note.validateOctave(+octaveStr) : void 0;
274
354
  return { noteLetter, accidental, octave };
275
355
  }
356
+ /**
357
+ * Get scientific note name from given note name.
358
+ * @param noteName - Note name.
359
+ * @param symbolSet - Symbol set (ascii/unicode) for scientific note name.
360
+ * @returns - Scientific note name.
361
+ */
276
362
  static getScientificNoteName(noteName, symbolSet) {
277
363
  let p = _Note.parseNote(noteName);
278
364
  if (!p) {
@@ -281,9 +367,20 @@ var _Note = class _Note {
281
367
  let { noteLetter, accidental, octave } = p;
282
368
  return noteLetter + _Note.getAccidentalSymbol(accidental, symbolSet) + (octave != null ? octave : "");
283
369
  }
370
+ /**
371
+ * Get symbol of given accidental in given symbol set (ascii/unicide).
372
+ * @param accidental - Accidental.
373
+ * @param symbolsSet - Symbol set.
374
+ * @returns - Accidental symbol or undefined (invalid accidental).
375
+ */
284
376
  static getAccidentalSymbol(accidental, symbolsSet) {
285
377
  return symbolsSet === 1 /* Unicode */ ? AccidentalUnicodeSymbolMap.get(accidental) : AccidentalAsciiSymbolMap.get(accidental);
286
378
  }
379
+ /**
380
+ * Get accidental value from given accidental symbol.
381
+ * @param accidentalSymbol - Accidental symbol (e.g. "#").
382
+ * @returns - Accidental vlaue.
383
+ */
287
384
  static getAccidental(accidentalSymbol) {
288
385
  let accidental = AccidentalMap.get(accidentalSymbol);
289
386
  if (accidental === void 0) {
@@ -291,15 +388,32 @@ var _Note = class _Note {
291
388
  }
292
389
  return accidental;
293
390
  }
391
+ /**
392
+ * Get note letter from given diatonic id.
393
+ * @param diatonicId - Diatonic id.
394
+ * @returns - Note letter.
395
+ */
294
396
  static getNoteLetter(diatonicId) {
295
397
  return NoteLetters[_Note.getDiatonicClass(diatonicId)];
296
398
  }
399
+ /**
400
+ * Find next lowest possible diatonic id that is above given bottom level.
401
+ * @param diatonicId - Diatonic id to begin with.
402
+ * @param bottomDiatonicId - Bottom diatonic id.
403
+ * @param addOctaveIfEqual - If true then add one octave if diatonic id would equal to bottom diatonic id.
404
+ * @returns - Diatonic id.
405
+ */
297
406
  static findNextDiatonicIdAbove(diatonicId, bottomDiatonicId, addOctaveIfEqual) {
298
407
  let diatonicClass = _Note.getDiatonicClass(diatonicId);
299
408
  let bottomDiatonicClass = _Note.getDiatonicClass(bottomDiatonicId);
300
409
  let addOctave = addOctaveIfEqual ? diatonicClass <= bottomDiatonicClass ? 1 : 0 : diatonicClass < bottomDiatonicClass ? 1 : 0;
301
410
  return _Note.getDiatonicIdInOctave(diatonicClass, _Note.getOctaveFromDiatonicId(bottomDiatonicId) + addOctave);
302
411
  }
412
+ /**
413
+ * Validate if given argument is diatonic id.
414
+ * @param diatonicId - Diatonic id to validate.
415
+ * @returns - Valid diatonic id or throws.
416
+ */
303
417
  static validateDiatonicId(diatonicId) {
304
418
  if (import_ts_utils_lib2.Utils.Is.isInteger(diatonicId)) {
305
419
  return diatonicId;
@@ -307,13 +421,23 @@ var _Note = class _Note {
307
421
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid diatonicId: ${diatonicId}`);
308
422
  }
309
423
  }
424
+ /**
425
+ * Validate if given argument is diatonic class.
426
+ * @param diatonicClass - Diatonic class to validate.
427
+ * @returns - Valid diatonic class or throws.
428
+ */
310
429
  static validateDiatonicClass(diatonicClass) {
311
- if (import_ts_utils_lib2.Utils.Is.isInteger(diatonicClass) && diatonicClass >= 0 && diatonicClass < 7) {
430
+ if (import_ts_utils_lib2.Utils.Is.isIntegerBetween(diatonicClass, 0, 6)) {
312
431
  return diatonicClass;
313
432
  } else {
314
433
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid diatonicClass: ${diatonicClass}`);
315
434
  }
316
435
  }
436
+ /**
437
+ * Validate if given argument is chromatic id.
438
+ * @param chromaticId - Chromatic id to validate.
439
+ * @returns - Valid chromatic id, or throws.
440
+ */
317
441
  static validateChromaticId(chromaticId) {
318
442
  if (import_ts_utils_lib2.Utils.Is.isInteger(chromaticId)) {
319
443
  return chromaticId;
@@ -321,20 +445,35 @@ var _Note = class _Note {
321
445
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid chromaticId: ${chromaticId}`);
322
446
  }
323
447
  }
448
+ /**
449
+ * Validate if given argument is chromatic class.
450
+ * @param chromaticClass - Chromatic class to validate.
451
+ * @returns - Valid chromatic class, or throws.
452
+ */
324
453
  static validatechromaticClass(chromaticClass) {
325
- if (import_ts_utils_lib2.Utils.Is.isInteger(chromaticClass) && chromaticClass >= 0 && chromaticClass < 12) {
454
+ if (import_ts_utils_lib2.Utils.Is.isIntegerBetween(chromaticClass, 0, 11)) {
326
455
  return chromaticClass;
327
456
  } else {
328
457
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid chromaticClass: ${chromaticClass}`);
329
458
  }
330
459
  }
331
- static validateNoteLetter(note) {
332
- if (NoteLetters.some((n) => n === note)) {
333
- return note;
460
+ /**
461
+ * Validate if given argument if note letter.
462
+ * @param noteLetter - Note letter to validate.
463
+ * @returns - Valid note letter or throws.
464
+ */
465
+ static validateNoteLetter(noteLetter) {
466
+ if (NoteLetters.some((n) => n === noteLetter)) {
467
+ return noteLetter;
334
468
  } else {
335
- throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid note: ${note}`);
469
+ throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid note: ${noteLetter}`);
336
470
  }
337
471
  }
472
+ /**
473
+ * Validate if given argument is octave.
474
+ * @param octave - Octave to validate.
475
+ * @returns - Valid octave or throws.
476
+ */
338
477
  static validateOctave(octave) {
339
478
  if (import_ts_utils_lib2.Utils.Is.isInteger(octave)) {
340
479
  return octave;
@@ -342,8 +481,13 @@ var _Note = class _Note {
342
481
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid octave: ${octave}`);
343
482
  }
344
483
  }
484
+ /**
485
+ * Validate if given argument is valid accidental.
486
+ * @param acc - Accidental to validate.
487
+ * @returns - Valid accidental or thorws.
488
+ */
345
489
  static validateAccidental(acc) {
346
- if (import_ts_utils_lib2.Utils.Is.isInteger(acc) && acc >= -2 && acc <= 2) {
490
+ if (import_ts_utils_lib2.Utils.Is.isIntegerBetween(acc, -2, 2)) {
347
491
  return acc;
348
492
  } else {
349
493
  throw new import_core2.MusicError(import_core2.MusicErrorType.Note, `Invalid accidental: ${acc}`);
@@ -371,6 +515,12 @@ var _Note = class _Note {
371
515
  });
372
516
  return uniqueSet;
373
517
  }
518
+ /**
519
+ * Function to compare two notes using diatonic id and accidental properties of notes.
520
+ * @param a - Note a.
521
+ * @param b - Note b.
522
+ * @returns - -1, 0 or 1.
523
+ */
374
524
  static compareFunc(a, b) {
375
525
  if (a.diatonicId < b.diatonicId) {
376
526
  return -1;
@@ -492,6 +642,10 @@ var _KeySignature = class _KeySignature {
492
642
  }
493
643
  this.orderedAccidentedNotes = flats.length > 0 ? flats : sharps;
494
644
  }
645
+ /**
646
+ * Get accidental type sharps, flats, or natural (without accidentals).
647
+ * @returns - Accidental type.
648
+ */
495
649
  getAccidentalType() {
496
650
  if (this.orderedAccidentedNotes.length === 0) {
497
651
  return 0 /* Natural */;
@@ -501,23 +655,40 @@ var _KeySignature = class _KeySignature {
501
655
  return 2 /* Sharps */;
502
656
  }
503
657
  }
658
+ /**
659
+ * Get natural scale notes of this key signature, natural scale has 7 steps (e.g. Major scale: W, W, H, W, W, W, H).
660
+ * @returns - Array of notes.
661
+ */
504
662
  getNaturalScaleNotes() {
505
663
  return this.naturalScaleNotes;
506
664
  }
665
+ /**
666
+ * Get accidental for given diatonic id.
667
+ * @param diatonicId - Diatonic id.
668
+ * @returns - Accidental -2, -1, 0, 1 or 2.
669
+ */
507
670
  getAccidental(diatonicId) {
508
671
  var _a;
509
672
  return (_a = this.accidentalByDiatonicClass[Note.getDiatonicClass(diatonicId)]) != null ? _a : 0;
510
673
  }
674
+ /**
675
+ * Get number of accidentals this key signature has.
676
+ * @returns - Number of accidentals.
677
+ */
511
678
  getNumAccidentals() {
512
679
  return this.orderedAccidentedNotes.length;
513
680
  }
681
+ /**
682
+ * Get accidental notes in correct order.
683
+ * @returns - Array of accidental notes.
684
+ */
514
685
  getOrderedAccidentalNotes() {
515
686
  return this.orderedAccidentedNotes;
516
687
  }
517
688
  /**
518
- *
519
- * @param degree - number 1..7 or string e.g "b5" or "#4"
520
- * @returns
689
+ * Get note of key signature by degree value.
690
+ * @param degree - Degree number in range [1, 7] or string e.g "b5" or "#4".
691
+ * @returns - Note.
521
692
  */
522
693
  getNoteByDegree(degree) {
523
694
  let { deg, acc } = parseDegree(degree);
@@ -528,6 +699,12 @@ var _KeySignature = class _KeySignature {
528
699
  return new Note(note.diatonicId, note.accidental + acc);
529
700
  }
530
701
  }
702
+ /**
703
+ * Test equality of given key signatures.
704
+ * @param a - Key signature a.
705
+ * @param b - Key signature b.
706
+ * @returns - True/false.
707
+ */
531
708
  static equals(a, b) {
532
709
  if (a == null && b == null) {
533
710
  return true;
@@ -665,9 +842,13 @@ var Interval = class _Interval {
665
842
  constructor(note1, note2) {
666
843
  this.note1 = note1;
667
844
  this.note2 = note2;
845
+ /** Interval direction. */
668
846
  __publicField(this, "direction");
847
+ /** Number of semitones. */
669
848
  __publicField(this, "semitones");
849
+ /** Interval quantity. */
670
850
  __publicField(this, "quantity");
851
+ /** Interval quality. */
671
852
  __publicField(this, "quality");
672
853
  if (note2.diatonicId >= note1.diatonicId) {
673
854
  this.direction = note2.diatonicId === note1.diatonicId ? "Unison" : "Ascending";
@@ -685,6 +866,12 @@ var Interval = class _Interval {
685
866
  throw new InvalidIntervalException("Unknown interval quality");
686
867
  }
687
868
  }
869
+ /**
870
+ * Get interval between given two notes.
871
+ * @param note1 - First note.
872
+ * @param note2 - Second note.
873
+ * @returns - Interval if valid, or undefined.
874
+ */
688
875
  static get(note1, note2) {
689
876
  try {
690
877
  return new _Interval(note1, note2);
@@ -696,12 +883,20 @@ var Interval = class _Interval {
696
883
  }
697
884
  }
698
885
  }
886
+ /**
887
+ * Get string presentation of interval (e.g. "Descending Major 2").
888
+ * @returns - Interval string.
889
+ */
699
890
  toString() {
700
891
  let direction = this.direction === "Unison" ? "" : this.direction + " ";
701
892
  let quality = this.quality + " ";
702
893
  let quantity = this.direction === "Unison" ? "Unison" : formatQuantity(this.quantity);
703
894
  return direction + quality + quantity;
704
895
  }
896
+ /**
897
+ * Get abbrevated string presentation of interval (e.g. "↓M2").
898
+ * @returns - Interval abbrevated string.
899
+ */
705
900
  toAbbrString() {
706
901
  var _a;
707
902
  let direction = this.direction === "Descending" ? "\u2193" : "";
@@ -796,12 +991,20 @@ function getMode(scaleType) {
796
991
  }
797
992
  }
798
993
  var Scale = class extends KeySignature {
994
+ /**
995
+ * Create nev scale object instance.
996
+ * @param tonic - Tonic (e.g. "C" in "C Major").
997
+ * @param scaleType - Scale typo ("e.g. "Major" in "C Major").
998
+ */
799
999
  constructor(tonic, scaleType) {
800
1000
  super(tonic, getMode(scaleType));
801
1001
  this.tonic = tonic;
802
1002
  this.scaleType = scaleType;
1003
+ /** Degrees of scale notes. */
803
1004
  __publicField(this, "scaleDegrees");
1005
+ /** Scale notes. */
804
1006
  __publicField(this, "scaleNotes");
1007
+ /** Degrees (or undefined) of chromatic classes. */
805
1008
  __publicField(this, "chromaticClassDegree");
806
1009
  __publicField(this, "preferredChromaticNoteCache", /* @__PURE__ */ new Map());
807
1010
  switch (scaleType) {
@@ -833,6 +1036,12 @@ var Scale = class extends KeySignature {
833
1036
  return id >= 0 ? this.scaleDegrees[id] : void 0;
834
1037
  });
835
1038
  }
1039
+ /**
1040
+ * Compare if two scales equals.
1041
+ * @param a - Scale a.
1042
+ * @param b - Scale b.
1043
+ * @returns - Boolean equality of given scales.
1044
+ */
836
1045
  static equals(a, b) {
837
1046
  if (a == null && b == null) {
838
1047
  return true;
@@ -842,6 +1051,11 @@ var Scale = class extends KeySignature {
842
1051
  return a === b || a.getScaleName() === b.getScaleName();
843
1052
  }
844
1053
  }
1054
+ /**
1055
+ * Get scale name.
1056
+ * @param symbolSet - Symbol set to format scale name in ascii or unicode.
1057
+ * @returns - Scale name string.
1058
+ */
845
1059
  getScaleName(symbolSet) {
846
1060
  switch (symbolSet) {
847
1061
  case 1 /* Unicode */:
@@ -850,6 +1064,12 @@ var Scale = class extends KeySignature {
850
1064
  return this.tonic + " " + this.scaleType;
851
1065
  }
852
1066
  }
1067
+ /**
1068
+ * Get scale notes.
1069
+ * @param bottomNote - Computed scale notes begin no lower than this note.
1070
+ * @param numOctaves - How many octaves?
1071
+ * @returns - Array of scale notes.
1072
+ */
853
1073
  getScaleNotes(bottomNote, numOctaves) {
854
1074
  if (!import_ts_utils_lib5.Utils.Is.isIntegerGte(numOctaves, 1)) {
855
1075
  throw new import_core5.MusicError(import_core5.MusicErrorType.Scale, `Invalid numOctaves: ${numOctaves}`);
@@ -865,9 +1085,17 @@ var Scale = class extends KeySignature {
865
1085
  return new Note(diatonicId, note.accidental);
866
1086
  });
867
1087
  }
1088
+ /**
1089
+ * Get scale overview (e.g. "C - D - E - F - G - A - B" for "C Major" scale).
1090
+ * @returns - Scale overview string.
1091
+ */
868
1092
  getScaleOverview() {
869
1093
  return this.getScaleNotes("C4", 1).map((note) => note.formatOmitOctave(1 /* Unicode */)).join(" - ");
870
1094
  }
1095
+ /**
1096
+ * Get scale steps, array of 1 (half step) and 2 (whole step), (e.g. [2, 2, 1, 2, 2, 2, 1] for Major scale).
1097
+ * @returns - Array of scale steps.
1098
+ */
871
1099
  getScaleSteps() {
872
1100
  let chromaticIds = this.getScaleNotes("C4", 1).map((note) => note.chromaticId);
873
1101
  let steps = [];
@@ -876,15 +1104,34 @@ var Scale = class extends KeySignature {
876
1104
  }
877
1105
  return steps;
878
1106
  }
1107
+ /**
1108
+ * Get scale steps string presentation, array of "H" (half step) and "W" (whole step), (e.g. ["W", "W", "H", "W", "W", "W", "H"] for Major scale).
1109
+ * @returns - Array of scale steps string presentation.
1110
+ */
879
1111
  getScaleStringSteps() {
880
1112
  return this.getScaleSteps().map((step) => step === 1 ? "H" : step === 2 ? "W" : step.toString() + "H");
881
1113
  }
1114
+ /**
1115
+ * Test if given note is scale note.
1116
+ * @param note - Note to test.
1117
+ * @returns - True/false.
1118
+ */
882
1119
  isScaleNote(note) {
883
1120
  return this.chromaticClassDegree[note.chromaticClass] !== void 0;
884
1121
  }
1122
+ /**
1123
+ * Test if given note is scale root note.
1124
+ * @param note - Note to test.
1125
+ * @returns - True/false.
1126
+ */
885
1127
  isScaleRootNote(note) {
886
1128
  return String(this.chromaticClassDegree[note.chromaticClass]) === "1";
887
1129
  }
1130
+ /**
1131
+ * Get interval value between scale root note and given note.
1132
+ * @param note - Note.
1133
+ * @returns - Interval.
1134
+ */
888
1135
  getIntervalFromRootNote(note) {
889
1136
  let rootNote = this.getScaleNotes("C0", 1)[0];
890
1137
  while (note.chromaticId >= rootNote.chromaticId + 12) {
@@ -900,6 +1147,11 @@ var Scale = class extends KeySignature {
900
1147
  return interval;
901
1148
  }
902
1149
  }
1150
+ /**
1151
+ * Get preferred chromatic note from given chromatic id.
1152
+ * @param chromaticId - Chromatic id.
1153
+ * @returns - Note.
1154
+ */
903
1155
  getPreferredChromaticNote(chromaticId) {
904
1156
  Note.validateChromaticId(chromaticId);
905
1157
  let note = this.preferredChromaticNoteCache.get(chromaticId);
@@ -942,6 +1194,10 @@ var Scale = class extends KeySignature {
942
1194
  }
943
1195
  };
944
1196
  var ScaleFactory = class {
1197
+ /**
1198
+ * Create new scale factory object instance.
1199
+ * @param type - Scale type.
1200
+ */
945
1201
  constructor(type) {
946
1202
  this.type = type;
947
1203
  __publicField(this, "tonicList", []);
@@ -987,15 +1243,32 @@ var ScaleFactory = class {
987
1243
  ...flatScales.sort(SortByAccidentalCountFunc).map((scale) => scale.tonic)
988
1244
  ];
989
1245
  }
1246
+ /**
1247
+ * Get list of tonics (e.g. "C", "C#", ... for Major scale type).
1248
+ * @returns - Array of tonics.
1249
+ */
990
1250
  getTonicList() {
991
1251
  return this.tonicList;
992
1252
  }
1253
+ /**
1254
+ * Get default tonic.
1255
+ * @returns - Default tonic.
1256
+ */
993
1257
  getDefaultTonic() {
994
1258
  return this.tonicList[0];
995
1259
  }
1260
+ /**
1261
+ * Get scale type.
1262
+ * @returns - SCale type.
1263
+ */
996
1264
  getType() {
997
1265
  return this.type;
998
1266
  }
1267
+ /**
1268
+ * Get scale by given tonic.
1269
+ * @param tonic - Tonic (e.g. "C").
1270
+ * @returns - Scale.
1271
+ */
999
1272
  getScale(tonic) {
1000
1273
  let scale = this.scaleMap.get(tonic);
1001
1274
  if (!scale) {
@@ -1004,6 +1277,11 @@ var ScaleFactory = class {
1004
1277
  return scale;
1005
1278
  }
1006
1279
  }
1280
+ /**
1281
+ * Test if this scale factory has scale for given tonic value.
1282
+ * @param tonic - Tonic.
1283
+ * @returns - True/false.
1284
+ */
1007
1285
  hasScale(tonic) {
1008
1286
  return this.scaleMap.get(tonic) !== void 0;
1009
1287
  }
@@ -1168,9 +1446,13 @@ var Chord = class _Chord {
1168
1446
  constructor(chordInfo, chordNotes, rootNote, bassNote) {
1169
1447
  this.chordInfo = chordInfo;
1170
1448
  this.rootNote = rootNote;
1449
+ /** Chord name. */
1171
1450
  __publicField(this, "name");
1451
+ /** Notes of this chord. */
1172
1452
  __publicField(this, "notes");
1453
+ /** Notes that are omitted in this chord (partial chord). */
1173
1454
  __publicField(this, "omitNotes");
1455
+ /** Bass note if not chord root note (e.g. "B" in "C/B"). */
1174
1456
  __publicField(this, "slashBassNote");
1175
1457
  this.name = chordInfo.name;
1176
1458
  let notesLeft = chordNotes.slice();
@@ -1209,6 +1491,11 @@ var Chord = class _Chord {
1209
1491
  throw new InvalidChordException("Power chord no bass note allowed!");
1210
1492
  }
1211
1493
  }
1494
+ /**
1495
+ * Get all chords that can be made up with given notes.
1496
+ * @param notes - Array of notes.
1497
+ * @returns - Array of chords.
1498
+ */
1212
1499
  static getChords(notes) {
1213
1500
  let chords = [];
1214
1501
  let chordNotes = Note.sort(notes);
@@ -1248,7 +1535,8 @@ var Chord = class _Chord {
1248
1535
  return true;
1249
1536
  }
1250
1537
  /**
1251
- * @returns Chord name e.g. "C/B"
1538
+ * Get chord string presentation.
1539
+ * @returns Chord string presentation (e.g. "C/B").
1252
1540
  */
1253
1541
  toString() {
1254
1542
  let symbolSet = 1 /* Unicode */;
@@ -1257,7 +1545,8 @@ var Chord = class _Chord {
1257
1545
  return rootNoteStr + this.name + slashBassStr;
1258
1546
  }
1259
1547
  /**
1260
- * @returns Degree notation string, e.g. "E - 1(C) - 3(E) - 5(G)"
1548
+ * Get degree notation string (e.g. "E - 1(C) - 3(E) - 5(G)").
1549
+ * @returns Degree notation string.
1261
1550
  */
1262
1551
  getDegreeNotationString() {
1263
1552
  let symbolSet = 1 /* Unicode */;
@@ -1268,7 +1557,8 @@ var Chord = class _Chord {
1268
1557
  return bassNoteStr + degreeNoteStr;
1269
1558
  }
1270
1559
  /**
1271
- * @returns Omitted degrees string e.g. "Omits 5(G), 9(D)"
1560
+ * Get string presentation of omitted degrees (e.g. "Omits 5(G), 9(D)").
1561
+ * @returns - String presentation of omitted degrees.
1272
1562
  */
1273
1563
  getOmittedDegreesString() {
1274
1564
  let omittedStrList = this.omitNotes.map((omit, i) => {
@@ -1277,15 +1567,17 @@ var Chord = class _Chord {
1277
1567
  return omittedStrList.length > 0 ? "Omits " + omittedStrList.join(", ") : "";
1278
1568
  }
1279
1569
  /**
1280
- * @param i - Degree index
1281
- * @returns Degree string for given degree index, e.g. "3"
1570
+ * Degree index for given degree index (e.g. "3").
1571
+ * @param i - Chord degree index (e.g. 0 is first note degree of chord).
1572
+ * @returns Degree string.
1282
1573
  */
1283
1574
  getDegreeStr(i) {
1284
1575
  return Note.replaceAccidentalSymbols("" + this.chordInfo.degrees[i], 1 /* Unicode */);
1285
1576
  }
1286
1577
  /**
1287
- * @param i - Degree index
1288
- * @returns Note string for given degree index, e.g. "E"
1578
+ * Get note name for given degree index (e.g. "E").
1579
+ * @param i - Chord degree index (e.g. 0 is first note degree of chord).
1580
+ * @returns - Note name string.
1289
1581
  */
1290
1582
  getNoteStr(i) {
1291
1583
  return this.notes[i].formatOmitOctave(1 /* Unicode */);
@@ -1597,6 +1889,7 @@ var NoteLength = /* @__PURE__ */ ((NoteLength3) => {
1597
1889
  NoteLength3["Whole"] = "1n";
1598
1890
  NoteLength3["WholeTriplet"] = "1t";
1599
1891
  NoteLength3["WholeDot"] = "1.";
1892
+ NoteLength3["Whole2Dots"] = "1..";
1600
1893
  NoteLength3["Whole12Dots"] = "1..";
1601
1894
  NoteLength3["Whole3Dots"] = "1...";
1602
1895
  NoteLength3["Whole4Dots"] = "1....";
@@ -1639,17 +1932,24 @@ function validateNoteLength(noteLength) {
1639
1932
  }
1640
1933
  }
1641
1934
  var _NoteLengthProps = class _NoteLengthProps {
1642
- // Is solid (black) note head?
1643
1935
  constructor(noteLength) {
1936
+ /** Note length. */
1644
1937
  __publicField(this, "noteLength");
1938
+ /** Note size (whole=1, half=2, quarter=4, ...). */
1645
1939
  __publicField(this, "noteSize");
1940
+ /** Number of ticks (not altered by isTriplet). */
1646
1941
  __publicField(this, "ticks");
1647
- // Not altered by isTriplet!
1942
+ /** Flag count. */
1648
1943
  __publicField(this, "flagCount");
1944
+ /** Dot count. */
1649
1945
  __publicField(this, "dotCount");
1946
+ /** Max dot count. */
1650
1947
  __publicField(this, "maxDotCount");
1948
+ /** Is triplet? */
1651
1949
  __publicField(this, "isTriplet");
1950
+ /** Has note stem. */
1652
1951
  __publicField(this, "hasStem");
1952
+ /** Is note head solid (black)? */
1653
1953
  __publicField(this, "isSolid");
1654
1954
  this.noteLength = validateNoteLength(noteLength);
1655
1955
  this.noteSize = parseInt(noteLength);
@@ -1666,6 +1966,11 @@ var _NoteLengthProps = class _NoteLengthProps {
1666
1966
  throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `noteLength "${this.noteLength}" is both triplet and dotted!`);
1667
1967
  }
1668
1968
  }
1969
+ /**
1970
+ * Get note length props.
1971
+ * @param noteLength - Note length.
1972
+ * @returns - Note length props.
1973
+ */
1669
1974
  static get(noteLength) {
1670
1975
  let p = this.cache.get(noteLength);
1671
1976
  if (!p) {
@@ -1673,6 +1978,12 @@ var _NoteLengthProps = class _NoteLengthProps {
1673
1978
  }
1674
1979
  return p;
1675
1980
  }
1981
+ /**
1982
+ * Create note length props.
1983
+ * @param noteLength - Note length or note size.
1984
+ * @param dotCount - Dot count.
1985
+ * @returns - Note length props.
1986
+ */
1676
1987
  static create(noteLength, dotCount = 0) {
1677
1988
  let noteSize = typeof noteLength === "number" ? noteLength : this.get(noteLength).noteSize;
1678
1989
  return this.get(noteSize + (import_ts_utils_lib8.Utils.Is.isIntegerGte(dotCount, 1) ? ".".repeat(dotCount) : "n"));
@@ -1702,7 +2013,9 @@ var _NoteLengthProps = class _NoteLengthProps {
1702
2013
  return aNoteSize === bNoteSize;
1703
2014
  }
1704
2015
  };
2016
+ /** Longest note size (e.g. 1 = whole note). */
1705
2017
  __publicField(_NoteLengthProps, "LongestNoteSize", Math.min(...import_ts_utils_lib8.Utils.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
2018
+ /** Shortest note size (e.g. 64 = sixtyfourth note). */
1706
2019
  __publicField(_NoteLengthProps, "ShortestNoteSize", Math.max(...import_ts_utils_lib8.Utils.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
1707
2020
  __publicField(_NoteLengthProps, "cache", /* @__PURE__ */ new Map());
1708
2021
  var NoteLengthProps = _NoteLengthProps;
@@ -1714,23 +2027,30 @@ function validateTupletRatio(tupletRatio) {
1714
2027
  }
1715
2028
  }
1716
2029
  var Tuplet = {
1717
- /** 2 in the time of 3 */
2030
+ /** Duplet: 2 in the time of 3 */
1718
2031
  Duplet: { parts: 2, inTimeOf: 3 },
1719
- /** 3 in the time of 2 */
2032
+ /** Triplet: 3 in the time of 2 */
1720
2033
  Triplet: { parts: 3, inTimeOf: 2 },
1721
- /** 4 in the time of 3 */
2034
+ /** Quadruplet: 4 in the time of 3 */
1722
2035
  Quadruplet: { parts: 4, inTimeOf: 3 }
1723
2036
  };
1724
2037
  var _RhythmProps = class _RhythmProps {
1725
2038
  constructor(noteLength, dotCount, tupletRatio) {
2039
+ /** Note length. */
1726
2040
  __publicField(this, "noteLength");
2041
+ /** Note size (whole=1, half=2, quarter=4, ...). */
1727
2042
  __publicField(this, "noteSize");
1728
- // whole=1, half=2, quarter=4, etc.
2043
+ /** Dot count. */
1729
2044
  __publicField(this, "dotCount");
2045
+ /** Tuplet ratio. */
1730
2046
  __publicField(this, "tupletRatio");
2047
+ /** Number of ticks. */
1731
2048
  __publicField(this, "ticks");
2049
+ /** Flag count. */
1732
2050
  __publicField(this, "flagCount");
2051
+ /** Has note stem. */
1733
2052
  __publicField(this, "hasStem");
2053
+ /** Is note head solid (black)? */
1734
2054
  __publicField(this, "isSolidNoteHead");
1735
2055
  this.noteLength = validateNoteLength(noteLength);
1736
2056
  let p = NoteLengthProps.get(noteLength);
@@ -1759,11 +2079,22 @@ var _RhythmProps = class _RhythmProps {
1759
2079
  this.ticks *= this.tupletRatio.inTimeOf / this.tupletRatio.parts;
1760
2080
  }
1761
2081
  }
2082
+ /**
2083
+ * Get string presentation of rhythm props.
2084
+ * @returns - String presentation.
2085
+ */
1762
2086
  toString() {
1763
2087
  let sym = _RhythmProps.NoteSymbolMap.get(this.noteSize);
1764
2088
  let dots = ".".repeat(this.dotCount);
1765
2089
  return sym ? sym + dots : "" + this.noteSize + (dots.length > 0 ? dots : "n");
1766
2090
  }
2091
+ /**
2092
+ * Get rhythm props with given arguments.
2093
+ * @param noteLength - Note length.
2094
+ * @param dotCount - Dot count.
2095
+ * @param tupletRatio - Tuplet ratio.
2096
+ * @returns - Rhythm props.
2097
+ */
1767
2098
  static get(noteLength, dotCount, tupletRatio) {
1768
2099
  if (dotCount !== void 0 || tupletRatio !== void 0) {
1769
2100
  return new _RhythmProps(noteLength, dotCount, tupletRatio);
@@ -1800,22 +2131,50 @@ var RhythmProps = _RhythmProps;
1800
2131
 
1801
2132
  // src/theory/time-signature.ts
1802
2133
  var import_core9 = require("@tspro/web-music-score/core");
2134
+ var TimeSignatures = /* @__PURE__ */ ((TimeSignatures2) => {
2135
+ TimeSignatures2["_2_4"] = "2/4";
2136
+ TimeSignatures2["_3_4"] = "3/4";
2137
+ TimeSignatures2["_4_4"] = "4/4";
2138
+ TimeSignatures2["_5_8"] = "5/8";
2139
+ TimeSignatures2["_6_8"] = "6/8";
2140
+ TimeSignatures2["_7_8"] = "7/8";
2141
+ TimeSignatures2["_9_8"] = "9/8";
2142
+ TimeSignatures2["_12_8"] = "12/8";
2143
+ return TimeSignatures2;
2144
+ })(TimeSignatures || {});
2145
+ var BeamGrouping = /* @__PURE__ */ ((BeamGrouping2) => {
2146
+ BeamGrouping2["_2_3"] = "2-3";
2147
+ BeamGrouping2["_3_2"] = "3-2";
2148
+ BeamGrouping2["_2_2_3"] = "2-2-3";
2149
+ BeamGrouping2["_3_2_2"] = "3-2-2";
2150
+ return BeamGrouping2;
2151
+ })(BeamGrouping || {});
1803
2152
  var TimeSignature = class {
1804
2153
  constructor(...args) {
2154
+ /** Number of beats in measure, upper value (e.g. "3" in "3/4"). */
1805
2155
  __publicField(this, "beatCount");
2156
+ /** Beat size of time signature, lower value (e.g. "4" in "3/4"). */
1806
2157
  __publicField(this, "beatSize");
1807
- /** Lengths in ticks */
2158
+ /** Beat length. */
1808
2159
  __publicField(this, "beatLength");
2160
+ /** Number of ticks in measure. */
1809
2161
  __publicField(this, "measureTicks");
1810
- __publicField(this, "beamGroupCount");
1811
- __publicField(this, "beamGroupLength");
1812
- if (args.length === 1 && typeof args[0] === "string") {
2162
+ /** Beam groups (e.g. [[2], [2]] or [[2, 2], [2, 2]] (first try as [[4], [4]])). */
2163
+ __publicField(this, "beamGroupSizes", []);
2164
+ let beamGrouping;
2165
+ if (import_ts_utils_lib9.Utils.Is.isEnumValue(args[0], TimeSignatures)) {
1813
2166
  let parts = args[0].split("/");
1814
2167
  this.beatCount = +parts[0];
1815
2168
  this.beatSize = +parts[1];
1816
- } else if (args.length === 2 && typeof args[0] === "number" && typeof args[1] === "number") {
2169
+ if (import_ts_utils_lib9.Utils.Is.isEnumValue(args[1], BeamGrouping)) {
2170
+ beamGrouping = args[1];
2171
+ }
2172
+ } else if (import_ts_utils_lib9.Utils.Is.isIntegerGte(args[0], 2) && import_ts_utils_lib9.Utils.Is.isIntegerGte(args[1], 2)) {
1817
2173
  this.beatCount = args[0];
1818
2174
  this.beatSize = args[1];
2175
+ if (import_ts_utils_lib9.Utils.Is.isEnumValue(args[2], BeamGrouping)) {
2176
+ beamGrouping = args[2];
2177
+ }
1819
2178
  } else {
1820
2179
  throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Invalid args: ${args}`);
1821
2180
  }
@@ -1824,25 +2183,55 @@ var TimeSignature = class {
1824
2183
  } else if (!import_ts_utils_lib9.Utils.Is.isIntegerGte(this.beatSize, 1)) {
1825
2184
  throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Invalid beatSize: ${this.beatSize}`);
1826
2185
  }
1827
- let props = NoteLengthProps.create(this.beatSize);
1828
- this.beatLength = props.noteLength;
1829
- this.measureTicks = this.beatCount * props.ticks;
1830
- if (this.is(2, 4) || this.is(3, 4) || this.is(4, 4)) {
1831
- this.beamGroupCount = this.beatCount;
1832
- } else if (this.is(6, 8) || this.is(9, 8)) {
1833
- this.beamGroupCount = this.beatCount / 3;
1834
- } else {
1835
- console.warn("Not necessarily an error, but unsupported time signature: " + this.toString());
1836
- this.beamGroupCount = 1;
2186
+ let { noteLength, ticks } = NoteLengthProps.create(this.beatSize);
2187
+ this.beatLength = noteLength;
2188
+ this.measureTicks = this.beatCount * ticks;
2189
+ if (this.is(2, 4)) {
2190
+ this.beamGroupSizes = [[2], [2]];
2191
+ } else if (this.is(3, 4)) {
2192
+ this.beamGroupSizes = [[2], [2], [2]];
2193
+ } else if (this.is(4, 4)) {
2194
+ this.beamGroupSizes = [[2, 2], [2, 2]];
2195
+ } else if (this.is(5, 8)) {
2196
+ if (!import_ts_utils_lib9.Utils.Is.isUndefined(beamGrouping) && beamGrouping !== "2-3" /* _2_3 */ && beamGrouping !== "3-2" /* _3_2 */) {
2197
+ throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Invalid beam grouping "${beamGrouping}" for time signature "${this.toString()}".`);
2198
+ } else {
2199
+ this.beamGroupSizes = beamGrouping === "3-2" /* _3_2 */ ? [[3], [2]] : [[2], [3]];
2200
+ beamGrouping = void 0;
2201
+ }
2202
+ } else if (this.is(6, 8)) {
2203
+ this.beamGroupSizes = [[3], [3]];
2204
+ } else if (this.is(7, 8)) {
2205
+ if (!import_ts_utils_lib9.Utils.Is.isUndefined(beamGrouping) && beamGrouping !== "2-2-3" /* _2_2_3 */ && beamGrouping !== "3-2-2" /* _3_2_2 */) {
2206
+ throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Invalid beam grouping "${beamGrouping}" for time signature "${this.toString()}".`);
2207
+ } else {
2208
+ this.beamGroupSizes = beamGrouping === "3-2-2" /* _3_2_2 */ ? [[3], [2], [2]] : [[2], [2], [3]];
2209
+ beamGrouping = void 0;
2210
+ }
2211
+ } else if (this.is(9, 8)) {
2212
+ this.beamGroupSizes = [[3], [3], [3]];
2213
+ } else if (this.is(12, 8)) {
2214
+ this.beamGroupSizes = [[3], [3], [3], [3]];
1837
2215
  }
1838
- this.beamGroupLength = this.measureTicks / this.beamGroupCount;
1839
- if (!import_ts_utils_lib9.Utils.Is.isIntegerGte(this.beamGroupLength, 1)) {
1840
- throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Invalid beamGroupLength: ${this.beamGroupLength}`);
2216
+ if (this.beamGroupSizes.length === 0) {
2217
+ throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Unimplemented time signature "${this.toString()}".`);
2218
+ } else if (beamGrouping !== void 0) {
2219
+ throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Invalid beam grouping "${beamGrouping}" for time signature "${this.toString()}".`);
1841
2220
  }
1842
2221
  }
2222
+ /**
2223
+ * Test whether this time signature has given beat count and size.
2224
+ * @param beatCount - Beat count.
2225
+ * @param beatSize - Beat size.
2226
+ * @returns - Boolean whether this time signature match given beat count and size.
2227
+ */
1843
2228
  is(beatCount, beatSize) {
1844
2229
  return this.beatCount === beatCount && this.beatSize === beatSize;
1845
2230
  }
2231
+ /**
2232
+ * Get string representation of this time signature (e.g. "3/4").
2233
+ * @returns - String representation.
2234
+ */
1846
2235
  toString() {
1847
2236
  return this.beatCount + "/" + this.beatSize;
1848
2237
  }
@@ -1879,6 +2268,7 @@ var import_core10 = require("@tspro/web-music-score/core");
1879
2268
  // Annotate the CommonJS export names for ESM import in node:
1880
2269
  0 && (module.exports = {
1881
2270
  AccidentalType,
2271
+ BeamGrouping,
1882
2272
  Chord,
1883
2273
  DefaultGuitarNoteLabel,
1884
2274
  DefaultHandedness,
@@ -1901,6 +2291,7 @@ var import_core10 = require("@tspro/web-music-score/core");
1901
2291
  ScaleType,
1902
2292
  SymbolSet,
1903
2293
  TimeSignature,
2294
+ TimeSignatures,
1904
2295
  TuningNameList,
1905
2296
  Tuplet,
1906
2297
  alterTempoSpeed,