@tspro/web-music-score 5.4.1 → 5.4.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 (39) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/README.md +4 -4
  3. package/dist/audio/index.d.mts +1 -1
  4. package/dist/audio/index.js +1 -1
  5. package/dist/audio/index.mjs +3 -3
  6. package/dist/audio-cg/index.js +1 -1
  7. package/dist/audio-cg/index.mjs +3 -3
  8. package/dist/audio-synth/index.js +1 -1
  9. package/dist/audio-synth/index.mjs +3 -3
  10. package/dist/{chunk-A5SMODAT.mjs → chunk-42IBAVOC.mjs} +3 -3
  11. package/dist/{chunk-5I5KENEC.mjs → chunk-CVYTUTL6.mjs} +2 -2
  12. package/dist/{chunk-6P4ECBUH.mjs → chunk-MMWSQGVR.mjs} +3 -3
  13. package/dist/{chunk-U2ACCEHX.mjs → chunk-ROBXPR34.mjs} +2 -2
  14. package/dist/core/index.js +2 -2
  15. package/dist/core/index.mjs +4 -4
  16. package/dist/{guitar-DXlB-9vK.d.mts → guitar-DK18GZ6h.d.mts} +1 -1
  17. package/dist/iife/audio-cg.global.js +1 -1
  18. package/dist/iife/index.global.js +11 -11
  19. package/dist/{music-objects-DYMqx839.d.mts → music-objects-DqoO-Sfv.d.mts} +93 -39
  20. package/dist/{music-objects-DumXKWJp.d.ts → music-objects-T8u8bnNP.d.ts} +91 -37
  21. package/dist/{note-RVXvpfyV.d.mts → note-CJuq5aBy.d.mts} +1 -1
  22. package/dist/pieces/index.d.mts +3 -3
  23. package/dist/pieces/index.d.ts +1 -1
  24. package/dist/pieces/index.js +1 -1
  25. package/dist/pieces/index.mjs +2 -2
  26. package/dist/react-ui/index.d.mts +5 -5
  27. package/dist/react-ui/index.d.ts +1 -1
  28. package/dist/react-ui/index.js +1 -1
  29. package/dist/react-ui/index.mjs +2 -2
  30. package/dist/{scale-C8gHC448.d.mts → scale-DWM4RQco.d.mts} +2 -2
  31. package/dist/score/index.d.mts +5 -5
  32. package/dist/score/index.d.ts +2 -2
  33. package/dist/score/index.js +623 -441
  34. package/dist/score/index.mjs +516 -335
  35. package/dist/{tempo-BlCGZuYg.d.mts → tempo-Cxu8vusu.d.mts} +1 -1
  36. package/dist/theory/index.d.mts +6 -6
  37. package/dist/theory/index.js +1 -1
  38. package/dist/theory/index.mjs +3 -3
  39. package/package.json +2 -1
@@ -1,15 +1,15 @@
1
- /* WebMusicScore v5.4.1 | (c) 2023-2025 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v5.4.2 | (c) 2023-2025 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  import {
3
3
  MusicError
4
- } from "../chunk-6P4ECBUH.mjs";
4
+ } from "../chunk-MMWSQGVR.mjs";
5
5
  import {
6
6
  NoteLengthProps,
7
7
  RhythmProps,
8
8
  validateNoteLength
9
- } from "../chunk-A5SMODAT.mjs";
9
+ } from "../chunk-42IBAVOC.mjs";
10
10
  import {
11
11
  __publicField
12
- } from "../chunk-U2ACCEHX.mjs";
12
+ } from "../chunk-ROBXPR34.mjs";
13
13
 
14
14
  // src/score/pub/div-rect.ts
15
15
  import { Utils } from "@tspro/ts-utils-lib";
@@ -537,13 +537,52 @@ var MusicObject = class {
537
537
  }
538
538
  updateRect() {
539
539
  }
540
+ forceRectUpdate() {
541
+ this.needRectUpdate = true;
542
+ this.updateRect();
543
+ this.needRectUpdate = false;
544
+ }
540
545
  getRect() {
541
- if (this.needRectUpdate) {
542
- this.updateRect();
543
- this.needRectUpdate = false;
544
- }
546
+ if (this.needRectUpdate)
547
+ this.forceRectUpdate();
545
548
  return this.rect;
546
549
  }
550
+ offsetX(dx) {
551
+ this.offset(dx, 0);
552
+ }
553
+ offsetY(dy) {
554
+ this.offset(0, dy);
555
+ }
556
+ setLeft(x) {
557
+ this.offset(x - this.getRect().left, 0);
558
+ }
559
+ setRight(x) {
560
+ this.offset(x - this.getRect().right, 0);
561
+ }
562
+ setTop(y) {
563
+ this.offset(0, y - this.getRect().top);
564
+ }
565
+ setBottom(y) {
566
+ this.offset(0, y - this.getRect().bottom);
567
+ }
568
+ setAnchor(x, y) {
569
+ this.offset(x - this.getRect().anchorX, y - this.getRect().anchorY);
570
+ }
571
+ setAnchorX(x) {
572
+ this.offset(x - this.getRect().anchorX, 0);
573
+ }
574
+ setAnchorY(y) {
575
+ this.offset(0, y - this.getRect().anchorY);
576
+ }
577
+ setCenter(x, y) {
578
+ this.offset(x - this.getRect().centerX, y - this.getRect().centerY);
579
+ }
580
+ setCenterX(x) {
581
+ this.offset(x - this.getRect().centerX, 0);
582
+ }
583
+ setCenterY(y) {
584
+ this.offset(0, y - this.getRect().centerY);
585
+ }
547
586
  /**
548
587
  * Most objects are simple rects in shape.
549
588
  * Some objects might be more complex consisting of multiple rects.
@@ -587,7 +626,7 @@ var DebugSettings = {
587
626
  };
588
627
  var DocumentSettings = {
589
628
  DocumentScale: 1,
590
- DocumentMinWidth: 75,
629
+ MinStaffWidth: 75,
591
630
  MinColumnsWidth: 10,
592
631
  ColumnWidthScale: 1.7,
593
632
  PostMeasureBreakWidth: 10,
@@ -1149,72 +1188,112 @@ var RenderContext = class {
1149
1188
  }
1150
1189
  }
1151
1190
  arc(x, y, radius, startRadians, endRadians) {
1152
- var _a;
1153
- (_a = this.ctx) == null ? void 0 : _a.arc(x, y, radius, startRadians, endRadians);
1191
+ if (this.ctx) this.ctx.arc(x, y, radius, startRadians, endRadians);
1192
+ return this;
1154
1193
  }
1155
1194
  fillCircle(x, y, radius) {
1156
- if (this.ctx) {
1157
- this.ctx.beginPath();
1158
- this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
1159
- this.ctx.fill();
1160
- }
1195
+ if (!this.ctx) return this;
1196
+ this.ctx.beginPath();
1197
+ this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
1198
+ this.ctx.fill();
1199
+ return this;
1161
1200
  }
1162
1201
  strokeLine(startX, startY, endX, endY) {
1163
- if (this.ctx) {
1164
- this.ctx.beginPath();
1165
- this.ctx.moveTo(startX, startY);
1166
- this.ctx.lineTo(endX, endY);
1167
- this.ctx.stroke();
1168
- }
1202
+ if (!this.ctx) return this;
1203
+ this.ctx.beginPath();
1204
+ this.ctx.moveTo(startX, startY);
1205
+ this.ctx.lineTo(endX, endY);
1206
+ this.ctx.stroke();
1207
+ return this;
1169
1208
  }
1170
1209
  strokePartialLine(startX, startY, endX, endY, startT, endT) {
1210
+ if (!this.ctx) return this;
1171
1211
  let x1 = startX + (endX - startX) * startT;
1172
1212
  let y1 = startY + (endY - startY) * startT;
1173
1213
  let x2 = startX + (endX - startX) * endT;
1174
1214
  let y2 = startY + (endY - startY) * endT;
1175
- if (this.ctx) {
1176
- this.ctx.beginPath();
1177
- this.ctx.moveTo(x1, y1);
1178
- this.ctx.lineTo(x2, y2);
1179
- this.ctx.stroke();
1180
- }
1215
+ this.ctx.beginPath();
1216
+ this.ctx.moveTo(x1, y1);
1217
+ this.ctx.lineTo(x2, y2);
1218
+ this.ctx.stroke();
1219
+ return this;
1181
1220
  }
1221
+ /** @deprecated - Use {@link drawBracket} instead. */
1182
1222
  drawBrace(rect, side) {
1183
- if (this.ctx) {
1184
- let { left, right, width, top, bottom, anchorY } = rect;
1185
- if (side === "right") {
1186
- [left, right, width] = [right, left, -width];
1187
- }
1188
- this.ctx.beginPath();
1189
- this.ctx.moveTo(right, top);
1190
- this.ctx.bezierCurveTo(
1191
- left + width * 0.1,
1192
- top,
1193
- left + width * 0.8,
1194
- anchorY,
1195
- left,
1196
- anchorY
1197
- );
1198
- this.ctx.moveTo(right, bottom);
1199
- this.ctx.bezierCurveTo(
1200
- left + width * 0.1,
1201
- bottom,
1202
- left + width * 0.8,
1203
- anchorY,
1204
- left,
1205
- anchorY
1206
- );
1207
- this.ctx.stroke();
1223
+ return this.drawBracket(rect, side === "left" ? "{" : "}");
1224
+ }
1225
+ drawBracket(rect, bracket) {
1226
+ if (!this.ctx) return this;
1227
+ let { left, right, width, top, bottom, height, anchorY } = rect;
1228
+ if ([")", "]", "}", ">"].includes(bracket)) {
1229
+ [left, right, width] = [right, left, -width];
1230
+ }
1231
+ switch (bracket) {
1232
+ case "(":
1233
+ case ")":
1234
+ this.ctx.beginPath();
1235
+ this.ctx.moveTo(right, top);
1236
+ this.ctx.bezierCurveTo(
1237
+ left - width * 0.2,
1238
+ top + height * 0.3,
1239
+ left - width * 0.2,
1240
+ top + height * 0.7,
1241
+ right,
1242
+ bottom
1243
+ );
1244
+ this.ctx.stroke();
1245
+ break;
1246
+ case "{":
1247
+ case "}":
1248
+ this.ctx.beginPath();
1249
+ this.ctx.moveTo(right, top);
1250
+ this.ctx.bezierCurveTo(
1251
+ left + width * 0.1,
1252
+ top,
1253
+ left + width * 0.8,
1254
+ anchorY,
1255
+ left,
1256
+ anchorY
1257
+ );
1258
+ this.ctx.moveTo(right, bottom);
1259
+ this.ctx.bezierCurveTo(
1260
+ left + width * 0.1,
1261
+ bottom,
1262
+ left + width * 0.8,
1263
+ anchorY,
1264
+ left,
1265
+ anchorY
1266
+ );
1267
+ this.ctx.stroke();
1268
+ break;
1269
+ case "[":
1270
+ case "]":
1271
+ this.ctx.beginPath();
1272
+ this.ctx.moveTo(right, top);
1273
+ this.ctx.lineTo(left, top);
1274
+ this.ctx.lineTo(left, bottom);
1275
+ this.ctx.lineTo(right, bottom);
1276
+ this.ctx.stroke();
1277
+ break;
1278
+ case "<":
1279
+ case ">":
1280
+ this.ctx.beginPath();
1281
+ this.ctx.moveTo(right, top);
1282
+ this.ctx.lineTo(left, anchorY);
1283
+ this.ctx.lineTo(right, bottom);
1284
+ this.ctx.stroke();
1285
+ break;
1208
1286
  }
1287
+ return this;
1209
1288
  }
1210
1289
  };
1211
1290
 
1212
1291
  // src/score/engine/obj-staff-and-tab.ts
1213
1292
  import { MusicError as MusicError15, MusicErrorType as MusicErrorType15 } from "@tspro/web-music-score/core";
1214
- import { AnchoredRect as AnchoredRect22, Guard as Guard9, UniMap as UniMap7, Utils as Utils10 } from "@tspro/ts-utils-lib";
1293
+ import { AnchoredRect as AnchoredRect22, Guard as Guard9, UniMap as UniMap8, Utils as Utils10 } from "@tspro/ts-utils-lib";
1215
1294
 
1216
1295
  // src/score/engine/obj-measure.ts
1217
- import { Guard as Guard8, IndexArray as IndexArray2, UniMap as UniMap5, TriMap as TriMap2, ValueSet, Utils as Utils9, asMulti, AnchoredRect as AnchoredRect20 } from "@tspro/ts-utils-lib";
1296
+ import { Guard as Guard8, IndexArray as IndexArray2, UniMap as UniMap6, TriMap as TriMap2, ValueSet, Utils as Utils9, asMulti, AnchoredRect as AnchoredRect20 } from "@tspro/ts-utils-lib";
1218
1297
  import { getScale, Scale, validateScaleType, Note as Note7, RhythmProps as RhythmProps5, KeySignature as KeySignature2, getDefaultKeySignature, PitchNotation, SymbolSet, validateNoteLength as validateNoteLength2, NoteLengthProps as NoteLengthProps5 } from "@tspro/web-music-score/theory";
1219
1298
  import { getDefaultTempo, getDefaultTimeSignature } from "@tspro/web-music-score/theory";
1220
1299
 
@@ -1642,20 +1721,21 @@ var ObjStaffSignature = class extends MusicObject {
1642
1721
  if (this.clefImage) {
1643
1722
  x += paddingX;
1644
1723
  this.clefImage.layout(ctx);
1645
- this.clefImage.offset(x, staff.getDiatonicIdY(staff.clefLineDiatonicId));
1724
+ this.clefImage.setAnchor(x, staff.getDiatonicIdY(staff.clefLineDiatonicId));
1646
1725
  this.rect.expandInPlace(this.clefImage.getRect());
1647
1726
  x = this.rect.right;
1648
1727
  if (this.eightBelowClef) {
1649
1728
  let r = this.clefImage.getRect();
1650
1729
  this.eightBelowClef.layout(ctx);
1651
- this.eightBelowClef.offset(r.centerX, Math.max(r.anchorY + r.height * 0.3, staff.getBottomLineY()));
1730
+ this.eightBelowClef.setCenterX(r.centerX);
1731
+ this.eightBelowClef.setTop(Math.max(r.anchorY + r.height * 0.3, staff.getBottomLineY()));
1652
1732
  this.rect.expandInPlace(this.eightBelowClef.getRect());
1653
1733
  }
1654
1734
  }
1655
1735
  if (this.measureNumber) {
1656
1736
  this.measureNumber.layout(ctx);
1657
- let y = Math.min(staff.getTopLineY(), this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY());
1658
- this.measureNumber.offset(0, y);
1737
+ this.measureNumber.setLeft(0);
1738
+ this.measureNumber.setBottom(Math.min(staff.getTopLineY(), this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY()));
1659
1739
  this.rect.expandInPlace(this.measureNumber.getRect());
1660
1740
  x = Math.max(x, this.rect.right);
1661
1741
  }
@@ -1663,7 +1743,8 @@ var ObjStaffSignature = class extends MusicObject {
1663
1743
  x += paddingX;
1664
1744
  this.ksNeutralizeAccidentals.forEach((objAcc) => {
1665
1745
  objAcc.layout(ctx);
1666
- objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1746
+ objAcc.setLeft(x);
1747
+ objAcc.setAnchorY(staff.getDiatonicIdY(objAcc.diatonicId));
1667
1748
  this.rect.expandInPlace(objAcc.getRect());
1668
1749
  x = this.rect.right;
1669
1750
  });
@@ -1672,7 +1753,8 @@ var ObjStaffSignature = class extends MusicObject {
1672
1753
  x += paddingX;
1673
1754
  this.ksNewAccidentals.forEach((objAcc) => {
1674
1755
  objAcc.layout(ctx);
1675
- objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1756
+ objAcc.setLeft(x);
1757
+ objAcc.setAnchorY(staff.getDiatonicIdY(objAcc.diatonicId));
1676
1758
  this.rect.expandInPlace(objAcc.getRect());
1677
1759
  x = this.rect.right;
1678
1760
  });
@@ -1682,24 +1764,34 @@ var ObjStaffSignature = class extends MusicObject {
1682
1764
  (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1683
1765
  let tsWidth = Math.max((_d = (_c = this.beatCountText) == null ? void 0 : _c.getRect().width) != null ? _d : 0, (_f = (_e = this.beatSizeText) == null ? void 0 : _e.getRect().width) != null ? _f : 0);
1684
1766
  if (this.beatCountText) {
1685
- this.beatCountText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.middleLineDiatonicId + 2));
1767
+ this.beatCountText.setCenter(
1768
+ x + tsWidth / 2 + paddingX,
1769
+ staff.getDiatonicIdY(staff.middleLineDiatonicId + 2)
1770
+ );
1686
1771
  this.rect.expandInPlace(this.beatCountText.getRect());
1687
1772
  right = Math.max(right, this.rect.right);
1688
1773
  }
1689
1774
  if (this.beatSizeText) {
1690
- this.beatSizeText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.bottomLineDiatonicId + 2));
1775
+ this.beatSizeText.setCenter(
1776
+ x + tsWidth / 2 + paddingX,
1777
+ staff.getDiatonicIdY(staff.bottomLineDiatonicId + 2)
1778
+ );
1691
1779
  this.rect.expandInPlace(this.beatSizeText.getRect());
1692
1780
  right = Math.max(right, this.rect.right);
1693
1781
  }
1694
1782
  x = right;
1695
1783
  if (this.tempoText) {
1696
- let tempoBottom = Math.min(
1697
- this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY(),
1698
- ...this.ksNeutralizeAccidentals.map((o) => o.getRect().top),
1699
- ...this.ksNewAccidentals.map((o) => o.getRect().top)
1700
- );
1701
1784
  this.tempoText.layout(ctx);
1702
- this.tempoText.offset(x, tempoBottom);
1785
+ this.tempoText.setCenterX(x);
1786
+ this.tempoText.setBottom(staff.getTopLineY());
1787
+ if (this.clefImage && AnchoredRect6.overlap(this.clefImage.getRect(), this.tempoText.getRect())) {
1788
+ this.tempoText.setBottom(this.clefImage.getRect().top);
1789
+ }
1790
+ [...this.ksNeutralizeAccidentals, ...this.ksNewAccidentals].forEach((acc) => {
1791
+ if (this.tempoText && AnchoredRect6.overlap(acc.getRect(), this.tempoText.getRect())) {
1792
+ this.tempoText.setBottom(acc.getRect().top);
1793
+ }
1794
+ });
1703
1795
  this.rect.expandInPlace(this.tempoText.getRect());
1704
1796
  }
1705
1797
  this.rect.right += paddingX;
@@ -1810,7 +1902,8 @@ var ObjTabSignature = class extends MusicObject {
1810
1902
  this.rect = new AnchoredRect6();
1811
1903
  if (this.measureNumber) {
1812
1904
  this.measureNumber.layout(ctx);
1813
- this.measureNumber.offset(0, topLineY);
1905
+ this.measureNumber.setLeft(0);
1906
+ this.measureNumber.setBottom(topLineY);
1814
1907
  this.rect.expandInPlace(this.measureNumber.getRect());
1815
1908
  x = Math.max(x, this.rect.right);
1816
1909
  }
@@ -1818,16 +1911,23 @@ var ObjTabSignature = class extends MusicObject {
1818
1911
  (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1819
1912
  let tsWidth = Math.max((_d = (_c = this.beatCountText) == null ? void 0 : _c.getRect().width) != null ? _d : 0, (_f = (_e = this.beatSizeText) == null ? void 0 : _e.getRect().width) != null ? _f : 0);
1820
1913
  if (this.beatCountText) {
1821
- this.beatCountText.offset(0 + tsWidth / 2 + paddingX, tab.getRect().anchorY - this.beatCountText.getRect().bottomh);
1914
+ this.beatCountText.setCenter(
1915
+ 0 + tsWidth / 2 + paddingX,
1916
+ tab.getRect().anchorY - this.beatCountText.getRect().bottomh
1917
+ );
1822
1918
  this.rect.expandInPlace(this.beatCountText.getRect());
1823
1919
  }
1824
1920
  if (this.beatSizeText) {
1825
- this.beatSizeText.offset(0 + tsWidth / 2 + paddingX, tab.getRect().anchorY + this.beatSizeText.getRect().toph);
1921
+ this.beatSizeText.setCenter(
1922
+ 0 + tsWidth / 2 + paddingX,
1923
+ tab.getRect().anchorY + this.beatSizeText.getRect().toph
1924
+ );
1826
1925
  this.rect.expandInPlace(this.beatSizeText.getRect());
1827
1926
  }
1828
1927
  if (this.tempoText) {
1829
1928
  this.tempoText.layout(ctx);
1830
- this.tempoText.offset(x + unitSize * 2, topLineY);
1929
+ this.tempoText.setLeft(x + unitSize * 2);
1930
+ this.tempoText.setBottom(topLineY);
1831
1931
  this.rect.expandInPlace(this.tempoText.getRect());
1832
1932
  }
1833
1933
  this.rect.right += paddingX;
@@ -2126,7 +2226,7 @@ var _ObjRest = class _ObjRest extends MusicObject {
2126
2226
  let dotY = this.getRestDotVerticalDisplacement(noteSize) * unitSize;
2127
2227
  obj.dotRects.push(AnchoredRect8.createCentered(dotX, dotY, dotWidth, dotWidth));
2128
2228
  }
2129
- obj.offset(0, staff.getDiatonicIdY(diatonicId));
2229
+ obj.setAnchor(0, staff.getDiatonicIdY(diatonicId));
2130
2230
  this.staffObjects.push(obj);
2131
2231
  this.measure.addStaticObject(staff, obj);
2132
2232
  });
@@ -2634,7 +2734,10 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2634
2734
  let acc = obj.accidentals[noteIndex] = new ObjAccidental(this, note.diatonicId, note.accidental, this.color);
2635
2735
  if (acc) {
2636
2736
  acc.layout(ctx);
2637
- acc.offset(-noteHeadRect.leftw - unitSize * DocumentSettings.NoteAccSpace - acc.getRect().rightw, noteY);
2737
+ acc.setAnchor(
2738
+ -noteHeadRect.leftw - unitSize * DocumentSettings.NoteAccSpace - acc.getRect().rightw,
2739
+ noteY
2740
+ );
2638
2741
  }
2639
2742
  noteStaff.addObject(acc);
2640
2743
  }
@@ -2698,9 +2801,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2698
2801
  let color = fretId < 0 ? "red" : "black";
2699
2802
  let fretNumber = new ObjText(this, { text: String(fretId), color, bgcolor: "white" }, 0.5, 0.5);
2700
2803
  fretNumber.layout(ctx);
2701
- let x = this.col.getRect().anchorX;
2702
- let y = tab.getStringY(stringNumber - 1);
2703
- fretNumber.offset(x, y);
2804
+ fretNumber.setAnchor(this.col.getRect().anchorX, tab.getStringY(stringNumber - 1));
2704
2805
  obj.fretNumbers.push(fretNumber);
2705
2806
  }
2706
2807
  });
@@ -2875,7 +2976,7 @@ var ObjRhythmColumn = class extends MusicObject {
2875
2976
  return Math.max(0, nextPositionTicks - curPositionTicks);
2876
2977
  }
2877
2978
  getShapeRects() {
2878
- this.getRect();
2979
+ this.forceRectUpdate();
2879
2980
  return this.shapeRects;
2880
2981
  }
2881
2982
  get doc() {
@@ -3041,6 +3142,8 @@ var ObjRhythmColumn = class extends MusicObject {
3041
3142
  return;
3042
3143
  }
3043
3144
  let { row } = this;
3145
+ this.rect = new AnchoredRect10();
3146
+ this.requestRectUpdate();
3044
3147
  let leftw = 0;
3045
3148
  let rightw = 0;
3046
3149
  this.voiceSymbol.forEach((symbol) => {
@@ -3054,7 +3157,7 @@ var ObjRhythmColumn = class extends MusicObject {
3054
3157
  this.arpeggios.forEach((a) => a.layout(ctx));
3055
3158
  const arpeggioWidth = this.arpeggios.map((a) => a.getRect().width).reduce((accState2, cur) => Math.max(accState2, cur)) + ctx.unitSize;
3056
3159
  this.arpeggios.forEach((a) => {
3057
- a.offset(-leftw - arpeggioWidth + a.getRect().leftw, a.line.getRect().anchorY - a.getRect().anchorY);
3160
+ a.setAnchor(-leftw - arpeggioWidth / 2, a.line.getRect().anchorY);
3058
3161
  a.line.addObject(a);
3059
3162
  this.measure.addStaticObject(a.line, a);
3060
3163
  });
@@ -3069,7 +3172,9 @@ var ObjRhythmColumn = class extends MusicObject {
3069
3172
  rightw = Math.max(rightw, MinColumnWidth / 2);
3070
3173
  leftw *= DocumentSettings.ColumnWidthScale;
3071
3174
  rightw *= DocumentSettings.ColumnWidthScale;
3072
- this.rect = new AnchoredRect10(-leftw, 0, rightw, 0, 0, 0);
3175
+ this.rect.left = -leftw;
3176
+ this.rect.anchorX = 0;
3177
+ this.rect.right = rightw;
3073
3178
  this.requestRectUpdate();
3074
3179
  this.voiceSymbol.forEach((symbol) => symbol.updateAccidentalState(accState));
3075
3180
  this.row.getStaves().forEach((staff) => {
@@ -3221,8 +3326,8 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3221
3326
  let codaText = this.components[1];
3222
3327
  codaSym.layout(ctx);
3223
3328
  codaText.layout(ctx);
3224
- codaSym.offset(0, codaText.getRect().centerY);
3225
- codaText.offset(codaSym.getRect().right, 0);
3329
+ codaSym.setAnchorY(codaText.getRect().centerY);
3330
+ codaText.setLeft(codaSym.getRect().right);
3226
3331
  this.rect = new AnchoredRect11(
3227
3332
  codaSym.getRect().left,
3228
3333
  codaSym.getRect().anchorX,
@@ -3238,8 +3343,8 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3238
3343
  let codaSym = this.components[1];
3239
3344
  toCodaText.layout(ctx);
3240
3345
  codaSym.layout(ctx);
3241
- codaSym.offset(0, toCodaText.getRect().centerY);
3242
- toCodaText.offset(codaSym.getRect().left, 0);
3346
+ codaSym.setAnchorY(toCodaText.getRect().centerY);
3347
+ toCodaText.setRight(codaSym.getRect().left);
3243
3348
  this.rect = new AnchoredRect11(
3244
3349
  toCodaText.getRect().left,
3245
3350
  codaSym.getRect().anchorX,
@@ -3818,17 +3923,17 @@ var Player = class _Player {
3818
3923
  };
3819
3924
 
3820
3925
  // src/score/engine/obj-bar-line.ts
3821
- import { AnchoredRect as AnchoredRect13 } from "@tspro/ts-utils-lib";
3822
- var ObjStaffTabBarLine = class extends MusicObject {
3926
+ import { AnchoredRect as AnchoredRect13, UniMap as UniMap4 } from "@tspro/ts-utils-lib";
3927
+ var ObjStaffBarLine = class extends MusicObject {
3823
3928
  constructor(barLine, line) {
3824
3929
  super(line);
3825
3930
  this.barLine = barLine;
3826
3931
  this.line = line;
3827
- __publicField(this, "verticalLines", []);
3932
+ __publicField(this, "vlines", []);
3828
3933
  __publicField(this, "dots", []);
3829
3934
  __publicField(this, "mi");
3830
3935
  line.addObject(this);
3831
- this.mi = new MStaffTabBarLine(this);
3936
+ this.mi = new MStaffBarLine(this);
3832
3937
  }
3833
3938
  getMusicInterface() {
3834
3939
  return this.mi;
@@ -3836,11 +3941,17 @@ var ObjStaffTabBarLine = class extends MusicObject {
3836
3941
  pick(x, y) {
3837
3942
  return this.getRect().contains(x, y) ? [this] : [];
3838
3943
  }
3839
- setRect(r) {
3840
- this.rect = r;
3944
+ updateRect() {
3945
+ this.rect = new AnchoredRect13(0, 0, this.line.getTopLineY(), this.line.getBottomLineY());
3946
+ this.vlines.forEach(
3947
+ (l) => this.rect.expandInPlace(new AnchoredRect13(l.left, l.left + l.width, this.rect.top, this.rect.bottom))
3948
+ );
3949
+ this.dots.forEach(
3950
+ (d) => this.rect.expandInPlace(new AnchoredRect13(d.x - d.r, d.x + d.r, d.y - d.r, d.y + d.r))
3951
+ );
3841
3952
  }
3842
3953
  offset(dx, dy) {
3843
- this.verticalLines.forEach((l) => l.left += dx);
3954
+ this.vlines.forEach((l) => l.left += dx);
3844
3955
  this.dots.forEach((d) => {
3845
3956
  d.x += dx;
3846
3957
  d.y += dy;
@@ -3852,16 +3963,16 @@ var ObjBarLine = class extends MusicObject {
3852
3963
  constructor(measure) {
3853
3964
  super(measure);
3854
3965
  this.measure = measure;
3855
- __publicField(this, "staffTabObjects", []);
3856
- __publicField(this, "staffTabObjectGroups", []);
3966
+ __publicField(this, "notationLineObjects", []);
3967
+ __publicField(this, "notationLineObjectsByGrp", new UniMap4());
3857
3968
  __publicField(this, "barLineType", 0 /* None */);
3858
3969
  }
3859
3970
  pick(x, y) {
3860
3971
  if (!this.getRect().contains(x, y)) {
3861
3972
  return [];
3862
3973
  }
3863
- for (let i = 0; i < this.staffTabObjects.length; i++) {
3864
- let arr = this.staffTabObjects[i].pick(x, y);
3974
+ for (let i = 0; i < this.notationLineObjects.length; i++) {
3975
+ let arr = this.notationLineObjects[i].pick(x, y);
3865
3976
  if (arr.length > 0) {
3866
3977
  return [this, ...arr];
3867
3978
  }
@@ -3870,7 +3981,6 @@ var ObjBarLine = class extends MusicObject {
3870
3981
  }
3871
3982
  layout(ctx) {
3872
3983
  this.requestRectUpdate();
3873
- this.staffTabObjects.length = 0;
3874
3984
  this.barLineType = this.solveBarLineType();
3875
3985
  let { unitSize, _lineWidth } = ctx;
3876
3986
  let { measure, barLineType } = this;
@@ -3880,102 +3990,95 @@ var ObjBarLine = class extends MusicObject {
3880
3990
  let spaceW = 0.7 * unitSize;
3881
3991
  let dotW = DocumentSettings.DotSize * unitSize;
3882
3992
  let dotRadius = dotW / 2;
3883
- row.getNotationLines().forEach((line) => {
3884
- let obj = new ObjStaffTabBarLine(this, line);
3885
- let lineCenterY;
3886
- let lineDotOff;
3887
- let top, bottom;
3888
- const addVerticalLine = (left, width) => {
3889
- obj.verticalLines.push({ left, width });
3890
- };
3891
- const addDotPair = (cx) => {
3892
- for (let i = -1; i <= 1; i += 2) {
3893
- let y = lineCenterY + i * lineDotOff;
3894
- obj.dots.push({ x: cx, y, r: dotRadius });
3993
+ this.notationLineObjects = [];
3994
+ this.notationLineObjectsByGrp.clear();
3995
+ row.getRowGroups().forEach((grp) => {
3996
+ grp.lines.forEach((line) => {
3997
+ let obj = new ObjStaffBarLine(this, line);
3998
+ this.notationLineObjects.push(obj);
3999
+ this.notationLineObjectsByGrp.getOrCreate(grp, []).push(obj);
4000
+ let lineCenterY;
4001
+ let lineDotOff;
4002
+ const addVerticalLine = (left, width) => {
4003
+ obj.vlines.push({ left, width });
4004
+ };
4005
+ const addDotPair = (cx) => {
4006
+ for (let i = -1; i <= 1; i += 2) {
4007
+ let y = lineCenterY + i * lineDotOff;
4008
+ obj.dots.push({ x: cx, y, r: dotRadius });
4009
+ }
4010
+ };
4011
+ if (line instanceof ObjStaff) {
4012
+ lineCenterY = line.getMiddleLineY();
4013
+ lineDotOff = line.getDiatonicSpacing();
4014
+ } else {
4015
+ lineCenterY = (line.getBottomLineY() + line.getTopLineY()) / 2;
4016
+ lineDotOff = (line.getBottomLineY() - line.getTopLineY()) / 6;
3895
4017
  }
3896
- };
3897
- if (line instanceof ObjStaff) {
3898
- lineCenterY = line.getMiddleLineY();
3899
- lineDotOff = line.getDiatonicSpacing();
3900
- } else {
3901
- lineCenterY = (line.getBottomLineY() + line.getTopLineY()) / 2;
3902
- lineDotOff = (line.getBottomLineY() - line.getTopLineY()) / 6;
3903
- }
3904
- top = line.getTopLineY();
3905
- bottom = line.getBottomLineY();
3906
- switch (barLineType) {
3907
- case 0 /* None */:
3908
- obj.setRect(new AnchoredRect13(0, 0, 0, top, 0, bottom));
3909
- break;
3910
- case 1 /* Single */:
3911
- obj.setRect(new AnchoredRect13(-thinW, 0, 0, top, 0, bottom));
3912
- addVerticalLine(-thinW, thinW);
3913
- break;
3914
- case 2 /* Double */:
3915
- obj.setRect(new AnchoredRect13(-thinW - spaceW - thinW, 0, 0, top, 0, bottom));
3916
- addVerticalLine(-thinW - spaceW - thinW, thinW);
3917
- addVerticalLine(-thinW, thinW);
3918
- break;
3919
- case 3 /* EndSong */:
3920
- obj.setRect(new AnchoredRect13(-thicW - spaceW - thinW, 0, 0, top, 0, bottom));
3921
- addVerticalLine(-thinW - spaceW - thicW, thinW);
3922
- addVerticalLine(-thicW, thicW);
3923
- break;
3924
- case 4 /* StartRepeat */:
3925
- obj.setRect(new AnchoredRect13(0, 0, thicW + spaceW + thinW + spaceW + dotW, top, 0, bottom));
3926
- addVerticalLine(0, thicW);
3927
- addVerticalLine(thicW + spaceW, thinW);
3928
- addDotPair(thicW + spaceW + thinW + spaceW + dotRadius);
3929
- break;
3930
- case 5 /* EndRepeat */:
3931
- obj.setRect(new AnchoredRect13(-thicW - spaceW - thinW - spaceW - dotW, 0, 0, top, 0, bottom));
3932
- addVerticalLine(-thinW - spaceW - thicW, thinW);
3933
- addVerticalLine(-thicW, thicW);
3934
- addDotPair(-thinW - spaceW - thicW - spaceW - dotRadius);
3935
- break;
3936
- case 6 /* EndStartRepeat */:
3937
- obj.setRect(new AnchoredRect13(-dotW - spaceW - thinW - spaceW - thicW / 2, 0, thicW / 2 + spaceW + thinW + spaceW + dotW, top, 0, bottom));
3938
- addVerticalLine(-thicW / 2, thicW);
3939
- addVerticalLine(-thicW / 2 - spaceW - thinW, thinW);
3940
- addVerticalLine(thicW / 2 + spaceW, thinW);
3941
- addDotPair(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
3942
- addDotPair(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
3943
- break;
3944
- }
3945
- this.staffTabObjects.push(obj);
4018
+ switch (barLineType) {
4019
+ case 0 /* None */:
4020
+ break;
4021
+ case 1 /* Single */:
4022
+ addVerticalLine(-thinW, thinW);
4023
+ break;
4024
+ case 2 /* Double */:
4025
+ addVerticalLine(-thinW - spaceW - thinW, thinW);
4026
+ addVerticalLine(-thinW, thinW);
4027
+ break;
4028
+ case 3 /* EndSong */:
4029
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
4030
+ addVerticalLine(-thicW, thicW);
4031
+ break;
4032
+ case 4 /* StartRepeat */:
4033
+ addVerticalLine(0, thicW);
4034
+ addVerticalLine(thicW + spaceW, thinW);
4035
+ addDotPair(thicW + spaceW + thinW + spaceW + dotRadius);
4036
+ break;
4037
+ case 5 /* EndRepeat */:
4038
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
4039
+ addVerticalLine(-thicW, thicW);
4040
+ addDotPair(-thinW - spaceW - thicW - spaceW - dotRadius);
4041
+ break;
4042
+ case 6 /* EndStartRepeat */:
4043
+ addVerticalLine(-thicW / 2, thicW);
4044
+ addVerticalLine(-thicW / 2 - spaceW - thinW, thinW);
4045
+ addVerticalLine(thicW / 2 + spaceW, thinW);
4046
+ addDotPair(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
4047
+ addDotPair(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
4048
+ break;
4049
+ }
4050
+ obj.forceRectUpdate();
4051
+ });
3946
4052
  });
3947
- this.staffTabObjectGroups = row.getInstrumentLineGroups().map(
3948
- (lines) => lines.map((line) => this.staffTabObjects.find((obj) => obj.line === line)).filter((obj) => obj !== void 0)
3949
- );
3950
4053
  }
3951
4054
  updateRect() {
3952
- if (this.staffTabObjects.length > 0) {
3953
- this.rect = this.staffTabObjects[0].getRect().clone();
3954
- for (let i = 1; i < this.staffTabObjects.length; i++) {
3955
- this.rect.expandInPlace(this.staffTabObjects[i].getRect());
4055
+ if (this.notationLineObjects.length > 0) {
4056
+ this.rect = this.notationLineObjects[0].getRect().clone();
4057
+ for (let i = 1; i < this.notationLineObjects.length; i++) {
4058
+ this.rect.expandInPlace(this.notationLineObjects[i].getRect());
3956
4059
  }
3957
4060
  } else {
3958
4061
  this.rect = new AnchoredRect13();
3959
4062
  }
3960
4063
  }
3961
4064
  offset(dx, dy) {
3962
- this.staffTabObjects.forEach((obj) => obj.offset(dx, 0));
4065
+ this.notationLineObjects.forEach((obj) => obj.offset(dx, 0));
3963
4066
  this.requestRectUpdate();
3964
4067
  }
3965
4068
  draw(ctx) {
3966
- if (this.barLineType === 0 /* None */) {
4069
+ if (this.barLineType === 0 /* None */)
3967
4070
  return;
3968
- }
3969
4071
  ctx.drawDebugRect(this.getRect());
3970
4072
  ctx.color("black");
3971
- this.staffTabObjectGroups.forEach((objs) => {
3972
- if (objs.length > 0) {
3973
- objs.forEach((obj) => obj.dots.forEach((d) => ctx.fillCircle(d.x, d.y, d.r)));
3974
- let top = objs[0].getRect().top;
3975
- let height = objs[objs.length - 1].getRect().bottom - top;
3976
- objs[0].verticalLines.forEach((vline) => ctx.fillRect(vline.left, top, vline.width, height));
3977
- }
3978
- });
4073
+ for (const [grp, objects] of this.notationLineObjectsByGrp) {
4074
+ objects.forEach((obj, i) => {
4075
+ obj.dots.forEach((d) => ctx.fillCircle(d.x, d.y, d.r));
4076
+ if (i === 0) {
4077
+ let { top, height } = obj.barLine.getRect();
4078
+ obj.vlines.forEach((l) => ctx.fillRect(l.left, top, l.width, height));
4079
+ }
4080
+ });
4081
+ }
3979
4082
  }
3980
4083
  };
3981
4084
  var ObjBarLineLeft = class extends ObjBarLine {
@@ -4092,7 +4195,8 @@ var ObjEnding = class extends MusicObject {
4092
4195
  let measureContent = measure.getColumnsContentRect();
4093
4196
  let endingHeight = textRect.height;
4094
4197
  this.rect = new AnchoredRect14(measureContent.left + unitSize, measureContent.right - unitSize, -endingHeight, 0);
4095
- this.endingText.offset(this.rect.left + unitSize / 2, this.rect.bottom);
4198
+ this.endingText.setLeft(this.rect.left + unitSize / 2);
4199
+ this.endingText.setBottom(this.rect.bottom);
4096
4200
  this.shapeRects = [
4097
4201
  new AnchoredRect14(this.rect.left, this.rect.left + 1, this.rect.top, this.rect.bottom),
4098
4202
  new AnchoredRect14(this.rect.left, this.rect.right, this.rect.top, this.rect.top + 1),
@@ -4519,8 +4623,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4519
4623
  });
4520
4624
  }
4521
4625
  if (obj.tupletNumber) {
4522
- let y = (left.y + right.y) / 2 + obj.tupletNumberOffsetY;
4523
- obj.tupletNumber.offset(0, -obj.tupletNumber.getRect().anchorY + y);
4626
+ obj.tupletNumber.setAnchorY((left.y + right.y) / 2 + obj.tupletNumberOffsetY);
4524
4627
  }
4525
4628
  });
4526
4629
  }
@@ -5156,7 +5259,7 @@ var ObjLyrics = class extends MusicObject {
5156
5259
  };
5157
5260
 
5158
5261
  // src/score/engine/obj-tab-rhythm.ts
5159
- import { AnchoredRect as AnchoredRect19, UniMap as UniMap4, Utils as Utils8 } from "@tspro/ts-utils-lib";
5262
+ import { AnchoredRect as AnchoredRect19, UniMap as UniMap5, Utils as Utils8 } from "@tspro/ts-utils-lib";
5160
5263
  var ObjTabRhythm = class extends MusicObject {
5161
5264
  constructor(measure, tab) {
5162
5265
  super(measure);
@@ -5165,7 +5268,7 @@ var ObjTabRhythm = class extends MusicObject {
5165
5268
  __publicField(this, "voiceId");
5166
5269
  __publicField(this, "mi");
5167
5270
  // Keep non-static
5168
- __publicField(this, "tupletPartsTextObjMap", new UniMap4());
5271
+ __publicField(this, "tupletPartsTextObjMap", new UniMap5());
5169
5272
  this.voiceId = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5170
5273
  this.rect = new AnchoredRect19();
5171
5274
  this.mi = new MTabRhythm(this);
@@ -5280,8 +5383,7 @@ var ObjTabRhythm = class extends MusicObject {
5280
5383
  this.tupletPartsTextObjMap.set(text, textObj = new ObjText(this, { text, scale: 0.75 }, 0.5, 0.5));
5281
5384
  textObj.layout(ctx);
5282
5385
  }
5283
- textObj.offset(-textObj.getRect().anchorX, -textObj.getRect().anchorY);
5284
- textObj.offset(cx, stemTop - fontSize / 2);
5386
+ textObj.setCenter(cx, stemTop - fontSize / 2);
5285
5387
  textObj.draw(ctx);
5286
5388
  }
5287
5389
  if (symbols.length > 1) {
@@ -5392,7 +5494,7 @@ var ObjMeasure = class extends MusicObject {
5392
5494
  __publicField(this, "endRepeatPlayCount", 2);
5393
5495
  // play twice.
5394
5496
  __publicField(this, "endRepeatPlayCountText");
5395
- __publicField(this, "staticObjectsCache", new UniMap5());
5497
+ __publicField(this, "staticObjectsCache", new UniMap6());
5396
5498
  __publicField(this, "lyricsObjectsCache", new TriMap2());
5397
5499
  __publicField(this, "mi");
5398
5500
  this.mi = new MMeasure(this);
@@ -6323,7 +6425,8 @@ var ObjMeasure = class extends MusicObject {
6323
6425
  let note = tab.getTuningStrings()[stringId].format(PitchNotation.Helmholtz, SymbolSet.Unicode);
6324
6426
  let obj = new ObjText(this, { text: note, scale: 0.8 }, 1, 0.5);
6325
6427
  obj.layout(ctx);
6326
- obj.offset(this.regions.tabTuning_0 * 0.8, tab.getStringY(stringId));
6428
+ obj.setRight(this.regions.tabTuning_0 * 0.8);
6429
+ obj.setCenterY(tab.getStringY(stringId));
6327
6430
  this.tabStringNotes.push(obj);
6328
6431
  tab.addObject(obj);
6329
6432
  }
@@ -6349,7 +6452,6 @@ var ObjMeasure = class extends MusicObject {
6349
6452
  this.regions.rightBarLine_6 = this.barLineRight.getRect().width;
6350
6453
  }
6351
6454
  layoutWidth(ctx, width) {
6352
- var _a;
6353
6455
  if (!this.needLayout) {
6354
6456
  return;
6355
6457
  }
@@ -6357,17 +6459,19 @@ var ObjMeasure = class extends MusicObject {
6357
6459
  this.rect = new AnchoredRect20();
6358
6460
  this.rect.anchorX = this.rect.left + width / 2;
6359
6461
  this.rect.right = this.rect.left + width;
6360
- let rect;
6361
6462
  this.signatures.forEach((signature) => {
6362
- rect = signature.getRect();
6363
- signature.offset(this.rect.left + this.regions.tabTuning_0 - rect.left, -rect.anchorY);
6463
+ signature.setLeft(this.rect.left + this.regions.tabTuning_0);
6464
+ signature.setAnchorY(this.rect.anchorY);
6364
6465
  });
6365
6466
  let signaturesWidth = Math.max(0, ...this.signatures.map((signature) => signature.getRect().width));
6366
- rect = this.barLineLeft.getRect();
6367
- this.barLineLeft.offset(this.rect.left + this.regions.tabTuning_0 + signaturesWidth - rect.left, -rect.anchorY);
6368
- rect = this.barLineRight.getRect();
6369
- this.barLineRight.offset(this.rect.right - rect.right, -rect.anchorY);
6370
- (_a = this.endRepeatPlayCountText) == null ? void 0 : _a.offset(this.barLineRight.getRect().left, this.barLineRight.getRect().top);
6467
+ this.barLineLeft.setLeft(this.rect.left + this.regions.tabTuning_0 + signaturesWidth);
6468
+ this.barLineLeft.setAnchorY(this.rect.anchorY);
6469
+ this.barLineRight.setRight(this.rect.right);
6470
+ this.barLineRight.setAnchorY(this.rect.anchorY);
6471
+ if (this.endRepeatPlayCountText) {
6472
+ this.endRepeatPlayCountText.setCenterX(this.barLineRight.getRect().left);
6473
+ this.endRepeatPlayCountText.setBottom(this.barLineRight.getRect().top);
6474
+ }
6371
6475
  let columnsLeft = this.rect.left + this.regions.leftSolid;
6372
6476
  let columnsRight = this.rect.right - this.regions.rightSolid;
6373
6477
  let columnsWidth = columnsRight - columnsLeft;
@@ -6375,9 +6479,9 @@ var ObjMeasure = class extends MusicObject {
6375
6479
  let columnScale = columnsWidth / columnsMinWidth;
6376
6480
  let curColumnLeft = columnsLeft;
6377
6481
  this.columns.forEach((col) => {
6378
- rect = col.getRect();
6482
+ let rect = col.getRect();
6379
6483
  let columnAnchorX = curColumnLeft + rect.leftw * columnScale;
6380
- col.offset(columnAnchorX - rect.anchorX, -rect.anchorY);
6484
+ col.setAnchor(columnAnchorX, this.rect.anchorY);
6381
6485
  curColumnLeft += rect.width * columnScale;
6382
6486
  });
6383
6487
  getVoiceIds().forEach((voiceId) => {
@@ -6386,8 +6490,7 @@ var ObjMeasure = class extends MusicObject {
6386
6490
  if (!onlyRest) return;
6387
6491
  const isOnlySymbolInCol = getVoiceIds().map((voiceId2) => onlyRest.col.getVoiceSymbol(voiceId2)).filter((sym) => sym !== void 0 && sym !== onlyRest).length === 0;
6388
6492
  if (isOnlySymbolInCol) return;
6389
- const r = this.getColumnsContentRect();
6390
- onlyRest.offset(r.centerX - onlyRest.getRect().anchorX, 0);
6493
+ onlyRest.setAnchorX(this.getColumnsContentRect().centerX);
6391
6494
  });
6392
6495
  }
6393
6496
  layoutConnectives(ctx) {
@@ -6456,9 +6559,8 @@ var ObjMeasure = class extends MusicObject {
6456
6559
  this.barLineLeft.offset(dx, dy);
6457
6560
  this.columns.forEach((col) => col.offset(dx, dy));
6458
6561
  this.barLineRight.offset(dx, dy);
6459
- if (this.endRepeatPlayCountText) {
6562
+ if (this.endRepeatPlayCountText)
6460
6563
  this.endRepeatPlayCountText.offset(dx, dy);
6461
- }
6462
6564
  this.connectives.forEach((connective) => connective.offset(dx, 0));
6463
6565
  this.beamGroups.forEach((beam) => beam.offset(dx, dy));
6464
6566
  this.layoutObjects.forEach((layoutObj) => layoutObj.offset(dx, 0));
@@ -6498,7 +6600,7 @@ var ObjMeasure = class extends MusicObject {
6498
6600
 
6499
6601
  // src/score/engine/layout-object.ts
6500
6602
  import { MusicError as MusicError14, MusicErrorType as MusicErrorType14 } from "@tspro/web-music-score/core";
6501
- import { AnchoredRect as AnchoredRect21, asMulti as asMulti2, IndexArray as IndexArray3, UniMap as UniMap6 } from "@tspro/ts-utils-lib";
6603
+ import { AnchoredRect as AnchoredRect21, asMulti as asMulti2, IndexArray as IndexArray3, UniMap as UniMap7 } from "@tspro/ts-utils-lib";
6502
6604
  var LayoutGroupId = /* @__PURE__ */ ((LayoutGroupId2) => {
6503
6605
  LayoutGroupId2[LayoutGroupId2["TabRhythm"] = 0] = "TabRhythm";
6504
6606
  LayoutGroupId2[LayoutGroupId2["Fermata"] = 1] = "Fermata";
@@ -6513,7 +6615,7 @@ var LayoutGroupId = /* @__PURE__ */ ((LayoutGroupId2) => {
6513
6615
  LayoutGroupId2[LayoutGroupId2["LyricsVerse3"] = 10] = "LyricsVerse3";
6514
6616
  return LayoutGroupId2;
6515
6617
  })(LayoutGroupId || {});
6516
- var LayoutGroupIdAttrs = new UniMap6([
6618
+ var LayoutGroupIdAttrs = new UniMap7([
6517
6619
  [0 /* TabRhythm */, { rowAlign: true }],
6518
6620
  [1 /* Fermata */, { reserveSpace: true }],
6519
6621
  [2 /* NoteLabel */, { reserveSpace: true }],
@@ -6606,6 +6708,9 @@ var LayoutObjectWrapper = class {
6606
6708
  offset(dx, dy) {
6607
6709
  this.musicObj.offset(dx, dy);
6608
6710
  }
6711
+ setAnchorY(y) {
6712
+ this.musicObj.setAnchorY(y);
6713
+ }
6609
6714
  getRect() {
6610
6715
  return this.musicObj.getRect();
6611
6716
  }
@@ -6649,7 +6754,7 @@ var ObjNotationLine5 = class extends MusicObject {
6649
6754
  super(row);
6650
6755
  this.row = row;
6651
6756
  __publicField(this, "objects", []);
6652
- __publicField(this, "layoutGroups", new UniMap7());
6757
+ __publicField(this, "layoutGroups", new UniMap8());
6653
6758
  }
6654
6759
  addObject(o) {
6655
6760
  this.objects.push(o);
@@ -6676,7 +6781,7 @@ var ObjNotationLine5 = class extends MusicObject {
6676
6781
  if (y === void 0) {
6677
6782
  return;
6678
6783
  }
6679
- layoutObj.offset(0, y - layoutObj.getRect().anchorY);
6784
+ layoutObj.setAnchorY(y - layoutObj.getRect().anchorY);
6680
6785
  layoutObj.setPositionResolved();
6681
6786
  }
6682
6787
  alignObjectsY(ctx, layoutObjects, verticalPos) {
@@ -6697,7 +6802,7 @@ var ObjNotationLine5 = class extends MusicObject {
6697
6802
  if (musicObj instanceof ObjEnding || musicObj instanceof ObjExtensionLine || musicObj instanceof ObjTabRhythm) {
6698
6803
  musicObj.layoutFitToMeasure(ctx);
6699
6804
  } else {
6700
- musicObj.offset(anchor.getRect().anchorX - musicObj.getRect().anchorX, 0);
6805
+ musicObj.setAnchorX(anchor.getRect().anchorX);
6701
6806
  }
6702
6807
  });
6703
6808
  if (layoutGroup.rowAlign) {
@@ -6977,7 +7082,112 @@ var ObjTab = class extends ObjNotationLine5 {
6977
7082
 
6978
7083
  // src/score/engine/obj-score-row.ts
6979
7084
  import { MusicError as MusicError16, MusicErrorType as MusicErrorType16 } from "@tspro/web-music-score/core";
6980
- import { AnchoredRect as AnchoredRect23, Guard as Guard10, Utils as Utils11 } from "@tspro/ts-utils-lib";
7085
+ import { AnchoredRect as AnchoredRect24, Guard as Guard10, Utils as Utils11 } from "@tspro/ts-utils-lib";
7086
+
7087
+ // src/score/engine/obj-score-row-group.ts
7088
+ import { AnchoredRect as AnchoredRect23 } from "@tspro/ts-utils-lib";
7089
+ var ObjScoreRowGroup = class extends MusicObject {
7090
+ constructor(lines) {
7091
+ var _a;
7092
+ super(lines[0].row);
7093
+ this.lines = lines;
7094
+ __publicField(this, "space", 0);
7095
+ __publicField(this, "instrument");
7096
+ __publicField(this, "instrText");
7097
+ __publicField(this, "braceRect", new AnchoredRect23());
7098
+ __publicField(this, "mi");
7099
+ this.instrument = (_a = lines[0].getConfig().instrument) != null ? _a : "";
7100
+ this.instrText = new ObjText(this, { text: this.instrument, color: "black", scale: 1 }, 1, 0.5);
7101
+ this.mi = new MScoreRowGroup(this);
7102
+ }
7103
+ getMusicInterface() {
7104
+ return this.mi;
7105
+ }
7106
+ get row() {
7107
+ return this.lines[0].row;
7108
+ }
7109
+ get hasBrace() {
7110
+ return this.hasInstrument && this.lines.length > 1;
7111
+ }
7112
+ get hasInstrument() {
7113
+ return this.instrument.length > 0;
7114
+ }
7115
+ pick(x, y) {
7116
+ if (!this.getRect().contains(x, y))
7117
+ return [];
7118
+ let arr = this.instrText.pick(x, y);
7119
+ if (arr.length > 0) {
7120
+ return [this, ...arr];
7121
+ }
7122
+ return [this];
7123
+ }
7124
+ updateRect() {
7125
+ this.instrText.setRight(this.braceRect.left - this.space);
7126
+ this.instrText.setCenterY(this.braceRect.anchorY);
7127
+ this.rect = this.instrText.getRect().clone().expandInPlace(this.braceRect);
7128
+ }
7129
+ layout(ctx) {
7130
+ this.space = ctx.unitSize;
7131
+ this.instrText.layout(ctx);
7132
+ this.braceRect = new AnchoredRect23(-(this.hasBrace ? ctx.unitSize * 5 : 0), 0, 0, 0);
7133
+ this.forceRectUpdate();
7134
+ }
7135
+ layoutToNotationLines() {
7136
+ this.braceRect.top = this.lines[0].getTopLineY();
7137
+ this.braceRect.bottom = this.lines[this.lines.length - 1].getBottomLineY();
7138
+ this.braceRect.anchorY = this.braceRect.centerY;
7139
+ this.forceRectUpdate();
7140
+ }
7141
+ offset(dx, dy) {
7142
+ this.instrText.offset(dx, dy);
7143
+ this.braceRect.offsetInPlace(dx, dy);
7144
+ this.rect.offsetInPlace(dx, dy);
7145
+ }
7146
+ draw(ctx) {
7147
+ this.instrText.draw(ctx);
7148
+ if (this.hasBrace) {
7149
+ ctx.color("brack").lineWidth(1).drawBracket(this.braceRect, "{");
7150
+ }
7151
+ }
7152
+ };
7153
+
7154
+ // src/score/engine/obj-score-row.ts
7155
+ var ScoreRowRegions = class {
7156
+ constructor() {
7157
+ __publicField(this, "instrWidth", 0);
7158
+ __publicField(this, "staffWidth", 0);
7159
+ }
7160
+ resetWidths() {
7161
+ this.instrWidth = this.staffWidth = 0;
7162
+ }
7163
+ addRowInstrWidth(w) {
7164
+ this.instrWidth = Math.max(this.instrWidth, w);
7165
+ }
7166
+ addRowstaffWidth(w) {
7167
+ this.staffWidth = Math.max(this.staffWidth, w);
7168
+ }
7169
+ get instrLeft() {
7170
+ return 0;
7171
+ }
7172
+ get instrRight() {
7173
+ return this.instrWidth;
7174
+ }
7175
+ get staffLeft() {
7176
+ return this.instrRight;
7177
+ }
7178
+ get staffRight() {
7179
+ return this.staffLeft + this.staffWidth;
7180
+ }
7181
+ get left() {
7182
+ return this.instrLeft;
7183
+ }
7184
+ get right() {
7185
+ return this.staffRight;
7186
+ }
7187
+ get width() {
7188
+ return this.instrWidth + this.staffWidth;
7189
+ }
7190
+ };
6981
7191
  var ObjScoreRow = class extends MusicObject {
6982
7192
  constructor(doc, prevRow, scoreConfig) {
6983
7193
  super(doc);
@@ -6985,12 +7195,10 @@ var ObjScoreRow = class extends MusicObject {
6985
7195
  this.prevRow = prevRow;
6986
7196
  this.scoreConfig = scoreConfig;
6987
7197
  __publicField(this, "nextRow");
6988
- __publicField(this, "minWidth", 0);
6989
7198
  __publicField(this, "notationLines");
6990
- __publicField(this, "instrumentLineGroups");
7199
+ __publicField(this, "rowGroups");
6991
7200
  __publicField(this, "staves");
6992
7201
  __publicField(this, "tabs");
6993
- __publicField(this, "instrumentNames");
6994
7202
  __publicField(this, "measures", []);
6995
7203
  __publicField(this, "needLayout", true);
6996
7204
  __publicField(this, "mi");
@@ -7007,10 +7215,7 @@ var ObjScoreRow = class extends MusicObject {
7007
7215
  prevGroup.push(line);
7008
7216
  }
7009
7217
  }
7010
- this.instrumentLineGroups = lineGroups;
7011
- this.instrumentNames = this.instrumentLineGroups.map((lines) => {
7012
- return lines.length > 0 && Guard10.isNonEmptyString(lines[0].getConfig().instrument) ? new ObjText(this, String(lines[0].getConfig().instrument), 0, 0.5) : void 0;
7013
- });
7218
+ this.rowGroups = lineGroups.filter((lines) => lines.length > 0).map((lines) => new ObjScoreRowGroup(lines));
7014
7219
  if (this.prevRow) {
7015
7220
  this.prevRow.nextRow = this;
7016
7221
  }
@@ -7034,14 +7239,17 @@ var ObjScoreRow = class extends MusicObject {
7034
7239
  getNotationLines() {
7035
7240
  return this.notationLines;
7036
7241
  }
7037
- getInstrumentLineGroups() {
7038
- return this.instrumentLineGroups;
7242
+ getRowGroups() {
7243
+ return this.rowGroups;
7039
7244
  }
7040
7245
  findMatchingLine(line) {
7041
7246
  return line.row === this ? line : this.notationLines.find(
7042
7247
  (curLine) => Utils11.Obj.deepEqual(line.row.scoreConfig, curLine.row.scoreConfig) && line.id === curLine.id || Guard10.isNonEmptyString(line.getConfig().name) && line.getConfig().name === curLine.getConfig().name && line.getConfig().type === curLine.getConfig().type
7043
7248
  );
7044
7249
  }
7250
+ get regions() {
7251
+ return this.doc.regions;
7252
+ }
7045
7253
  getStaves() {
7046
7254
  return this.staves;
7047
7255
  }
@@ -7087,7 +7295,6 @@ var ObjScoreRow = class extends MusicObject {
7087
7295
  this.notationLines.forEach((line) => line.layoutLayoutGroups(ctx));
7088
7296
  }
7089
7297
  pick(x, y) {
7090
- var _a, _b;
7091
7298
  if (!this.getRect().contains(x, y)) {
7092
7299
  return [];
7093
7300
  }
@@ -7097,8 +7304,8 @@ var ObjScoreRow = class extends MusicObject {
7097
7304
  return [this, ...arr];
7098
7305
  }
7099
7306
  }
7100
- for (let i = 0; i < this.instrumentNames.length; i++) {
7101
- let arr = (_b = (_a = this.instrumentNames[i]) == null ? void 0 : _a.pick(x, y)) != null ? _b : [];
7307
+ for (let i = 0; i < this.rowGroups.length; i++) {
7308
+ let arr = this.rowGroups[i].pick(x, y);
7102
7309
  if (arr.length > 0) {
7103
7310
  return [this, ...arr];
7104
7311
  }
@@ -7115,7 +7322,7 @@ var ObjScoreRow = class extends MusicObject {
7115
7322
  let r = this.getRect();
7116
7323
  let firstMeasure = this.getFirstMeasure();
7117
7324
  let left = firstMeasure ? firstMeasure.getColumnsContentRect().left : r.left;
7118
- return new AnchoredRect23(left, (left + r.right) / 2, r.right, r.top, r.anchorY, r.bottom);
7325
+ return new AnchoredRect24(left, (left + r.right) / 2, r.right, r.top, r.anchorY, r.bottom);
7119
7326
  }
7120
7327
  getDiatonicIdAt(y) {
7121
7328
  for (let i = 0; i < this.notationLines.length; i++) {
@@ -7151,9 +7358,6 @@ var ObjScoreRow = class extends MusicObject {
7151
7358
  getLastMeasure() {
7152
7359
  return this.measures.length > 0 ? this.measures[this.measures.length - 1] : void 0;
7153
7360
  }
7154
- getMinWidth() {
7155
- return this.minWidth;
7156
- }
7157
7361
  solveAutoStemDir(symbols) {
7158
7362
  if (symbols.length === 0) {
7159
7363
  return "up" /* Up */;
@@ -7170,9 +7374,6 @@ var ObjScoreRow = class extends MusicObject {
7170
7374
  return staves.length > 0 ? avgDiatonicId >= staves[0].middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */ : "up" /* Up */;
7171
7375
  }
7172
7376
  }
7173
- getInstrumentNameWidth(ctx) {
7174
- return Math.max(0, ...this.instrumentNames.map((obj) => obj ? obj.getRect().width : 0));
7175
- }
7176
7377
  requestLayout() {
7177
7378
  if (!this.needLayout) {
7178
7379
  this.needLayout = true;
@@ -7184,37 +7385,39 @@ var ObjScoreRow = class extends MusicObject {
7184
7385
  return;
7185
7386
  }
7186
7387
  this.requestRectUpdate();
7187
- this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.layout(ctx));
7188
7388
  this.notationLines.forEach((line) => {
7189
7389
  line.removeObjects();
7190
7390
  line.layoutHeight(ctx);
7191
7391
  });
7192
- this.minWidth = 0;
7193
- this.measures.forEach((m) => {
7194
- m.layout(ctx);
7195
- this.minWidth += m.getMinWidth();
7196
- this.minWidth += m.getPostMeasureBreakWidth();
7392
+ this.rowGroups.forEach((grp) => {
7393
+ grp.layout(ctx);
7394
+ this.regions.addRowInstrWidth(grp.getRect().width);
7197
7395
  });
7396
+ this.measures.forEach((m) => m.layout(ctx));
7397
+ let packedWidth = this.measures.map((m) => m.getMinWidth() + m.getPostMeasureBreakWidth()).reduce((acc, cur) => acc + cur);
7398
+ this.regions.addRowstaffWidth(packedWidth);
7198
7399
  }
7199
- layoutWidth(ctx, left, right) {
7400
+ layoutStretch(ctx) {
7200
7401
  if (!this.needLayout) {
7201
7402
  return;
7202
7403
  }
7203
- this.rect = new AnchoredRect23(0, right, 0, 0);
7404
+ this.rect = new AnchoredRect24(this.regions.left, this.regions.right, 0, 0);
7204
7405
  this.notationLines.forEach((line) => line.layoutWidth(ctx));
7205
- let targetColumnsAreaWidth = right - left;
7406
+ this.rowGroups.forEach((grp) => grp.setRight(this.regions.instrRight));
7407
+ let targetColumnsAreaWidth = this.regions.staffWidth;
7206
7408
  let minColumnsAreaWidth = 0;
7207
7409
  this.measures.forEach((m) => {
7208
7410
  targetColumnsAreaWidth -= m.getTotalSolidWidth() + m.getPostMeasureBreakWidth();
7209
7411
  minColumnsAreaWidth += m.getMinColumnsWidth();
7210
7412
  });
7211
7413
  let columnsAreaScale = targetColumnsAreaWidth / minColumnsAreaWidth;
7212
- let x = this.doc.getInstrumentGroupRegions(ctx).braceRight;
7414
+ let x = this.regions.staffLeft;
7213
7415
  this.measures.forEach((m) => {
7214
7416
  let newMeasureWidth = m.getTotalSolidWidth() + m.getMinColumnsWidth() * columnsAreaScale;
7215
7417
  m.layoutWidth(ctx, newMeasureWidth);
7216
7418
  let r = m.getRect();
7217
- m.offset(x - r.left, -r.anchorY);
7419
+ m.setLeft(x);
7420
+ m.setAnchorY(0);
7218
7421
  x += r.width;
7219
7422
  x += m.getPostMeasureBreakWidth();
7220
7423
  });
@@ -7224,11 +7427,20 @@ var ObjScoreRow = class extends MusicObject {
7224
7427
  });
7225
7428
  }
7226
7429
  updateRect() {
7227
- let left = 0;
7228
- let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : left;
7229
- let top = this.measures.length > 0 ? Math.min(...this.measures.map((m) => m.getRect().top)) : 0;
7230
- let bottom = this.measures.length > 0 ? Math.max(...this.measures.map((m) => m.getRect().bottom)) : 0;
7231
- this.rect = new AnchoredRect23(left, right, top, bottom);
7430
+ var _a;
7431
+ let left = this.regions.left;
7432
+ let right = this.regions.right;
7433
+ let top = 0;
7434
+ let bottom = 0;
7435
+ const fermata = (_a = this.getLastMeasure()) == null ? void 0 : _a.getBarLineRight().getAnchoredLayoutObjects().map((o) => o.musicObj).find((o) => o instanceof ObjFermata);
7436
+ if (fermata) {
7437
+ right = Math.max(right, fermata.getRect().right);
7438
+ }
7439
+ if (this.measures.length > 0) {
7440
+ top = Math.min(...this.measures.map((m) => m.getRect().top));
7441
+ bottom = Math.max(...this.measures.map((m) => m.getRect().bottom));
7442
+ }
7443
+ this.rect = new AnchoredRect24(left, right, top, bottom);
7232
7444
  }
7233
7445
  alignStemsToBeams() {
7234
7446
  this.measures.forEach((m) => m.alignStemsToBeams());
@@ -7240,10 +7452,10 @@ var ObjScoreRow = class extends MusicObject {
7240
7452
  let cur = this.notationLines[i];
7241
7453
  if (prev instanceof ObjStaff && cur instanceof ObjStaff && prev.staffConfig.grandId !== void 0 && prev.staffConfig.grandId === cur.staffConfig.grandId) {
7242
7454
  let dy = prev.getBottomLineY() - cur.getTopLineY() + unitSize * 6;
7243
- cur.offset(0, dy);
7455
+ cur.offsetY(dy);
7244
7456
  } else {
7245
7457
  let dy = prev.calcBottom() - cur.calcTop() + unitSize * 3;
7246
- cur.offset(0, dy);
7458
+ cur.offsetY(dy);
7247
7459
  }
7248
7460
  }
7249
7461
  this.measures.forEach((m) => {
@@ -7258,26 +7470,10 @@ var ObjScoreRow = class extends MusicObject {
7258
7470
  });
7259
7471
  });
7260
7472
  });
7261
- this.instrumentNames.forEach((obj, i) => {
7262
- let grp = this.instrumentLineGroups[i];
7263
- if (obj && grp.length > 0) {
7264
- obj.offset(
7265
- -obj.getRect().left,
7266
- -obj.getRect().anchorY + (grp[0].getRect().top + grp[grp.length - 1].getRect().bottom) / 2
7267
- );
7268
- }
7269
- });
7473
+ this.rowGroups.forEach((grp) => grp.layoutToNotationLines());
7270
7474
  this.alignStemsToBeams();
7271
7475
  this.requestRectUpdate();
7272
7476
  }
7273
- layoutPadding(ctx) {
7274
- let p = ctx.unitSize / 2;
7275
- this.getRect();
7276
- this.rect.left -= p;
7277
- this.rect.right += p;
7278
- this.rect.top -= p;
7279
- this.rect.bottom += p;
7280
- }
7281
7477
  layoutDone() {
7282
7478
  this.measures.forEach((m) => m.layoutDone());
7283
7479
  this.needLayout = false;
@@ -7286,13 +7482,14 @@ var ObjScoreRow = class extends MusicObject {
7286
7482
  this.measures.forEach((m) => m.offset(dx, dy));
7287
7483
  this.rect.offsetInPlace(dx, dy);
7288
7484
  this.notationLines.forEach((l) => l.offset(dx, dy));
7289
- this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.offset(dx, dy));
7485
+ this.rowGroups.forEach((grp) => grp.offset(dx, dy));
7290
7486
  }
7291
7487
  draw(ctx) {
7292
7488
  ctx.drawDebugRect(this.getRect());
7489
+ const { left, top, width, height } = this.getRect();
7490
+ const p = ctx._lineWidth;
7293
7491
  ctx.save();
7294
- let { left, top, width, height } = this.getRect();
7295
- ctx.rect(left, top, width, height);
7492
+ ctx.rect(left - p, top, width + 2 * p, height);
7296
7493
  ctx.clip();
7297
7494
  if (this.getFirstMeasure() && (this.notationLines.length > 1 || this.notationLines[0] instanceof ObjTab)) {
7298
7495
  let left2 = this.getFirstMeasure().getStaffLineLeft();
@@ -7302,31 +7499,17 @@ var ObjScoreRow = class extends MusicObject {
7302
7499
  }
7303
7500
  this.measures.forEach((m) => m.draw(ctx));
7304
7501
  this.notationLines.forEach((m) => m.draw(ctx));
7305
- let grpSize = this.doc.getInstrumentGroupRegions(ctx);
7306
- this.instrumentNames.forEach((obj, i) => {
7307
- let grp = this.instrumentLineGroups[i];
7308
- if (grp.length > 1) {
7309
- let r = new AnchoredRect23(
7310
- grpSize.braceLeft,
7311
- grpSize.braceRight,
7312
- grp[0].getTopLineY(),
7313
- grp[grp.length - 1].getBottomLineY()
7314
- );
7315
- ctx.color("brack").lineWidth(1).drawBrace(r, "left");
7316
- }
7317
- if (obj) {
7318
- obj.draw(ctx);
7319
- }
7320
- });
7502
+ this.rowGroups.forEach((grp) => grp.draw(ctx));
7321
7503
  ctx.restore();
7322
7504
  }
7323
7505
  };
7324
7506
 
7325
7507
  // src/score/engine/obj-header.ts
7326
- import { AnchoredRect as AnchoredRect24 } from "@tspro/ts-utils-lib";
7508
+ import { AnchoredRect as AnchoredRect25 } from "@tspro/ts-utils-lib";
7327
7509
  var ObjHeader = class extends MusicObject {
7328
7510
  constructor(doc, title, composer, arranger) {
7329
7511
  super(doc);
7512
+ this.doc = doc;
7330
7513
  this.title = title;
7331
7514
  this.composer = composer;
7332
7515
  this.arranger = arranger;
@@ -7366,24 +7549,29 @@ var ObjHeader = class extends MusicObject {
7366
7549
  }
7367
7550
  return [this];
7368
7551
  }
7369
- layoutWidth(ctx, left, right) {
7552
+ layout(ctx) {
7370
7553
  let top = 0;
7371
- this.rect = new AnchoredRect24(left, right, 0, 0);
7554
+ const left = this.doc.regions.staffLeft;
7555
+ const right = this.doc.regions.staffRight;
7556
+ this.rect = new AnchoredRect25(left, right, 0, 0);
7372
7557
  if (this.titleText) {
7373
7558
  this.titleText.layout(ctx);
7374
- this.titleText.offset((left + right) / 2, top);
7559
+ this.titleText.setCenterX((left + right) / 2);
7560
+ this.titleText.setTop(top);
7375
7561
  top += this.titleText.getRect().height;
7376
7562
  this.rect.expandInPlace(this.titleText.getRect());
7377
7563
  }
7378
7564
  if (this.composerText) {
7379
7565
  this.composerText.layout(ctx);
7380
- this.composerText.offset(right, top);
7566
+ this.composerText.setRight(right);
7567
+ this.composerText.setTop(top);
7381
7568
  top += this.composerText.getRect().height;
7382
7569
  this.rect.expandInPlace(this.composerText.getRect());
7383
7570
  }
7384
7571
  if (this.arrangerText) {
7385
7572
  this.arrangerText.layout(ctx);
7386
- this.arrangerText.offset(right, top);
7573
+ this.arrangerText.setRight(right);
7574
+ this.arrangerText.setTop(top);
7387
7575
  top += this.arrangerText.getRect().height;
7388
7576
  this.rect.expandInPlace(this.arrangerText.getRect());
7389
7577
  }
@@ -7414,30 +7602,14 @@ var ObjHeader = class extends MusicObject {
7414
7602
  };
7415
7603
 
7416
7604
  // src/score/engine/obj-document.ts
7417
- import { AnchoredRect as AnchoredRect25, Guard as Guard11, UniMap as UniMap8 } from "@tspro/ts-utils-lib";
7605
+ import { AnchoredRect as AnchoredRect26, Guard as Guard11, UniMap as UniMap9 } from "@tspro/ts-utils-lib";
7418
7606
  import { MusicError as MusicError17, MusicErrorType as MusicErrorType17 } from "@tspro/web-music-score/core";
7419
- var InstrumentGroupRegions = class {
7420
- constructor() {
7421
- __publicField(this, "nameLeft", 0);
7422
- __publicField(this, "nameRight", 0);
7423
- __publicField(this, "braceLeft", 0);
7424
- __publicField(this, "braceRight", 0);
7425
- }
7426
- get left() {
7427
- return this.nameLeft;
7428
- }
7429
- get right() {
7430
- return this.braceRight;
7431
- }
7432
- get width() {
7433
- return this.right - this.left;
7434
- }
7435
- };
7436
7607
  var ObjDocument = class extends MusicObject {
7437
7608
  constructor() {
7438
7609
  super(void 0);
7439
7610
  __publicField(this, "needLayout", true);
7440
7611
  __publicField(this, "ctx");
7612
+ __publicField(this, "regions", new ScoreRowRegions());
7441
7613
  __publicField(this, "rows", []);
7442
7614
  __publicField(this, "measures", []);
7443
7615
  __publicField(this, "measuresPerRow", Infinity);
@@ -7445,8 +7617,7 @@ var ObjDocument = class extends MusicObject {
7445
7617
  __publicField(this, "header");
7446
7618
  __publicField(this, "newRowRequested", false);
7447
7619
  __publicField(this, "allConnectiveProps", []);
7448
- __publicField(this, "staffGroups", new UniMap8());
7449
- __publicField(this, "instrumentGroupRegions", new InstrumentGroupRegions());
7620
+ __publicField(this, "staffGroups", new UniMap9());
7450
7621
  __publicField(this, "mi");
7451
7622
  this.mi = new MDocument2(this);
7452
7623
  }
@@ -7643,17 +7814,6 @@ var ObjDocument = class extends MusicObject {
7643
7814
  this.ctx.updateCursorRect(cursorRect);
7644
7815
  }
7645
7816
  }
7646
- getInstrumentGroupRegions(ctx) {
7647
- let nameWidth = Math.max(0, ...this.rows.map((row) => row.getInstrumentNameWidth(ctx)));
7648
- let hasName = nameWidth > 0;
7649
- let padding = hasName ? ctx.unitSize : 0;
7650
- let braceWidth = hasName ? ctx.unitSize * 5 : 0;
7651
- this.instrumentGroupRegions.nameLeft = 0;
7652
- this.instrumentGroupRegions.nameRight = nameWidth;
7653
- this.instrumentGroupRegions.braceLeft = nameWidth + padding;
7654
- this.instrumentGroupRegions.braceRight = nameWidth + padding + braceWidth + padding;
7655
- return this.instrumentGroupRegions;
7656
- }
7657
7817
  requestLayout() {
7658
7818
  this.needLayout = true;
7659
7819
  }
@@ -7681,28 +7841,27 @@ var ObjDocument = class extends MusicObject {
7681
7841
  this.allConnectiveProps.forEach((props) => props.removeConnectives());
7682
7842
  this.allConnectiveProps.forEach((props) => props.createConnectives());
7683
7843
  this.rows.forEach((row) => row.resetLayoutGroups(ctx));
7844
+ this.regions.resetWidths();
7845
+ this.regions.addRowstaffWidth(DocumentSettings.MinStaffWidth * unitSize);
7684
7846
  this.rows.forEach((row) => row.layout(ctx));
7685
- let rowLeft = this.getInstrumentGroupRegions(ctx).right;
7686
- let rowRight = rowLeft + Math.max(
7687
- DocumentSettings.DocumentMinWidth * unitSize,
7688
- ...this.rows.map((row) => row.getMinWidth())
7689
- );
7690
- this.rows.forEach((row) => row.layoutWidth(ctx, rowLeft, rowRight));
7847
+ this.rows.forEach((row) => row.layoutStretch(ctx));
7691
7848
  this.rows.forEach((row) => row.layoutLayoutGroups(ctx));
7692
7849
  this.rows.forEach((row) => row.layoutSetNotationLines(ctx));
7693
- this.rows.forEach((row) => row.layoutPadding(ctx));
7694
- this.rect = new AnchoredRect25();
7850
+ this.rect = new AnchoredRect26();
7695
7851
  if (this.header) {
7696
- this.header.layoutWidth(ctx, rowLeft, rowRight);
7852
+ this.header.layout(ctx);
7697
7853
  this.rect.expandInPlace(this.header.getRect());
7698
7854
  }
7699
7855
  this.rows.forEach((row) => {
7700
- row.offset(-this.rect.left, this.rect.bottom + unitSize * 2 - row.getRect().top);
7856
+ row.setLeft(0);
7857
+ row.setTop(this.rect.bottom + unitSize * 2);
7701
7858
  this.rect.expandInPlace(row.getRect());
7702
7859
  });
7703
7860
  this.rows.forEach((row) => row.layoutDone());
7704
7861
  this.needLayout = false;
7705
7862
  }
7863
+ offset(dx, dy) {
7864
+ }
7706
7865
  drawContent() {
7707
7866
  const { ctx } = this;
7708
7867
  if (!ctx) {
@@ -8480,7 +8639,7 @@ var ScoreObjectEvent = class extends ScoreEvent {
8480
8639
 
8481
8640
  // src/score/pub/music-interface.ts
8482
8641
  import * as Audio2 from "@tspro/web-music-score/audio";
8483
- import { Guard as Guard14, UniMap as UniMap9, ValueSet as ValueSet2, Utils as Utils13 } from "@tspro/ts-utils-lib";
8642
+ import { Guard as Guard14, UniMap as UniMap10, ValueSet as ValueSet2, Utils as Utils13 } from "@tspro/ts-utils-lib";
8484
8643
 
8485
8644
  // src/score/pub/music-objects.ts
8486
8645
  import { Guard as Guard13 } from "@tspro/ts-utils-lib";
@@ -8827,10 +8986,10 @@ var _MBarLineLeft = class _MBarLineLeft extends MusicInterface5 {
8827
8986
  /** Object name. */
8828
8987
  __publicField(_MBarLineLeft, "Name", "BarLineLeft");
8829
8988
  var MBarLineLeft = _MBarLineLeft;
8830
- var _MStaffTabBarLine = class _MStaffTabBarLine extends MusicInterface5 {
8989
+ var _MStaffBarLine = class _MStaffBarLine extends MusicInterface5 {
8831
8990
  /** @internal */
8832
8991
  constructor(obj) {
8833
- super(_MStaffTabBarLine.Name);
8992
+ super(_MStaffBarLine.Name);
8834
8993
  this.obj = obj;
8835
8994
  }
8836
8995
  /** @internal */
@@ -8846,7 +9005,7 @@ var _MStaffTabBarLine = class _MStaffTabBarLine extends MusicInterface5 {
8846
9005
  if (barLine instanceof ObjBarLineLeft || barLine instanceof ObjBarLineRight) {
8847
9006
  return barLine.getMusicInterface();
8848
9007
  } else {
8849
- throw new MusicError20(MusicErrorType20.Score, `Bar line not let nor right.`);
9008
+ throw new MusicError20(MusicErrorType20.Score, `Bar line not left nor right.`);
8850
9009
  }
8851
9010
  }
8852
9011
  /**
@@ -8858,8 +9017,8 @@ var _MStaffTabBarLine = class _MStaffTabBarLine extends MusicInterface5 {
8858
9017
  }
8859
9018
  };
8860
9019
  /** Object name. */
8861
- __publicField(_MStaffTabBarLine, "Name", "StaffTabBarLine");
8862
- var MStaffTabBarLine = _MStaffTabBarLine;
9020
+ __publicField(_MStaffBarLine, "Name", "StaffBarLine");
9021
+ var MStaffBarLine = _MStaffBarLine;
8863
9022
  var _MNoteGroup = class _MNoteGroup extends MusicInterface5 {
8864
9023
  /** @internal */
8865
9024
  constructor(obj) {
@@ -9140,6 +9299,27 @@ var _MScoreRow = class _MScoreRow extends MusicInterface5 {
9140
9299
  /** Object name. */
9141
9300
  __publicField(_MScoreRow, "Name", "ScoreRow");
9142
9301
  var MScoreRow = _MScoreRow;
9302
+ var _MScoreRowGroup = class _MScoreRowGroup extends MusicInterface5 {
9303
+ /** @internal */
9304
+ constructor(obj) {
9305
+ super(_MScoreRowGroup.Name);
9306
+ this.obj = obj;
9307
+ }
9308
+ /** @internal */
9309
+ getMusicObject() {
9310
+ return this.obj;
9311
+ }
9312
+ /**
9313
+ * Get instrument name.
9314
+ * @returns - instrument name.
9315
+ */
9316
+ getInstrument() {
9317
+ return this.obj.instrument;
9318
+ }
9319
+ };
9320
+ /** Object name. */
9321
+ __publicField(_MScoreRowGroup, "Name", "ScoreRowGroup");
9322
+ var MScoreRowGroup = _MScoreRowGroup;
9143
9323
  var _MStaff = class _MStaff extends MusicInterface5 {
9144
9324
  /** @internal */
9145
9325
  constructor(obj) {
@@ -9658,7 +9838,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9658
9838
  this.savedOnClickListeners.getOrCreate(btn, []).push(onClickListener);
9659
9839
  }
9660
9840
  };
9661
- __publicField(_MPlaybackButtons, "savedOnClickListeners", new UniMap9());
9841
+ __publicField(_MPlaybackButtons, "savedOnClickListeners", new UniMap10());
9662
9842
  var MPlaybackButtons = _MPlaybackButtons;
9663
9843
 
9664
9844
  // src/score/index.ts
@@ -9698,13 +9878,14 @@ export {
9698
9878
  MRest,
9699
9879
  MRhythmColumn,
9700
9880
  MScoreRow,
9881
+ MScoreRowGroup,
9701
9882
  MSpecialText,
9702
9883
  MStaff,
9884
+ MStaffBarLine,
9703
9885
  MStaffBeamGroup,
9704
9886
  MStaffNoteGroup,
9705
9887
  MStaffRest,
9706
9888
  MStaffSignature,
9707
- MStaffTabBarLine,
9708
9889
  MTab,
9709
9890
  MTabNoteGroup,
9710
9891
  MTabRhythm,