@tspro/web-music-score 3.2.0 → 4.0.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 (38) hide show
  1. package/CHANGELOG.md +26 -10
  2. package/README.md +189 -331
  3. package/dist/audio/index.d.ts +1 -1
  4. package/dist/audio/index.js +1 -1
  5. package/dist/audio/index.mjs +2 -2
  6. package/dist/audio-cg/index.js +1 -1
  7. package/dist/audio-cg/index.mjs +2 -2
  8. package/dist/{chunk-LCTM7BID.mjs → chunk-D643HZHM.mjs} +2 -2
  9. package/dist/core/index.js +2 -2
  10. package/dist/core/index.mjs +3 -3
  11. package/dist/{guitar-C2Cp71NZ.d.ts → guitar-cNmE-EvH.d.ts} +1 -1
  12. package/dist/iife/index.global.js +11 -11
  13. package/dist/{interface-BlNl69uT.d.ts → interface-7k8qGG44.d.ts} +89 -81
  14. package/dist/{interface-Bn5HFt_U.d.mts → interface-XoKiryoV.d.mts} +88 -80
  15. package/dist/{note-BFa43I86.d.ts → note-CcVdUFqS.d.ts} +1 -1
  16. package/dist/pieces/index.d.mts +2 -2
  17. package/dist/pieces/index.d.ts +3 -3
  18. package/dist/pieces/index.js +4 -7
  19. package/dist/pieces/index.mjs +8 -11
  20. package/dist/react-ui/index.d.mts +3 -3
  21. package/dist/react-ui/index.d.ts +5 -5
  22. package/dist/react-ui/index.js +1 -1
  23. package/dist/react-ui/index.mjs +2 -2
  24. package/dist/{scale-DRR-t4Kr.d.mts → scale-C2pCNxdE.d.mts} +4 -3
  25. package/dist/{scale-ebJm37q1.d.ts → scale-CvPbJvfN.d.ts} +5 -4
  26. package/dist/score/index.d.mts +98 -31
  27. package/dist/score/index.d.ts +99 -32
  28. package/dist/score/index.js +748 -567
  29. package/dist/score/index.mjs +755 -574
  30. package/dist/tempo-BAYoZ_Li.d.mts +187 -0
  31. package/dist/tempo-r2sb6Ku2.d.ts +187 -0
  32. package/dist/theory/index.d.mts +3 -3
  33. package/dist/theory/index.d.ts +6 -6
  34. package/dist/theory/index.js +221 -78
  35. package/dist/theory/index.mjs +218 -76
  36. package/package.json +2 -2
  37. package/dist/tempo-B4h5Ktob.d.mts +0 -104
  38. package/dist/tempo-DgqDEsn0.d.ts +0 -104
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v3.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.0.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;
@@ -34,11 +34,10 @@ __export(theory_exports, {
34
34
  Handedness: () => Handedness,
35
35
  Interval: () => Interval,
36
36
  KeySignature: () => KeySignature,
37
- MaxNoteLength: () => MaxNoteLength,
38
- MinNoteLength: () => MinNoteLength,
39
37
  Mode: () => Mode,
40
38
  Note: () => Note,
41
39
  NoteLength: () => NoteLength,
40
+ NoteLengthProps: () => NoteLengthProps,
42
41
  PitchNotation: () => PitchNotation,
43
42
  PitchNotationList: () => PitchNotationList,
44
43
  RhythmProps: () => RhythmProps,
@@ -48,6 +47,7 @@ __export(theory_exports, {
48
47
  SymbolSet: () => SymbolSet,
49
48
  TimeSignature: () => TimeSignature,
50
49
  TuningNameList: () => TuningNameList,
50
+ Tuplet: () => Tuplet,
51
51
  alterTempoSpeed: () => alterTempoSpeed,
52
52
  getDefaultKeySignature: () => getDefaultKeySignature,
53
53
  getDefaultScale: () => getDefaultScale,
@@ -65,7 +65,8 @@ __export(theory_exports, {
65
65
  validateNoteLength: () => validateNoteLength,
66
66
  validatePitchNotation: () => validatePitchNotation,
67
67
  validateScaleType: () => validateScaleType,
68
- validateTuningName: () => validateTuningName
68
+ validateTuningName: () => validateTuningName,
69
+ validateTupletRatio: () => validateTupletRatio
69
70
  });
70
71
  module.exports = __toCommonJS(theory_exports);
71
72
 
@@ -91,10 +92,10 @@ var PitchNotation = /* @__PURE__ */ ((PitchNotation2) => {
91
92
  var PitchNotationList = import_ts_utils_lib.Utils.Enum.getEnumValues(PitchNotation);
92
93
  var DefaultPitchNotation = 0 /* Scientific */;
93
94
  function validatePitchNotation(pn) {
94
- if (!import_ts_utils_lib.Utils.Is.isEnumValue(pn, PitchNotation)) {
95
- throw new import_core.MusicError(import_core.MusicErrorType.InvalidArg, `Invalid pitchNotation: ${pn}`);
96
- } else {
95
+ if (import_ts_utils_lib.Utils.Is.isEnumValue(pn, PitchNotation)) {
97
96
  return pn;
97
+ } else {
98
+ throw new import_core.MusicError(import_core.MusicErrorType.InvalidArg, `Invalid pitchNotation: ${pn}`);
98
99
  }
99
100
  }
100
101
  function getPitchNotationName(pn) {
@@ -109,10 +110,10 @@ var GuitarNoteLabel = /* @__PURE__ */ ((GuitarNoteLabel2) => {
109
110
  var DefaultGuitarNoteLabel = "Default" /* Default */;
110
111
  var GuitarNoteLabelList = import_ts_utils_lib.Utils.Enum.getEnumValues(GuitarNoteLabel);
111
112
  function validateGuitarNoteLabel(label) {
112
- if (!import_ts_utils_lib.Utils.Is.isEnumValue(label, GuitarNoteLabel)) {
113
- throw new import_core.MusicError(import_core.MusicErrorType.Timesignature, `Invalid guitarNoteLabel: ${label}`);
114
- } else {
113
+ if (import_ts_utils_lib.Utils.Is.isEnumValue(label, GuitarNoteLabel)) {
115
114
  return label;
115
+ } else {
116
+ throw new import_core.MusicError(import_core.MusicErrorType.Timesignature, `Invalid guitarNoteLabel: ${label}`);
116
117
  }
117
118
  }
118
119
 
@@ -1048,10 +1049,19 @@ function validateScaleType(scaleType) {
1048
1049
  if (import_ts_utils_lib5.Utils.Is.isEnumValue(scaleType, ScaleType)) {
1049
1050
  return scaleType;
1050
1051
  } else {
1051
- throw new import_core5.MusicError(import_core5.MusicErrorType.Scale, `Invalid scaleType: ${scaleType}`);
1052
+ throw new import_core5.MusicError(import_core5.MusicErrorType.Scale, `Invalid scaleType: "${scaleType}"`);
1052
1053
  }
1053
1054
  }
1054
- function getScale(tonic, scaleType) {
1055
+ function getScale(arg0, arg1) {
1056
+ let tonic;
1057
+ let scaleType;
1058
+ if (arg1 !== void 0) {
1059
+ tonic = arg0;
1060
+ scaleType = validateScaleType(arg1);
1061
+ } else {
1062
+ tonic = arg0.split(" ")[0];
1063
+ scaleType = validateScaleType(arg0.substring(tonic.length + 1));
1064
+ }
1055
1065
  return getScaleFactory(scaleType).getScale(tonic);
1056
1066
  }
1057
1067
  var DefaultScale = getScale("C", "Major" /* Major */);
@@ -1542,10 +1552,10 @@ var Handedness = /* @__PURE__ */ ((Handedness2) => {
1542
1552
  })(Handedness || {});
1543
1553
  var DefaultHandedness = 0 /* RightHanded */;
1544
1554
  function validateHandedness(h) {
1545
- if (!import_ts_utils_lib7.Utils.Is.isEnumValue(h, Handedness)) {
1546
- throw new import_core7.MusicError(import_core7.MusicErrorType.InvalidArg, `Invalid handedness: ${h}`);
1547
- } else {
1555
+ if (import_ts_utils_lib7.Utils.Is.isEnumValue(h, Handedness)) {
1548
1556
  return h;
1557
+ } else {
1558
+ throw new import_core7.MusicError(import_core7.MusicErrorType.InvalidArg, `Invalid handedness: ${h}`);
1549
1559
  }
1550
1560
  }
1551
1561
  var TuningNameList = tunings_default.list.map((data) => data.name);
@@ -1580,81 +1590,213 @@ var import_ts_utils_lib9 = require("@tspro/ts-utils-lib");
1580
1590
  // src/theory/rhythm.ts
1581
1591
  var import_ts_utils_lib8 = require("@tspro/ts-utils-lib");
1582
1592
  var import_core8 = require("@tspro/web-music-score/core");
1593
+ var cmp = (a, b) => a === b ? 0 : a < b ? -1 : 1;
1594
+ var MaxTupletRatioValue = 12;
1595
+ var TicksMultiplier = 12 * 11 * 9 * 7 * 5;
1583
1596
  var NoteLength = /* @__PURE__ */ ((NoteLength3) => {
1584
- NoteLength3[NoteLength3["Whole"] = 192] = "Whole";
1585
- NoteLength3[NoteLength3["Half"] = 96] = "Half";
1586
- NoteLength3[NoteLength3["Quarter"] = 48] = "Quarter";
1587
- NoteLength3[NoteLength3["Eighth"] = 24] = "Eighth";
1588
- NoteLength3[NoteLength3["Sixteenth"] = 12] = "Sixteenth";
1589
- NoteLength3[NoteLength3["ThirtySecond"] = 6] = "ThirtySecond";
1590
- NoteLength3[NoteLength3["SixtyFourth"] = 3] = "SixtyFourth";
1597
+ NoteLength3["Whole"] = "1n";
1598
+ NoteLength3["WholeTriplet"] = "1t";
1599
+ NoteLength3["WholeDot"] = "1.";
1600
+ NoteLength3["Whole12Dots"] = "1..";
1601
+ NoteLength3["Whole3Dots"] = "1...";
1602
+ NoteLength3["Whole4Dots"] = "1....";
1603
+ NoteLength3["Whole5Dots"] = "1.....";
1604
+ NoteLength3["Whole6Dots"] = "1......";
1605
+ NoteLength3["Half"] = "2n";
1606
+ NoteLength3["HalfTriplet"] = "2t";
1607
+ NoteLength3["HalfDot"] = "2.";
1608
+ NoteLength3["Half2Dots"] = "2..";
1609
+ NoteLength3["Half3Dots"] = "2...";
1610
+ NoteLength3["Half4Dots"] = "2....";
1611
+ NoteLength3["Half5Dots"] = "2.....";
1612
+ NoteLength3["Quarter"] = "4n";
1613
+ NoteLength3["QuarterTriplet"] = "4t";
1614
+ NoteLength3["QuarterDot"] = "4.";
1615
+ NoteLength3["Quarter2Dots"] = "4..";
1616
+ NoteLength3["Quarter3Dots"] = "4...";
1617
+ NoteLength3["Quarter4Dots"] = "4....";
1618
+ NoteLength3["Eighth"] = "8n";
1619
+ NoteLength3["EighthTriplet"] = "8t";
1620
+ NoteLength3["EighthDot"] = "8.";
1621
+ NoteLength3["Eighth2Dots"] = "8..";
1622
+ NoteLength3["Eighth3Dots"] = "8...";
1623
+ NoteLength3["Sixteenth"] = "16n";
1624
+ NoteLength3["SixteenthTriplet"] = "16t";
1625
+ NoteLength3["SixteenthDot"] = "16.";
1626
+ NoteLength3["Sixteenth2Dots"] = "16..";
1627
+ NoteLength3["ThirtySecond"] = "32n";
1628
+ NoteLength3["ThirtySecondTriplet"] = "32t";
1629
+ NoteLength3["ThirtySecondDot"] = "32.";
1630
+ NoteLength3["SixtyFourth"] = "64n";
1631
+ NoteLength3["SixtyFourthTriplet"] = "64t";
1591
1632
  return NoteLength3;
1592
1633
  })(NoteLength || {});
1593
- var MaxNoteLength = 192 /* Whole */;
1594
- var MinNoteLength = 3 /* SixtyFourth */;
1595
- var FlagCountMap = /* @__PURE__ */ new Map([
1596
- [192 /* Whole */, 0],
1597
- [96 /* Half */, 0],
1598
- [48 /* Quarter */, 0],
1599
- [24 /* Eighth */, 1],
1600
- [12 /* Sixteenth */, 2],
1601
- [6 /* ThirtySecond */, 3],
1602
- [3 /* SixtyFourth */, 4]
1603
- ]);
1604
- var NoteSymbolMap = /* @__PURE__ */ new Map([
1605
- [192 /* Whole */, "\u{1D15D}"],
1606
- [96 /* Half */, "\u{1D15E}"],
1607
- [48 /* Quarter */, "\u{1D15F}"],
1608
- [24 /* Eighth */, "\u{1D160}"],
1609
- [12 /* Sixteenth */, "\u{1D161}"],
1610
- [6 /* ThirtySecond */, "\u{1D162}"],
1611
- [3 /* SixtyFourth */, "\u{1D163}"]
1612
- ]);
1613
1634
  function validateNoteLength(noteLength) {
1614
- if (!import_ts_utils_lib8.Utils.Is.isEnumValue(noteLength, NoteLength)) {
1635
+ if (import_ts_utils_lib8.Utils.Is.isEnumValue(noteLength, NoteLength)) {
1636
+ return noteLength;
1637
+ } else {
1615
1638
  throw new import_core8.MusicError(import_core8.MusicErrorType.InvalidArg, `Invalid noteLength: ${noteLength}`);
1639
+ }
1640
+ }
1641
+ var _NoteLengthProps = class _NoteLengthProps {
1642
+ // Is solid (black) note head?
1643
+ constructor(noteLength) {
1644
+ __publicField(this, "noteLength");
1645
+ __publicField(this, "noteSize");
1646
+ __publicField(this, "ticks");
1647
+ // Not altered by isTriplet!
1648
+ __publicField(this, "flagCount");
1649
+ __publicField(this, "dotCount");
1650
+ __publicField(this, "maxDotCount");
1651
+ __publicField(this, "isTriplet");
1652
+ __publicField(this, "hasStem");
1653
+ __publicField(this, "isSolid");
1654
+ this.noteLength = validateNoteLength(noteLength);
1655
+ this.noteSize = parseInt(noteLength);
1656
+ this.isTriplet = noteLength.endsWith("t");
1657
+ this.maxDotCount = this.isTriplet ? 0 : Math.floor(Math.log2(_NoteLengthProps.ShortestNoteSize / this.noteSize));
1658
+ this.dotCount = import_ts_utils_lib8.Utils.Str.charCount(noteLength, ".");
1659
+ this.flagCount = this.noteSize > 4 ? Math.floor(Math.log2(this.noteSize / 4)) : 0;
1660
+ this.ticks = TicksMultiplier * _NoteLengthProps.ShortestNoteSize / this.noteSize;
1661
+ this.hasStem = this.noteSize > 1;
1662
+ this.isSolid = this.noteSize > 2;
1663
+ if (this.dotCount > this.maxDotCount) {
1664
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `dotCount ${this.dotCount} > maxDotCount ${this.maxDotCount}, for noteLength "${this.noteLength}".`);
1665
+ } else if (this.isTriplet && this.dotCount > 0) {
1666
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `noteLength "${this.noteLength}" is both triplet and dotted!`);
1667
+ }
1668
+ }
1669
+ static get(noteLength) {
1670
+ let p = this.cache.get(noteLength);
1671
+ if (!p) {
1672
+ this.cache.set(noteLength, p = new _NoteLengthProps(noteLength));
1673
+ }
1674
+ return p;
1675
+ }
1676
+ static create(noteLength, dotCount = 0) {
1677
+ let noteSize = typeof noteLength === "number" ? noteLength : this.get(noteLength).noteSize;
1678
+ return this.get(noteSize + (import_ts_utils_lib8.Utils.Is.isIntegerGte(dotCount, 1) ? ".".repeat(dotCount) : "n"));
1679
+ }
1680
+ /**
1681
+ * Compare note lengths/sizes. Whole (1) > half (2) > quarter (4), etc.
1682
+ * Ignores possible triplet property of note length.
1683
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
1684
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
1685
+ * @returns - -1: a < b, 0: a === b, +1: a > b (note length/size comparisons)
1686
+ */
1687
+ static cmp(a, b) {
1688
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
1689
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
1690
+ return cmp(bNoteSize, aNoteSize);
1691
+ }
1692
+ /**
1693
+ * Compare note lengths/sizes for equality.
1694
+ * Ignores possible triplet property of note length.
1695
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
1696
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
1697
+ * @returns - true: a === b, false: a !== b (note length/size comparisons)
1698
+ */
1699
+ static equals(a, b) {
1700
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
1701
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
1702
+ return aNoteSize === bNoteSize;
1703
+ }
1704
+ };
1705
+ __publicField(_NoteLengthProps, "LongestNoteSize", Math.min(...import_ts_utils_lib8.Utils.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
1706
+ __publicField(_NoteLengthProps, "ShortestNoteSize", Math.max(...import_ts_utils_lib8.Utils.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
1707
+ __publicField(_NoteLengthProps, "cache", /* @__PURE__ */ new Map());
1708
+ var NoteLengthProps = _NoteLengthProps;
1709
+ function validateTupletRatio(tupletRatio) {
1710
+ if (import_ts_utils_lib8.Utils.Is.isObject(tupletRatio) && import_ts_utils_lib8.Utils.Is.isIntegerBetween(tupletRatio.parts, 2, MaxTupletRatioValue) && import_ts_utils_lib8.Utils.Is.isIntegerBetween(tupletRatio.inTimeOf, 2, MaxTupletRatioValue)) {
1711
+ return tupletRatio;
1616
1712
  } else {
1617
- return noteLength;
1713
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `Invalid tupletRatio ${JSON.stringify(tupletRatio)}`);
1618
1714
  }
1619
1715
  }
1620
- var RhythmProps = class _RhythmProps {
1621
- constructor(noteLength, dotted, triplet) {
1716
+ var Tuplet = {
1717
+ /** 2 in the time of 3 */
1718
+ Duplet: { parts: 2, inTimeOf: 3 },
1719
+ /** 3 in the time of 2 */
1720
+ Triplet: { parts: 3, inTimeOf: 2 },
1721
+ /** 4 in the time of 3 */
1722
+ Quadruplet: { parts: 4, inTimeOf: 3 }
1723
+ };
1724
+ var _RhythmProps = class _RhythmProps {
1725
+ constructor(noteLength, dotCount, tupletRatio) {
1622
1726
  __publicField(this, "noteLength");
1623
- __publicField(this, "dotted");
1624
- __publicField(this, "triplet");
1727
+ __publicField(this, "noteSize");
1728
+ // whole=1, half=2, quarter=4, etc.
1729
+ __publicField(this, "dotCount");
1730
+ __publicField(this, "tupletRatio");
1625
1731
  __publicField(this, "ticks");
1626
1732
  __publicField(this, "flagCount");
1627
- var _a;
1733
+ __publicField(this, "hasStem");
1734
+ __publicField(this, "isSolidNoteHead");
1628
1735
  this.noteLength = validateNoteLength(noteLength);
1629
- this.dotted = dotted === true;
1630
- this.triplet = triplet === true;
1631
- this.ticks = this.noteLength;
1632
- this.flagCount = (_a = FlagCountMap.get(this.noteLength)) != null ? _a : 0;
1633
- if (this.dotted && this.triplet) {
1634
- throw new import_core8.MusicError(import_core8.MusicErrorType.Note, "Note cannot be both dotted and triplet!");
1635
- } else if (this.dotted && this.noteLength === MinNoteLength) {
1636
- throw new import_core8.MusicError(import_core8.MusicErrorType.Note, "Shortest note cannot be dotted!");
1736
+ let p = NoteLengthProps.get(noteLength);
1737
+ this.noteSize = p.noteSize;
1738
+ this.ticks = p.ticks;
1739
+ this.flagCount = p.flagCount;
1740
+ this.dotCount = dotCount != null ? dotCount : p.dotCount;
1741
+ this.hasStem = p.hasStem;
1742
+ this.isSolidNoteHead = p.isSolid;
1743
+ if (import_ts_utils_lib8.Utils.Is.isObject(tupletRatio)) {
1744
+ this.tupletRatio = validateTupletRatio(tupletRatio);
1745
+ } else if (p.isTriplet) {
1746
+ this.tupletRatio = Tuplet.Triplet;
1747
+ } else {
1748
+ this.tupletRatio = void 0;
1637
1749
  }
1638
- if (this.dotted) {
1639
- this.ticks += this.noteLength / 2;
1750
+ if (this.dotCount > 0 && this.tupletRatio !== void 0) {
1751
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `Note cannot be both dotted and tuplet!`);
1752
+ } else if (this.dotCount > p.maxDotCount) {
1753
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `Too big dot count ${this.dotCount} for note length ${this.noteLength}.`);
1640
1754
  }
1641
- if (this.triplet) {
1642
- this.ticks = this.ticks * 2 / 3;
1755
+ for (let add = this.ticks / 2, i = 1; i <= this.dotCount; i++, add /= 2) {
1756
+ this.ticks += add;
1757
+ }
1758
+ if (this.tupletRatio) {
1759
+ this.ticks *= this.tupletRatio.inTimeOf / this.tupletRatio.parts;
1643
1760
  }
1644
1761
  }
1645
- static createFromNoteSize(noteSize) {
1646
- return new _RhythmProps(MaxNoteLength / noteSize);
1762
+ toString() {
1763
+ let sym = _RhythmProps.NoteSymbolMap.get(this.noteSize);
1764
+ let dots = ".".repeat(this.dotCount);
1765
+ return sym ? sym + dots : "" + this.noteSize + (dots.length > 0 ? dots : "n");
1647
1766
  }
1648
- canDot() {
1649
- return !this.dotted && this.noteLength !== MinNoteLength;
1767
+ static get(noteLength, dotCount, tupletRatio) {
1768
+ if (dotCount !== void 0 || tupletRatio !== void 0) {
1769
+ return new _RhythmProps(noteLength, dotCount, tupletRatio);
1770
+ } else {
1771
+ let rhythmProps = this.cache.get(noteLength);
1772
+ if (!rhythmProps) {
1773
+ this.cache.set(noteLength, rhythmProps = new _RhythmProps(noteLength));
1774
+ }
1775
+ return rhythmProps;
1776
+ }
1650
1777
  }
1651
- hasStem() {
1652
- return this.noteLength < 192 /* Whole */;
1778
+ /**
1779
+ * Compare duration of rhythm props.
1780
+ * @param a - RhythmProps
1781
+ * @param b - RhythmProps
1782
+ * @returns - -1: a < b, 0: a === b, +1: a > b (duration comparisons)
1783
+ */
1784
+ static cmp(a, b) {
1785
+ return cmp(a.ticks, b.ticks);
1653
1786
  }
1654
- toString() {
1655
- return NoteSymbolMap.get(this.noteLength) + (this.dotted ? "." : "");
1787
+ /**
1788
+ * Compare duration equality of rhythm props.
1789
+ * @param a - RhythmProps
1790
+ * @param b - RhythmProps
1791
+ * @returns - true: a === b, false: a !== b (duration comparisons)
1792
+ */
1793
+ static equals(a, b) {
1794
+ return a.ticks === b.ticks;
1656
1795
  }
1657
1796
  };
1797
+ __publicField(_RhythmProps, "NoteSymbolMap", /* @__PURE__ */ new Map([[1, "\u{1D15D}"], [2, "\u{1D15E}"], [4, "\u{1D15F}"], [8, "\u{1D160}"], [16, "\u{1D161}"], [32, "\u{1D162}"], [64, "\u{1D163}"], [128, "\u{1D164}"]]));
1798
+ __publicField(_RhythmProps, "cache", /* @__PURE__ */ new Map());
1799
+ var RhythmProps = _RhythmProps;
1658
1800
 
1659
1801
  // src/theory/time-signature.ts
1660
1802
  var import_core9 = require("@tspro/web-music-score/core");
@@ -1682,9 +1824,9 @@ var TimeSignature = class {
1682
1824
  } else if (!import_ts_utils_lib9.Utils.Is.isIntegerGte(this.beatSize, 1)) {
1683
1825
  throw new import_core9.MusicError(import_core9.MusicErrorType.Timesignature, `Invalid beatSize: ${this.beatSize}`);
1684
1826
  }
1685
- let beatLengthValue = RhythmProps.createFromNoteSize(this.beatSize);
1686
- this.beatLength = beatLengthValue.noteLength;
1687
- this.measureTicks = this.beatCount * beatLengthValue.ticks;
1827
+ let props = NoteLengthProps.create(this.beatSize);
1828
+ this.beatLength = props.noteLength;
1829
+ this.measureTicks = this.beatCount * props.ticks;
1688
1830
  if (this.is(2, 4) || this.is(3, 4) || this.is(4, 4)) {
1689
1831
  this.beamGroupCount = this.beatCount;
1690
1832
  } else if (this.is(6, 8) || this.is(9, 8)) {
@@ -1717,17 +1859,17 @@ function getDefaultTimeSignature() {
1717
1859
  var defaultTempo;
1718
1860
  function getDefaultTempo() {
1719
1861
  if (!defaultTempo) {
1720
- defaultTempo = { beatsPerMinute: 120, options: { beatLength: 48 /* Quarter */, dotted: false } };
1862
+ defaultTempo = { beatsPerMinute: 120, options: { beatLength: "4n" /* Quarter */, dotCount: 0 } };
1721
1863
  }
1722
1864
  return defaultTempo;
1723
1865
  }
1724
1866
  function getTempoString(tempo) {
1725
- return new RhythmProps(tempo.options.beatLength, tempo.options.dotted).toString() + "=" + tempo.beatsPerMinute;
1867
+ return RhythmProps.get(tempo.options.beatLength, tempo.options.dotCount).toString() + "=" + tempo.beatsPerMinute;
1726
1868
  }
1727
1869
  function alterTempoSpeed(tempo, speed) {
1728
1870
  return {
1729
1871
  beatsPerMinute: tempo.beatsPerMinute * speed,
1730
- options: { beatLength: tempo.options.beatLength, dotted: tempo.options.dotted }
1872
+ options: { beatLength: tempo.options.beatLength, dotCount: tempo.options.dotCount }
1731
1873
  };
1732
1874
  }
1733
1875
 
@@ -1747,11 +1889,10 @@ var import_core10 = require("@tspro/web-music-score/core");
1747
1889
  Handedness,
1748
1890
  Interval,
1749
1891
  KeySignature,
1750
- MaxNoteLength,
1751
- MinNoteLength,
1752
1892
  Mode,
1753
1893
  Note,
1754
1894
  NoteLength,
1895
+ NoteLengthProps,
1755
1896
  PitchNotation,
1756
1897
  PitchNotationList,
1757
1898
  RhythmProps,
@@ -1761,6 +1902,7 @@ var import_core10 = require("@tspro/web-music-score/core");
1761
1902
  SymbolSet,
1762
1903
  TimeSignature,
1763
1904
  TuningNameList,
1905
+ Tuplet,
1764
1906
  alterTempoSpeed,
1765
1907
  getDefaultKeySignature,
1766
1908
  getDefaultScale,
@@ -1778,6 +1920,7 @@ var import_core10 = require("@tspro/web-music-score/core");
1778
1920
  validateNoteLength,
1779
1921
  validatePitchNotation,
1780
1922
  validateScaleType,
1781
- validateTuningName
1923
+ validateTuningName,
1924
+ validateTupletRatio
1782
1925
  });
1783
1926
  //# sourceMappingURL=index.js.map