@tspro/web-music-score 5.1.0 → 5.3.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 +22 -0
  2. package/README.md +13 -12
  3. package/dist/audio/index.d.ts +1 -1
  4. package/dist/audio/index.js +2 -2
  5. package/dist/audio/index.mjs +4 -4
  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-2EQHSQWO.mjs → chunk-C6UQDKWU.mjs} +2 -2
  11. package/dist/{chunk-ROPTZBKD.mjs → chunk-PMDIUO22.mjs} +2 -2
  12. package/dist/{chunk-QVYFIK3L.mjs → chunk-ZBA5XLYR.mjs} +3 -3
  13. package/dist/core/index.js +2 -2
  14. package/dist/core/index.mjs +3 -3
  15. package/dist/{guitar-CaZJDA05.d.ts → guitar-BsSayRsH.d.ts} +1 -1
  16. package/dist/iife/audio-cg.global.js +9 -2
  17. package/dist/iife/index.global.js +11 -11
  18. package/dist/{music-objects-DTDFSro0.d.mts → music-objects-BGiRQIXW.d.mts} +218 -149
  19. package/dist/{music-objects-CMdYZeC6.d.ts → music-objects-Ih9vCl4p.d.ts} +220 -151
  20. package/dist/{note-eA2xPPiG.d.ts → note-CgCIBwvR.d.ts} +1 -1
  21. package/dist/pieces/index.d.mts +11 -2
  22. package/dist/pieces/index.d.ts +13 -4
  23. package/dist/pieces/index.js +20 -9
  24. package/dist/pieces/index.mjs +20 -10
  25. package/dist/react-ui/index.d.mts +2 -2
  26. package/dist/react-ui/index.d.ts +6 -6
  27. package/dist/react-ui/index.js +9 -9
  28. package/dist/react-ui/index.mjs +11 -11
  29. package/dist/{scale-DGx3tJH4.d.ts → scale-CBW4eTz7.d.ts} +2 -2
  30. package/dist/score/index.d.mts +6 -4
  31. package/dist/score/index.d.ts +9 -7
  32. package/dist/score/index.js +1406 -1182
  33. package/dist/score/index.mjs +1388 -1165
  34. package/dist/{tempo-GrstpD9G.d.ts → tempo-DMt3iwz9.d.ts} +1 -1
  35. package/dist/theory/index.d.ts +6 -6
  36. package/dist/theory/index.js +1 -1
  37. package/dist/theory/index.mjs +3 -3
  38. package/package.json +2 -2
@@ -1,12 +1,12 @@
1
- /* WebMusicScore v5.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v5.3.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  import {
3
3
  NoteLengthProps,
4
4
  RhythmProps,
5
5
  validateNoteLength
6
- } from "../chunk-QVYFIK3L.mjs";
6
+ } from "../chunk-ZBA5XLYR.mjs";
7
7
  import {
8
8
  __publicField
9
- } from "../chunk-2EQHSQWO.mjs";
9
+ } from "../chunk-C6UQDKWU.mjs";
10
10
 
11
11
  // src/score/pub/div-rect.ts
12
12
  import { Utils } from "@tspro/ts-utils-lib";
@@ -288,7 +288,7 @@ var DivRect = class _DivRect {
288
288
  };
289
289
 
290
290
  // src/score/pub/document-builder.ts
291
- import { Utils as Utils15 } from "@tspro/ts-utils-lib";
291
+ import { Utils as Utils16 } from "@tspro/ts-utils-lib";
292
292
 
293
293
  // src/score/pub/types.ts
294
294
  var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
@@ -300,10 +300,10 @@ var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
300
300
  StaffPreset3["GuitarCombined"] = "guitarCombined";
301
301
  return StaffPreset3;
302
302
  })(StaffPreset || {});
303
- var Clef = /* @__PURE__ */ ((Clef4) => {
304
- Clef4["G"] = "G";
305
- Clef4["F"] = "F";
306
- return Clef4;
303
+ var Clef = /* @__PURE__ */ ((Clef2) => {
304
+ Clef2["G"] = "G";
305
+ Clef2["F"] = "F";
306
+ return Clef2;
307
307
  })(Clef || {});
308
308
  function getVoiceIds() {
309
309
  return [0, 1, 2, 3];
@@ -499,7 +499,7 @@ import { Note as Note9 } from "@tspro/web-music-score/theory";
499
499
  // src/score/engine/obj-staff-and-tab.ts
500
500
  import { getTuningStrings, Note as Note8, validateTuningName } from "@tspro/web-music-score/theory";
501
501
 
502
- // src/score/engine/renderer.ts
502
+ // src/score/engine/render-context.ts
503
503
  import { Utils as Utils2, Vec2, Device } from "@tspro/ts-utils-lib";
504
504
 
505
505
  // src/score/engine/settings.ts
@@ -524,6 +524,7 @@ var DocumentSettings = {
524
524
  FlagSeparation: 2,
525
525
  BeamSeparation: 1.25,
526
526
  BeamAngleFactor: 0.5,
527
+ BeamThickness: 4,
527
528
  RestDotSpace: 0.5,
528
529
  LedgerLineWidth: 3.6,
529
530
  StubTieLength: 5,
@@ -531,22 +532,22 @@ var DocumentSettings = {
531
532
  TabHeight: 20
532
533
  };
533
534
 
534
- // src/score/engine/renderer.ts
535
+ // src/score/engine/render-context.ts
535
536
  import { MusicError as MusicError2, MusicErrorType as MusicErrorType2 } from "@tspro/web-music-score/core";
536
537
 
537
- // src/score/engine/assets/treble-clef.png
538
- var treble_clef_default = "data:image/png;base64,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TTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6NDA3ODVjMzYtNDAxZC00YTZlLTkxODctMDQ1NTI4MmM0ZGY2IgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjhiZTJkYzc1LTVlYjQtNDk0Yy1iNWRlLWQ2MzZkNzZhNjI2YiIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmU3YWE0MWNhLTNiYjMtNGU5Yi05NDQxLTllNTNmZTJiZjM5ZiIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09IldpbmRvd3MiCiAgIEdJTVA6VGltZVN0YW1wPSIxNjg2NDA4NjA5MzE2NDM4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzQiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIgogICB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzOjA2OjEwVDE3OjUwOjA5KzAzOjAwIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMzowNjoxMFQxNzo1MDowOSswMzowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjI3MzY2YmY0LWVkZDMtNDE5OC05NjJhLWU5ZTM5MTBlNThiZSIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOC0yMlQwMjo1NTozNiIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo5NjVlMTM3OS0wZDlmLTQ5ODItYWQ3MC05MzhjOWMzOWE0ZjMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjItMDktMTFUMTY6MzU6MDAiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MTBmYmEwYTMtOTI5Yi00NTRlLThjNGMtOGVkOGM4YWJhZGRjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEwVDE3OjUwOjA5Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Ppn4NIQAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgoOMgm5WlWBAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAACHtJREFUeNrtnXuQVmMcxz+77cauTWUpbGSVu2w3BpnUEBq3chkmBjGayG1GBuNWLtUgw5SJkBkjl4QKg1wyQyarK0lRSlstU20bWam9+OM8O3P6vc8553nOe97tnO18Z84f57zP7XvOc/ndnueFfQx5e6neUmAI0B3oDPwD/AJ8Dvzcml5we+Al4D+gyeOaB1S0BrLHAut9iLqv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";
538
+ // src/score/engine/assets/F-clef.png
539
+ var F_clef_default = "data:image/png;base64,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IHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo0MDc4NWMzNi00MDFkLTRhNmUtOTE4Ny0wNDU1MjgyYzRkZjYiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Nzg3YjYxN2YtMjg1MS00YzhlLTg2MTYtZWM3NGMwYzYwMWVlIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZTdhYTQxY2EtM2JiMy00ZTliLTk0NDEtOWU1M2ZlMmJmMzlmIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iV2luZG93cyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODY2MTM5NDcxOTU2ODAiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjM6MDY6MTNUMDI6NTI6MjUrMDM6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIzOjA2OjEzVDAyOjUyOjI1KzAzOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MjczNjZiZjQtZWRkMy00MTk4LTk2MmEtZTllMzkxMGU1OGJlIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIyLTA4LTIyVDAyOjU1OjM2Ii8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjk2NWUxMzc5LTBkOWYtNDk4Mi1hZDcwLTkzOGM5YzM5YTRmMyIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOS0xMVQxNjozNTowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxMGZiYTBhMy05MjliLTQ1NGUtOGM0Yy04ZWQ4YzhhYmFkZGMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjMtMDYtMTBUMTc6NTA6MDkiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MDBmYjM4YTMtZjZiMi00NjQ1LTliMTYtMjlhNWE0ODZlMjhhIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEzVDAyOjUyOjI3Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PsIRrtIAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgwXNBsqJURsAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAABF9JREFUeNrtmluIF1Ucxz9/E8P1VnnJ9dJWC4Frmq2JJmqolGEILoQvK2gZeXlRCSm1Fx9UEsJQERWsXhRftECs0Gq70EK9ZHlbFyHbds3VVXFX91+7664P81tYhpnfmft//st84TzMzDm/8/vOnPO7nYEMGTJkyJAhQ4YMGSJBLkJZw4FyYAIwDHgU+A9oAxqBv4C7xfyySoBlwKfAFaAb6DG0euAzoAoYXCxEnwH2A60eCGrtFrALGJNWokNEwY6QRO2tFXgPGJAmss8DlyImam/fASPTQHaeGJueBFod8FQhrfSLwM+ynDX8L1/oV+BP4LZY58eBUUAlMB94ycPSvQTMERmJ4jGgwYPh2Qg84VFmGbAP6DTI/aoQS/lzg1JfA2MDyn4ZuGaQvyZJspUGv3oKGBhyjmeBJmWOmxLMJIITiiIXIgwaZgFdylxbDeNHANXAZmAVUBpEiScNe2xRxC/3Y2WuRmUlLRHD1rd/HljvV4F3FAVqYlhNo4B7Pl/wdPEMbmOq/ShwRBH0Vkxb6LAy536fW64HuOpn8vOKoLKYCC9Q5rzs0L/JQxDjyYPkgHYXAW0xGslByrLuFuPUFw0eCI92mmiAQ4LgZoEbYyTcAZxVPsJk271ag7x6cWueCLvhfsyu8LzybKLtersUF9ywxe2BnXBnAZOUJuXZeNv1OSki3LLdzwPrgONuguw+7g7wAHjEoW+vEagAXgeelr1yUSZoCUn4hvJsqMO9byRaWyLGtFkiwOtBJnYzBKcVg/ZuSMIrlHl3RrWMnFK1OqX/q8oXOAisDqFLVxL7xonw9yHk7Q5RoxpuyLdjI3wmhLzBwMqAY0ck4SGcCNeKIQqKOTF84RtxEu4BPgohc2QM467HSRjgqBL5mBDUPU1Rnl1JwqBNUuJqrW0M+OLdYuk8Cdas38Rf4b3FR0HP/nLdZNYaioKbxSVuA6ZGQfoNvNWlO6VvEKxW5O5yGbNc4ml7ZrUtCtLjgGMSdjop9Q+wMIT8GoXwKw79ZxrKUG9r+a8flMoyr5AA4ybwo1QgggYHpZJ6Ou3Ta5IpddvufwEsVWQ2xFisCI1Nypf6RMmsIql4JI0S8bFuSs9UvmCgikeh8b6i8C/KuKOYD+VShzGSwLsprRnByYYYoSqNhE8qCv/kYfxrYjT7jmuPIC+PBWsVsl1YRzBeE45qqWGtwjo1SR0WoZ8a7KAfYa5h7/2OVaPuF1gqtS83srclpi565IAP0c+b7wOz+wPZckOc3Jt0LC52oiXABx7y6VasGnfRYgiwwRAu9raGqPLXQmAGcADvvyN+m9bgXnP4i4E9wN8+KiJ5WQG5QilumnioJP9lwHPANKw/fF7A+fxJw2ms/y9SFdiPBf4Vn9hJNL8T/iFxbyoxgej+m6zBOtnLpXlvhiXcDOyVJV8UCEL4KnBI/OnAtBP0q+ADMTq/SfshrdUFr4TzwJdY9d57WIdYzRIk1GMdeXSQIUOGDBmSwUMtd8u2ArdcUAAAAABJRU5ErkJggg==";
539
540
 
540
- // src/score/engine/assets/bass-clef.png
541
- var bass_clef_default = "data:image/png;base64,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IHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo0MDc4NWMzNi00MDFkLTRhNmUtOTE4Ny0wNDU1MjgyYzRkZjYiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Nzg3YjYxN2YtMjg1MS00YzhlLTg2MTYtZWM3NGMwYzYwMWVlIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZTdhYTQxY2EtM2JiMy00ZTliLTk0NDEtOWU1M2ZlMmJmMzlmIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iV2luZG93cyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODY2MTM5NDcxOTU2ODAiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjM6MDY6MTNUMDI6NTI6MjUrMDM6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIzOjA2OjEzVDAyOjUyOjI1KzAzOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MjczNjZiZjQtZWRkMy00MTk4LTk2MmEtZTllMzkxMGU1OGJlIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIyLTA4LTIyVDAyOjU1OjM2Ii8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjk2NWUxMzc5LTBkOWYtNDk4Mi1hZDcwLTkzOGM5YzM5YTRmMyIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOS0xMVQxNjozNTowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxMGZiYTBhMy05MjliLTQ1NGUtOGM0Yy04ZWQ4YzhhYmFkZGMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjMtMDYtMTBUMTc6NTA6MDkiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MDBmYjM4YTMtZjZiMi00NjQ1LTliMTYtMjlhNWE0ODZlMjhhIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEzVDAyOjUyOjI3Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PsIRrtIAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgwXNBsqJURsAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAABF9JREFUeNrtmluIF1Ucxz9/E8P1VnnJ9dJWC4Frmq2JJmqolGEILoQvK2gZeXlRCSm1Fx9UEsJQERWsXhRftECs0Gq70EK9ZHlbFyHbds3VVXFX91+7664P81tYhpnfmft//st84TzMzDm/8/vOnPO7nYEMGTJkyJAhQ4YMGSJBLkJZw4FyYAIwDHgU+A9oAxqBv4C7xfyySoBlwKfAFaAb6DG0euAzoAoYXCxEnwH2A60eCGrtFrALGJNWokNEwY6QRO2tFXgPGJAmss8DlyImam/fASPTQHaeGJueBFod8FQhrfSLwM+ynDX8L1/oV+BP4LZY58eBUUAlMB94ycPSvQTMERmJ4jGgwYPh2Qg84VFmGbAP6DTI/aoQS/lzg1JfA2MDyn4ZuGaQvyZJspUGv3oKGBhyjmeBJmWOmxLMJIITiiIXIgwaZgFdylxbDeNHANXAZmAVUBpEiScNe2xRxC/3Y2WuRmUlLRHD1rd/HljvV4F3FAVqYlhNo4B7Pl/wdPEMbmOq/ShwRBH0Vkxb6LAy536fW64HuOpn8vOKoLKYCC9Q5rzs0L/JQxDjyYPkgHYXAW0xGslByrLuFuPUFw0eCI92mmiAQ4LgZoEbYyTcAZxVPsJk271ag7x6cWueCLvhfsyu8LzybKLtersUF9ywxe2BnXBnAZOUJuXZeNv1OSki3LLdzwPrgONuguw+7g7wAHjEoW+vEagAXgeelr1yUSZoCUn4hvJsqMO9byRaWyLGtFkiwOtBJnYzBKcVg/ZuSMIrlHl3RrWMnFK1OqX/q8oXOAisDqFLVxL7xonw9yHk7Q5RoxpuyLdjI3wmhLzBwMqAY0ck4SGcCNeKIQqKOTF84RtxEu4BPgohc2QM467HSRjgqBL5mBDUPU1Rnl1JwqBNUuJqrW0M+OLdYuk8Cdas38Rf4b3FR0HP/nLdZNYaioKbxSVuA6ZGQfoNvNWlO6VvEKxW5O5yGbNc4ml7ZrUtCtLjgGMSdjop9Q+wMIT8GoXwKw79ZxrKUG9r+a8flMoyr5AA4ybwo1QgggYHpZJ6Ou3Ta5IpddvufwEsVWQ2xFisCI1Nypf6RMmsIql4JI0S8bFuSs9UvmCgikeh8b6i8C/KuKOYD+VShzGSwLsprRnByYYYoSqNhE8qCv/kYfxrYjT7jmuPIC+PBWsVsl1YRzBeE45qqWGtwjo1SR0WoZ8a7KAfYa5h7/2OVaPuF1gqtS83srclpi565IAP0c+b7wOz+wPZckOc3Jt0LC52oiXABx7y6VasGnfRYgiwwRAu9raGqPLXQmAGcADvvyN+m9bgXnP4i4E9wN8+KiJ5WQG5QilumnioJP9lwHPANKw/fF7A+fxJw2ms/y9SFdiPBf4Vn9hJNL8T/iFxbyoxgej+m6zBOtnLpXlvhiXcDOyVJV8UCEL4KnBI/OnAtBP0q+ADMTq/SfshrdUFr4TzwJdY9d57WIdYzRIk1GMdeXSQIUOGDBmSwUMtd8u2ArdcUAAAAABJRU5ErkJggg==";
541
+ // src/score/engine/assets/G-clef.png
542
+ var G_clef_default = "data:image/png;base64,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TTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6NDA3ODVjMzYtNDAxZC00YTZlLTkxODctMDQ1NTI4MmM0ZGY2IgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjhiZTJkYzc1LTVlYjQtNDk0Yy1iNWRlLWQ2MzZkNzZhNjI2YiIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmU3YWE0MWNhLTNiYjMtNGU5Yi05NDQxLTllNTNmZTJiZjM5ZiIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09IldpbmRvd3MiCiAgIEdJTVA6VGltZVN0YW1wPSIxNjg2NDA4NjA5MzE2NDM4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzQiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIgogICB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzOjA2OjEwVDE3OjUwOjA5KzAzOjAwIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMzowNjoxMFQxNzo1MDowOSswMzowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjI3MzY2YmY0LWVkZDMtNDE5OC05NjJhLWU5ZTM5MTBlNThiZSIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOC0yMlQwMjo1NTozNiIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo5NjVlMTM3OS0wZDlmLTQ5ODItYWQ3MC05MzhjOWMzOWE0ZjMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjItMDktMTFUMTY6MzU6MDAiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MTBmYmEwYTMtOTI5Yi00NTRlLThjNGMtOGVkOGM4YWJhZGRjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEwVDE3OjUwOjA5Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Ppn4NIQAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgoOMgm5WlWBAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAACHtJREFUeNrtnXuQVmMcxz+77cauTWUpbGSVu2w3BpnUEBq3chkmBjGayG1GBuNWLtUgw5SJkBkjl4QKg1wyQyarK0lRSlstU20bWam9+OM8O3P6vc8553nOe97tnO18Z84f57zP7XvOc/ndnueFfQx5e6neUmAI0B3oDPwD/AJ8Dvzcml5we+Al4D+gyeOaB1S0BrLHAut9iLqv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";
542
543
 
543
- // src/score/engine/renderer.ts
544
+ // src/score/engine/render-context.ts
544
545
  var HilightStaffPosRectColor = "#55cc55";
545
546
  var HilightObjectRectColor = "#55cc55";
546
547
  var PlayPosIndicatorColor = "#44aa44";
547
548
  var ImageAssets = /* @__PURE__ */ new Map([
548
- [0 /* TrebleClefPng */, { src: treble_clef_default }],
549
- [1 /* BassClefPng */, { src: bass_clef_default }]
549
+ [0 /* G_Clef */, { src: G_clef_default }],
550
+ [1 /* F_Clef */, { src: F_clef_default }]
550
551
  ]);
551
552
  function staffPosEquals(a, b) {
552
553
  if (!a && !b) return true;
@@ -558,14 +559,13 @@ function objectsEquals(a, b) {
558
559
  else if (!a || !b) return false;
559
560
  else return a.length === b.length && a.every((a2, i) => a2 === b[i]);
560
561
  }
561
- var Renderer = class {
562
+ var RenderContext = class {
562
563
  constructor(mi) {
563
564
  this.mi = mi;
564
565
  __publicField(this, "devicePixelRatio");
565
566
  __publicField(this, "fontSize");
566
567
  __publicField(this, "unitSize");
567
- __publicField(this, "lineWidth");
568
- __publicField(this, "beamThickness");
568
+ __publicField(this, "_lineWidth");
569
569
  __publicField(this, "scoreEventListener");
570
570
  __publicField(this, "canvas");
571
571
  __publicField(this, "ctx");
@@ -585,8 +585,7 @@ var Renderer = class {
585
585
  this.devicePixelRatio = window.devicePixelRatio;
586
586
  this.fontSize = Device.FontSize * DocumentSettings.DocumentScale * this.devicePixelRatio;
587
587
  this.unitSize = this.fontSize * 0.3;
588
- this.lineWidth = this.unitSize * 0.2;
589
- this.beamThickness = this.unitSize * 0.8;
588
+ this._lineWidth = this.unitSize * 0.2;
590
589
  ImageAssets.forEach((asset) => {
591
590
  if (asset.finished !== true) {
592
591
  const img = new Image();
@@ -632,10 +631,10 @@ var Renderer = class {
632
631
  let prevMDoc = this.mdoc;
633
632
  this.mdoc = mdoc;
634
633
  if (prevMDoc) {
635
- prevMDoc.getMusicObject().setRenderer(void 0);
634
+ prevMDoc.getMusicObject().setRenderContext(void 0);
636
635
  }
637
636
  if (mdoc) {
638
- mdoc.getMusicObject().setRenderer(this);
637
+ mdoc.getMusicObject().setRenderContext(this);
639
638
  }
640
639
  }
641
640
  setCanvas(canvas) {
@@ -771,22 +770,24 @@ var Renderer = class {
771
770
  }
772
771
  }
773
772
  draw() {
774
- let { ctx, doc } = this;
775
- if (!ctx || !doc) {
776
- return;
773
+ try {
774
+ let { doc } = this;
775
+ if (doc) {
776
+ doc.layout();
777
+ this.updateCanvasSize();
778
+ this.clearCanvas();
779
+ this.drawHilightStaffPosRect();
780
+ this.drawHilightObjectRect();
781
+ this.drawPlayCursor();
782
+ doc.drawContent();
783
+ }
784
+ } catch (err) {
785
+ console.error("Render failed!", err);
777
786
  }
778
- doc.layout();
779
- this.updateCanvasSize();
780
- this.clearCanvas();
781
- this.drawHilightStaffPosRect();
782
- this.drawHilightObjectRect();
783
- this.drawPlayCursor();
784
- doc.drawContent();
785
787
  }
786
788
  drawHilightStaffPosRect() {
787
- let ctx = this.getCanvasContext();
788
789
  let { mousePos, hilightedStaffPos, unitSize } = this;
789
- if (!ctx || !hilightedStaffPos) {
790
+ if (!hilightedStaffPos) {
790
791
  return;
791
792
  }
792
793
  let { scoreRow, diatonicId } = hilightedStaffPos;
@@ -794,26 +795,25 @@ var Renderer = class {
794
795
  if (!staff) {
795
796
  return;
796
797
  }
797
- ctx.fillStyle = HilightStaffPosRectColor;
798
- ctx.fillRect(0, staff.getDiatonicIdY(diatonicId) - unitSize, ctx.canvas.width, 2 * unitSize);
798
+ this.fillColor(HilightStaffPosRectColor);
799
+ this.fillRect(staff.row.getRect().left, staff.getDiatonicIdY(diatonicId) - unitSize, staff.row.getRect().width, 2 * unitSize);
799
800
  if (mousePos !== void 0) {
800
801
  this.drawLedgerLines(staff, diatonicId, mousePos.x);
801
802
  }
802
803
  }
803
804
  drawHilightObjectRect() {
804
- let ctx = this.getCanvasContext();
805
805
  let { hilightedObj } = this;
806
- if (!ctx || !hilightedObj) {
806
+ if (!hilightedObj) {
807
807
  return;
808
808
  }
809
809
  let rect = hilightedObj.getRect();
810
- ctx.strokeStyle = HilightObjectRectColor;
811
- ctx.strokeRect(rect.left, rect.top, rect.width, rect.height);
810
+ this.lineColor(HilightObjectRectColor);
811
+ this.strokeRect(rect.left, rect.top, rect.width, rect.height);
812
812
  }
813
813
  drawPlayCursor() {
814
- let { cursorRect: r, lineWidth } = this;
814
+ let { cursorRect: r } = this;
815
815
  if (r) {
816
- this.drawLine(r.centerX, r.top, r.centerX, r.bottom, PlayPosIndicatorColor, lineWidth * 2);
816
+ this.color(PlayPosIndicatorColor).lineWidth(2).strokeLine(r.centerX, r.top, r.centerX, r.bottom);
817
817
  }
818
818
  }
819
819
  txFromScreenCoord(screenCoord) {
@@ -822,75 +822,13 @@ var Renderer = class {
822
822
  txToScreenCoord(coord) {
823
823
  return coord.div(this.devicePixelRatio);
824
824
  }
825
- getCanvasContext() {
826
- return this.ctx;
827
- }
828
825
  clearCanvas() {
829
- let ctx = this.getCanvasContext();
830
- if (ctx) {
831
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
832
- }
833
- }
834
- getTextWidth(text, font) {
835
- let ctx = this.getCanvasContext();
836
- if (ctx) {
837
- let savedFont = ctx.font;
838
- ctx.font = font;
839
- let metrics = ctx.measureText(text);
840
- ctx.font = savedFont;
841
- return metrics.width;
842
- } else {
843
- return Utils2.Dom.getCanvasTextWidth(text, font);
844
- }
826
+ var _a;
827
+ (_a = this.ctx) == null ? void 0 : _a.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
845
828
  }
846
829
  drawDebugRect(r) {
847
- if (!DebugSettings.DrawDebugRects) {
848
- return;
849
- }
850
- let ctx = this.getCanvasContext();
851
- if (ctx) {
852
- ctx.lineWidth = 1;
853
- ctx.strokeStyle = "red";
854
- ctx.beginPath();
855
- ctx.rect(r.left, r.top, r.right - r.left, r.bottom - r.top);
856
- ctx.stroke();
857
- }
858
- }
859
- fillCircle(x, y, radius, color) {
860
- let ctx = this.getCanvasContext();
861
- if (ctx) {
862
- if (color !== void 0) {
863
- ctx.fillStyle = color;
864
- }
865
- ctx.beginPath();
866
- ctx.arc(x, y, radius, 0, 2 * Math.PI);
867
- ctx.fill();
868
- }
869
- }
870
- drawLine(startX, startY, endX, endY, color, lineWidth) {
871
- let ctx = this.getCanvasContext();
872
- if (ctx) {
873
- ctx.strokeStyle = color != null ? color : "black";
874
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
875
- ctx.beginPath();
876
- ctx.moveTo(startX, startY);
877
- ctx.lineTo(endX, endY);
878
- ctx.stroke();
879
- }
880
- }
881
- drawPartialLine(startX, startY, endX, endY, startT, endT, color, lineWidth) {
882
- let ctx = this.getCanvasContext();
883
- if (ctx) {
884
- let x1 = startX + (endX - startX) * startT;
885
- let y1 = startY + (endY - startY) * startT;
886
- let x2 = startX + (endX - startX) * endT;
887
- let y2 = startY + (endY - startY) * endT;
888
- ctx.strokeStyle = color != null ? color : "black";
889
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
890
- ctx.beginPath();
891
- ctx.moveTo(x1, y1);
892
- ctx.lineTo(x2, y2);
893
- ctx.stroke();
830
+ if (DebugSettings.DrawDebugRects) {
831
+ this.color("red").lineWidth(1).strokeRect(r.left, r.top, r.width, r.height);
894
832
  }
895
833
  }
896
834
  drawLedgerLines(staff, diatonicId, x) {
@@ -900,14 +838,14 @@ var Renderer = class {
900
838
  for (let lineDiatonicId = staff.topLineDiatonicId + 2; lineDiatonicId <= diatonicId; lineDiatonicId += 2) {
901
839
  if (staff.containsDiatonicId(lineDiatonicId)) {
902
840
  let y = staff.getDiatonicIdY(lineDiatonicId);
903
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
841
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
904
842
  }
905
843
  }
906
844
  } else if (diatonicId <= staff.bottomLineDiatonicId - 2) {
907
845
  for (let lineDiatonicId = staff.bottomLineDiatonicId - 2; lineDiatonicId >= diatonicId; lineDiatonicId -= 2) {
908
846
  if (staff.containsDiatonicId(lineDiatonicId)) {
909
847
  let y = staff.getDiatonicIdY(lineDiatonicId);
910
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
848
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
911
849
  }
912
850
  }
913
851
  }
@@ -943,44 +881,38 @@ var Renderer = class {
943
881
  }
944
882
  return new DivRect(-leftw, 0, rightw, -toph, 0, bottomh);
945
883
  }
946
- drawRest(restSize, x, y, color) {
947
- let ctx = this.getCanvasContext();
948
- if (!ctx) {
949
- return;
950
- }
951
- let { unitSize, lineWidth } = this;
884
+ drawRest(restSize, x, y) {
885
+ let { unitSize } = this;
952
886
  let { flagCount } = NoteLengthProps.get(validateNoteLength(restSize + "n"));
953
- ctx.strokeStyle = ctx.fillStyle = color;
954
- ctx.lineWidth = lineWidth;
955
887
  if (NoteLengthProps.equals(restSize, "1n" /* Whole */)) {
956
- ctx.fillRect(x - unitSize, y, unitSize * 2, unitSize);
888
+ this.fillRect(x - unitSize, y, unitSize * 2, unitSize);
957
889
  } else if (NoteLengthProps.equals(restSize, "2n" /* Half */)) {
958
- ctx.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
890
+ this.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
959
891
  } else if (NoteLengthProps.equals(restSize, "4n" /* Quarter */)) {
960
- ctx.beginPath();
961
- ctx.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
962
- ctx.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
963
- ctx.quadraticCurveTo(
892
+ this.beginPath();
893
+ this.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
894
+ this.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
895
+ this.quadraticCurveTo(
964
896
  x - unitSize * 0.8,
965
897
  y - unitSize * 0.5,
966
898
  x + unitSize * 1,
967
899
  y + unitSize * 1.5
968
900
  );
969
- ctx.lineTo(x - unitSize * 1, y - unitSize * 0.75);
970
- ctx.quadraticCurveTo(
901
+ this.lineTo(x - unitSize * 1, y - unitSize * 0.75);
902
+ this.quadraticCurveTo(
971
903
  x + unitSize * 0.2,
972
904
  y - unitSize * 1.5,
973
905
  x - unitSize * 0.6,
974
906
  y - unitSize * 3.2
975
907
  );
976
- ctx.moveTo(x + unitSize * 1, y + unitSize * 1.5);
977
- ctx.quadraticCurveTo(
908
+ this.moveTo(x + unitSize * 1, y + unitSize * 1.5);
909
+ this.quadraticCurveTo(
978
910
  x - unitSize * 0.8,
979
911
  y + unitSize * 1,
980
912
  x - unitSize * 0.2,
981
913
  y + unitSize * 2.8
982
914
  );
983
- ctx.bezierCurveTo(
915
+ this.bezierCurveTo(
984
916
  x - unitSize * 1.8,
985
917
  y + unitSize * 1.5,
986
918
  x - unitSize * 0.6,
@@ -988,46 +920,42 @@ var Renderer = class {
988
920
  x + unitSize * 0.9,
989
921
  y + unitSize * 1.5
990
922
  );
991
- ctx.fill();
992
- ctx.stroke();
923
+ this.fill();
924
+ this.stroke();
993
925
  } else if (flagCount > 0) {
994
926
  let adj = 1 - flagCount % 2;
995
927
  let fx = (p) => x + (-p * 0.25 + 0.5) * unitSize;
996
928
  let fy = (p) => y + (p + adj) * unitSize;
997
- ctx.beginPath();
998
- ctx.moveTo(fx(1 + flagCount), fy(1 + flagCount));
999
- ctx.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
1000
- ctx.stroke();
929
+ this.beginPath();
930
+ this.moveTo(fx(1 + flagCount), fy(1 + flagCount));
931
+ this.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
932
+ this.stroke();
1001
933
  for (let i = 0; i < flagCount; i++) {
1002
934
  let t = flagCount - i * 2;
1003
- ctx.beginPath();
1004
- ctx.moveTo(fx(t - 2.5), fy(t - 2.5));
1005
- ctx.quadraticCurveTo(
935
+ this.beginPath();
936
+ this.moveTo(fx(t - 2.5), fy(t - 2.5));
937
+ this.quadraticCurveTo(
1006
938
  fx(t - 0.5) + unitSize * 0.25,
1007
939
  fy(t - 1.5),
1008
940
  fx(t - 1.5) - unitSize * 1.5,
1009
941
  fy(t - 1.5)
1010
942
  );
1011
- ctx.stroke();
1012
- ctx.beginPath();
1013
- ctx.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
1014
- ctx.fill();
943
+ this.stroke();
944
+ this.beginPath();
945
+ this.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
946
+ this.fill();
1015
947
  }
1016
948
  }
1017
949
  }
1018
950
  drawFlag(rect, dir) {
1019
- let ctx = this.getCanvasContext();
1020
- if (!ctx) {
1021
- return;
1022
- }
1023
951
  let left = rect.left;
1024
952
  let right = rect.right;
1025
953
  let width = right - left;
1026
954
  let top = dir === "up" ? rect.top : rect.bottom;
1027
955
  let bottom = dir === "up" ? rect.bottom : rect.top;
1028
- ctx.beginPath();
1029
- ctx.moveTo(left, top);
1030
- ctx.bezierCurveTo(
956
+ this.beginPath();
957
+ this.moveTo(left, top);
958
+ this.bezierCurveTo(
1031
959
  left,
1032
960
  top * 0.75 + bottom * 0.25,
1033
961
  left + width * 1.5,
@@ -1035,7 +963,169 @@ var Renderer = class {
1035
963
  left + width * 0.5,
1036
964
  bottom
1037
965
  );
1038
- ctx.stroke();
966
+ this.stroke();
967
+ }
968
+ color(color) {
969
+ if (this.ctx) this.ctx.strokeStyle = this.ctx.fillStyle = color;
970
+ return this;
971
+ }
972
+ lineColor(color) {
973
+ if (this.ctx) this.ctx.strokeStyle = color;
974
+ return this;
975
+ }
976
+ fillColor(color) {
977
+ if (this.ctx) this.ctx.fillStyle = color;
978
+ return this;
979
+ }
980
+ lineWidth(lineWidth) {
981
+ if (this.ctx) this.ctx.lineWidth = this._lineWidth * (lineWidth != null ? lineWidth : 1);
982
+ return this;
983
+ }
984
+ font(font) {
985
+ if (this.ctx) this.ctx.font = font;
986
+ return this;
987
+ }
988
+ beginPath() {
989
+ if (this.ctx) this.ctx.beginPath();
990
+ return this;
991
+ }
992
+ stroke() {
993
+ if (this.ctx) this.ctx.stroke();
994
+ return this;
995
+ }
996
+ fill() {
997
+ if (this.ctx) this.ctx.fill();
998
+ return this;
999
+ }
1000
+ moveTo(x, y) {
1001
+ if (this.ctx) this.ctx.moveTo(x, y);
1002
+ return this;
1003
+ }
1004
+ lineTo(x, y) {
1005
+ if (this.ctx) this.ctx.lineTo(x, y);
1006
+ return this;
1007
+ }
1008
+ bezierCurveTo(x1, y1, x2, y2, x3, y3) {
1009
+ if (this.ctx) this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
1010
+ return this;
1011
+ }
1012
+ quadraticCurveTo(x1, y1, x2, y2) {
1013
+ if (this.ctx) this.ctx.quadraticCurveTo(x1, y1, x2, y2);
1014
+ return this;
1015
+ }
1016
+ fillRect(x, y, w, h) {
1017
+ if (this.ctx) this.ctx.fillRect(x, y, w, h);
1018
+ return this;
1019
+ }
1020
+ setLineDash(pattern) {
1021
+ if (this.ctx) this.ctx.setLineDash(pattern);
1022
+ return this;
1023
+ }
1024
+ drawImage(img, x, y, w, h) {
1025
+ if (this.ctx) this.ctx.drawImage(img, x, y, w, h);
1026
+ return this;
1027
+ }
1028
+ ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle) {
1029
+ if (this.ctx) this.ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle);
1030
+ return this;
1031
+ }
1032
+ clip() {
1033
+ if (this.ctx) this.ctx.clip();
1034
+ return this;
1035
+ }
1036
+ save() {
1037
+ if (this.ctx) this.ctx.save();
1038
+ return this;
1039
+ }
1040
+ restore() {
1041
+ if (this.ctx) this.ctx.restore();
1042
+ return this;
1043
+ }
1044
+ rect(x, y, w, h) {
1045
+ if (this.ctx) this.ctx.rect(x, y, w, h);
1046
+ return this;
1047
+ }
1048
+ scale(x, y) {
1049
+ if (this.ctx) this.ctx.scale(x, y);
1050
+ return this;
1051
+ }
1052
+ strokeRect(x, y, w, h) {
1053
+ if (this.ctx) this.ctx.strokeRect(x, y, w, h);
1054
+ return this;
1055
+ }
1056
+ fillText(text, x, y) {
1057
+ if (this.ctx) this.ctx.fillText(text, x, y);
1058
+ return this;
1059
+ }
1060
+ getTextWidth(text, font) {
1061
+ if (this.ctx) {
1062
+ let savedFont = this.ctx.font;
1063
+ this.ctx.font = font;
1064
+ let metrics = this.ctx.measureText(text);
1065
+ this.ctx.font = savedFont;
1066
+ return metrics.width;
1067
+ } else {
1068
+ return Utils2.Dom.getCanvasTextWidth(text, font);
1069
+ }
1070
+ }
1071
+ arc(x, y, radius, startRadians, endRadians) {
1072
+ var _a;
1073
+ (_a = this.ctx) == null ? void 0 : _a.arc(x, y, radius, startRadians, endRadians);
1074
+ }
1075
+ fillCircle(x, y, radius) {
1076
+ if (this.ctx) {
1077
+ this.ctx.beginPath();
1078
+ this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
1079
+ this.ctx.fill();
1080
+ }
1081
+ }
1082
+ strokeLine(startX, startY, endX, endY) {
1083
+ if (this.ctx) {
1084
+ this.ctx.beginPath();
1085
+ this.ctx.moveTo(startX, startY);
1086
+ this.ctx.lineTo(endX, endY);
1087
+ this.ctx.stroke();
1088
+ }
1089
+ }
1090
+ strokePartialLine(startX, startY, endX, endY, startT, endT) {
1091
+ let x1 = startX + (endX - startX) * startT;
1092
+ let y1 = startY + (endY - startY) * startT;
1093
+ let x2 = startX + (endX - startX) * endT;
1094
+ let y2 = startY + (endY - startY) * endT;
1095
+ if (this.ctx) {
1096
+ this.ctx.beginPath();
1097
+ this.ctx.moveTo(x1, y1);
1098
+ this.ctx.lineTo(x2, y2);
1099
+ this.ctx.stroke();
1100
+ }
1101
+ }
1102
+ drawBrace(rect, side) {
1103
+ if (this.ctx) {
1104
+ let { left, right, width, top, bottom, centerY } = rect;
1105
+ if (side === "right") {
1106
+ [left, right, width] = [right, left, -width];
1107
+ }
1108
+ this.ctx.beginPath();
1109
+ this.ctx.moveTo(right, top);
1110
+ this.ctx.bezierCurveTo(
1111
+ left + width * 0.1,
1112
+ top,
1113
+ left + width * 0.8,
1114
+ centerY,
1115
+ left,
1116
+ centerY
1117
+ );
1118
+ this.ctx.moveTo(right, bottom);
1119
+ this.ctx.bezierCurveTo(
1120
+ left + width * 0.1,
1121
+ bottom,
1122
+ left + width * 0.8,
1123
+ centerY,
1124
+ left,
1125
+ centerY
1126
+ );
1127
+ this.ctx.stroke();
1128
+ }
1039
1129
  }
1040
1130
  };
1041
1131
 
@@ -1044,8 +1134,8 @@ import { MusicError as MusicError15, MusicErrorType as MusicErrorType15 } from "
1044
1134
  import { Utils as Utils13 } from "@tspro/ts-utils-lib";
1045
1135
 
1046
1136
  // src/score/engine/obj-measure.ts
1047
- import { Utils as Utils12 } from "@tspro/ts-utils-lib";
1048
- import { getScale, Scale, validateScaleType, Note as Note7, RhythmProps as RhythmProps5, KeySignature as KeySignature2, getDefaultKeySignature, PitchNotation, SymbolSet, validateNoteLength as validateNoteLength3, NoteLengthProps as NoteLengthProps5 } from "@tspro/web-music-score/theory";
1137
+ import { Map3 as Map32, Utils as Utils12 } from "@tspro/ts-utils-lib";
1138
+ 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";
1049
1139
  import { getDefaultTempo, getDefaultTimeSignature } from "@tspro/web-music-score/theory";
1050
1140
 
1051
1141
  // src/score/engine/acc-state.ts
@@ -1090,9 +1180,9 @@ var ObjImage = class extends MusicObject {
1090
1180
  pick(x, y) {
1091
1181
  return this.rect.contains(x, y) ? [this] : [];
1092
1182
  }
1093
- layout(renderer) {
1183
+ layout(ctx) {
1094
1184
  let { anchorX, anchorY, image, imageScale } = this;
1095
- let { unitSize } = renderer;
1185
+ let { unitSize } = ctx;
1096
1186
  try {
1097
1187
  let w = image.naturalWidth * imageScale * unitSize;
1098
1188
  let h = image.naturalHeight * imageScale * unitSize;
@@ -1104,17 +1194,10 @@ var ObjImage = class extends MusicObject {
1104
1194
  offset(dx, dy) {
1105
1195
  this.rect.offsetInPlace(dx, dy);
1106
1196
  }
1107
- draw(renderer) {
1108
- let ctx = renderer.getCanvasContext();
1109
- if (!ctx) {
1110
- return;
1111
- }
1197
+ draw(ctx) {
1112
1198
  let r = this.rect;
1113
- renderer.drawDebugRect(r);
1114
- try {
1115
- ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1116
- } catch (err) {
1117
- }
1199
+ ctx.drawDebugRect(r);
1200
+ ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1118
1201
  }
1119
1202
  };
1120
1203
 
@@ -1135,8 +1218,8 @@ var ObjAccidental = class extends MusicObject {
1135
1218
  pick(x, y) {
1136
1219
  return this.rect.contains(x, y) ? [this] : [];
1137
1220
  }
1138
- layout(renderer) {
1139
- let { unitSize } = renderer;
1221
+ layout(ctx) {
1222
+ let { unitSize } = ctx;
1140
1223
  switch (this.accidental) {
1141
1224
  case -2:
1142
1225
  this.rect = DivRect.createSections(unitSize * 1.25, unitSize * 1.25, unitSize * 4, unitSize * 1.2);
@@ -1160,34 +1243,23 @@ var ObjAccidental = class extends MusicObject {
1160
1243
  offset(dx, dy) {
1161
1244
  this.rect.offsetInPlace(dx, dy);
1162
1245
  }
1163
- draw(renderer) {
1164
- let ctx = renderer.getCanvasContext();
1165
- if (!ctx) {
1166
- return;
1167
- }
1168
- renderer.drawDebugRect(this.rect);
1169
- let { unitSize, lineWidth } = renderer;
1246
+ draw(ctx) {
1247
+ ctx.drawDebugRect(this.rect);
1248
+ let { unitSize } = ctx;
1170
1249
  let { accidental } = this;
1171
1250
  let x = this.rect.centerX;
1172
1251
  let y = this.rect.centerY;
1173
- ctx.strokeStyle = ctx.fillStyle = this.color;
1174
- function draw_b(x2, y2) {
1175
- if (ctx) {
1176
- ctx.lineWidth = lineWidth;
1177
- ctx.beginPath();
1178
- ctx.moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4);
1179
- ctx.lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1);
1180
- ctx.bezierCurveTo(
1181
- x2 + unitSize * 0.75,
1182
- y2 - unitSize * 0,
1183
- x2 + unitSize * 0.75,
1184
- y2 - unitSize * 2.2,
1185
- x2 - unitSize * 0.75,
1186
- y2 - unitSize * 0.5
1187
- );
1188
- ctx.stroke();
1189
- }
1190
- }
1252
+ ctx.color(this.color);
1253
+ const draw_b = (x2, y2) => {
1254
+ ctx.lineWidth(1).beginPath().moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4).lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1).bezierCurveTo(
1255
+ x2 + unitSize * 0.75,
1256
+ y2 - unitSize * 0,
1257
+ x2 + unitSize * 0.75,
1258
+ y2 - unitSize * 2.2,
1259
+ x2 - unitSize * 0.75,
1260
+ y2 - unitSize * 0.5
1261
+ ).stroke();
1262
+ };
1191
1263
  if (accidental === -2) {
1192
1264
  draw_b(x - unitSize * 0.5, y);
1193
1265
  draw_b(x + unitSize * 0.5, y);
@@ -1195,47 +1267,11 @@ var ObjAccidental = class extends MusicObject {
1195
1267
  draw_b(x, y);
1196
1268
  }
1197
1269
  if (accidental === 0) {
1198
- ctx.beginPath();
1199
- ctx.lineWidth = lineWidth;
1200
- ctx.moveTo(x - unitSize * 0.5, y - unitSize * 2.2);
1201
- ctx.lineTo(x - unitSize * 0.5, y + unitSize * 1);
1202
- ctx.moveTo(x + unitSize * 0.5, y + unitSize * 2.2);
1203
- ctx.lineTo(x + unitSize * 0.5, y - unitSize * 1);
1204
- ctx.stroke();
1205
- ctx.beginPath();
1206
- ctx.lineWidth = lineWidth * 2;
1207
- ctx.moveTo(x - unitSize * 0.5, y + unitSize * 1);
1208
- ctx.lineTo(x + unitSize * 0.5, y + unitSize * 0.6);
1209
- ctx.moveTo(x + unitSize * 0.5, y - unitSize * 1);
1210
- ctx.lineTo(x - unitSize * 0.5, y - unitSize * 0.6);
1211
- ctx.stroke();
1270
+ ctx.beginPath().lineWidth(1).moveTo(x - unitSize * 0.5, y - unitSize * 2.2).lineTo(x - unitSize * 0.5, y + unitSize * 1).moveTo(x + unitSize * 0.5, y + unitSize * 2.2).lineTo(x + unitSize * 0.5, y - unitSize * 1).stroke().beginPath().lineWidth(2).moveTo(x - unitSize * 0.5, y + unitSize * 1).lineTo(x + unitSize * 0.5, y + unitSize * 0.6).moveTo(x + unitSize * 0.5, y - unitSize * 1).lineTo(x - unitSize * 0.5, y - unitSize * 0.6).stroke();
1212
1271
  } else if (accidental === 1) {
1213
- ctx.lineWidth = lineWidth;
1214
- ctx.beginPath();
1215
- ctx.moveTo(x - unitSize * 0.3, y - unitSize * 1.6);
1216
- ctx.lineTo(x - unitSize * 0.3, y + unitSize * 2);
1217
- ctx.moveTo(x + unitSize * 0.3, y - unitSize * 2);
1218
- ctx.lineTo(x + unitSize * 0.3, y + unitSize * 1.6);
1219
- ctx.stroke();
1220
- ctx.lineWidth = lineWidth * 2;
1221
- ctx.beginPath();
1222
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.5);
1223
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.9);
1224
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.9);
1225
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.5);
1226
- ctx.stroke();
1272
+ ctx.lineWidth(1).beginPath().moveTo(x - unitSize * 0.3, y - unitSize * 1.6).lineTo(x - unitSize * 0.3, y + unitSize * 2).moveTo(x + unitSize * 0.3, y - unitSize * 2).lineTo(x + unitSize * 0.3, y + unitSize * 1.6).stroke().lineWidth(2).beginPath().moveTo(x - unitSize * 0.75, y - unitSize * 0.5).lineTo(x + unitSize * 0.75, y - unitSize * 0.9).moveTo(x - unitSize * 0.75, y + unitSize * 0.9).lineTo(x + unitSize * 0.75, y + unitSize * 0.5).stroke();
1227
1273
  } else if (accidental === 2) {
1228
- ctx.lineWidth = lineWidth;
1229
- ctx.beginPath();
1230
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.75);
1231
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.75);
1232
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.75);
1233
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.75);
1234
- ctx.stroke();
1235
- ctx.fillRect(x - unitSize * 1, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1236
- ctx.fillRect(x + unitSize * 0.3, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1237
- ctx.fillRect(x - unitSize * 1, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1238
- ctx.fillRect(x + unitSize * 0.3, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1274
+ ctx.lineWidth(1).beginPath().moveTo(x - unitSize * 0.75, y - unitSize * 0.75).lineTo(x + unitSize * 0.75, y + unitSize * 0.75).moveTo(x - unitSize * 0.75, y + unitSize * 0.75).lineTo(x + unitSize * 0.75, y - unitSize * 0.75).stroke().fillRect(x - unitSize * 1, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7).fillRect(x + unitSize * 0.3, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7).fillRect(x - unitSize * 1, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7).fillRect(x + unitSize * 0.3, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1239
1275
  }
1240
1276
  }
1241
1277
  };
@@ -1301,13 +1337,13 @@ var ObjText = class extends MusicObject {
1301
1337
  pick(x, y) {
1302
1338
  return this.rect.contains(x, y) ? [this] : [];
1303
1339
  }
1304
- layout(renderer) {
1340
+ layout(ctx) {
1305
1341
  let { scale, anchorX, anchorY, bold, italic } = this;
1306
- let fontSize = renderer.fontSize * scale;
1342
+ let fontSize = ctx.fontSize * scale;
1307
1343
  this.font = (italic ? "italic " : "") + (bold ? "bold " : "") + fontSize + "px Times New Roman";
1308
- this.lineWidths = this.textLines.map((text) => renderer.getTextWidth(text, this.font));
1344
+ this.lineWidths = this.textLines.map((text) => ctx.getTextWidth(text, this.font));
1309
1345
  this.lineHeight = fontSize;
1310
- let p = this.padding * renderer.unitSize;
1346
+ let p = this.padding * ctx.unitSize;
1311
1347
  let w = p + Math.max(...this.lineWidths) + p;
1312
1348
  let h = p + this.lineHeight * this.textLines.length + p;
1313
1349
  if (this.boxed === "square" || this.boxed === "circle") {
@@ -1318,19 +1354,14 @@ var ObjText = class extends MusicObject {
1318
1354
  offset(dx, dy) {
1319
1355
  this.rect.offsetInPlace(dx, dy);
1320
1356
  }
1321
- draw(renderer) {
1322
- const ctx = renderer.getCanvasContext();
1323
- if (!ctx) {
1324
- return;
1325
- }
1326
- renderer.drawDebugRect(this.rect);
1327
- ctx.lineWidth = renderer.lineWidth;
1328
- ctx.strokeStyle = ctx.fillStyle = this.color;
1329
- ctx.font = this.font;
1357
+ draw(ctx) {
1358
+ var _a;
1359
+ ctx.drawDebugRect(this.rect);
1360
+ ctx.lineWidth(1).font(this.font);
1330
1361
  let { rect, padding, lineHeight, lineWidths, anchorX, anchorY, italic } = this;
1331
1362
  if (this.bgcolor !== void 0) {
1332
1363
  ctx.save();
1333
- ctx.fillStyle = this.bgcolor;
1364
+ ctx.fillColor((_a = this.bgcolor) != null ? _a : "black");
1334
1365
  ctx.beginPath();
1335
1366
  ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
1336
1367
  ctx.fill();
@@ -1338,10 +1369,11 @@ var ObjText = class extends MusicObject {
1338
1369
  }
1339
1370
  let lineCount = this.textLines.length;
1340
1371
  let textHeight = lineCount * lineHeight;
1341
- let fixY = -lineHeight * (italic ? 0.25 : 0.175);
1342
- let p = padding * renderer.unitSize;
1372
+ let fixY = -lineHeight * (italic ? 0.25 : 0.2);
1373
+ let p = padding * ctx.unitSize;
1343
1374
  let centerX = (rect.left + p) * (1 - anchorX) + (rect.right - p) * anchorX;
1344
1375
  let centerY = (rect.top + p) * (1 - anchorY) + (rect.bottom - p) * anchorY;
1376
+ ctx.color(this.color);
1345
1377
  this.textLines.forEach((textLine, i) => {
1346
1378
  let x = centerX - lineWidths[i] * anchorX;
1347
1379
  let y = centerY - textHeight * anchorY + lineHeight * (i + 1) + fixY;
@@ -1387,9 +1419,9 @@ var ObjStaffSignature = class extends MusicObject {
1387
1419
  getMusicInterface() {
1388
1420
  return this.mi;
1389
1421
  }
1390
- updateClefImage(renderer, showClef) {
1422
+ updateClefImage(ctx, showClef) {
1391
1423
  if (showClef) {
1392
- let img = renderer.getImageAsset(this.staff.clefImageAsset);
1424
+ let img = ctx.getImageAsset(this.staff.clefImageAsset);
1393
1425
  this.clefImage = img ? new ObjImage(this, img, 0, 0.5, 0.1) : void 0;
1394
1426
  this.eightBelowClef = this.clefImage && this.staff.isOctaveDown ? new ObjText(this, "8", 0.5, 0) : void 0;
1395
1427
  } else {
@@ -1520,29 +1552,29 @@ var ObjStaffSignature = class extends MusicObject {
1520
1552
  }
1521
1553
  return [this];
1522
1554
  }
1523
- layout(renderer) {
1555
+ layout(ctx) {
1524
1556
  var _a, _b, _c, _d, _e, _f;
1525
- let { unitSize } = renderer;
1557
+ let { unitSize } = ctx;
1526
1558
  let { staff } = this;
1527
1559
  let paddingX = unitSize;
1528
1560
  let x = 0;
1529
1561
  this.rect = new DivRect();
1530
1562
  if (this.clefImage) {
1531
1563
  x += paddingX;
1532
- this.clefImage.layout(renderer);
1564
+ this.clefImage.layout(ctx);
1533
1565
  this.clefImage.offset(x, staff.getDiatonicIdY(staff.clefLineDiatonicId));
1534
1566
  this.rect.expandInPlace(this.clefImage.getRect());
1535
1567
  x = this.rect.right;
1536
1568
  if (this.eightBelowClef) {
1537
1569
  let r = this.clefImage.getRect();
1538
- this.eightBelowClef.layout(renderer);
1570
+ this.eightBelowClef.layout(ctx);
1539
1571
  this.eightBelowClef.offset(r.left + r.width / 2, Math.max(r.centerY + r.height * 0.3, staff.getBottomLineY()));
1540
1572
  this.rect.expandInPlace(this.eightBelowClef.getRect());
1541
1573
  }
1542
1574
  }
1543
1575
  if (this.measureNumber) {
1544
- this.measureNumber.layout(renderer);
1545
- let y = this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY();
1576
+ this.measureNumber.layout(ctx);
1577
+ let y = Math.min(staff.getTopLineY(), this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY());
1546
1578
  this.measureNumber.offset(0, y);
1547
1579
  this.rect.expandInPlace(this.measureNumber.getRect());
1548
1580
  x = Math.max(x, this.rect.right);
@@ -1550,7 +1582,7 @@ var ObjStaffSignature = class extends MusicObject {
1550
1582
  if (this.ksNeutralizeAccidentals.length > 0) {
1551
1583
  x += paddingX;
1552
1584
  this.ksNeutralizeAccidentals.forEach((objAcc) => {
1553
- objAcc.layout(renderer);
1585
+ objAcc.layout(ctx);
1554
1586
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1555
1587
  this.rect.expandInPlace(objAcc.getRect());
1556
1588
  x = this.rect.right;
@@ -1559,15 +1591,15 @@ var ObjStaffSignature = class extends MusicObject {
1559
1591
  if (this.ksNewAccidentals) {
1560
1592
  x += paddingX;
1561
1593
  this.ksNewAccidentals.forEach((objAcc) => {
1562
- objAcc.layout(renderer);
1594
+ objAcc.layout(ctx);
1563
1595
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1564
1596
  this.rect.expandInPlace(objAcc.getRect());
1565
1597
  x = this.rect.right;
1566
1598
  });
1567
1599
  }
1568
1600
  let right = x;
1569
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
1570
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
1601
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
1602
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1571
1603
  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);
1572
1604
  if (this.beatCountText) {
1573
1605
  this.beatCountText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.middleLineDiatonicId + 2));
@@ -1586,7 +1618,7 @@ var ObjStaffSignature = class extends MusicObject {
1586
1618
  ...this.ksNeutralizeAccidentals.map((o) => o.getRect().top),
1587
1619
  ...this.ksNewAccidentals.map((o) => o.getRect().top)
1588
1620
  );
1589
- this.tempoText.layout(renderer);
1621
+ this.tempoText.layout(ctx);
1590
1622
  this.tempoText.offset(x, tempoBottom);
1591
1623
  this.rect.expandInPlace(this.tempoText.getRect());
1592
1624
  }
@@ -1604,16 +1636,16 @@ var ObjStaffSignature = class extends MusicObject {
1604
1636
  (_f = this.tempoText) == null ? void 0 : _f.offset(dx, dy);
1605
1637
  this.rect.offsetInPlace(dx, dy);
1606
1638
  }
1607
- draw(renderer) {
1639
+ draw(ctx) {
1608
1640
  var _a, _b, _c, _d, _e, _f;
1609
- (_a = this.clefImage) == null ? void 0 : _a.draw(renderer);
1610
- (_b = this.eightBelowClef) == null ? void 0 : _b.draw(renderer);
1611
- (_c = this.measureNumber) == null ? void 0 : _c.draw(renderer);
1612
- this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(renderer));
1613
- this.ksNewAccidentals.forEach((acc) => acc.draw(renderer));
1614
- (_d = this.beatCountText) == null ? void 0 : _d.draw(renderer);
1615
- (_e = this.beatSizeText) == null ? void 0 : _e.draw(renderer);
1616
- (_f = this.tempoText) == null ? void 0 : _f.draw(renderer);
1641
+ (_a = this.clefImage) == null ? void 0 : _a.draw(ctx);
1642
+ (_b = this.eightBelowClef) == null ? void 0 : _b.draw(ctx);
1643
+ (_c = this.measureNumber) == null ? void 0 : _c.draw(ctx);
1644
+ this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(ctx));
1645
+ this.ksNewAccidentals.forEach((acc) => acc.draw(ctx));
1646
+ (_d = this.beatCountText) == null ? void 0 : _d.draw(ctx);
1647
+ (_e = this.beatSizeText) == null ? void 0 : _e.draw(ctx);
1648
+ (_f = this.tempoText) == null ? void 0 : _f.draw(ctx);
1617
1649
  }
1618
1650
  };
1619
1651
  var ObjTabSignature = class extends MusicObject {
@@ -1688,22 +1720,22 @@ var ObjTabSignature = class extends MusicObject {
1688
1720
  }
1689
1721
  return [this];
1690
1722
  }
1691
- layout(renderer) {
1723
+ layout(ctx) {
1692
1724
  var _a, _b, _c, _d, _e, _f;
1693
- let { unitSize } = renderer;
1725
+ let { unitSize } = ctx;
1694
1726
  let { tab } = this;
1695
1727
  let paddingX = unitSize;
1696
1728
  let x = 0;
1697
1729
  let topLineY = tab.getTopLineY();
1698
1730
  this.rect = new DivRect();
1699
1731
  if (this.measureNumber) {
1700
- this.measureNumber.layout(renderer);
1732
+ this.measureNumber.layout(ctx);
1701
1733
  this.measureNumber.offset(0, topLineY);
1702
1734
  this.rect.expandInPlace(this.measureNumber.getRect());
1703
1735
  x = Math.max(x, this.rect.right);
1704
1736
  }
1705
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
1706
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
1737
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
1738
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1707
1739
  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);
1708
1740
  if (this.beatCountText) {
1709
1741
  this.beatCountText.offset(0 + tsWidth / 2 + paddingX, tab.getRect().centerY - this.beatCountText.getRect().bottomh);
@@ -1714,7 +1746,7 @@ var ObjTabSignature = class extends MusicObject {
1714
1746
  this.rect.expandInPlace(this.beatSizeText.getRect());
1715
1747
  }
1716
1748
  if (this.tempoText) {
1717
- this.tempoText.layout(renderer);
1749
+ this.tempoText.layout(ctx);
1718
1750
  this.tempoText.offset(x + unitSize * 2, topLineY);
1719
1751
  this.rect.expandInPlace(this.tempoText.getRect());
1720
1752
  }
@@ -1728,22 +1760,22 @@ var ObjTabSignature = class extends MusicObject {
1728
1760
  (_d = this.tempoText) == null ? void 0 : _d.offset(dx, dy);
1729
1761
  this.rect.offsetInPlace(dx, dy);
1730
1762
  }
1731
- draw(renderer) {
1763
+ draw(ctx) {
1732
1764
  var _a, _b, _c, _d;
1733
- (_a = this.measureNumber) == null ? void 0 : _a.draw(renderer);
1734
- (_b = this.beatCountText) == null ? void 0 : _b.draw(renderer);
1735
- (_c = this.beatSizeText) == null ? void 0 : _c.draw(renderer);
1736
- (_d = this.tempoText) == null ? void 0 : _d.draw(renderer);
1765
+ (_a = this.measureNumber) == null ? void 0 : _a.draw(ctx);
1766
+ (_b = this.beatCountText) == null ? void 0 : _b.draw(ctx);
1767
+ (_c = this.beatSizeText) == null ? void 0 : _c.draw(ctx);
1768
+ (_d = this.tempoText) == null ? void 0 : _d.draw(ctx);
1737
1769
  }
1738
1770
  };
1739
1771
 
1740
1772
  // src/score/engine/player.ts
1741
- import { Utils as Utils6 } from "@tspro/ts-utils-lib";
1742
- import { NoteLength as NoteLength6, RhythmProps as RhythmProps4, alterTempoSpeed } from "@tspro/web-music-score/theory";
1773
+ import { Utils as Utils5 } from "@tspro/ts-utils-lib";
1774
+ import { NoteLength as NoteLength4, RhythmProps as RhythmProps4, alterTempoSpeed } from "@tspro/web-music-score/theory";
1743
1775
  import * as Audio from "@tspro/web-music-score/audio";
1744
1776
 
1745
1777
  // src/score/engine/obj-rhythm-column.ts
1746
- import { Note as Note5, validateNoteLength as validateNoteLength2 } from "@tspro/web-music-score/theory";
1778
+ import { Note as Note5 } from "@tspro/web-music-score/theory";
1747
1779
 
1748
1780
  // src/score/engine/obj-arpeggio.ts
1749
1781
  var ObjArpeggio = class extends MusicObject {
@@ -1766,8 +1798,8 @@ var ObjArpeggio = class extends MusicObject {
1766
1798
  pick(x, y) {
1767
1799
  return this.rect.contains(x, y) ? [this] : [];
1768
1800
  }
1769
- layout(renderer) {
1770
- let { unitSize } = renderer;
1801
+ layout(ctx) {
1802
+ let { unitSize } = ctx;
1771
1803
  this.topArrowHeight = this.arpeggioDir === "up" /* Up */ ? unitSize : 0;
1772
1804
  this.bottomArrowHeight = this.arpeggioDir === "down" /* Down */ ? unitSize : 0;
1773
1805
  let top = this.line.getTopLineY();
@@ -1781,16 +1813,11 @@ var ObjArpeggio = class extends MusicObject {
1781
1813
  offset(dx, dy) {
1782
1814
  this.rect.offsetInPlace(dx, dy);
1783
1815
  }
1784
- draw(renderer) {
1785
- let ctx = renderer.getCanvasContext();
1786
- if (!ctx) {
1787
- return;
1788
- }
1789
- let { lineWidth } = renderer;
1816
+ draw(ctx) {
1790
1817
  let { rect, topArrowHeight, bottomArrowHeight } = this;
1791
- renderer.drawDebugRect(this.rect);
1792
- ctx.strokeStyle = ctx.fillStyle = this.color;
1793
- ctx.lineWidth = lineWidth * 2;
1818
+ ctx.drawDebugRect(this.rect);
1819
+ ctx.color(this.color);
1820
+ ctx.lineWidth(2);
1794
1821
  ctx.beginPath();
1795
1822
  for (let i = 0, y = rect.top + topArrowHeight; i < this.numCycles; i++, y += this.cycleHeight) {
1796
1823
  ctx.moveTo(rect.centerX, y);
@@ -1857,40 +1884,33 @@ var ObjStaffRest = class extends MusicObject {
1857
1884
  this.dotRects.forEach((r) => this.rect.expandInPlace(r));
1858
1885
  }
1859
1886
  };
1860
- var ObjRest = class extends MusicObject {
1887
+ var _ObjRest = class _ObjRest extends MusicObject {
1861
1888
  constructor(col, voiceId, noteLength, options, tupletRatio) {
1862
- var _a, _b;
1889
+ var _a, _b, _c, _d;
1863
1890
  super(col);
1864
1891
  this.col = col;
1865
1892
  this.voiceId = voiceId;
1866
- __publicField(this, "ownStemDir");
1867
- __publicField(this, "ownDiatonicId");
1893
+ this.options = options;
1868
1894
  __publicField(this, "color");
1869
1895
  __publicField(this, "hide");
1870
1896
  __publicField(this, "oldStyleTriplet");
1871
1897
  __publicField(this, "rhythmProps");
1898
+ __publicField(this, "setDiatonicId");
1899
+ __publicField(this, "runningDiatonicId");
1900
+ // Staff position of rest.
1901
+ __publicField(this, "runningStemDir");
1872
1902
  __publicField(this, "beamGroup");
1873
1903
  __publicField(this, "staffObjects", []);
1874
1904
  __publicField(this, "mi");
1875
- let diatonicId = getDiatonicIdFromStaffPos(options == null ? void 0 : options.staffPos);
1876
- if (diatonicId !== void 0) {
1877
- let hasStaff = this.row.hasStaff;
1878
- let staff2 = this.row.getStaff(diatonicId);
1879
- if (hasStaff && !staff2) {
1880
- throw new MusicError5(MusicErrorType5.Score, "Rest staffPos is out of staff boundaries!");
1881
- }
1882
- }
1883
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, diatonicId);
1884
- this.ownStemDir = this.measure.updateOwnStemDir(
1885
- this
1886
- /*, options?.stem*/
1887
- );
1888
- let staff = this.row.getStaff(this.ownDiatonicId);
1889
- if (staff && staff.isSpace(this.ownDiatonicId)) {
1890
- this.ownDiatonicId += this.ownDiatonicId >= staff.middleLineDiatonicId ? 1 : -1;
1891
- }
1892
- this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
1893
- this.hide = (_b = options == null ? void 0 : options.hide) != null ? _b : false;
1905
+ this.setDiatonicId = (_b = getDiatonicIdFromStaffPos((_a = this.options) == null ? void 0 : _a.staffPos)) != null ? _b : _ObjRest.UndefinedDiatonicId;
1906
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(this.voiceId));
1907
+ if (this.setDiatonicId !== _ObjRest.UndefinedDiatonicId && staves.length > 0 && staves[0].isSpace(this.setDiatonicId)) {
1908
+ this.setDiatonicId += this.setDiatonicId >= staves[0].middleLineDiatonicId ? 1 : -1;
1909
+ }
1910
+ this.runningDiatonicId = this.setDiatonicId;
1911
+ this.runningStemDir = "up" /* Up */;
1912
+ this.color = (_c = options == null ? void 0 : options.color) != null ? _c : "black";
1913
+ this.hide = (_d = options == null ? void 0 : options.hide) != null ? _d : false;
1894
1914
  this.oldStyleTriplet = tupletRatio === void 0 && ((options == null ? void 0 : options.triplet) === true || NoteLengthProps2.get(noteLength).isTriplet);
1895
1915
  let dotCount = typeof (options == null ? void 0 : options.dotted) === "number" ? options.dotted > 0 ? options.dotted : void 0 : (options == null ? void 0 : options.dotted) === true ? 1 : void 0;
1896
1916
  this.rhythmProps = RhythmProps2.get(noteLength, dotCount, (tupletRatio != null ? tupletRatio : this.oldStyleTriplet) ? Tuplet.Triplet : void 0);
@@ -1911,8 +1931,27 @@ var ObjRest = class extends MusicObject {
1911
1931
  get noteLength() {
1912
1932
  return this.rhythmProps.noteLength;
1913
1933
  }
1934
+ getDiatonicId(staff) {
1935
+ if (this.runningDiatonicId === _ObjRest.UndefinedDiatonicId) {
1936
+ if (staff) {
1937
+ if (NoteLengthProps2.equals(this.noteLength, "1n")) {
1938
+ return staff.middleLineDiatonicId + 2;
1939
+ } else {
1940
+ return staff.middleLineDiatonicId;
1941
+ }
1942
+ } else {
1943
+ return Note3.getNote("G4").diatonicId;
1944
+ }
1945
+ } else {
1946
+ return this.runningDiatonicId;
1947
+ }
1948
+ }
1914
1949
  get stemDir() {
1915
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
1950
+ return this.runningStemDir;
1951
+ }
1952
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
1953
+ this.runningDiatonicId = diatonicId;
1954
+ this.runningStemDir = stemDir;
1916
1955
  }
1917
1956
  getStaticObjects(line) {
1918
1957
  let staticObjects = [];
@@ -1984,28 +2023,28 @@ var ObjRest = class extends MusicObject {
1984
2023
  }
1985
2024
  updateAccidentalState(accState) {
1986
2025
  }
1987
- layout(renderer, accState) {
2026
+ layout(ctx, accState) {
1988
2027
  this.requestRectUpdate();
1989
2028
  this.staffObjects.length = 0;
1990
2029
  if (this.hide) {
1991
2030
  return;
1992
2031
  }
1993
- let { unitSize } = renderer;
1994
- let { ownDiatonicId } = this;
2032
+ let { unitSize } = ctx;
1995
2033
  let { noteSize, dotCount } = this.rhythmProps;
1996
2034
  this.row.getStaves().forEach((staff) => {
1997
- if (!staff.containsDiatonicId(ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2035
+ let diatonicId = this.getDiatonicId(staff);
2036
+ if (!staff.containsDiatonicId(diatonicId) || !staff.containsVoiceId(this.voiceId)) {
1998
2037
  return;
1999
2038
  }
2000
2039
  let obj = new ObjStaffRest(staff, this);
2001
- obj.restRect = renderer.getRestRect(noteSize);
2040
+ obj.restRect = ctx.getRestRect(noteSize);
2002
2041
  for (let i = 0; i < dotCount; i++) {
2003
2042
  let dotWidth = DocumentSettings.DotSize * unitSize;
2004
2043
  let dotX = obj.restRect.rightw + (DocumentSettings.RestDotSpace + DocumentSettings.DotSize * unitSize) + i * DocumentSettings.DotSize * unitSize * 1.5;
2005
2044
  let dotY = this.getRestDotVerticalDisplacement(noteSize) * unitSize;
2006
2045
  obj.dotRects.push(DivRect.createCentered(dotX, dotY, dotWidth, dotWidth));
2007
2046
  }
2008
- obj.offset(0, staff.getDiatonicIdY(ownDiatonicId));
2047
+ obj.offset(0, staff.getDiatonicIdY(diatonicId));
2009
2048
  this.staffObjects.push(obj);
2010
2049
  });
2011
2050
  }
@@ -2025,48 +2064,41 @@ var ObjRest = class extends MusicObject {
2025
2064
  this.staffObjects.forEach((s) => s.offset(dx, 0));
2026
2065
  this.requestRectUpdate();
2027
2066
  }
2028
- draw(renderer) {
2029
- let ctx = renderer.getCanvasContext();
2030
- if (!ctx || this.staffObjects.length === 0) {
2067
+ draw(ctx) {
2068
+ if (this.staffObjects.length === 0) {
2031
2069
  return;
2032
2070
  }
2033
- renderer.drawDebugRect(this.getRect());
2034
- let { lineWidth } = renderer;
2035
- let { color } = this;
2071
+ ctx.drawDebugRect(this.getRect());
2036
2072
  let { noteSize } = this.rhythmProps;
2037
- ctx.strokeStyle = ctx.fillStyle = color;
2038
- ctx.lineWidth = lineWidth;
2073
+ ctx.color(this.color).lineWidth(1);
2039
2074
  this.staffObjects.forEach((obj) => {
2040
2075
  let { dotRects, restRect } = obj;
2041
2076
  let x = restRect.centerX;
2042
2077
  let y = restRect.centerY;
2043
- renderer.drawRest(noteSize, x, y, color);
2044
- dotRects.forEach((r) => {
2045
- renderer.fillCircle(r.centerX, r.centerY, r.width / 2);
2046
- });
2078
+ ctx.drawRest(noteSize, x, y);
2079
+ dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
2047
2080
  });
2048
2081
  }
2049
2082
  };
2083
+ __publicField(_ObjRest, "UndefinedDiatonicId", Infinity);
2084
+ var ObjRest = _ObjRest;
2050
2085
 
2051
2086
  // src/score/engine/obj-note-group.ts
2052
2087
  import { Utils as Utils3 } from "@tspro/ts-utils-lib";
2053
2088
  import { Note as Note4, NoteLengthProps as NoteLengthProps3, RhythmProps as RhythmProps3, Tuplet as Tuplet2 } from "@tspro/web-music-score/theory";
2054
2089
  import { MusicError as MusicError6, MusicErrorType as MusicErrorType6 } from "@tspro/web-music-score/core";
2055
- function getStem(stem) {
2056
- return Utils3.Is.isEnumValue(stem, Stem) ? stem : void 0;
2057
- }
2058
2090
  function getArpeggio(a) {
2059
2091
  return Utils3.Is.isEnumValue(a, Arpeggio) ? a : a === true ? "up" /* Up */ : void 0;
2060
2092
  }
2061
- function sortNoteStringData(notes, strings) {
2093
+ function sortNotesAndStrings(notes, strings) {
2062
2094
  let stringArr = Utils3.Arr.isArray(strings) ? strings : strings !== void 0 ? [strings] : [];
2063
2095
  let noteStringData = notes.map((note, i) => {
2064
2096
  return { note, string: stringArr[i] };
2065
2097
  });
2066
2098
  noteStringData = Utils3.Arr.removeDuplicatesCmp(noteStringData, (a, b) => Note4.equals(a.note, b.note)).sort((a, b) => Note4.compareFunc(a.note, b.note));
2067
2099
  return {
2068
- notes: noteStringData.map((e) => e.note),
2069
- strings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2100
+ sortedNotes: noteStringData.map((e) => e.note),
2101
+ sortedStrings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2070
2102
  };
2071
2103
  }
2072
2104
  var ObjStaffNoteGroup = class extends MusicObject {
@@ -2138,7 +2170,6 @@ var ObjTabNoteGroup = class extends MusicObject {
2138
2170
  this.noteGroup = noteGroup;
2139
2171
  __publicField(this, "fretNumbers", []);
2140
2172
  __publicField(this, "mi");
2141
- tab.addObject(this);
2142
2173
  this.mi = new MTabNoteGroup(this);
2143
2174
  }
2144
2175
  getMusicInterface() {
@@ -2164,12 +2195,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2164
2195
  this.col = col;
2165
2196
  this.voiceId = voiceId;
2166
2197
  this.notes = notes;
2167
- __publicField(this, "minDiatonicId");
2168
- __publicField(this, "maxDiatonicId");
2169
- __publicField(this, "ownDiatonicId");
2198
+ this.options = options;
2199
+ __publicField(this, "setDiatonicId");
2200
+ __publicField(this, "setStringsNumbers");
2201
+ __publicField(this, "runningDiatonicId");
2170
2202
  // Average diatonicId of notes.
2171
- __publicField(this, "ownStemDir");
2172
- __publicField(this, "ownString");
2203
+ __publicField(this, "runningStemDir");
2204
+ __publicField(this, "runningStringNumbers");
2173
2205
  __publicField(this, "color");
2174
2206
  __publicField(this, "staccato");
2175
2207
  __publicField(this, "diamond");
@@ -2187,13 +2219,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2187
2219
  if (!Utils3.Is.isIntegerGte(notes.length, 1)) {
2188
2220
  throw new MusicError6(MusicErrorType6.Score, "Cannot create note group object because notes array is empty.");
2189
2221
  }
2190
- let noteStringData = sortNoteStringData(notes, options == null ? void 0 : options.string);
2191
- this.notes = noteStringData.notes;
2192
- this.minDiatonicId = this.notes[0].diatonicId;
2193
- this.maxDiatonicId = this.notes[this.notes.length - 1].diatonicId;
2194
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, Math.round((this.minDiatonicId + this.maxDiatonicId) / 2));
2195
- this.ownStemDir = this.measure.updateOwnStemDir(this, getStem(options == null ? void 0 : options.stem));
2196
- this.ownString = this.measure.updateOwnString(this, noteStringData.strings);
2222
+ let { sortedNotes, sortedStrings } = sortNotesAndStrings(notes, options == null ? void 0 : options.string);
2223
+ this.notes = sortedNotes;
2224
+ this.setStringsNumbers = sortedStrings;
2225
+ this.setDiatonicId = Math.round((this.minDiatonicId + this.maxDiatonicId) / 2);
2226
+ this.runningDiatonicId = this.setDiatonicId;
2227
+ this.runningStemDir = "up" /* Up */;
2228
+ this.runningStringNumbers = [];
2197
2229
  this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
2198
2230
  this.staccato = (_b = options == null ? void 0 : options.staccato) != null ? _b : false;
2199
2231
  this.diamond = (_c = options == null ? void 0 : options.diamond) != null ? _c : false;
@@ -2215,11 +2247,20 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2215
2247
  get row() {
2216
2248
  return this.col.row;
2217
2249
  }
2250
+ get minDiatonicId() {
2251
+ return this.notes[0].diatonicId;
2252
+ }
2253
+ get maxDiatonicId() {
2254
+ return this.notes[this.notes.length - 1].diatonicId;
2255
+ }
2256
+ getDiatonicId(staff) {
2257
+ return this.runningDiatonicId;
2258
+ }
2218
2259
  get stemDir() {
2219
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
2260
+ return this.runningStemDir;
2220
2261
  }
2221
2262
  enableConnective(line) {
2222
- return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.ownDiatonicId));
2263
+ return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.runningDiatonicId));
2223
2264
  }
2224
2265
  startConnective(connectiveProps) {
2225
2266
  if (!this.row.hasStaff && connectiveProps.connective === "tie" /* Tie */) {
@@ -2230,6 +2271,11 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2230
2271
  this.startConnnectives.push(connectiveProps);
2231
2272
  this.doc.addConnectiveProps(connectiveProps);
2232
2273
  }
2274
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
2275
+ this.runningDiatonicId = diatonicId === ObjRest.UndefinedDiatonicId ? this.setDiatonicId : diatonicId;
2276
+ this.runningStemDir = stemDir;
2277
+ this.runningStringNumbers = stringNumbers;
2278
+ }
2233
2279
  getStaticObjects(line) {
2234
2280
  let staticObjects = [];
2235
2281
  this.staffObjects.forEach((obj) => {
@@ -2269,12 +2315,12 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2269
2315
  return this.notes[0];
2270
2316
  }
2271
2317
  getConnectiveAnchorPoint(connectiveProps, line, noteIndex, noteAnchor, side) {
2318
+ var _a;
2272
2319
  if (line instanceof ObjStaff) {
2273
- let staff = line;
2274
2320
  if (noteIndex < 0 || noteIndex >= this.notes.length) {
2275
2321
  throw new MusicError6(MusicErrorType6.Score, "Invalid noteIndex: " + noteIndex);
2276
2322
  }
2277
- let obj = this.staffObjects.find((obj2) => obj2.staff === staff);
2323
+ let obj = this.staffObjects.find((obj2) => obj2.staff === line);
2278
2324
  if (!obj || noteIndex < 0 || noteIndex >= obj.noteHeadRects.length) {
2279
2325
  let r = this.getRect();
2280
2326
  return { x: r.centerX, y: r.bottom };
@@ -2322,11 +2368,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2322
2368
  default:
2323
2369
  throw new MusicError6(MusicErrorType6.Score, "Invalid noteAnchor: " + noteAnchor);
2324
2370
  }
2325
- } else {
2326
- let tab = line;
2327
- let obj = this.tabObjects.find((obj2) => obj2.tab === tab);
2328
- let fretNumber = obj == null ? void 0 : obj.fretNumbers[noteIndex];
2329
- if (!obj || !fretNumber) {
2371
+ } else if (line instanceof ObjTab) {
2372
+ let fretNumber = (_a = this.tabObjects.find((obj) => obj.tab === line)) == null ? void 0 : _a.fretNumbers[noteIndex];
2373
+ if (!fretNumber) {
2330
2374
  return { x: 0, y: 0 };
2331
2375
  }
2332
2376
  let r = fretNumber.getRect();
@@ -2334,26 +2378,29 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2334
2378
  let y;
2335
2379
  let s = 0.9;
2336
2380
  if (connectiveProps.connective === "slide" /* Slide */) {
2337
- let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(obj, 0);
2338
- let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(obj, 0);
2381
+ let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(line, 0);
2382
+ let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(line, 0);
2339
2383
  let slideUp = leftFretNumber === void 0 || rightFretNumber === void 0 || leftFretNumber <= rightFretNumber;
2340
2384
  if (side === "left") {
2341
- y = slideUp ? r.centerY + r.bottomh * s : r.centerY - r.toph * s;
2385
+ y = (slideUp ? r.centerY + r.bottomh : r.centerY - r.toph) * s;
2342
2386
  } else {
2343
- y = slideUp ? r.centerY - r.toph * s : r.centerY + r.bottomh * s;
2387
+ y = (slideUp ? r.centerY - r.toph : r.centerY + r.bottomh) * s;
2344
2388
  }
2345
2389
  } else {
2346
2390
  y = r.centerY + r.bottomh * s;
2347
2391
  }
2348
2392
  return { x, y };
2393
+ } else {
2394
+ return { x: 0, y: 0 };
2349
2395
  }
2350
2396
  }
2351
2397
  getFretNumberString(noteIndex) {
2352
- return this.ownString[noteIndex];
2398
+ return this.runningStringNumbers[noteIndex];
2353
2399
  }
2354
- getFretNumber(tabObj, noteIndex) {
2355
- let fretNumber = tabObj.fretNumbers[noteIndex];
2356
- return fretNumber === void 0 ? void 0 : +fretNumber.getText();
2400
+ getFretNumber(tab, noteIndex) {
2401
+ let tabObj = this.tabObjects.find((o) => o.tab === tab);
2402
+ let fretNumber = tabObj == null ? void 0 : tabObj.fretNumbers[noteIndex];
2403
+ return fretNumber ? parseInt(fretNumber.getText()) : void 0;
2357
2404
  }
2358
2405
  getNextNoteGroup() {
2359
2406
  let voiceNoteGroups = this.measure.getVoiceSymbols(this.voiceId).filter((s) => s instanceof _ObjNoteGroup);
@@ -2416,8 +2463,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2416
2463
  return { staff, x, y, stemHeight };
2417
2464
  });
2418
2465
  }
2419
- getStemHeight(renderer) {
2420
- let { unitSize } = renderer;
2466
+ getStemHeight(ctx) {
2467
+ let { unitSize } = ctx;
2421
2468
  let { flagCount, hasStem } = this.rhythmProps;
2422
2469
  if (hasStem) {
2423
2470
  let addY = this.hasBeamCount() ? DocumentSettings.BeamSeparation : DocumentSettings.FlagSeparation;
@@ -2480,9 +2527,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2480
2527
  }
2481
2528
  });
2482
2529
  }
2483
- layout(renderer, accState) {
2530
+ layout(ctx, accState) {
2484
2531
  this.requestRectUpdate();
2485
- let { unitSize } = renderer;
2532
+ let { unitSize } = ctx;
2486
2533
  let { row, stemDir } = this;
2487
2534
  let { dotCount, flagCount, hasStem } = this.rhythmProps;
2488
2535
  let dotWidth = DocumentSettings.DotSize * unitSize;
@@ -2490,7 +2537,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2490
2537
  let noteHeadHeight = (this.diamond ? DocumentSettings.DiamondNoteHeadSize : DocumentSettings.NoteHeadHeight) * unitSize;
2491
2538
  this.staffObjects.length = 0;
2492
2539
  row.getStaves().forEach((staff) => {
2493
- if (!staff.containsDiatonicId(this.ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2540
+ if (!staff.containsDiatonicId(this.runningDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2494
2541
  return;
2495
2542
  }
2496
2543
  let obj = new ObjStaffNoteGroup(staff, this);
@@ -2513,7 +2560,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2513
2560
  if (accState.needAccidental(note)) {
2514
2561
  let acc = obj.accidentals[noteIndex] = new ObjAccidental(this, note.diatonicId, note.accidental, this.color);
2515
2562
  if (acc) {
2516
- acc.layout(renderer);
2563
+ acc.layout(ctx);
2517
2564
  acc.offset(-noteHeadRect.leftw - unitSize * DocumentSettings.NoteAccSpace - acc.getRect().rightw, noteY);
2518
2565
  }
2519
2566
  noteStaff.addObject(acc);
@@ -2544,7 +2591,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2544
2591
  let bottomNoteY = obj.noteHeadRects[0].centerY;
2545
2592
  let topNoteY = obj.noteHeadRects[obj.noteHeadRects.length - 1].centerY;
2546
2593
  let stemX = stemDir === "up" /* Up */ ? noteHeadWidth / 2 : -noteHeadWidth / 2;
2547
- let stemHeight = this.getStemHeight(renderer);
2594
+ let stemHeight = this.getStemHeight(ctx);
2548
2595
  let stemTipY = stemDir === "up" /* Up */ ? topNoteY - stemHeight : bottomNoteY + stemHeight;
2549
2596
  let stemBaseY = stemDir === "up" /* Up */ ? bottomNoteY : topNoteY;
2550
2597
  if (hasStem) {
@@ -2571,20 +2618,21 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2571
2618
  }
2572
2619
  let obj = new ObjTabNoteGroup(tab, this);
2573
2620
  this.notes.forEach((note, noteIndex) => {
2574
- if (this.ownString[noteIndex] !== void 0) {
2575
- let stringId = this.ownString[noteIndex] - 1;
2576
- let fretId = note.chromaticId - tab.getTuningStrings()[stringId].chromaticId;
2621
+ let stringNumber = this.runningStringNumbers[noteIndex];
2622
+ if (Utils3.Is.isIntegerBetween(stringNumber, 1, 6)) {
2623
+ let fretId = note.chromaticId - tab.getTuningStrings()[stringNumber - 1].chromaticId;
2577
2624
  let color = fretId < 0 ? "red" : "black";
2578
2625
  let fretNumber = new ObjText(this, { text: String(fretId), color, bgcolor: "white" }, 0.5, 0.5);
2579
- obj.fretNumbers.push(fretNumber);
2580
- fretNumber.layout(renderer);
2626
+ fretNumber.layout(ctx);
2581
2627
  let x = this.col.getRect().centerX;
2582
- let y = tab.getStringY(stringId);
2628
+ let y = tab.getStringY(stringNumber - 1);
2583
2629
  fretNumber.offset(x, y);
2630
+ obj.fretNumbers.push(fretNumber);
2584
2631
  }
2585
2632
  });
2586
2633
  if (obj.fretNumbers.length > 0) {
2587
2634
  this.tabObjects.push(obj);
2635
+ tab.addObject(obj);
2588
2636
  }
2589
2637
  });
2590
2638
  }
@@ -2612,19 +2660,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2612
2660
  this.tabObjects.forEach((obj) => obj.offset(dx, 0));
2613
2661
  this.requestRectUpdate();
2614
2662
  }
2615
- draw(renderer) {
2616
- const ctx = renderer.getCanvasContext();
2617
- if (!ctx) {
2618
- return;
2619
- }
2620
- renderer.drawDebugRect(this.getRect());
2621
- let { lineWidth } = renderer;
2622
- let { color, stemDir } = this;
2663
+ draw(ctx) {
2664
+ ctx.drawDebugRect(this.getRect());
2665
+ let { stemDir } = this;
2623
2666
  let { isSolidNoteHead } = this.rhythmProps;
2624
2667
  this.staffObjects.forEach((obj) => {
2625
- obj.accidentals.forEach((d) => d.draw(renderer));
2626
- ctx.strokeStyle = ctx.fillStyle = color;
2627
- ctx.lineWidth = lineWidth;
2668
+ obj.accidentals.forEach((d) => d.draw(ctx));
2669
+ ctx.color(this.color);
2670
+ ctx.lineWidth(1);
2628
2671
  obj.noteHeadRects.forEach((r) => {
2629
2672
  if (this.diamond) {
2630
2673
  if (isSolidNoteHead) {
@@ -2637,14 +2680,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2637
2680
  ctx.fill();
2638
2681
  } else {
2639
2682
  ctx.beginPath();
2640
- ctx.lineWidth = lineWidth * 2.5;
2683
+ ctx.lineWidth(2.5);
2641
2684
  ctx.moveTo(r.centerX, r.top);
2642
2685
  ctx.lineTo(r.right, r.centerY);
2643
2686
  ctx.moveTo(r.left, r.centerY);
2644
2687
  ctx.lineTo(r.centerX, r.bottom);
2645
2688
  ctx.stroke();
2646
2689
  ctx.beginPath();
2647
- ctx.lineWidth = lineWidth;
2690
+ ctx.lineWidth(1);
2648
2691
  ctx.moveTo(r.right, r.centerY);
2649
2692
  ctx.lineTo(r.centerX, r.bottom);
2650
2693
  ctx.moveTo(r.centerX, r.top);
@@ -2661,16 +2704,16 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2661
2704
  }
2662
2705
  }
2663
2706
  });
2664
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
2707
+ obj.dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
2665
2708
  if (obj.stemTip && obj.stemBase) {
2666
2709
  ctx.beginPath();
2667
2710
  ctx.moveTo(obj.stemBase.centerX, obj.stemBase.centerY);
2668
2711
  ctx.lineTo(obj.stemTip.centerX, obj.stemTip.centerY);
2669
2712
  ctx.stroke();
2670
2713
  }
2671
- obj.flagRects.forEach((rect) => renderer.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
2714
+ obj.flagRects.forEach((rect) => ctx.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
2672
2715
  });
2673
- this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(renderer)));
2716
+ this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(ctx)));
2674
2717
  }
2675
2718
  getDotVerticalDisplacement(staff, diatonicId, stemDir) {
2676
2719
  if (staff.isLine(diatonicId)) {
@@ -2696,87 +2739,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2696
2739
 
2697
2740
  // src/score/engine/obj-rhythm-column.ts
2698
2741
  import { MusicError as MusicError7, MusicErrorType as MusicErrorType7 } from "@tspro/web-music-score/core";
2699
-
2700
- // src/score/engine/obj-lyrics.ts
2701
- import { Utils as Utils4 } from "@tspro/ts-utils-lib";
2702
- var LyricsContainer = class {
2703
- constructor(col, lyricsLength) {
2704
- this.col = col;
2705
- __publicField(this, "lyricsObjects", []);
2706
- __publicField(this, "rhythmProps");
2707
- this.rhythmProps = RhythmProps.get(lyricsLength);
2708
- }
2709
- addLyricsObject(lyricsObj) {
2710
- var _a;
2711
- this.lyricsObjects.push(lyricsObj);
2712
- (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
2713
- }
2714
- };
2715
- var ObjLyrics = class extends MusicObject {
2716
- constructor(col, verse, line, vpos, lyricsText, lyricsOptions) {
2717
- super(col);
2718
- this.col = col;
2719
- this.verse = verse;
2720
- this.line = line;
2721
- this.vpos = vpos;
2722
- __publicField(this, "nextLyricsObject");
2723
- __publicField(this, "color", "black");
2724
- __publicField(this, "hyphen");
2725
- __publicField(this, "text");
2726
- __publicField(this, "mi");
2727
- let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
2728
- this.hyphen = Utils4.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
2729
- this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
2730
- this.rect = new DivRect();
2731
- this.mi = new MLyrics(this);
2732
- }
2733
- getMusicInterface() {
2734
- return this.mi;
2735
- }
2736
- get measure() {
2737
- return this.col.measure;
2738
- }
2739
- getText() {
2740
- return this.text.getText();
2741
- }
2742
- setNextLyricsObject(lyricsObj) {
2743
- this.nextLyricsObject = lyricsObj;
2744
- }
2745
- pick(x, y) {
2746
- return this.rect.contains(x, y) ? [this] : [];
2747
- }
2748
- layout(renderer) {
2749
- this.text.layout(renderer);
2750
- this.rect = this.text.getRect().copy();
2751
- }
2752
- offset(dx, dy) {
2753
- this.text.offset(dx, dy);
2754
- this.rect.offsetInPlace(dx, dy);
2755
- }
2756
- draw(renderer) {
2757
- var _a;
2758
- this.text.draw(renderer);
2759
- const ctx = renderer.getCanvasContext();
2760
- if (ctx && this.hyphen !== void 0) {
2761
- let l = this.getRect();
2762
- let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
2763
- let hyphenw = renderer.unitSize * 1.5;
2764
- let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
2765
- let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
2766
- if (w > 0) {
2767
- ctx.lineWidth = renderer.lineWidth;
2768
- ctx.strokeStyle = ctx.fillStyle = this.color;
2769
- let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
2770
- let cy = (l.top + l.bottom) / 2;
2771
- ctx.moveTo(cx - w / 2, cy);
2772
- ctx.lineTo(cx + w / 2, cy);
2773
- ctx.stroke();
2774
- }
2775
- }
2776
- }
2777
- };
2778
-
2779
- // src/score/engine/obj-rhythm-column.ts
2742
+ import { Map3 } from "@tspro/ts-utils-lib";
2780
2743
  var noteHeadDataCompareFunc = (a, b) => {
2781
2744
  let cmp = Note5.compareFunc(a.note, b.note);
2782
2745
  if (cmp === 0) {
@@ -2790,7 +2753,7 @@ var ObjRhythmColumn = class extends MusicObject {
2790
2753
  this.measure = measure;
2791
2754
  this.positionTicks = positionTicks;
2792
2755
  __publicField(this, "voiceSymbol", []);
2793
- __publicField(this, "lyricsContainers", []);
2756
+ __publicField(this, "lyricsObject", new Map3());
2794
2757
  __publicField(this, "minDiatonicId");
2795
2758
  __publicField(this, "maxDiatonicId");
2796
2759
  __publicField(this, "staffMinDiatonicId", /* @__PURE__ */ new Map());
@@ -2900,8 +2863,11 @@ var ObjRhythmColumn = class extends MusicObject {
2900
2863
  validateVoiceId(voiceId);
2901
2864
  this.voiceSymbol[voiceId] = symbol;
2902
2865
  if (symbol instanceof ObjRest && !symbol.hide) {
2903
- this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(this.minDiatonicId, symbol.ownDiatonicId);
2904
- this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(this.maxDiatonicId, symbol.ownDiatonicId);
2866
+ this.row.getStaves().forEach((staff) => {
2867
+ let diatonicId = symbol.getDiatonicId(staff);
2868
+ this.minDiatonicId = this.minDiatonicId === void 0 ? diatonicId : Math.min(this.minDiatonicId, diatonicId);
2869
+ this.maxDiatonicId = this.maxDiatonicId === void 0 ? diatonicId : Math.max(this.maxDiatonicId, diatonicId);
2870
+ });
2905
2871
  } else if (symbol instanceof ObjNoteGroup) {
2906
2872
  this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.notes[0].diatonicId : Math.min(this.minDiatonicId, symbol.notes[0].diatonicId);
2907
2873
  this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.notes[symbol.notes.length - 1].diatonicId : Math.max(this.maxDiatonicId, symbol.notes[symbol.notes.length - 1].diatonicId);
@@ -2916,18 +2882,11 @@ var ObjRhythmColumn = class extends MusicObject {
2916
2882
  getVoiceSymbol(voiceId) {
2917
2883
  return this.voiceSymbol[voiceId];
2918
2884
  }
2919
- getLyricsContainerDatas() {
2920
- return this.lyricsContainers;
2885
+ getLyricsObject(verse, line, vpos) {
2886
+ return this.lyricsObject.get(verse, line, vpos);
2921
2887
  }
2922
- getLyricsContainer(verse, line, vpos, lyricsLength) {
2923
- let data = this.lyricsContainers.find((data2) => data2.verse === verse && data2.line === line && data2.vpos === vpos);
2924
- if (data === void 0 && lyricsLength !== void 0) {
2925
- data = { lyricsContainer: new LyricsContainer(this, validateNoteLength2(lyricsLength)), verse, line, vpos };
2926
- this.lyricsContainers.push(data);
2927
- this.requestLayout();
2928
- this.requestRectUpdate();
2929
- }
2930
- return data == null ? void 0 : data.lyricsContainer;
2888
+ addLyricsObject(lyricsObj) {
2889
+ this.lyricsObject.set(lyricsObj.verse, lyricsObj.line, lyricsObj.vpos, lyricsObj);
2931
2890
  }
2932
2891
  getMinWidth() {
2933
2892
  let maxNoteSize = Math.max(...this.voiceSymbol.map((s) => s.rhythmProps.noteSize));
@@ -3038,19 +2997,19 @@ var ObjRhythmColumn = class extends MusicObject {
3038
2997
  this.measure.requestLayout();
3039
2998
  }
3040
2999
  }
3041
- layout(renderer, accState) {
3000
+ layout(ctx, accState) {
3042
3001
  if (!this.needLayout) {
3043
3002
  return;
3044
3003
  }
3045
3004
  this.requestRectUpdate();
3046
3005
  this.rect = new DivRect();
3047
3006
  let { row } = this;
3048
- let { unitSize } = renderer;
3007
+ let { unitSize } = ctx;
3049
3008
  let halfMinWidth = this.getMinWidth() * unitSize / 2;
3050
3009
  let leftw = halfMinWidth;
3051
3010
  let rightw = halfMinWidth;
3052
3011
  this.voiceSymbol.forEach((symbol) => {
3053
- symbol.layout(renderer, accState);
3012
+ symbol.layout(ctx, accState);
3054
3013
  let r = symbol.getRect();
3055
3014
  leftw = Math.max(leftw, r.leftw);
3056
3015
  rightw = Math.max(rightw, r.rightw);
@@ -3059,7 +3018,7 @@ var ObjRhythmColumn = class extends MusicObject {
3059
3018
  let arpeggioWidth = 0;
3060
3019
  this.arpeggios = row.getNotationLines().map((line) => {
3061
3020
  let arpeggio = new ObjArpeggio(this, line, this.getArpeggioDir());
3062
- arpeggio.layout(renderer);
3021
+ arpeggio.layout(ctx);
3063
3022
  arpeggio.offset(-leftw - arpeggio.getRect().right, line.getRect().centerY - arpeggio.getRect().centerY);
3064
3023
  arpeggioWidth = Math.max(arpeggioWidth, arpeggio.getRect().width);
3065
3024
  line.addObject(arpeggio);
@@ -3089,8 +3048,9 @@ var ObjRhythmColumn = class extends MusicObject {
3089
3048
  minDiatonicId = minDiatonicId === void 0 ? symbol.minDiatonicId : Math.min(minDiatonicId, symbol.minDiatonicId);
3090
3049
  maxDiatonicId = maxDiatonicId === void 0 ? symbol.maxDiatonicId : Math.max(maxDiatonicId, symbol.maxDiatonicId);
3091
3050
  } else if (symbol instanceof ObjRest) {
3092
- minDiatonicId = minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(minDiatonicId, symbol.ownDiatonicId);
3093
- maxDiatonicId = maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(maxDiatonicId, symbol.ownDiatonicId);
3051
+ let diatonicId = symbol.getDiatonicId(staff);
3052
+ minDiatonicId = minDiatonicId === void 0 ? diatonicId : Math.min(minDiatonicId, diatonicId);
3053
+ maxDiatonicId = maxDiatonicId === void 0 ? diatonicId : Math.max(maxDiatonicId, diatonicId);
3094
3054
  }
3095
3055
  }
3096
3056
  });
@@ -3124,23 +3084,23 @@ var ObjRhythmColumn = class extends MusicObject {
3124
3084
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
3125
3085
  this.rect.offsetInPlace(dx, dy);
3126
3086
  }
3127
- draw(renderer) {
3087
+ draw(ctx) {
3128
3088
  this.row.getStaves().forEach((staff) => {
3129
3089
  let minDiatonicId = this.staffMinDiatonicId.get(staff);
3130
3090
  let maxDiatonicId = this.staffMaxDiatonicId.get(staff);
3131
3091
  if (minDiatonicId !== void 0) {
3132
- renderer.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3092
+ ctx.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3133
3093
  }
3134
3094
  if (maxDiatonicId !== void 0) {
3135
- renderer.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3095
+ ctx.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3136
3096
  }
3137
3097
  });
3138
3098
  this.voiceSymbol.forEach((symbol) => {
3139
3099
  if (symbol) {
3140
- symbol.draw(renderer);
3100
+ symbol.draw(ctx);
3141
3101
  }
3142
3102
  });
3143
- this.arpeggios.forEach((arpeggio) => arpeggio.draw(renderer));
3103
+ this.arpeggios.forEach((arpeggio) => arpeggio.draw(ctx));
3144
3104
  }
3145
3105
  };
3146
3106
 
@@ -3148,7 +3108,7 @@ var ObjRhythmColumn = class extends MusicObject {
3148
3108
  import { MusicError as MusicError8, MusicErrorType as MusicErrorType8 } from "@tspro/web-music-score/core";
3149
3109
 
3150
3110
  // src/score/engine/element-data.ts
3151
- import { Utils as Utils5 } from "@tspro/ts-utils-lib";
3111
+ import { Utils as Utils4 } from "@tspro/ts-utils-lib";
3152
3112
 
3153
3113
  // src/score/engine/obj-special-text.ts
3154
3114
  var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
@@ -3188,13 +3148,13 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3188
3148
  pick(x, y) {
3189
3149
  return this.rect.contains(x, y) ? [this] : [];
3190
3150
  }
3191
- layout(renderer) {
3151
+ layout(ctx) {
3192
3152
  switch (this.text) {
3193
3153
  case _ObjSpecialText.Coda: {
3194
3154
  let codaSym = this.components[0];
3195
3155
  let codaText = this.components[1];
3196
- codaSym.layout(renderer);
3197
- codaText.layout(renderer);
3156
+ codaSym.layout(ctx);
3157
+ codaText.layout(ctx);
3198
3158
  codaSym.offset(0, (codaText.getRect().top + codaText.getRect().bottom) / 2);
3199
3159
  codaText.offset(codaSym.getRect().right, 0);
3200
3160
  this.rect = new DivRect(
@@ -3210,8 +3170,8 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3210
3170
  case _ObjSpecialText.toCoda: {
3211
3171
  let toCodaText = this.components[0];
3212
3172
  let codaSym = this.components[1];
3213
- toCodaText.layout(renderer);
3214
- codaSym.layout(renderer);
3173
+ toCodaText.layout(ctx);
3174
+ codaSym.layout(ctx);
3215
3175
  codaSym.offset(0, (toCodaText.getRect().top + toCodaText.getRect().bottom) / 2);
3216
3176
  toCodaText.offset(codaSym.getRect().left, 0);
3217
3177
  this.rect = new DivRect(
@@ -3226,7 +3186,7 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3226
3186
  }
3227
3187
  default: {
3228
3188
  let text = this.components[0];
3229
- text.layout(renderer);
3189
+ text.layout(ctx);
3230
3190
  this.rect = text.getRect().copy();
3231
3191
  break;
3232
3192
  }
@@ -3236,9 +3196,9 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3236
3196
  this.components.forEach((c) => c.offset(dx, dy));
3237
3197
  this.rect.offsetInPlace(dx, dy);
3238
3198
  }
3239
- draw(renderer) {
3240
- renderer.drawDebugRect(this.rect);
3241
- this.components.forEach((c) => c.draw(renderer));
3199
+ draw(ctx) {
3200
+ ctx.drawDebugRect(this.rect);
3201
+ this.components.forEach((c) => c.draw(ctx));
3242
3202
  }
3243
3203
  };
3244
3204
  __publicField(_ObjSpecialText, "toCoda", "\u{1D10C} toCoda");
@@ -3270,23 +3230,23 @@ function getNavigationString(navigation) {
3270
3230
  }
3271
3231
  }
3272
3232
  function isDynamicsText(text) {
3273
- return Utils5.Is.isEnumValue(text, DynamicsAnnotation);
3233
+ return Utils4.Is.isEnumValue(text, DynamicsAnnotation);
3274
3234
  }
3275
3235
  function getDynamicsVolume(text) {
3276
3236
  if (/^(p+|f+|m|mp|mf)$/.test(text)) {
3277
- let volume = 0.5 - Utils5.Str.charCount(text, "p") * 0.1 + Utils5.Str.charCount(text, "f") * 0.1;
3278
- return Utils5.Math.clamp(volume, 0, 1);
3237
+ let volume = 0.5 - Utils4.Str.charCount(text, "p") * 0.1 + Utils4.Str.charCount(text, "f") * 0.1;
3238
+ return Utils4.Math.clamp(volume, 0, 1);
3279
3239
  } else {
3280
3240
  return void 0;
3281
3241
  }
3282
3242
  }
3283
3243
  function isTempoText(text) {
3284
- return Utils5.Is.isEnumValue(text, TempoAnnotation);
3244
+ return Utils4.Is.isEnumValue(text, TempoAnnotation);
3285
3245
  }
3286
3246
  function getAnnotation(text) {
3287
- if (Utils5.Is.isEnumValue(text, DynamicsAnnotation)) {
3247
+ if (Utils4.Is.isEnumValue(text, DynamicsAnnotation)) {
3288
3248
  return "dynamics" /* Dynamics */;
3289
- } else if (Utils5.Is.isEnumValue(text, TempoAnnotation)) {
3249
+ } else if (Utils4.Is.isEnumValue(text, TempoAnnotation)) {
3290
3250
  return "tempo" /* Tempo */;
3291
3251
  } else {
3292
3252
  return void 0;
@@ -3442,7 +3402,7 @@ var PlayerColumnProps = class {
3442
3402
  return this.speed;
3443
3403
  }
3444
3404
  getTempo() {
3445
- let speed = Utils6.Math.clamp(this.getSpeed(), 0.1, 10);
3405
+ let speed = Utils5.Math.clamp(this.getSpeed(), 0.1, 10);
3446
3406
  return alterTempoSpeed(this.measure.getTempo(), speed);
3447
3407
  }
3448
3408
  setVolume(volume) {
@@ -3467,7 +3427,7 @@ var PlayerColumnProps = class {
3467
3427
  if (symbolsTicks.length === 0) {
3468
3428
  return 0;
3469
3429
  } else {
3470
- return Utils6.Math.sum(symbolsTicks) / symbolsTicks.length;
3430
+ return Utils5.Math.sum(symbolsTicks) / symbolsTicks.length;
3471
3431
  }
3472
3432
  }
3473
3433
  }
@@ -3616,7 +3576,7 @@ var Player = class _Player {
3616
3576
  } else if (layoutObj.musicObj.getLink() instanceof Extension) {
3617
3577
  let extension = layoutObj.musicObj.getLink();
3618
3578
  let { columnRange, extensionBreakText } = extension.getExtensionRangeInfo();
3619
- let totalTicks = Utils6.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
3579
+ let totalTicks = Utils5.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
3620
3580
  switch (text) {
3621
3581
  case "accel." /* accel */: {
3622
3582
  let startSpeed = curSpeed;
@@ -3670,11 +3630,11 @@ var Player = class _Player {
3670
3630
  });
3671
3631
  let speedArr = (_a = speedMap.get(col)) != null ? _a : [];
3672
3632
  if (speedArr.length > 0) {
3673
- curSpeed = Utils6.Math.sum(speedArr) / speedArr.length;
3633
+ curSpeed = Utils5.Math.sum(speedArr) / speedArr.length;
3674
3634
  }
3675
3635
  let volumeArr = (_b = volumeMap.get(col)) != null ? _b : [];
3676
3636
  if (volumeArr.length > 0) {
3677
- curVolume = Utils6.Math.sum(volumeArr) / volumeArr.length;
3637
+ curVolume = Utils5.Math.sum(volumeArr) / volumeArr.length;
3678
3638
  }
3679
3639
  col.getPlayerProps().setSpeed(curSpeed);
3680
3640
  col.getPlayerProps().setVolume(curVolume);
@@ -3700,6 +3660,10 @@ var Player = class _Player {
3700
3660
  return;
3701
3661
  }
3702
3662
  const col = this.playerColumnSequence[this.playPos];
3663
+ if (!col) {
3664
+ this.stop();
3665
+ return;
3666
+ }
3703
3667
  const getDuration = (ticks, tempo2) => {
3704
3668
  let seconds = calcTicksDuration(ticks, tempo2);
3705
3669
  return Math.max(0, seconds);
@@ -3712,11 +3676,11 @@ var Player = class _Player {
3712
3676
  } else {
3713
3677
  let playerNotes = col.getPlayerNotes();
3714
3678
  playerNotes.forEach((note, i) => {
3715
- let arpeggioDelayTicks = col.hasArpeggio() ? RhythmProps4.get(NoteLength6.ThirtySecond).ticks * i : 0;
3679
+ let arpeggioDelayTicks = col.hasArpeggio() ? RhythmProps4.get(NoteLength4.ThirtySecond).ticks * i : 0;
3716
3680
  let noteSeconds = getDuration(note.ticks + fermataHoldTicks - arpeggioDelayTicks, tempo);
3717
3681
  if (noteSeconds > 0) {
3718
3682
  if (note.staccato) {
3719
- noteSeconds = Math.min(getDuration(RhythmProps4.get(NoteLength6.Eighth).ticks, tempo) / 2, noteSeconds / 2);
3683
+ noteSeconds = Math.min(getDuration(RhythmProps4.get(NoteLength4.Eighth).ticks, tempo) / 2, noteSeconds / 2);
3720
3684
  }
3721
3685
  let volume = adjustVolume(col.getPlayerProps().getVolume());
3722
3686
  if (note.slur === "slurred") {
@@ -3784,6 +3748,9 @@ var Player = class _Player {
3784
3748
  return void 0;
3785
3749
  }
3786
3750
  let col = this.playerColumnSequence[this.playPos];
3751
+ if (!col) {
3752
+ return void 0;
3753
+ }
3787
3754
  let measure = col.measure;
3788
3755
  let x = col.getRect().centerX;
3789
3756
  let top = measure.row.getRect().top;
@@ -3798,8 +3765,8 @@ var ObjStaffTabBarLine = class extends MusicObject {
3798
3765
  super(line);
3799
3766
  this.barLine = barLine;
3800
3767
  this.line = line;
3801
- __publicField(this, "lineRects", []);
3802
- __publicField(this, "dotRects", []);
3768
+ __publicField(this, "verticalLines", []);
3769
+ __publicField(this, "dots", []);
3803
3770
  __publicField(this, "mi");
3804
3771
  line.addObject(this);
3805
3772
  this.mi = new MStaffTabBarLine(this);
@@ -3814,8 +3781,11 @@ var ObjStaffTabBarLine = class extends MusicObject {
3814
3781
  this.rect = r;
3815
3782
  }
3816
3783
  offset(dx, dy) {
3817
- this.lineRects.forEach((r) => r.offsetInPlace(dx, dy));
3818
- this.dotRects.forEach((r) => r.offsetInPlace(dx, dy));
3784
+ this.verticalLines.forEach((l) => l.left += dx);
3785
+ this.dots.forEach((d) => {
3786
+ d.x += dx;
3787
+ d.y += dy;
3788
+ });
3819
3789
  this.rect.offsetInPlace(dx, dy);
3820
3790
  }
3821
3791
  };
@@ -3824,6 +3794,7 @@ var ObjBarLine = class extends MusicObject {
3824
3794
  super(measure);
3825
3795
  this.measure = measure;
3826
3796
  __publicField(this, "staffTabObjects", []);
3797
+ __publicField(this, "staffTabObjectGroups", []);
3827
3798
  __publicField(this, "barLineType", 0 /* None */);
3828
3799
  }
3829
3800
  pick(x, y) {
@@ -3838,14 +3809,14 @@ var ObjBarLine = class extends MusicObject {
3838
3809
  }
3839
3810
  return [this];
3840
3811
  }
3841
- layout(renderer) {
3812
+ layout(ctx) {
3842
3813
  this.requestRectUpdate();
3843
3814
  this.staffTabObjects.length = 0;
3844
3815
  this.barLineType = this.solveBarLineType();
3845
- let { unitSize, lineWidth } = renderer;
3816
+ let { unitSize, _lineWidth } = ctx;
3846
3817
  let { measure, barLineType } = this;
3847
3818
  let { row } = measure;
3848
- let thinW = lineWidth;
3819
+ let thinW = _lineWidth;
3849
3820
  let thicW = 0.7 * unitSize;
3850
3821
  let spaceW = 0.7 * unitSize;
3851
3822
  let dotW = DocumentSettings.DotSize * unitSize;
@@ -3855,13 +3826,13 @@ var ObjBarLine = class extends MusicObject {
3855
3826
  let lineCenterY;
3856
3827
  let lineDotOff;
3857
3828
  let top, bottom;
3858
- const addRect = (left, width) => {
3859
- obj.lineRects.push(new DivRect(left, left + width / 2, left + width, top, 0, bottom));
3829
+ const addVerticalLine = (left, width) => {
3830
+ obj.verticalLines.push({ left, width });
3860
3831
  };
3861
- const addDots = (cx) => {
3832
+ const addDotPair = (cx) => {
3862
3833
  for (let i = -1; i <= 1; i += 2) {
3863
3834
  let y = lineCenterY + i * lineDotOff;
3864
- obj.dotRects.push(new DivRect(cx - dotRadius, cx, cx + dotRadius, y - dotRadius, y, y + dotRadius));
3835
+ obj.dots.push({ x: cx, y, r: dotRadius });
3865
3836
  }
3866
3837
  };
3867
3838
  if (line instanceof ObjStaff) {
@@ -3879,41 +3850,44 @@ var ObjBarLine = class extends MusicObject {
3879
3850
  break;
3880
3851
  case 1 /* Single */:
3881
3852
  obj.setRect(new DivRect(-thinW, 0, 0, top, 0, bottom));
3882
- addRect(-thinW, thinW);
3853
+ addVerticalLine(-thinW, thinW);
3883
3854
  break;
3884
3855
  case 2 /* Double */:
3885
3856
  obj.setRect(new DivRect(-thinW - spaceW - thinW, 0, 0, top, 0, bottom));
3886
- addRect(-thinW - spaceW - thinW, thinW);
3887
- addRect(-thinW, thinW);
3857
+ addVerticalLine(-thinW - spaceW - thinW, thinW);
3858
+ addVerticalLine(-thinW, thinW);
3888
3859
  break;
3889
3860
  case 3 /* EndSong */:
3890
3861
  obj.setRect(new DivRect(-thicW - spaceW - thinW, 0, 0, top, 0, bottom));
3891
- addRect(-thinW - spaceW - thicW, thinW);
3892
- addRect(-thicW, thicW);
3862
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
3863
+ addVerticalLine(-thicW, thicW);
3893
3864
  break;
3894
3865
  case 4 /* StartRepeat */:
3895
3866
  obj.setRect(new DivRect(0, 0, thicW + spaceW + thinW + spaceW + dotW, top, 0, bottom));
3896
- addRect(0, thicW);
3897
- addRect(thicW + spaceW, thinW);
3898
- addDots(thicW + spaceW + thinW + spaceW + dotRadius);
3867
+ addVerticalLine(0, thicW);
3868
+ addVerticalLine(thicW + spaceW, thinW);
3869
+ addDotPair(thicW + spaceW + thinW + spaceW + dotRadius);
3899
3870
  break;
3900
3871
  case 5 /* EndRepeat */:
3901
3872
  obj.setRect(new DivRect(-thicW - spaceW - thinW - spaceW - dotW, 0, 0, top, 0, bottom));
3902
- addRect(-thinW - spaceW - thicW, thinW);
3903
- addRect(-thicW, thicW);
3904
- addDots(-thinW - spaceW - thicW - spaceW - dotRadius);
3873
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
3874
+ addVerticalLine(-thicW, thicW);
3875
+ addDotPair(-thinW - spaceW - thicW - spaceW - dotRadius);
3905
3876
  break;
3906
3877
  case 6 /* EndStartRepeat */:
3907
3878
  obj.setRect(new DivRect(-dotW - spaceW - thinW - spaceW - thicW / 2, 0, thicW / 2 + spaceW + thinW + spaceW + dotW, top, 0, bottom));
3908
- addRect(-thicW / 2, thicW);
3909
- addRect(-thicW / 2 - spaceW - thinW, thinW);
3910
- addRect(thicW / 2 + spaceW, thinW);
3911
- addDots(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
3912
- addDots(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
3879
+ addVerticalLine(-thicW / 2, thicW);
3880
+ addVerticalLine(-thicW / 2 - spaceW - thinW, thinW);
3881
+ addVerticalLine(thicW / 2 + spaceW, thinW);
3882
+ addDotPair(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
3883
+ addDotPair(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
3913
3884
  break;
3914
3885
  }
3915
3886
  this.staffTabObjects.push(obj);
3916
3887
  });
3888
+ this.staffTabObjectGroups = row.getInstrumentLineGroups().map(
3889
+ (lines) => lines.map((line) => this.staffTabObjects.find((obj) => obj.line === line)).filter((obj) => obj !== void 0)
3890
+ );
3917
3891
  }
3918
3892
  updateRect() {
3919
3893
  if (this.staffTabObjects.length > 0) {
@@ -3929,16 +3903,19 @@ var ObjBarLine = class extends MusicObject {
3929
3903
  this.staffTabObjects.forEach((obj) => obj.offset(dx, 0));
3930
3904
  this.requestRectUpdate();
3931
3905
  }
3932
- draw(renderer) {
3933
- const ctx = renderer.getCanvasContext();
3934
- if (!ctx || this.barLineType === 0 /* None */) {
3906
+ draw(ctx) {
3907
+ if (this.barLineType === 0 /* None */) {
3935
3908
  return;
3936
3909
  }
3937
- renderer.drawDebugRect(this.getRect());
3938
- ctx.strokeStyle = ctx.fillStyle = "black";
3939
- this.staffTabObjects.forEach((obj) => {
3940
- obj.lineRects.forEach((r) => ctx.fillRect(r.left, r.top, r.width, r.height));
3941
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
3910
+ ctx.drawDebugRect(this.getRect());
3911
+ ctx.color("black");
3912
+ this.staffTabObjectGroups.forEach((objs) => {
3913
+ if (objs.length > 0) {
3914
+ objs.forEach((obj) => obj.dots.forEach((d) => ctx.fillCircle(d.x, d.y, d.r)));
3915
+ let top = objs[0].getRect().top;
3916
+ let height = objs[objs.length - 1].getRect().bottom - top;
3917
+ objs[0].verticalLines.forEach((vline) => ctx.fillRect(vline.left, top, vline.width, height));
3918
+ }
3942
3919
  });
3943
3920
  }
3944
3921
  };
@@ -4004,7 +3981,7 @@ var ObjBarLineRight = class extends ObjBarLine {
4004
3981
  };
4005
3982
 
4006
3983
  // src/score/engine/obj-ending.ts
4007
- import { Utils as Utils7 } from "@tspro/ts-utils-lib";
3984
+ import { Utils as Utils6 } from "@tspro/ts-utils-lib";
4008
3985
  import { MusicError as MusicError9, MusicErrorType as MusicErrorType9 } from "@tspro/web-music-score/core";
4009
3986
  var ObjEnding = class extends MusicObject {
4010
3987
  constructor(measure, passages) {
@@ -4015,9 +3992,9 @@ var ObjEnding = class extends MusicObject {
4015
3992
  __publicField(this, "shapeRects", []);
4016
3993
  __publicField(this, "mi");
4017
3994
  this.mi = new MEnding(this);
4018
- if (!Utils7.Is.isIntegerGte(passages.length, 1)) {
3995
+ if (!Utils6.Is.isIntegerGte(passages.length, 1)) {
4019
3996
  throw new MusicError9(MusicErrorType9.Score, "Passages is empty.");
4020
- } else if (!this.passages.every((p) => Utils7.Is.isIntegerGte(p, 1))) {
3997
+ } else if (!this.passages.every((p) => Utils6.Is.isIntegerGte(p, 1))) {
4021
3998
  throw new MusicError9(MusicErrorType9.Score, "Invalid passages: " + this.passages);
4022
3999
  }
4023
4000
  this.passages.sort((a, b) => a - b);
@@ -4044,14 +4021,14 @@ var ObjEnding = class extends MusicObject {
4044
4021
  pick(x, y) {
4045
4022
  return this.rect.contains(x, y) ? [this] : [];
4046
4023
  }
4047
- layout(renderer) {
4024
+ layout(ctx) {
4048
4025
  this.rect = new DivRect();
4049
4026
  this.shapeRects = [this.rect.copy()];
4050
4027
  }
4051
- layoutFitToMeasure(renderer) {
4052
- let { unitSize } = renderer;
4028
+ layoutFitToMeasure(ctx) {
4029
+ let { unitSize } = ctx;
4053
4030
  let { measure } = this;
4054
- this.endingText.layout(renderer);
4031
+ this.endingText.layout(ctx);
4055
4032
  let textRect = this.endingText.getRect();
4056
4033
  let measureContent = measure.getColumnsContentRect();
4057
4034
  let endingHeight = textRect.height;
@@ -4069,16 +4046,10 @@ var ObjEnding = class extends MusicObject {
4069
4046
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
4070
4047
  this.rect.offsetInPlace(dx, dy);
4071
4048
  }
4072
- draw(renderer) {
4073
- let ctx = renderer.getCanvasContext();
4074
- if (!ctx) {
4075
- return;
4076
- }
4077
- let { lineWidth } = renderer;
4049
+ draw(ctx) {
4078
4050
  let { rect } = this;
4079
- renderer.drawDebugRect(this.rect);
4080
- ctx.strokeStyle = ctx.fillStyle = "black";
4081
- ctx.lineWidth = lineWidth;
4051
+ ctx.drawDebugRect(this.rect);
4052
+ ctx.color("black").lineWidth(1);
4082
4053
  ctx.beginPath();
4083
4054
  ctx.moveTo(rect.left, rect.bottom);
4084
4055
  ctx.lineTo(rect.left, rect.top);
@@ -4087,13 +4058,13 @@ var ObjEnding = class extends MusicObject {
4087
4058
  ctx.lineTo(rect.right, rect.bottom);
4088
4059
  }
4089
4060
  ctx.stroke();
4090
- this.endingText.draw(renderer);
4061
+ this.endingText.draw(ctx);
4091
4062
  }
4092
4063
  };
4093
4064
 
4094
4065
  // src/score/engine/obj-beam-group.ts
4095
- import { Utils as Utils8 } from "@tspro/ts-utils-lib";
4096
- import { NoteLength as NoteLength7, Tuplet as Tuplet3, NoteLengthProps as NoteLengthProps4 } from "@tspro/web-music-score/theory";
4066
+ import { Utils as Utils7 } from "@tspro/ts-utils-lib";
4067
+ import { NoteLength as NoteLength5, Tuplet as Tuplet3, NoteLengthProps as NoteLengthProps4 } from "@tspro/web-music-score/theory";
4097
4068
  import { MusicError as MusicError10, MusicErrorType as MusicErrorType10 } from "@tspro/web-music-score/core";
4098
4069
  var adjustBeamAngle = (dx, dy) => {
4099
4070
  let T = DocumentSettings.BeamAngleFactor;
@@ -4162,6 +4133,12 @@ var ObjStaffBeamGroup = class extends MusicObject {
4162
4133
  }
4163
4134
  }
4164
4135
  };
4136
+ var InvalidBeamGroup = class {
4137
+ constructor(beamGroup, message) {
4138
+ this.beamGroup = beamGroup;
4139
+ this.message = message;
4140
+ }
4141
+ };
4165
4142
  var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4166
4143
  constructor(symbols, tupletRatio) {
4167
4144
  super(symbols[0].measure);
@@ -4182,7 +4159,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4182
4159
  if (symbols.length >= 3 && symbols[0] instanceof ObjNoteGroup && symbols[symbols.length - 1] instanceof ObjNoteGroup && symbols[0].rhythmProps.flagCount === symbols[symbols.length - 1].rhythmProps.flagCount) {
4183
4160
  isGroup = false;
4184
4161
  }
4185
- if (symbols.some((s) => NoteLengthProps4.cmp(s.rhythmProps.noteLength, NoteLength7.Quarter) >= 0)) {
4162
+ if (symbols.some((s) => NoteLengthProps4.cmp(s.rhythmProps.noteLength, NoteLength5.Quarter) >= 0)) {
4186
4163
  isGroup = true;
4187
4164
  }
4188
4165
  this.type = isGroup ? 2 /* TupletGroup */ : 1 /* TupletBeam */;
@@ -4202,10 +4179,30 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4202
4179
  let first = i === 0;
4203
4180
  let last = i === this.symbols.length - 1;
4204
4181
  if (first && sym.getRightBeamCount() === 0 || last && sym.getLeftBeamCount() === 0 || !first && !last && (sym.getLeftBeamCount() === 0 || sym.getRightBeamCount() === 0)) {
4205
- this.detach();
4182
+ throw new InvalidBeamGroup(this, "Beam has zero left or right beam count!");
4206
4183
  }
4207
4184
  });
4208
4185
  }
4186
+ if (symbols.some((symbol) => symbol.voiceId !== symbols[0].voiceId)) {
4187
+ if (this.type === 0 /* RegularBeam */) {
4188
+ throw new InvalidBeamGroup(this, "Beam symbols have different voiceId.");
4189
+ } else {
4190
+ throw new MusicError10(MusicErrorType10.Score, `Tuplet symbols have different voiceId.`);
4191
+ }
4192
+ }
4193
+ symbols[0].row.getStaves().forEach((staff) => {
4194
+ if (staff.getActualStaff(symbols[0].getDiatonicId(staff)) && staff.containsVoiceId(symbols[0].voiceId)) {
4195
+ symbols.forEach((sym) => {
4196
+ let actualStaff = staff.getActualStaff(sym.getDiatonicId(staff));
4197
+ if (!actualStaff || !actualStaff.containsVoiceId(sym.voiceId)) {
4198
+ throw new InvalidBeamGroup(this, "Some of beam or tuplet symbols are not visible!");
4199
+ }
4200
+ });
4201
+ }
4202
+ });
4203
+ }
4204
+ get stemDir() {
4205
+ return this.symbols[0].stemDir;
4209
4206
  }
4210
4207
  get showTupletRatio() {
4211
4208
  var _a;
@@ -4213,26 +4210,54 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4213
4210
  }
4214
4211
  static createBeam(noteGroups) {
4215
4212
  if (noteGroups.length > 1 && noteGroups.every((ng) => !ng.hasTuplet())) {
4216
- new _ObjBeamGroup(noteGroups, void 0);
4213
+ try {
4214
+ new _ObjBeamGroup(noteGroups, void 0);
4215
+ return true;
4216
+ } catch (err) {
4217
+ if (err instanceof InvalidBeamGroup) {
4218
+ err.beamGroup.detach();
4219
+ } else {
4220
+ throw err;
4221
+ }
4222
+ }
4217
4223
  }
4224
+ return false;
4218
4225
  }
4219
4226
  static createOldStyleTriplet(symbols) {
4220
- let s2 = symbols.slice(0, 2);
4221
- let n2 = s2.map((s) => s.rhythmProps.noteSize);
4222
- if (s2.length === 2 && s2.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && (n2[0] * 2 === n2[1] || n2[1] * 2 === n2[0])) {
4223
- new _ObjBeamGroup(s2, Tuplet3.Triplet);
4224
- return 2;
4225
- }
4226
- let s3 = symbols.slice(0, 3);
4227
- let n3 = s3.map((s) => s.rhythmProps.noteSize);
4228
- if (s3.length === 3 && s3.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && n3.every((n) => n === n3[0])) {
4229
- new _ObjBeamGroup(s3, Tuplet3.Triplet);
4230
- return 3;
4227
+ try {
4228
+ let s2 = symbols.slice(0, 2);
4229
+ let n2 = s2.map((s) => s.rhythmProps.noteSize);
4230
+ if (s2.length === 2 && s2.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && (n2[0] * 2 === n2[1] || n2[1] * 2 === n2[0])) {
4231
+ new _ObjBeamGroup(s2, Tuplet3.Triplet);
4232
+ return 2;
4233
+ }
4234
+ let s3 = symbols.slice(0, 3);
4235
+ let n3 = s3.map((s) => s.rhythmProps.noteSize);
4236
+ if (s3.length === 3 && s3.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && n3.every((n) => n === n3[0])) {
4237
+ new _ObjBeamGroup(s3, Tuplet3.Triplet);
4238
+ return 3;
4239
+ }
4240
+ } catch (err) {
4241
+ if (err instanceof InvalidBeamGroup) {
4242
+ console.error(err.message);
4243
+ err.beamGroup.detach();
4244
+ } else {
4245
+ throw err;
4246
+ }
4231
4247
  }
4232
4248
  return 0;
4233
4249
  }
4234
4250
  static createTuplet(symbols, tupletRatio) {
4235
- new _ObjBeamGroup(symbols, tupletRatio);
4251
+ try {
4252
+ new _ObjBeamGroup(symbols, tupletRatio);
4253
+ } catch (err) {
4254
+ if (err instanceof InvalidBeamGroup) {
4255
+ console.error(err.message);
4256
+ err.beamGroup.detach();
4257
+ } else {
4258
+ throw err;
4259
+ }
4260
+ }
4236
4261
  }
4237
4262
  getMusicInterface() {
4238
4263
  return this.mi;
@@ -4274,22 +4299,18 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4274
4299
  getLastSymbol() {
4275
4300
  return this.symbols[this.symbols.length - 1];
4276
4301
  }
4277
- get stemDir() {
4278
- return this.symbols[0].ownStemDir;
4302
+ get color() {
4303
+ return this.symbols[0].color;
4279
4304
  }
4280
- layout(renderer) {
4305
+ layout(ctx) {
4281
4306
  this.requestRectUpdate();
4282
4307
  this.staffObjects.length = 0;
4283
4308
  let symbols = this.getSymbols();
4284
4309
  if (symbols.length === 0) {
4285
4310
  return;
4286
4311
  }
4287
- let voiceId = symbols[0].voiceId;
4288
- if (symbols.some((symbol) => symbol.voiceId !== voiceId)) {
4289
- return;
4290
- }
4291
- let { unitSize } = renderer;
4292
- let { stemDir } = this;
4312
+ let { unitSize } = ctx;
4313
+ let { stemDir, type } = this;
4293
4314
  let symbolsBeamCoords = symbols.map((s) => s.getBeamCoords());
4294
4315
  symbolsBeamCoords[0].map((s) => s == null ? void 0 : s.staff).forEach((mainStaff, index) => {
4295
4316
  var _a, _b;
@@ -4325,7 +4346,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4325
4346
  }
4326
4347
  let leftStemHeight = (_a = symbolStemHeight[0]) != null ? _a : 0;
4327
4348
  let rightStemHeight = (_b = symbolStemHeight[symbolStemHeight.length - 1]) != null ? _b : 0;
4328
- if (this.type !== 2 /* TupletGroup */) {
4349
+ if (type !== 2 /* TupletGroup */) {
4329
4350
  let leftDy = leftStemHeight < rightStemHeight ? Math.sqrt(rightStemHeight - leftStemHeight) : 0;
4330
4351
  let rightDy = rightStemHeight < leftStemHeight ? Math.sqrt(leftStemHeight - rightStemHeight) : 0;
4331
4352
  if (stemDir === "up" /* Up */) {
@@ -4350,7 +4371,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4350
4371
  symbolY.forEach((symY, i) => {
4351
4372
  let symX = symbolX[i];
4352
4373
  if (symX !== void 0 && symY !== void 0) {
4353
- let beamY = Utils8.Math.interpolateY(leftX, leftY, rightX, rightY, symX);
4374
+ let beamY = Utils7.Math.interpolateY(leftX, leftY, rightX, rightY, symX);
4354
4375
  let raiseY = symY - beamY;
4355
4376
  if (stemDir === "up" /* Up */ && raiseY < 0) {
4356
4377
  raiseBeamY = Math.min(raiseBeamY, raiseY);
@@ -4363,21 +4384,21 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4363
4384
  rightY += raiseBeamY;
4364
4385
  symbolY = symbolY.map((y) => y === void 0 ? void 0 : y + raiseBeamY);
4365
4386
  let obj = new ObjStaffBeamGroup(mainStaff, this);
4366
- if (this.type === 2 /* TupletGroup */) {
4387
+ if (type === 2 /* TupletGroup */) {
4367
4388
  let ef = unitSize / (rightX - leftX);
4368
- let l = Utils8.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, -ef);
4369
- let r = Utils8.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, 1 + ef);
4389
+ let l = Utils7.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, -ef);
4390
+ let r = Utils7.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, 1 + ef);
4370
4391
  obj.points.push(new BeamPoint(leftStaff, this, leftSymbol, l.x, l.y));
4371
4392
  obj.points.push(new BeamPoint(rightStaff, this, rightSymbol, r.x, r.y));
4372
4393
  obj.tupletNumberOffsetY = 0;
4373
- } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TupletBeam */) {
4394
+ } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4374
4395
  raiseBeamY *= 0.5;
4375
- let { beamThickness } = renderer;
4396
+ let beamThickness = ctx._lineWidth * DocumentSettings.BeamThickness;
4376
4397
  const beamHeight = (i) => {
4377
4398
  let sym = symbols[i];
4378
4399
  if (sym instanceof ObjNoteGroup) {
4379
4400
  let beamCount = sym instanceof ObjNoteGroup ? Math.max(sym.getLeftBeamCount(), sym.getRightBeamCount()) : 0;
4380
- return DocumentSettings.BeamSeparation * unitSize * (this.stemDir === "up" /* Up */ ? beamCount - 1 : 0);
4401
+ return DocumentSettings.BeamSeparation * unitSize * (stemDir === "up" /* Up */ ? beamCount - 1 : 0);
4381
4402
  } else {
4382
4403
  return 0;
4383
4404
  }
@@ -4388,8 +4409,16 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4388
4409
  let symY = symbolY[i];
4389
4410
  if (symStaff && symX !== void 0 && symY !== void 0) {
4390
4411
  let pt = new BeamPoint(symStaff, this, sym, symX, symY);
4391
- pt.topBeamsHeight = beamThickness / 2 + (stemDir === "down" /* Down */ ? beamHeight(i) : 0);
4392
- pt.bottomBeamsHeight = beamThickness / 2 + (stemDir === "up" /* Up */ ? beamHeight(i) : 0);
4412
+ switch (stemDir) {
4413
+ case "up" /* Up */:
4414
+ pt.topBeamsHeight = beamThickness / 2;
4415
+ pt.bottomBeamsHeight = beamThickness / 2 + beamHeight(i);
4416
+ break;
4417
+ case "down" /* Down */:
4418
+ pt.topBeamsHeight = beamThickness / 2 + beamHeight(i);
4419
+ pt.bottomBeamsHeight = beamThickness / 2;
4420
+ break;
4421
+ }
4393
4422
  obj.points.push(pt);
4394
4423
  }
4395
4424
  });
@@ -4397,7 +4426,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4397
4426
  }
4398
4427
  if (this.isTuplet()) {
4399
4428
  obj.tupletNumber = new ObjText(this, this.getTupletRatioText(), 0.5, 0.5);
4400
- obj.tupletNumber.layout(renderer);
4429
+ obj.tupletNumber.layout(ctx);
4401
4430
  obj.tupletNumber.offset((leftX + rightX) / 2, (leftY + rightY) / 2 + obj.tupletNumberOffsetY);
4402
4431
  }
4403
4432
  if (obj.points.length >= 2) {
@@ -4424,7 +4453,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4424
4453
  obj.points.forEach((pt) => {
4425
4454
  if (pt.symbol instanceof ObjNoteGroup) {
4426
4455
  if (pt !== left && pt !== right) {
4427
- pt.y = Utils8.Math.interpolateY(left.x, left.y, right.x, right.y, pt.x);
4456
+ pt.y = Utils7.Math.interpolateY(left.x, left.y, right.x, right.y, pt.x);
4428
4457
  }
4429
4458
  pt.symbol.setStemTipY(pt.staff, pt.y);
4430
4459
  }
@@ -4440,55 +4469,56 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4440
4469
  this.staffObjects.forEach((obj) => obj.offset(dx, 0));
4441
4470
  this.requestRectUpdate();
4442
4471
  }
4443
- draw(renderer) {
4444
- let { unitSize, beamThickness, lineWidth } = renderer;
4445
- let color = "black";
4446
- this.staffObjects.forEach((obj) => {
4447
- if (this.type === 2 /* TupletGroup */) {
4448
- let l = obj.points[0];
4449
- let r = obj.points[obj.points.length - 1];
4450
- if (l && r) {
4451
- let tf = obj.tupletNumber ? obj.tupletNumber.getRect().width / (r.x - l.x) * 1.2 : 0;
4452
- let lc = Utils8.Math.interpolateCoord(l.x, l.y, r.x, r.y, 0.5 - tf / 2);
4453
- let rc = Utils8.Math.interpolateCoord(l.x, l.y, r.x, r.y, 0.5 + tf / 2);
4454
- let tipH = this.stemDir === "up" /* Up */ ? unitSize : -unitSize;
4455
- renderer.drawLine(l.x, l.y, lc.x, lc.y, color, lineWidth);
4456
- renderer.drawLine(rc.x, rc.y, r.x, r.y, color, lineWidth);
4457
- renderer.drawLine(l.x, l.y, l.x, l.y + tipH, color, lineWidth);
4458
- renderer.drawLine(r.x, r.y, r.x, r.y + tipH, color, lineWidth);
4472
+ draw(ctx) {
4473
+ let { unitSize } = ctx;
4474
+ let { stemDir, color, type } = this;
4475
+ if (type === 2 /* TupletGroup */) {
4476
+ ctx.color(color).lineWidth(1);
4477
+ let tipHeight = (stemDir === "up" /* Up */ ? 1 : -1) * unitSize;
4478
+ this.staffObjects.forEach((obj) => {
4479
+ let { x: lx, y: ly } = obj.points[0];
4480
+ let { x: rx, y: ry } = obj.points[obj.points.length - 1];
4481
+ if (obj.tupletNumber) {
4482
+ let tf = obj.tupletNumber.getRect().width / (rx - lx) * 1.2;
4483
+ let lc = Utils7.Math.interpolateCoord(lx, ly, rx, ry, 0.5 - tf / 2);
4484
+ let rc = Utils7.Math.interpolateCoord(lx, ly, rx, ry, 0.5 + tf / 2);
4485
+ ctx.strokeLine(lx, ly, lc.x, lc.y);
4486
+ ctx.strokeLine(rc.x, rc.y, rx, ry);
4487
+ } else {
4488
+ ctx.strokeLine(lx, ly, rx, ry);
4459
4489
  }
4460
- } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TupletBeam */) {
4461
- let beamSeparation = DocumentSettings.BeamSeparation * unitSize * (this.stemDir === "up" /* Up */ ? 1 : -1);
4490
+ ctx.strokeLine(lx, ly, lx, ly + tipHeight);
4491
+ ctx.strokeLine(rx, ry, rx, ry + tipHeight);
4492
+ });
4493
+ } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4494
+ ctx.color(color).lineWidth(DocumentSettings.BeamThickness);
4495
+ this.staffObjects.forEach((obj) => {
4462
4496
  let noteGroupPoints = obj.points.filter((p) => p.symbol instanceof ObjNoteGroup);
4497
+ let { x: lx, y: ly } = noteGroupPoints[0];
4498
+ let { x: rx, y: ry } = noteGroupPoints[noteGroupPoints.length - 1];
4499
+ let beamSeparation = DocumentSettings.BeamSeparation * unitSize * (stemDir === "up" /* Up */ ? 1 : -1) * (1 + 0.5 * Math.abs(Math.atan2(ry - ly, rx - lx)));
4463
4500
  for (let i = 0; i < noteGroupPoints.length - 1; i++) {
4464
- let left = noteGroupPoints[i];
4465
- let right = noteGroupPoints[i + 1];
4466
- if (!(left.symbol instanceof ObjNoteGroup && right.symbol instanceof ObjNoteGroup)) {
4467
- continue;
4468
- }
4469
- let leftBeamCount = left.symbol.getRightBeamCount();
4470
- let rightBeamCount = right.symbol.getLeftBeamCount();
4471
- let lx = left.x;
4472
- let ly = left.y;
4473
- let rx = right.x;
4474
- let ry = right.y;
4475
- let dy = beamSeparation * (1 + 0.5 * Math.abs(Math.atan2(ry - ly, rx - lx)));
4501
+ let { x: lx2, y: ly2, symbol: lsymbol } = noteGroupPoints[i];
4502
+ let { x: rx2, y: ry2, symbol: rsymbol } = noteGroupPoints[i + 1];
4503
+ let leftBeamCount = lsymbol.getRightBeamCount();
4504
+ let rightBeamCount = rsymbol.getLeftBeamCount();
4476
4505
  for (let beamId = 0; beamId < Math.max(leftBeamCount, rightBeamCount); beamId++) {
4477
4506
  if (beamId < leftBeamCount && beamId < rightBeamCount) {
4478
- renderer.drawLine(lx, ly, rx, ry, color, beamThickness);
4507
+ ctx.strokeLine(lx2, ly2, rx2, ry2);
4479
4508
  } else if (leftBeamCount > rightBeamCount) {
4480
- renderer.drawPartialLine(lx, ly, rx, ry, 0, 0.25, color, beamThickness);
4509
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0, 0.25);
4481
4510
  } else if (rightBeamCount > leftBeamCount) {
4482
- renderer.drawPartialLine(lx, ly, rx, ry, 0.75, 1, color, beamThickness);
4511
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0.75, 1);
4483
4512
  }
4484
- ly += dy;
4485
- ry += dy;
4513
+ ly2 += beamSeparation;
4514
+ ry2 += beamSeparation;
4486
4515
  }
4487
4516
  }
4488
- }
4489
- if (obj.tupletNumber) {
4490
- obj.tupletNumber.draw(renderer);
4491
- }
4517
+ });
4518
+ }
4519
+ this.staffObjects.forEach((obj) => {
4520
+ var _a;
4521
+ return (_a = obj.tupletNumber) == null ? void 0 : _a.draw(ctx);
4492
4522
  });
4493
4523
  }
4494
4524
  setBeamCounts() {
@@ -4588,8 +4618,8 @@ var ObjFermata = class extends MusicObject {
4588
4618
  pick(x, y) {
4589
4619
  return this.rect.contains(x, y) ? [this] : [];
4590
4620
  }
4591
- layout(renderer) {
4592
- let { unitSize } = renderer;
4621
+ layout(ctx) {
4622
+ let { unitSize } = ctx;
4593
4623
  let width = unitSize * 4;
4594
4624
  let height = unitSize * 3;
4595
4625
  this.rect = new DivRect(-width / 2, width / 2, -height, 0);
@@ -4597,12 +4627,8 @@ var ObjFermata = class extends MusicObject {
4597
4627
  offset(dx, dy) {
4598
4628
  this.rect.offsetInPlace(dx, dy);
4599
4629
  }
4600
- draw(renderer) {
4601
- let ctx = renderer.getCanvasContext();
4602
- if (!ctx) {
4603
- return;
4604
- }
4605
- let { lineWidth, unitSize } = renderer;
4630
+ draw(ctx) {
4631
+ let { unitSize } = ctx;
4606
4632
  let upsideDown = this.pos === 1 /* Below */;
4607
4633
  let dy = (upsideDown ? unitSize : -unitSize) * 0.7;
4608
4634
  let left = this.rect.left;
@@ -4610,9 +4636,8 @@ var ObjFermata = class extends MusicObject {
4610
4636
  let top = (upsideDown ? this.rect.bottom : this.rect.top) + dy;
4611
4637
  let bottom = (upsideDown ? this.rect.top : this.rect.bottom) + dy;
4612
4638
  let height = bottom - top;
4613
- renderer.drawDebugRect(this.rect);
4614
- ctx.strokeStyle = ctx.fillStyle = this.color;
4615
- ctx.lineWidth = lineWidth;
4639
+ ctx.drawDebugRect(this.rect);
4640
+ ctx.color("black").lineWidth(1);
4616
4641
  ctx.beginPath();
4617
4642
  ctx.moveTo(left, bottom);
4618
4643
  ctx.bezierCurveTo(left, top, right, top, right, bottom);
@@ -4620,7 +4645,7 @@ var ObjFermata = class extends MusicObject {
4620
4645
  ctx.stroke();
4621
4646
  ctx.fill();
4622
4647
  let r = height / 6;
4623
- renderer.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
4648
+ ctx.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
4624
4649
  }
4625
4650
  };
4626
4651
 
@@ -4663,8 +4688,8 @@ var ObjExtensionLine = class extends MusicObject {
4663
4688
  return this.rightObj.getRect().centerX;
4664
4689
  }
4665
4690
  }
4666
- layoutFitToMeasure(renderer) {
4667
- let { unitSize } = renderer;
4691
+ layoutFitToMeasure(ctx) {
4692
+ let { unitSize } = ctx;
4668
4693
  let lineLeft = this.getLineLeft();
4669
4694
  let lineRight = this.getLineRight();
4670
4695
  let lineRectH = unitSize;
@@ -4673,27 +4698,24 @@ var ObjExtensionLine = class extends MusicObject {
4673
4698
  pick(x, y) {
4674
4699
  return this.rect.contains(x, y) ? [this] : [];
4675
4700
  }
4676
- layout(renderer) {
4701
+ layout(ctx) {
4677
4702
  this.rect = new DivRect();
4678
4703
  }
4679
4704
  offset(dx, dy) {
4680
4705
  this.rect.offsetInPlace(dx, dy);
4681
4706
  }
4682
- draw(renderer) {
4683
- let ctx = renderer.getCanvasContext();
4684
- if (!ctx) {
4685
- return;
4686
- }
4707
+ draw(ctx) {
4687
4708
  let { rect } = this;
4688
4709
  if (this.extension.getLineStyle() === "dashed") {
4689
4710
  ctx.setLineDash([7, 3]);
4690
4711
  }
4691
- renderer.drawLine(rect.left, rect.centerY, rect.right, rect.centerY, "black", renderer.lineWidth);
4712
+ ctx.color("black").lineWidth(1);
4713
+ ctx.strokeLine(rect.left, rect.centerY, rect.right, rect.centerY);
4692
4714
  ctx.setLineDash([]);
4693
4715
  let tails = this.extension.getTails();
4694
4716
  if (tails.length > 0 && this === tails[tails.length - 1]) {
4695
- let tipH = rect.centerY > this.line.getRect().centerY ? -renderer.unitSize : renderer.unitSize;
4696
- renderer.drawLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH, "black", renderer.lineWidth);
4717
+ let tipH = rect.centerY > this.line.getRect().centerY ? -ctx.unitSize : ctx.unitSize;
4718
+ ctx.strokeLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH);
4697
4719
  }
4698
4720
  }
4699
4721
  };
@@ -4705,13 +4727,13 @@ import { MusicError as MusicError13, MusicErrorType as MusicErrorType13 } from "
4705
4727
  import { Note as Note6 } from "@tspro/web-music-score/theory";
4706
4728
 
4707
4729
  // src/score/engine/obj-connective.ts
4708
- import { Utils as Utils9 } from "@tspro/ts-utils-lib";
4730
+ import { Utils as Utils8 } from "@tspro/ts-utils-lib";
4709
4731
  import { MusicError as MusicError11, MusicErrorType as MusicErrorType11 } from "@tspro/web-music-score/core";
4710
4732
  var ObjConnective = class extends MusicObject {
4711
4733
  constructor(connectiveProps, line, measure, leftNoteGroup, leftNoteId, ...args) {
4734
+ var _a;
4712
4735
  super(measure);
4713
4736
  this.connectiveProps = connectiveProps;
4714
- this.line = line;
4715
4737
  this.measure = measure;
4716
4738
  __publicField(this, "lx", 0);
4717
4739
  __publicField(this, "ly", 0);
@@ -4722,19 +4744,21 @@ var ObjConnective = class extends MusicObject {
4722
4744
  __publicField(this, "cp2x", 0);
4723
4745
  __publicField(this, "cp2y", 0);
4724
4746
  __publicField(this, "arcHeight", 0);
4747
+ __publicField(this, "line");
4725
4748
  __publicField(this, "leftNoteGroup");
4726
4749
  __publicField(this, "leftNoteId");
4727
4750
  __publicField(this, "rightNoteGroup");
4728
4751
  __publicField(this, "rightNoteId");
4729
4752
  __publicField(this, "tieType");
4730
4753
  __publicField(this, "mi");
4754
+ this.line = (_a = this.measure.row.findMatchingLine(line)) != null ? _a : line;
4731
4755
  this.leftNoteGroup = leftNoteGroup;
4732
4756
  this.leftNoteId = leftNoteId;
4733
4757
  if (args[0] instanceof ObjNoteGroup && typeof args[1] === "number") {
4734
4758
  this.rightNoteGroup = args[0];
4735
4759
  this.rightNoteId = args[1];
4736
4760
  this.tieType = void 0;
4737
- } else if (Utils9.Is.isEnumValue(args[0], TieType)) {
4761
+ } else if (Utils8.Is.isEnumValue(args[0], TieType)) {
4738
4762
  this.rightNoteGroup = void 0;
4739
4763
  this.rightNoteId = void 0;
4740
4764
  this.tieType = args[0];
@@ -4751,8 +4775,8 @@ var ObjConnective = class extends MusicObject {
4751
4775
  pick(x, y) {
4752
4776
  return this.rect.contains(x, y) ? [this] : [];
4753
4777
  }
4754
- layout(renderer) {
4755
- let { unitSize } = renderer;
4778
+ layout(ctx) {
4779
+ let { unitSize } = ctx;
4756
4780
  let { measure, line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId, connectiveProps } = this;
4757
4781
  let { noteAnchor, arcDir } = connectiveProps;
4758
4782
  let { row } = measure;
@@ -4804,7 +4828,7 @@ var ObjConnective = class extends MusicObject {
4804
4828
  this.rx = rx;
4805
4829
  this.ry = ry;
4806
4830
  this.arcHeight = this.connectiveProps.connective === "slide" /* Slide */ ? 0 : arcHeight;
4807
- let { nx, ny } = Utils9.Math.calcNormal(lx, ly, rx, ry);
4831
+ let { nx, ny } = Utils8.Math.calcNormal(lx, ly, rx, ry);
4808
4832
  this.cp1x = lx * 0.7 + rx * 0.3 + nx * this.arcHeight;
4809
4833
  this.cp1y = ly * 0.7 + ry * 0.3 + ny * this.arcHeight;
4810
4834
  this.cp2x = lx * 0.3 + rx * 0.7 + nx * this.arcHeight;
@@ -4828,11 +4852,7 @@ var ObjConnective = class extends MusicObject {
4828
4852
  this.cp2y += dy;
4829
4853
  this.rect.offsetInPlace(dx, dy);
4830
4854
  }
4831
- draw(renderer) {
4832
- let ctx = renderer.getCanvasContext();
4833
- if (!ctx) {
4834
- return;
4835
- }
4855
+ draw(ctx) {
4836
4856
  if (this.rightNoteGroup === void 0) {
4837
4857
  } else if (this.leftNoteGroup.measure === this.rightNoteGroup.measure) {
4838
4858
  } else if (this.leftNoteGroup.row.getNextRow() === this.rightNoteGroup.row) {
@@ -4841,12 +4861,11 @@ var ObjConnective = class extends MusicObject {
4841
4861
  return;
4842
4862
  }
4843
4863
  let { rect } = this;
4844
- let { lineWidth } = renderer;
4845
- renderer.drawDebugRect(rect);
4846
- let t = lineWidth * 1.5;
4847
- let s = lineWidth * 0.25;
4848
- ctx.strokeStyle = ctx.fillStyle = "black";
4849
- ctx.lineWidth = lineWidth;
4864
+ let { _lineWidth } = ctx;
4865
+ ctx.drawDebugRect(rect);
4866
+ let t = _lineWidth * 1.5;
4867
+ let s = _lineWidth * 0.25;
4868
+ ctx.color("black").lineWidth(1);
4850
4869
  if (this.arcHeight === 0) {
4851
4870
  ctx.beginPath();
4852
4871
  ctx.moveTo(this.lx, this.ly);
@@ -4865,7 +4884,7 @@ var ObjConnective = class extends MusicObject {
4865
4884
 
4866
4885
  // src/score/engine/connective-props.ts
4867
4886
  import { MusicError as MusicError12, MusicErrorType as MusicErrorType12 } from "@tspro/web-music-score/core";
4868
- import { Utils as Utils10 } from "@tspro/ts-utils-lib";
4887
+ import { Utils as Utils9 } from "@tspro/ts-utils-lib";
4869
4888
  var ConnectiveProps = class {
4870
4889
  constructor(connective, span, noteAnchor, startNoteGroup) {
4871
4890
  this.connective = connective;
@@ -4896,7 +4915,7 @@ var ConnectiveProps = class {
4896
4915
  return false;
4897
4916
  }
4898
4917
  }
4899
- computeParams() {
4918
+ computeParams(line) {
4900
4919
  let { stemDir } = this.noteGroups[0];
4901
4920
  let { hasStem } = this.noteGroups[0].rhythmProps;
4902
4921
  if (this.noteAnchor === "stemTip" /* StemTip */) {
@@ -4913,9 +4932,8 @@ var ConnectiveProps = class {
4913
4932
  this.noteAnchor = "below" /* Below */;
4914
4933
  }
4915
4934
  } else if (this.noteAnchor === "center" /* Center */) {
4916
- let { row } = this.noteGroups[0].measure;
4917
- let diatonicId = this.noteGroups[0].ownDiatonicId;
4918
- let staff = row.getStaff(diatonicId);
4935
+ let staff = line instanceof ObjStaff ? line : void 0;
4936
+ let diatonicId = this.noteGroups[0].getDiatonicId(staff);
4919
4937
  this.arcDir = !staff || diatonicId < staff.middleLineDiatonicId ? "down" : "up";
4920
4938
  } else if (this.noteAnchor === "above" /* Above */) {
4921
4939
  this.arcDir = "up";
@@ -4931,68 +4949,73 @@ var ConnectiveProps = class {
4931
4949
  this.noteGroups.length = 1;
4932
4950
  }
4933
4951
  createConnectives() {
4952
+ if (this.noteGroups.length === 0) {
4953
+ return;
4954
+ }
4934
4955
  this.getStartNoteGroup().collectConnectiveProps();
4935
- this.computeParams();
4936
4956
  let { connective, span } = this;
4937
- if (connective === "tie" /* Tie */) {
4938
- if (Utils10.Is.isEnumValue(span, TieType)) {
4939
- let leftNoteGroup = this.noteGroups[0];
4940
- for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
4941
- this.createObjConnectiveWithTieType(leftNoteGroup, noteId, span);
4957
+ this.noteGroups[0].row.getNotationLines().forEach((line) => {
4958
+ this.computeParams(line);
4959
+ if (connective === "tie" /* Tie */) {
4960
+ if (Utils9.Is.isEnumValue(span, TieType)) {
4961
+ let leftNoteGroup = this.noteGroups[0];
4962
+ for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
4963
+ this.createObjConnectiveWithTieType(line, leftNoteGroup, noteId, span);
4964
+ }
4965
+ } else if (this.noteGroups.length >= 2) {
4966
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
4967
+ let leftNoteGroup = this.noteGroups[i];
4968
+ let rightNoteGroup = this.noteGroups[i + 1];
4969
+ leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
4970
+ let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => Note6.equals(rightNote, leftNote));
4971
+ if (rightNoteId >= 0) {
4972
+ this.createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
4973
+ }
4974
+ });
4975
+ }
4942
4976
  }
4943
- } else if (this.noteGroups.length >= 2) {
4944
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
4945
- let leftNoteGroup = this.noteGroups[i];
4946
- let rightNoteGroup = this.noteGroups[i + 1];
4947
- leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
4948
- let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => Note6.equals(rightNote, leftNote));
4949
- if (rightNoteId >= 0) {
4950
- this.createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
4951
- }
4952
- });
4977
+ } else if (connective === "slur" /* Slur */) {
4978
+ if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
4979
+ let leftNoteGroup = this.noteGroups[0];
4980
+ let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
4981
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
4953
4982
  }
4954
- }
4955
- } else if (connective === "slur" /* Slur */) {
4956
- if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
4957
- let leftNoteGroup = this.noteGroups[0];
4958
- let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
4959
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
4960
- }
4961
- } else if (connective === "slide" /* Slide */) {
4962
- if (this.noteGroups.length >= 2) {
4963
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
4964
- let leftNoteGroup = this.noteGroups[i];
4965
- let rightNoteGroup = this.noteGroups[i + 1];
4966
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
4983
+ } else if (connective === "slide" /* Slide */) {
4984
+ if (this.noteGroups.length >= 2) {
4985
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
4986
+ let leftNoteGroup = this.noteGroups[i];
4987
+ let rightNoteGroup = this.noteGroups[i + 1];
4988
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
4989
+ }
4967
4990
  }
4968
4991
  }
4969
- }
4992
+ });
4970
4993
  }
4971
- createObjConnectiveWithTieType(leftNoteGroup, leftNoteId, tieType) {
4972
- leftNoteGroup.row.getNotationLines().filter((line) => leftNoteGroup.enableConnective(line)).forEach((line) => {
4973
- if (line instanceof ObjStaff) {
4994
+ createObjConnectiveWithTieType(line, leftNoteGroup, leftNoteId, tieType) {
4995
+ if (!leftNoteGroup.enableConnective(line)) {
4996
+ return;
4997
+ } else if (line instanceof ObjStaff) {
4998
+ new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
4999
+ } else if (line instanceof ObjTab) {
5000
+ let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
5001
+ if (leftString !== void 0) {
4974
5002
  new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
4975
- } else {
4976
- let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
4977
- if (leftString !== void 0) {
4978
- new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
4979
- }
4980
5003
  }
4981
- });
5004
+ }
4982
5005
  }
4983
- createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
5006
+ createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
4984
5007
  const addConnective = (measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2) => {
4985
- measure.row.getNotationLines().filter((line) => leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line)).forEach((line) => {
4986
- if (line instanceof ObjStaff) {
5008
+ if (!(leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line))) {
5009
+ return;
5010
+ } else if (line instanceof ObjStaff) {
5011
+ new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5012
+ } else if (line instanceof ObjTab) {
5013
+ let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
5014
+ let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
5015
+ if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
4987
5016
  new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
4988
- } else {
4989
- let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
4990
- let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
4991
- if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
4992
- new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
4993
- }
4994
5017
  }
4995
- });
5018
+ }
4996
5019
  };
4997
5020
  if (leftNoteGroup.measure === rightNoteGroup.measure) {
4998
5021
  addConnective(leftNoteGroup.measure, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
@@ -5005,6 +5028,72 @@ var ConnectiveProps = class {
5005
5028
  }
5006
5029
  };
5007
5030
 
5031
+ // src/score/engine/obj-lyrics.ts
5032
+ import { Utils as Utils10 } from "@tspro/ts-utils-lib";
5033
+ var ObjLyrics = class extends MusicObject {
5034
+ constructor(col, verse, line, vpos, lyricsLength, lyricsText, lyricsOptions) {
5035
+ super(col);
5036
+ this.col = col;
5037
+ this.verse = verse;
5038
+ this.line = line;
5039
+ this.vpos = vpos;
5040
+ __publicField(this, "nextLyricsObject");
5041
+ __publicField(this, "rhythmProps");
5042
+ __publicField(this, "color", "black");
5043
+ __publicField(this, "hyphen");
5044
+ __publicField(this, "text");
5045
+ __publicField(this, "mi");
5046
+ this.rhythmProps = RhythmProps.get(lyricsLength);
5047
+ let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
5048
+ this.hyphen = Utils10.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
5049
+ this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
5050
+ this.rect = new DivRect();
5051
+ this.mi = new MLyrics(this);
5052
+ }
5053
+ getMusicInterface() {
5054
+ return this.mi;
5055
+ }
5056
+ get measure() {
5057
+ return this.col.measure;
5058
+ }
5059
+ getText() {
5060
+ return this.text.getText();
5061
+ }
5062
+ setNextLyricsObject(lyricsObj) {
5063
+ this.nextLyricsObject = lyricsObj;
5064
+ }
5065
+ pick(x, y) {
5066
+ return this.rect.contains(x, y) ? [this] : [];
5067
+ }
5068
+ layout(ctx) {
5069
+ this.text.layout(ctx);
5070
+ this.rect = this.text.getRect().copy();
5071
+ }
5072
+ offset(dx, dy) {
5073
+ this.text.offset(dx, dy);
5074
+ this.rect.offsetInPlace(dx, dy);
5075
+ }
5076
+ draw(ctx) {
5077
+ var _a;
5078
+ this.text.draw(ctx);
5079
+ if (this.hyphen !== void 0) {
5080
+ ctx.color(this.color).lineWidth(1);
5081
+ let l = this.getRect();
5082
+ let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
5083
+ let hyphenw = ctx.unitSize * 1.5;
5084
+ let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
5085
+ let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
5086
+ if (w > 0) {
5087
+ let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
5088
+ let cy = (l.top + l.bottom) / 2;
5089
+ ctx.moveTo(cx - w / 2, cy);
5090
+ ctx.lineTo(cx + w / 2, cy);
5091
+ ctx.stroke();
5092
+ }
5093
+ }
5094
+ }
5095
+ };
5096
+
5008
5097
  // src/score/engine/obj-tab-rhythm.ts
5009
5098
  import { Utils as Utils11 } from "@tspro/ts-utils-lib";
5010
5099
  var ObjTabRhythm = class extends MusicObject {
@@ -5012,11 +5101,11 @@ var ObjTabRhythm = class extends MusicObject {
5012
5101
  super(measure);
5013
5102
  this.measure = measure;
5014
5103
  this.tab = tab;
5015
- __publicField(this, "voiceIds");
5104
+ __publicField(this, "voiceId");
5016
5105
  __publicField(this, "mi");
5017
5106
  // Keep non-static
5018
5107
  __publicField(this, "tupletPartsTextObjMap", /* @__PURE__ */ new Map());
5019
- this.voiceIds = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5108
+ this.voiceId = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5020
5109
  this.rect = new DivRect();
5021
5110
  this.mi = new MTabRhythm(this);
5022
5111
  }
@@ -5026,17 +5115,17 @@ var ObjTabRhythm = class extends MusicObject {
5026
5115
  pick(x, y) {
5027
5116
  return this.rect.contains(x, y) ? [this] : [];
5028
5117
  }
5029
- layout(renderer) {
5118
+ layout(ctx) {
5030
5119
  let columns = this.measure.getColumns();
5031
5120
  let numColsInVoiceId = getVoiceIds().map((voiceId) => Utils11.Math.sum(columns.map((col) => col.getVoiceSymbol(voiceId) ? 1 : 0)));
5032
- this.voiceIds.sort((a, b) => Utils11.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5121
+ this.voiceId.sort((a, b) => Utils11.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5033
5122
  this.rect = new DivRect();
5034
5123
  }
5035
5124
  hasTuplets() {
5036
5125
  return this.measure.getBeamGroups().some((beamGroup) => beamGroup.isTuplet());
5037
5126
  }
5038
- layoutFitToMeasure(renderer) {
5039
- let { unitSize, fontSize } = renderer;
5127
+ layoutFitToMeasure(ctx) {
5128
+ let { unitSize, fontSize } = ctx;
5040
5129
  let { measure } = this;
5041
5130
  let { left, right } = measure.getColumnsContentRect();
5042
5131
  let stemHeight = unitSize * 5;
@@ -5050,13 +5139,10 @@ var ObjTabRhythm = class extends MusicObject {
5050
5139
  offset(dx, dy) {
5051
5140
  this.rect.offsetInPlace(dx, dy);
5052
5141
  }
5053
- draw(renderer) {
5054
- const ctx = renderer.getCanvasContext();
5055
- if (!ctx) {
5056
- return;
5057
- }
5058
- renderer.drawDebugRect(this.rect);
5059
- let { unitSize, lineWidth, fontSize } = renderer;
5142
+ draw(ctx) {
5143
+ ctx.drawDebugRect(this.rect);
5144
+ ctx.color("black").lineWidth(1);
5145
+ let { unitSize, fontSize } = ctx;
5060
5146
  let flagSize = unitSize;
5061
5147
  let dotSpace = unitSize;
5062
5148
  let dotWidth = unitSize * 0.25;
@@ -5066,7 +5152,7 @@ var ObjTabRhythm = class extends MusicObject {
5066
5152
  let columns = this.measure.getColumns();
5067
5153
  for (let colId = 0; colId < columns.length; colId++) {
5068
5154
  let cur = columns[colId];
5069
- let curVoiceSymbol = this.voiceIds.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5155
+ let curVoiceSymbol = this.voiceId.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5070
5156
  if (!curVoiceSymbol) {
5071
5157
  continue;
5072
5158
  }
@@ -5078,16 +5164,17 @@ var ObjTabRhythm = class extends MusicObject {
5078
5164
  let colX = sym.col.getRect().centerX;
5079
5165
  if (sym instanceof ObjNoteGroup) {
5080
5166
  if (sym.rhythmProps.noteSize >= 2) {
5081
- let stemThickness = sym.rhythmProps.noteSize === 4 ? lineWidth * 2 : lineWidth;
5082
- renderer.drawLine(colX, stemBottom, colX, stemTop, "black", stemThickness);
5167
+ ctx.lineWidth(sym.rhythmProps.noteSize === 4 ? 2 : 1);
5168
+ ctx.strokeLine(colX, stemBottom, colX, stemTop);
5083
5169
  }
5170
+ ctx.lineWidth(1);
5084
5171
  if (symbols.length === 1) {
5085
5172
  for (let i = 0; i < sym.rhythmProps.flagCount; i++) {
5086
- renderer.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5173
+ ctx.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5087
5174
  }
5088
5175
  }
5089
5176
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5090
- renderer.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5177
+ ctx.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5091
5178
  }
5092
5179
  } else if (sym instanceof ObjRest) {
5093
5180
  let cx = colX;
@@ -5095,11 +5182,11 @@ var ObjTabRhythm = class extends MusicObject {
5095
5182
  let scale = 0.65;
5096
5183
  ctx.save();
5097
5184
  ctx.scale(scale, scale);
5098
- renderer.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale, "black");
5185
+ ctx.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale);
5099
5186
  ctx.restore();
5100
5187
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5101
5188
  cx += dotSpace * 1.5;
5102
- renderer.fillCircle(cx, cy + dotSpace, dotWidth);
5189
+ ctx.fillCircle(cx, cy + dotSpace, dotWidth);
5103
5190
  }
5104
5191
  }
5105
5192
  if (nextSym) {
@@ -5110,16 +5197,18 @@ var ObjTabRhythm = class extends MusicObject {
5110
5197
  let leftBeamCount = left.hasTuplet() ? 1 : left instanceof ObjNoteGroup ? left.getRightBeamCount() : 1;
5111
5198
  let rightBeamCount = right.hasTuplet() ? 1 : right instanceof ObjNoteGroup ? right.getLeftBeamCount() : 1;
5112
5199
  let maxBeamCount = Math.max(leftBeamCount, rightBeamCount);
5200
+ ctx.lineWidth(2);
5113
5201
  for (let i = 0; i < maxBeamCount; i++) {
5114
5202
  let leftT = rightBeamCount > leftBeamCount && i >= leftBeamCount ? 0.75 : 0;
5115
5203
  let rightT = leftBeamCount > rightBeamCount && i >= rightBeamCount ? 0.25 : 1;
5116
- renderer.drawPartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT, "black", lineWidth * 2);
5204
+ ctx.strokePartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT);
5117
5205
  }
5206
+ ctx.lineWidth(1);
5118
5207
  for (let i = 0; i < left.rhythmProps.dotCount; i++) {
5119
- renderer.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5208
+ ctx.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5120
5209
  }
5121
5210
  for (let i = 0; i < right.rhythmProps.dotCount; i++) {
5122
- renderer.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5211
+ ctx.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5123
5212
  }
5124
5213
  }
5125
5214
  if (beamGroup && beamGroup.isTuplet()) {
@@ -5128,11 +5217,11 @@ var ObjTabRhythm = class extends MusicObject {
5128
5217
  let textObj = this.tupletPartsTextObjMap.get(text);
5129
5218
  if (!textObj) {
5130
5219
  this.tupletPartsTextObjMap.set(text, textObj = new ObjText(this, { text, scale: 0.75 }, 0.5, 0.5));
5131
- textObj.layout(renderer);
5220
+ textObj.layout(ctx);
5132
5221
  }
5133
5222
  textObj.offset(-textObj.getRect().centerX, -textObj.getRect().centerY);
5134
5223
  textObj.offset(cx, stemTop - fontSize / 2);
5135
- textObj.draw(renderer);
5224
+ textObj.draw(ctx);
5136
5225
  }
5137
5226
  if (symbols.length > 1) {
5138
5227
  colId = columns.indexOf(symbols[symbols.length - 1].col);
@@ -5192,9 +5281,10 @@ function getVerseLayoutGroupId(verse) {
5192
5281
  }
5193
5282
  }
5194
5283
  var _ObjMeasure = class _ObjMeasure extends MusicObject {
5195
- constructor(row) {
5284
+ constructor(row, options) {
5196
5285
  super(row);
5197
5286
  this.row = row;
5287
+ this.options = options;
5198
5288
  __publicField(this, "prevMeasure");
5199
5289
  __publicField(this, "nextMeasure");
5200
5290
  __publicField(this, "keySignature", getDefaultKeySignature());
@@ -5216,9 +5306,6 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5216
5306
  __publicField(this, "leftSolidAreaWidth", 0);
5217
5307
  __publicField(this, "minColumnsAreaWidth", 0);
5218
5308
  __publicField(this, "rightSolidAreaWidth", 0);
5219
- __publicField(this, "useDiatonicId", []);
5220
- __publicField(this, "useStemDir", []);
5221
- __publicField(this, "useString", []);
5222
5309
  __publicField(this, "voiceSymbols", []);
5223
5310
  __publicField(this, "lastAddedRhythmColumn");
5224
5311
  __publicField(this, "lastAddedRhythmSymbol");
@@ -5235,7 +5322,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5235
5322
  // play twice.
5236
5323
  __publicField(this, "endRepeatPlayCountText");
5237
5324
  __publicField(this, "staticObjectsCache", /* @__PURE__ */ new Map());
5238
- __publicField(this, "lyricsObjectsCache", /* @__PURE__ */ new Map());
5325
+ __publicField(this, "lyricsObjectsCache", new Map32());
5239
5326
  __publicField(this, "mi");
5240
5327
  this.mi = new MMeasure(this);
5241
5328
  this.prevMeasure = row.doc.getLastMeasure();
@@ -5273,54 +5360,67 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5273
5360
  getPassCount() {
5274
5361
  return this.passCount;
5275
5362
  }
5276
- updateOwnDiatonicId(voiceId, setDiatonicId) {
5277
- if (typeof setDiatonicId == "number") {
5278
- this.useDiatonicId[voiceId] = setDiatonicId;
5279
- } else if (this.useDiatonicId[voiceId] === void 0) {
5280
- let prevMeasure = this.getPrevMeasure();
5281
- if (prevMeasure && prevMeasure.useDiatonicId[voiceId] !== void 0) {
5282
- this.useDiatonicId[voiceId] = prevMeasure.useDiatonicId[voiceId];
5283
- }
5284
- }
5285
- let diatonicId = this.useDiatonicId[voiceId];
5286
- if (diatonicId === void 0) {
5287
- if (this.row.hasStaff) {
5288
- diatonicId = this.row.getTopStaff().middleLineDiatonicId;
5289
- } else {
5290
- diatonicId = Note7.getNote("C4").diatonicId;
5291
- }
5292
- }
5293
- return this.useDiatonicId[voiceId] = Note7.validateDiatonicId(diatonicId);
5294
- }
5295
- updateOwnStemDir(symbol, setStemDir) {
5296
- var _a, _b;
5297
- let { voiceId } = symbol;
5298
- if (setStemDir !== void 0) {
5299
- this.useStemDir[voiceId] = setStemDir;
5300
- } else if (this.useStemDir[voiceId] === void 0) {
5301
- this.useStemDir[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useStemDir[voiceId]) != null ? _b : "auto" /* Auto */;
5302
- }
5303
- let stemDir = this.useStemDir[voiceId];
5304
- if (stemDir === "auto" /* Auto */ || stemDir === void 0) {
5305
- let staff = this.row.getStaff(symbol.ownDiatonicId);
5306
- if (staff) {
5307
- return symbol.ownDiatonicId > staff.middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */;
5308
- } else {
5309
- return "up" /* Up */;
5310
- }
5311
- } else {
5312
- return stemDir;
5313
- }
5314
- }
5315
- updateOwnString(symbol, setString) {
5316
- var _a, _b;
5317
- let { voiceId } = symbol;
5318
- if (setString !== void 0) {
5319
- this.useString[voiceId] = setString;
5320
- } else if (this.useString[voiceId] === void 0) {
5321
- this.useString[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useString[voiceId]) != null ? _b : [];
5322
- }
5323
- return this.useString[voiceId];
5363
+ updateRunningArguments(runningArgs) {
5364
+ var _a;
5365
+ runningArgs != null ? runningArgs : runningArgs = [];
5366
+ let numVoices = Utils12.Math.sum(getVoiceIds().map((voiceId) => this.getVoiceSymbols(voiceId).length > 0 ? 1 : 0));
5367
+ getVoiceIds().forEach((voiceId) => {
5368
+ var _a2;
5369
+ const getDefaultDiatonicId = () => {
5370
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(voiceId));
5371
+ let tabs = this.row.getTabs().filter((tab) => tab.containsVoiceId(voiceId));
5372
+ return staves.length > 0 ? staves[0].middleLineDiatonicId : tabs.length > 0 ? tabs[0].getTuningStrings()[3].diatonicId : Note7.getNote("G4").diatonicId;
5373
+ };
5374
+ const getDefaultStemDir = () => "auto" /* Auto */;
5375
+ const getDefaultStringNumbers = () => [];
5376
+ let args = (_a2 = runningArgs[voiceId]) != null ? _a2 : runningArgs[voiceId] = {
5377
+ diatonicId: getDefaultDiatonicId(),
5378
+ stemDir: getDefaultStemDir(),
5379
+ stringNumbers: getDefaultStringNumbers()
5380
+ };
5381
+ this.getVoiceSymbols(voiceId).forEach((sym, symId, symArr) => {
5382
+ var _a3, _b;
5383
+ if (sym.setDiatonicId === ObjRest.UndefinedDiatonicId) {
5384
+ if (numVoices < 2) {
5385
+ args.diatonicId = ObjRest.UndefinedDiatonicId;
5386
+ }
5387
+ } else {
5388
+ args.diatonicId = sym.setDiatonicId;
5389
+ }
5390
+ if (sym instanceof ObjNoteGroup) {
5391
+ if (sym.setStringsNumbers) {
5392
+ args.stringNumbers = sym.setStringsNumbers;
5393
+ }
5394
+ switch ((_a3 = sym.options) == null ? void 0 : _a3.stem) {
5395
+ case "up" /* Up */:
5396
+ case "up":
5397
+ args.stemDir = "up" /* Up */;
5398
+ break;
5399
+ case "down" /* Down */:
5400
+ case "down":
5401
+ args.stemDir = "down" /* Down */;
5402
+ break;
5403
+ case "auto" /* Auto */:
5404
+ case "auto":
5405
+ args.stemDir = "auto" /* Auto */;
5406
+ break;
5407
+ }
5408
+ }
5409
+ let beamSymbols = (_b = sym.getBeamGroup()) == null ? void 0 : _b.getSymbols();
5410
+ let setStemDir;
5411
+ if (beamSymbols === void 0) {
5412
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir([sym]) : args.stemDir;
5413
+ } else {
5414
+ if (sym === beamSymbols[0]) {
5415
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir(beamSymbols) : args.stemDir;
5416
+ } else {
5417
+ setStemDir = beamSymbols[0].stemDir;
5418
+ }
5419
+ }
5420
+ sym.updateRunningArguments(args.diatonicId, setStemDir, args.stringNumbers);
5421
+ });
5422
+ });
5423
+ (_a = this.getNextMeasure()) == null ? void 0 : _a.updateRunningArguments(runningArgs);
5324
5424
  }
5325
5425
  pick(x, y) {
5326
5426
  if (!this.getRect().contains(x, y)) {
@@ -5477,7 +5577,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5477
5577
  } else {
5478
5578
  let dotCount = typeof dotted === "number" && dotted > 0 ? dotted : dotted === true ? 1 : NoteLengthProps5.get(beatLength).dotCount;
5479
5579
  let options = {
5480
- beatLength: validateNoteLength3(beatLength),
5580
+ beatLength: validateNoteLength2(beatLength),
5481
5581
  dotCount: dotCount > 0 ? dotCount : void 0
5482
5582
  };
5483
5583
  this.alterTempo = { beatsPerMinute, options };
@@ -5821,16 +5921,15 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5821
5921
  }
5822
5922
  addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions) {
5823
5923
  this.forEachStaffGroup(staffTabOrGroups, 1 /* Below */, (line, vpos) => {
5924
+ var _a;
5824
5925
  let col = this.getRhythmColumn({ verse, line, vpos });
5825
- let lyricsContainer = col.getLyricsContainer(verse, line, vpos, validateNoteLength3(lyricsLength));
5826
- if (lyricsContainer) {
5827
- let lyricsObj = new ObjLyrics(col, verse, line, vpos, lyricsText, lyricsOptions);
5828
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
5829
- lyricsArr.push(lyricsObj);
5830
- lyricsArr.sort((a, b) => Utils12.Math.cmp(a.col.positionTicks, b.col.positionTicks));
5831
- lyricsContainer.addLyricsObject(lyricsObj);
5832
- this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
5833
- }
5926
+ let lyricsObj = new ObjLyrics(col, verse, line, vpos, validateNoteLength2(lyricsLength), lyricsText, lyricsOptions);
5927
+ col.addLyricsObject(lyricsObj);
5928
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
5929
+ lyricsArr.push(lyricsObj);
5930
+ lyricsArr.sort((a, b) => Utils12.Math.cmp(a.col.positionTicks, b.col.positionTicks));
5931
+ (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
5932
+ this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
5834
5933
  this.lastAddedRhythmColumn = col;
5835
5934
  });
5836
5935
  }
@@ -5843,7 +5942,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5843
5942
  let positionTicks = 0;
5844
5943
  for (let i = this.columns.length - 1; i >= 0 && positionTicks === 0; i--) {
5845
5944
  let col = this.columns[i];
5846
- let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsContainer(arg.verse, arg.line, arg.vpos);
5945
+ let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsObject(arg.verse, arg.line, arg.vpos);
5847
5946
  if (symbol) {
5848
5947
  positionTicks = col.positionTicks + symbol.rhythmProps.ticks;
5849
5948
  }
@@ -5911,31 +6010,21 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5911
6010
  return this.barLineRight.getRect().centerX;
5912
6011
  }
5913
6012
  getLyricsObjects(line, vpos, verse) {
5914
- let vposMap = this.lyricsObjectsCache.get(line);
5915
- if (vposMap === void 0) {
5916
- vposMap = /* @__PURE__ */ new Map();
5917
- this.lyricsObjectsCache.set(line, vposMap);
5918
- }
5919
- let verseMap = vposMap.get(vpos);
5920
- if (verseMap === void 0) {
5921
- verseMap = /* @__PURE__ */ new Map();
5922
- vposMap.set(vpos, verseMap);
5923
- }
5924
- let lyricsArr = verseMap.get(verse);
5925
- if (lyricsArr === void 0) {
5926
- lyricsArr = [];
5927
- verseMap.set(verse, lyricsArr);
6013
+ let lyricsObjs = this.lyricsObjectsCache.get(line, vpos, verse);
6014
+ if (!lyricsObjs) {
6015
+ this.lyricsObjectsCache.set(line, vpos, verse, lyricsObjs = []);
5928
6016
  }
5929
- return lyricsArr;
6017
+ return lyricsObjs;
5930
6018
  }
5931
6019
  getPrevLyricsObject(lyricsObj) {
5932
6020
  var _a;
5933
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6021
+ let { line, verse, vpos } = lyricsObj;
6022
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
5934
6023
  let i = lyricsArr.indexOf(lyricsObj);
5935
6024
  if (i > 0) {
5936
6025
  return lyricsArr[i - 1];
5937
6026
  } else if (i === 0) {
5938
- let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6027
+ let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(line, vpos, verse);
5939
6028
  if (lyricsArr2 && lyricsArr2.length > 0) {
5940
6029
  return lyricsArr2[lyricsArr2.length - 1];
5941
6030
  }
@@ -6051,22 +6140,24 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6051
6140
  if (beamGroupSize.length > 1) {
6052
6141
  beamGroupSizeList.unshift([Utils12.Math.sum(beamGroupSize)]);
6053
6142
  }
6054
- let beamsCreated = false;
6143
+ let beamCreated = false;
6055
6144
  let groupStartTicksSave = groupStartTicks;
6056
- while (beamGroupSizeList.length > 0 && !beamsCreated) {
6145
+ while (beamGroupSizeList.length > 0 && !beamCreated) {
6057
6146
  let beamGroupSize2 = beamGroupSizeList.shift();
6058
6147
  groupStartTicks = groupStartTicksSave;
6059
6148
  beamGroupSize2.forEach((beamGroupSize3) => {
6060
6149
  let beamGroupTicks = beamGroupSize3 * NoteLengthProps5.get("8n").ticks;
6150
+ let groupEndTicks = groupStartTicks + beamGroupTicks;
6061
6151
  let groupSymbols = symbols.filter((symbol) => {
6062
6152
  let symbolStartTicks = upBeatStartTicks + symbol.col.positionTicks;
6063
- let symbolTicks = symbol.rhythmProps.ticks;
6064
- return symbolStartTicks >= groupStartTicks && symbolStartTicks + symbolTicks <= groupStartTicks + beamGroupTicks;
6153
+ let symbolEndTicks = symbolStartTicks + symbol.rhythmProps.ticks;
6154
+ return symbolStartTicks >= groupStartTicks && symbolEndTicks <= groupEndTicks;
6065
6155
  });
6066
- let groupNotesTicks = Utils12.Math.sum(groupSymbols.map((sym) => sym.rhythmProps.ticks));
6067
- if (groupNotesTicks === beamGroupTicks && groupSymbols.every((n) => n instanceof ObjNoteGroup) && (groupSymbols.every((n) => n.rhythmProps.flagCount === 1) || beamGroupSizeList.length === 0)) {
6068
- ObjBeamGroup.createBeam(groupSymbols);
6069
- beamsCreated = true;
6156
+ let groupSymbolsTicks = Utils12.Math.sum(groupSymbols.map((sym) => sym.rhythmProps.ticks));
6157
+ if (groupSymbolsTicks === beamGroupTicks && groupSymbols.every((n) => n instanceof ObjNoteGroup) && (groupSymbols.every((n) => n.rhythmProps.flagCount === 1) || beamGroupSizeList.length === 0)) {
6158
+ if (ObjBeamGroup.createBeam(groupSymbols)) {
6159
+ beamCreated = true;
6160
+ }
6070
6161
  }
6071
6162
  groupStartTicks += beamGroupTicks;
6072
6163
  });
@@ -6126,20 +6217,20 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6126
6217
  this.row.requestLayout();
6127
6218
  }
6128
6219
  }
6129
- layout(renderer) {
6220
+ layout(ctx) {
6130
6221
  var _a;
6131
6222
  if (!this.needLayout) {
6132
6223
  return;
6133
6224
  }
6134
6225
  this.staticObjectsCache.clear();
6135
6226
  this.requestRectUpdate();
6136
- let { unitSize } = renderer;
6227
+ let { unitSize } = ctx;
6137
6228
  this.postMeasureBreakWidth = this.hasPostMeasureBreak() ? DocumentSettings.PostMeasureBreakWidth * unitSize : 0;
6138
6229
  let isFirstMeasureInRow = this === this.row.getFirstMeasure();
6139
6230
  let isAfterMeasureBreak = ((_a = this.getPrevMeasure()) == null ? void 0 : _a.hasPostMeasureBreak()) === true;
6140
6231
  this.tabStringNotesWidth = isFirstMeasureInRow && this.row.hasTab ? unitSize * 4 : 0;
6141
6232
  let showClef = isFirstMeasureInRow || isAfterMeasureBreak;
6142
- let showMeasureNumber = isFirstMeasureInRow && !this.row.isFirstRow();
6233
+ let showMeasureNumber = this.options.showNumber === false ? false : this.options.showNumber === true || isFirstMeasureInRow && !this.row.isFirstRow();
6143
6234
  let showKeySignature = isFirstMeasureInRow || isAfterMeasureBreak || !!this.alterKeySignature;
6144
6235
  let showTimeSignature = !!this.alterTimeSignature;
6145
6236
  let showTempo = !!this.alterTempo;
@@ -6149,12 +6240,12 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6149
6240
  let oldSignature = this.signatures.filter((s) => s instanceof ObjStaffSignature).find((s) => s.staff === line);
6150
6241
  let signature = oldSignature != null ? oldSignature : new ObjStaffSignature(this, line);
6151
6242
  signature.staff.addObject(signature);
6152
- signature.updateClefImage(renderer, showClef);
6243
+ signature.updateClefImage(ctx, showClef);
6153
6244
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6154
6245
  signature.updateKeySignature(showKeySignature);
6155
6246
  signature.updateTimeSignature(showTimeSignature);
6156
6247
  signature.updateTempo(showTempo && lineId === 0);
6157
- signature.layout(renderer);
6248
+ signature.layout(ctx);
6158
6249
  this.signatures.push(signature);
6159
6250
  } else if (line instanceof ObjTab && (showMeasureNumber || showTimeSignature || showTempo)) {
6160
6251
  let oldSignature = this.signatures.filter((s) => s instanceof ObjTabSignature).find((s) => s.tab === line);
@@ -6163,7 +6254,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6163
6254
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6164
6255
  signature.updateTimeSignature(showTimeSignature);
6165
6256
  signature.updateTempo(showTempo && lineId === 0);
6166
- signature.layout(renderer);
6257
+ signature.layout(ctx);
6167
6258
  this.signatures.push(signature);
6168
6259
  }
6169
6260
  });
@@ -6173,29 +6264,29 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6173
6264
  for (let stringId = 0; stringId < 6; stringId++) {
6174
6265
  let note = tab.getTuningStrings()[stringId].format(PitchNotation.Helmholtz, SymbolSet.Unicode);
6175
6266
  let obj = new ObjText(this, { text: note, scale: 0.8 }, 1, 0.5);
6176
- obj.layout(renderer);
6267
+ obj.layout(ctx);
6177
6268
  obj.offset(this.tabStringNotesWidth * 0.8, tab.getStringY(stringId));
6178
6269
  this.tabStringNotes.push(obj);
6179
6270
  tab.addObject(obj);
6180
6271
  }
6181
6272
  });
6182
6273
  }
6183
- this.barLineLeft.layout(renderer);
6274
+ this.barLineLeft.layout(ctx);
6184
6275
  const accState = new AccidentalState(this);
6185
- this.columns.forEach((col) => col.layout(renderer, accState));
6186
- this.barLineRight.layout(renderer);
6276
+ this.columns.forEach((col) => col.layout(ctx, accState));
6277
+ this.barLineRight.layout(ctx);
6187
6278
  if (this.endRepeatPlayCountText) {
6188
- this.endRepeatPlayCountText.layout(renderer);
6279
+ this.endRepeatPlayCountText.layout(ctx);
6189
6280
  }
6190
- this.layoutObjects.forEach((layoutObj) => layoutObj.layout(renderer));
6191
- let padding = renderer.unitSize;
6281
+ this.layoutObjects.forEach((layoutObj) => layoutObj.layout(ctx));
6282
+ let padding = ctx.unitSize;
6192
6283
  this.leftSolidAreaWidth = this.tabStringNotesWidth + Math.max(0, ...this.signatures.map((signature) => signature.getRect().width)) + this.barLineLeft.getRect().width + padding;
6193
6284
  this.rightSolidAreaWidth = padding + this.barLineRight.getRect().width;
6194
6285
  this.minColumnsAreaWidth = 0;
6195
6286
  this.columns.forEach((col) => this.minColumnsAreaWidth += col.getRect().width);
6196
6287
  this.minColumnsAreaWidth = Math.max(this.minColumnsAreaWidth, _ObjMeasure.MinFlexContentWidth * unitSize);
6197
6288
  }
6198
- layoutWidth(renderer, width) {
6289
+ layoutWidth(ctx, width) {
6199
6290
  if (!this.needLayout) {
6200
6291
  return;
6201
6292
  }
@@ -6229,22 +6320,22 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6229
6320
  columnLeft += rect.width * columnScale;
6230
6321
  });
6231
6322
  }
6232
- layoutConnectives(renderer) {
6323
+ layoutConnectives(ctx) {
6233
6324
  if (!this.needLayout) {
6234
6325
  return;
6235
6326
  }
6236
6327
  this.connectives.forEach((connective) => {
6237
- connective.layout(renderer);
6328
+ connective.layout(ctx);
6238
6329
  this.rect.top = Math.min(this.rect.top, connective.getRect().top);
6239
6330
  this.rect.bottom = Math.max(this.rect.bottom, connective.getRect().bottom);
6240
6331
  });
6241
6332
  }
6242
- layoutBeams(renderer) {
6333
+ layoutBeams(ctx) {
6243
6334
  if (!this.needLayout) {
6244
6335
  return;
6245
6336
  }
6246
6337
  this.beamGroups.forEach((beamGroup) => {
6247
- beamGroup.layout(renderer);
6338
+ beamGroup.layout(ctx);
6248
6339
  this.rect.top = Math.min(this.rect.top, beamGroup.getRect().top);
6249
6340
  this.rect.bottom = Math.max(this.rect.bottom, beamGroup.getRect().bottom);
6250
6341
  });
@@ -6304,13 +6395,13 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6304
6395
  this.rect.offsetInPlace(dx, dy);
6305
6396
  this.requestRectUpdate();
6306
6397
  }
6307
- draw(renderer) {
6308
- renderer.drawDebugRect(this.getRect());
6398
+ draw(ctx) {
6399
+ ctx.drawDebugRect(this.getRect());
6309
6400
  let left = this.getStaffLineLeft();
6310
6401
  let right = this.getStaffLineRight();
6311
- const drawLine = (y) => renderer.drawLine(left, y, right, y);
6312
- let { row } = this;
6313
- row.getNotationLines().forEach((line) => {
6402
+ ctx.color("black").lineWidth(1);
6403
+ const drawLine = (y) => ctx.strokeLine(left, y, right, y);
6404
+ this.row.getNotationLines().forEach((line) => {
6314
6405
  if (line instanceof ObjStaff) {
6315
6406
  for (let p = line.bottomLineDiatonicId; p <= line.topLineDiatonicId; p += 2) {
6316
6407
  drawLine(line.getDiatonicIdY(p));
@@ -6321,17 +6412,17 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6321
6412
  }
6322
6413
  }
6323
6414
  });
6324
- this.signatures.forEach((signature) => signature.draw(renderer));
6325
- this.tabStringNotes.forEach((obj) => obj.draw(renderer));
6326
- this.barLineLeft.draw(renderer);
6327
- this.columns.forEach((col) => col.draw(renderer));
6328
- this.barLineRight.draw(renderer);
6415
+ this.signatures.forEach((signature) => signature.draw(ctx));
6416
+ this.tabStringNotes.forEach((obj) => obj.draw(ctx));
6417
+ this.barLineLeft.draw(ctx);
6418
+ this.columns.forEach((col) => col.draw(ctx));
6419
+ this.barLineRight.draw(ctx);
6329
6420
  if (this.endRepeatPlayCountText) {
6330
- this.endRepeatPlayCountText.draw(renderer);
6421
+ this.endRepeatPlayCountText.draw(ctx);
6331
6422
  }
6332
- this.connectives.forEach((connective) => connective.draw(renderer));
6333
- this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(renderer));
6334
- this.beamGroups.forEach((beam) => beam.draw(renderer));
6423
+ this.connectives.forEach((connective) => connective.draw(ctx));
6424
+ this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(ctx));
6425
+ this.beamGroups.forEach((beam) => beam.draw(ctx));
6335
6426
  }
6336
6427
  };
6337
6428
  __publicField(_ObjMeasure, "MinFlexContentWidth", 10);
@@ -6401,11 +6492,11 @@ var LayoutObjectWrapper = class {
6401
6492
  isPositionResolved() {
6402
6493
  return this.positionResolved;
6403
6494
  }
6404
- resolveClosestToStaffY(renderer) {
6495
+ resolveClosestToStaffY(ctx) {
6405
6496
  let { musicObj, measure, verticalPos, line } = this;
6406
6497
  let lineTop = line.getTopLineY();
6407
6498
  let lineBottom = line.getBottomLineY();
6408
- let linePadding = renderer.unitSize * 2;
6499
+ let linePadding = ctx.unitSize * 2;
6409
6500
  let y = verticalPos === 1 /* Below */ ? lineBottom + linePadding + musicObj.getRect().toph : lineTop - linePadding - musicObj.getRect().bottomh;
6410
6501
  let staticObjects = measure.getStaticObjects(line);
6411
6502
  let objShapeRects = musicObj.getShapeRects();
@@ -6428,7 +6519,7 @@ var LayoutObjectWrapper = class {
6428
6519
  return void 0;
6429
6520
  }
6430
6521
  }
6431
- layout(renderer) {
6522
+ layout(ctx) {
6432
6523
  this.line.addObject(this);
6433
6524
  }
6434
6525
  offset(dx, dy) {
@@ -6463,20 +6554,21 @@ var LayoutGroup = class {
6463
6554
  }
6464
6555
  });
6465
6556
  }
6466
- clearPositionAndLayout(renderer) {
6557
+ clearPositionAndLayout(ctx) {
6467
6558
  this.layoutObjectTable.forEach((layoutObjects) => {
6468
6559
  layoutObjects.forEach((layoutObj) => {
6469
6560
  layoutObj.clearPositionResolved();
6470
- layoutObj.musicObj.layout(renderer);
6561
+ layoutObj.musicObj.layout(ctx);
6471
6562
  });
6472
6563
  });
6473
6564
  }
6474
6565
  };
6475
6566
 
6476
6567
  // src/score/engine/obj-staff-and-tab.ts
6477
- var ObjNotationLine4 = class extends MusicObject {
6478
- constructor(parent) {
6479
- super(parent);
6568
+ var ObjNotationLine5 = class extends MusicObject {
6569
+ constructor(row) {
6570
+ super(row);
6571
+ this.row = row;
6480
6572
  __publicField(this, "objects", []);
6481
6573
  __publicField(this, "layoutGroups", []);
6482
6574
  }
@@ -6493,18 +6585,18 @@ var ObjNotationLine4 = class extends MusicObject {
6493
6585
  }
6494
6586
  return layoutGroup;
6495
6587
  }
6496
- resetLayoutGroups(renderer) {
6588
+ resetLayoutGroups(ctx) {
6497
6589
  this.layoutGroups.forEach((layoutGroup) => {
6498
6590
  if (layoutGroup) {
6499
- layoutGroup.clearPositionAndLayout(renderer);
6591
+ layoutGroup.clearPositionAndLayout(ctx);
6500
6592
  }
6501
6593
  });
6502
6594
  }
6503
- layoutLayoutGroups(renderer) {
6595
+ layoutLayoutGroups(ctx) {
6504
6596
  this.layoutGroups.forEach((layoutGroup) => {
6505
6597
  if (layoutGroup) {
6506
- this.layoutLayoutGroup(renderer, layoutGroup, 0 /* Above */);
6507
- this.layoutLayoutGroup(renderer, layoutGroup, 1 /* Below */);
6598
+ this.layoutLayoutGroup(ctx, layoutGroup, 0 /* Above */);
6599
+ this.layoutLayoutGroup(ctx, layoutGroup, 1 /* Below */);
6508
6600
  }
6509
6601
  });
6510
6602
  }
@@ -6515,42 +6607,42 @@ var ObjNotationLine4 = class extends MusicObject {
6515
6607
  layoutObj.offset(0, y - layoutObj.getRect().centerY);
6516
6608
  layoutObj.setPositionResolved();
6517
6609
  }
6518
- alignObjectsY(renderer, layoutObjArr) {
6610
+ alignObjectsY(ctx, layoutObjArr) {
6519
6611
  layoutObjArr = layoutObjArr.filter((layoutObj) => !layoutObj.isPositionResolved());
6520
6612
  let rowY;
6521
6613
  layoutObjArr.forEach((layoutObj) => {
6522
- let y = layoutObj.resolveClosestToStaffY(renderer);
6614
+ let y = layoutObj.resolveClosestToStaffY(ctx);
6523
6615
  rowY = layoutObj.verticalPos === 1 /* Below */ ? Math.max(y, rowY != null ? rowY : y) : Math.min(y, rowY != null ? rowY : y);
6524
6616
  });
6525
6617
  layoutObjArr.forEach((layoutObj) => this.setObjectY(layoutObj, rowY));
6526
6618
  }
6527
- layoutLayoutGroup(renderer, layoutGroup, verticalPos) {
6619
+ layoutLayoutGroup(ctx, layoutGroup, verticalPos) {
6528
6620
  let rowLayoutObjs = layoutGroup.getLayoutObjects(verticalPos).filter((layoutObj) => !layoutObj.isPositionResolved());
6529
6621
  rowLayoutObjs.forEach((layoutObj) => {
6530
6622
  let { musicObj, anchor } = layoutObj;
6531
6623
  if (musicObj instanceof ObjEnding || musicObj instanceof ObjExtensionLine || musicObj instanceof ObjTabRhythm) {
6532
- musicObj.layoutFitToMeasure(renderer);
6624
+ musicObj.layoutFitToMeasure(ctx);
6533
6625
  } else {
6534
6626
  musicObj.offset(anchor.getRect().centerX - musicObj.getRect().centerX, 0);
6535
6627
  }
6536
6628
  });
6537
6629
  if (layoutGroup.rowAlign) {
6538
- this.alignObjectsY(renderer, rowLayoutObjs);
6630
+ this.alignObjectsY(ctx, rowLayoutObjs);
6539
6631
  } else {
6540
6632
  rowLayoutObjs.forEach((layoutObj) => {
6541
6633
  let link = layoutObj.musicObj.getLink();
6542
6634
  if (link && link.getHead() === layoutObj.musicObj) {
6543
6635
  let objectParts = [link.getHead(), ...link.getTails()];
6544
6636
  let layoutObjs = rowLayoutObjs.filter((layoutObj2) => objectParts.some((o) => o === layoutObj2.musicObj));
6545
- this.alignObjectsY(renderer, layoutObjs);
6637
+ this.alignObjectsY(ctx, layoutObjs);
6546
6638
  } else {
6547
- this.alignObjectsY(renderer, [layoutObj]);
6639
+ this.alignObjectsY(ctx, [layoutObj]);
6548
6640
  }
6549
6641
  });
6550
6642
  }
6551
6643
  }
6552
6644
  };
6553
- var ObjStaff = class extends ObjNotationLine4 {
6645
+ var ObjStaff = class extends ObjNotationLine5 {
6554
6646
  constructor(row, staffConfig, id) {
6555
6647
  super(row);
6556
6648
  this.row = row;
@@ -6569,11 +6661,11 @@ var ObjStaff = class extends ObjNotationLine4 {
6569
6661
  __publicField(this, "mi");
6570
6662
  const getDiatonicId = (noteName, isOctaveDown) => Note8.getNote(noteName).diatonicId - (isOctaveDown ? 7 : 0);
6571
6663
  if (staffConfig.clef === "G" /* G */) {
6572
- this.clefImageAsset = 0 /* TrebleClefPng */;
6664
+ this.clefImageAsset = 0 /* G_Clef */;
6573
6665
  this.clefLineDiatonicId = getDiatonicId("G4", staffConfig.isOctaveDown === true);
6574
6666
  this.middleLineDiatonicId = this.clefLineDiatonicId + 2;
6575
6667
  } else if (staffConfig.clef === "F" /* F */) {
6576
- this.clefImageAsset = 1 /* BassClefPng */;
6668
+ this.clefImageAsset = 1 /* F_Clef */;
6577
6669
  this.clefLineDiatonicId = getDiatonicId("F3", staffConfig.isOctaveDown === true);
6578
6670
  this.middleLineDiatonicId = this.clefLineDiatonicId - 2;
6579
6671
  } else {
@@ -6595,6 +6687,9 @@ var ObjStaff = class extends ObjNotationLine4 {
6595
6687
  var _a;
6596
6688
  return (_a = this.staffConfig.name) != null ? _a : "";
6597
6689
  }
6690
+ getConfig() {
6691
+ return this.staffConfig;
6692
+ }
6598
6693
  getTopLineY() {
6599
6694
  return this.topLineY;
6600
6695
  }
@@ -6648,7 +6743,7 @@ var ObjStaff = class extends ObjNotationLine4 {
6648
6743
  return diatonicId % 2 !== this.middleLineDiatonicId % 2;
6649
6744
  }
6650
6745
  containsVoiceId(voiceId) {
6651
- return !this.staffConfig.voiceIds || this.staffConfig.voiceIds.includes(voiceId);
6746
+ return Utils13.Is.isUndefined(this.staffConfig.voiceId) || Utils13.Arr.toArray(this.staffConfig.voiceId).includes(voiceId);
6652
6747
  }
6653
6748
  calcTop() {
6654
6749
  let top = this.topLineY;
@@ -6671,16 +6766,16 @@ var ObjStaff = class extends ObjNotationLine4 {
6671
6766
  return bottom;
6672
6767
  }
6673
6768
  pick(x, y) {
6674
- return [this];
6769
+ return this.getRect().contains(x, y) ? [this] : [];
6675
6770
  }
6676
- layoutHeight(renderer) {
6677
- let { unitSize } = renderer;
6771
+ layoutHeight(ctx) {
6772
+ let { unitSize } = ctx;
6678
6773
  let h = unitSize * DocumentSettings.StaffHeight;
6679
6774
  this.topLineY = -h / 2;
6680
6775
  this.bottomLineY = h / 2;
6681
6776
  this.rect = new DivRect(0, 0, this.topLineY, this.bottomLineY);
6682
6777
  }
6683
- layoutWidth(renderer) {
6778
+ layoutWidth(ctx) {
6684
6779
  this.rect.left = this.row.getRect().left;
6685
6780
  this.rect.right = this.row.getRect().right;
6686
6781
  }
@@ -6696,10 +6791,10 @@ var ObjStaff = class extends ObjNotationLine4 {
6696
6791
  });
6697
6792
  this.rect.offsetInPlace(dx, dy);
6698
6793
  }
6699
- draw(renderer) {
6794
+ draw(ctx) {
6700
6795
  }
6701
6796
  };
6702
- var ObjTab = class extends ObjNotationLine4 {
6797
+ var ObjTab = class extends ObjNotationLine5 {
6703
6798
  constructor(row, tabConfig, id) {
6704
6799
  super(row);
6705
6800
  this.row = row;
@@ -6729,6 +6824,9 @@ var ObjTab = class extends ObjNotationLine4 {
6729
6824
  var _a;
6730
6825
  return (_a = this.tabConfig.name) != null ? _a : "";
6731
6826
  }
6827
+ getConfig() {
6828
+ return this.tabConfig;
6829
+ }
6732
6830
  getTuningName() {
6733
6831
  return this.tuningName;
6734
6832
  }
@@ -6758,7 +6856,7 @@ var ObjTab = class extends ObjNotationLine4 {
6758
6856
  return this.bottom;
6759
6857
  }
6760
6858
  containsVoiceId(voiceId) {
6761
- return !this.tabConfig.voiceIds || this.tabConfig.voiceIds.includes(voiceId);
6859
+ return Utils13.Is.isUndefined(this.tabConfig.voiceId) || Utils13.Arr.toArray(this.tabConfig.voiceId).includes(voiceId);
6762
6860
  }
6763
6861
  containsDiatonicId(diatonicId) {
6764
6862
  return true;
@@ -6774,16 +6872,16 @@ var ObjTab = class extends ObjNotationLine4 {
6774
6872
  return bottom;
6775
6873
  }
6776
6874
  pick(x, y) {
6777
- return [this];
6875
+ return this.getRect().contains(x, y) ? [this] : [];
6778
6876
  }
6779
- layoutHeight(renderer) {
6780
- let { unitSize } = renderer;
6877
+ layoutHeight(ctx) {
6878
+ let { unitSize } = ctx;
6781
6879
  let h = unitSize * DocumentSettings.TabHeight;
6782
6880
  this.top = -h / 2;
6783
6881
  this.bottom = h / 2;
6784
6882
  this.rect = new DivRect(0, 0, this.top, this.bottom);
6785
6883
  }
6786
- layoutWidth(renderer) {
6884
+ layoutWidth(ctx) {
6787
6885
  this.rect.left = this.row.getRect().left;
6788
6886
  this.rect.right = this.row.getRect().right;
6789
6887
  }
@@ -6799,12 +6897,13 @@ var ObjTab = class extends ObjNotationLine4 {
6799
6897
  });
6800
6898
  this.rect.offsetInPlace(dx, dy);
6801
6899
  }
6802
- draw(renderer) {
6900
+ draw(ctx) {
6803
6901
  }
6804
6902
  };
6805
6903
 
6806
6904
  // src/score/engine/obj-score-row.ts
6807
6905
  import { MusicError as MusicError16, MusicErrorType as MusicErrorType16 } from "@tspro/web-music-score/core";
6906
+ import { Utils as Utils14 } from "@tspro/ts-utils-lib";
6808
6907
  var ObjScoreRow = class extends MusicObject {
6809
6908
  constructor(doc, prevRow, scoreConfig) {
6810
6909
  super(doc);
@@ -6814,14 +6913,30 @@ var ObjScoreRow = class extends MusicObject {
6814
6913
  __publicField(this, "nextRow");
6815
6914
  __publicField(this, "minWidth", 0);
6816
6915
  __publicField(this, "notationLines");
6916
+ __publicField(this, "instrumentLineGroups");
6817
6917
  __publicField(this, "staves");
6818
6918
  __publicField(this, "tabs");
6919
+ __publicField(this, "instrumentNames");
6819
6920
  __publicField(this, "measures", []);
6820
6921
  __publicField(this, "needLayout", true);
6821
6922
  __publicField(this, "mi");
6822
6923
  this.notationLines = this.createNotationLines();
6823
6924
  this.staves = this.notationLines.filter((line) => line instanceof ObjStaff);
6824
6925
  this.tabs = this.notationLines.filter((line) => line instanceof ObjTab);
6926
+ let lineGroups = [];
6927
+ for (let i = 0; i < this.notationLines.length; i++) {
6928
+ let line = this.notationLines[i];
6929
+ let prevGroup = lineGroups[lineGroups.length - 1];
6930
+ if (prevGroup === void 0 || prevGroup[0].getConfig().instrument === void 0 || prevGroup[0].getConfig().instrument !== line.getConfig().instrument) {
6931
+ lineGroups.push([line]);
6932
+ } else {
6933
+ prevGroup.push(line);
6934
+ }
6935
+ }
6936
+ this.instrumentLineGroups = lineGroups;
6937
+ this.instrumentNames = this.instrumentLineGroups.map((lines) => {
6938
+ return lines.length > 0 && Utils14.Is.isNonEmptyString(lines[0].getConfig().instrument) ? new ObjText(this, String(lines[0].getConfig().instrument), 0, 0.5) : void 0;
6939
+ });
6825
6940
  if (this.prevRow) {
6826
6941
  this.prevRow.nextRow = this;
6827
6942
  }
@@ -6845,6 +6960,14 @@ var ObjScoreRow = class extends MusicObject {
6845
6960
  getNotationLines() {
6846
6961
  return this.notationLines;
6847
6962
  }
6963
+ getInstrumentLineGroups() {
6964
+ return this.instrumentLineGroups;
6965
+ }
6966
+ findMatchingLine(line) {
6967
+ return line.row === this ? line : this.notationLines.find(
6968
+ (curLine) => Utils14.Obj.deepEqual(line.row.scoreConfig, curLine.row.scoreConfig) && line.id === curLine.id || Utils14.Is.isNonEmptyString(line.getConfig().name) && line.getConfig().name === curLine.getConfig().name && line.getConfig().type === curLine.getConfig().type
6969
+ );
6970
+ }
6848
6971
  getStaves() {
6849
6972
  return this.staves;
6850
6973
  }
@@ -6883,13 +7006,14 @@ var ObjScoreRow = class extends MusicObject {
6883
7006
  }
6884
7007
  return void 0;
6885
7008
  }
6886
- resetLayoutGroups(renderer) {
6887
- this.notationLines.forEach((line) => line.resetLayoutGroups(renderer));
7009
+ resetLayoutGroups(ctx) {
7010
+ this.notationLines.forEach((line) => line.resetLayoutGroups(ctx));
6888
7011
  }
6889
- layoutLayoutGroups(renderer) {
6890
- this.notationLines.forEach((line) => line.layoutLayoutGroups(renderer));
7012
+ layoutLayoutGroups(ctx) {
7013
+ this.notationLines.forEach((line) => line.layoutLayoutGroups(ctx));
6891
7014
  }
6892
7015
  pick(x, y) {
7016
+ var _a, _b;
6893
7017
  if (!this.getRect().contains(x, y)) {
6894
7018
  return [];
6895
7019
  }
@@ -6899,6 +7023,12 @@ var ObjScoreRow = class extends MusicObject {
6899
7023
  return [this, ...arr];
6900
7024
  }
6901
7025
  }
7026
+ for (let i = 0; i < this.instrumentNames.length; i++) {
7027
+ let arr = (_b = (_a = this.instrumentNames[i]) == null ? void 0 : _a.pick(x, y)) != null ? _b : [];
7028
+ if (arr.length > 0) {
7029
+ return [this, ...arr];
7030
+ }
7031
+ }
6902
7032
  for (let i = 0; i < this.notationLines.length; i++) {
6903
7033
  let arr = this.notationLines[i].pick(x, y);
6904
7034
  if (arr.length > 0) {
@@ -6950,61 +7080,78 @@ var ObjScoreRow = class extends MusicObject {
6950
7080
  getMinWidth() {
6951
7081
  return this.minWidth;
6952
7082
  }
7083
+ solveAutoStemDir(symbols) {
7084
+ if (symbols.length === 0) {
7085
+ return "up" /* Up */;
7086
+ } else {
7087
+ let voiceId = symbols[0].voiceId;
7088
+ let noteGroupDiatonicIds = symbols.filter((sym) => sym instanceof ObjNoteGroup).map((n) => n.setDiatonicId);
7089
+ let restDiatonicIds = symbols.filter((sym) => sym instanceof ObjRest && sym.setDiatonicId !== ObjRest.UndefinedDiatonicId).map((r) => r.setDiatonicId);
7090
+ if (noteGroupDiatonicIds.length === 0 && restDiatonicIds.length === 0) {
7091
+ return "up" /* Up */;
7092
+ }
7093
+ let diatonicIds = noteGroupDiatonicIds.length > 0 ? noteGroupDiatonicIds : restDiatonicIds;
7094
+ let avgDiatonicId = Math.floor(Utils14.Math.avg(...diatonicIds));
7095
+ let staves = this.getStaves().filter((staff) => staff.containsVoiceId(voiceId) && staff.containsDiatonicId(avgDiatonicId));
7096
+ return staves.length > 0 ? avgDiatonicId >= staves[0].middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */ : "up" /* Up */;
7097
+ }
7098
+ }
7099
+ getInstrumentNameWidth(ctx) {
7100
+ return Math.max(0, ...this.instrumentNames.map((obj) => obj ? obj.getRect().width : 0));
7101
+ }
6953
7102
  requestLayout() {
6954
7103
  if (!this.needLayout) {
6955
7104
  this.needLayout = true;
6956
7105
  this.doc.requestLayout();
6957
7106
  }
6958
7107
  }
6959
- layout(renderer) {
7108
+ layout(ctx) {
6960
7109
  if (!this.needLayout) {
6961
7110
  return;
6962
7111
  }
6963
7112
  this.requestRectUpdate();
7113
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.layout(ctx));
6964
7114
  this.notationLines.forEach((line) => {
6965
7115
  line.removeObjects();
6966
- line.layoutHeight(renderer);
7116
+ line.layoutHeight(ctx);
6967
7117
  });
6968
- this.rect = new DivRect(0, 0, 0, 0);
6969
7118
  this.minWidth = 0;
6970
7119
  this.measures.forEach((m) => {
6971
- m.layout(renderer);
7120
+ m.layout(ctx);
6972
7121
  this.minWidth += m.getMinWidth();
6973
7122
  this.minWidth += m.getPostMeasureBreakWidth();
6974
7123
  });
6975
7124
  }
6976
- layoutWidth(renderer, width) {
7125
+ layoutWidth(ctx, left, right) {
6977
7126
  if (!this.needLayout) {
6978
7127
  return;
6979
7128
  }
6980
- let rowWidth = Math.max(width, this.minWidth);
6981
- this.rect.centerX = this.rect.left + rowWidth / 2;
6982
- this.rect.right = this.rect.left + rowWidth;
6983
- this.notationLines.forEach((line) => line.layoutWidth(renderer));
6984
- let targetColumnsAreaWidth = rowWidth;
7129
+ this.rect = new DivRect(0, right, 0, 0);
7130
+ this.notationLines.forEach((line) => line.layoutWidth(ctx));
7131
+ let targetColumnsAreaWidth = right - left;
6985
7132
  let minColumnsAreaWidth = 0;
6986
7133
  this.measures.forEach((m) => {
6987
7134
  targetColumnsAreaWidth -= m.getSolidAreaWidth() + m.getPostMeasureBreakWidth();
6988
7135
  minColumnsAreaWidth += m.getMinColumnsAreaWidth();
6989
7136
  });
6990
7137
  let columnsAreaScale = targetColumnsAreaWidth / minColumnsAreaWidth;
6991
- let x = 0;
7138
+ let x = this.doc.getInstrumentGroupSize(ctx).braceRight;
6992
7139
  this.measures.forEach((m) => {
6993
7140
  let newMeasureWidth = m.getSolidAreaWidth() + m.getMinColumnsAreaWidth() * columnsAreaScale;
6994
- m.layoutWidth(renderer, newMeasureWidth);
7141
+ m.layoutWidth(ctx, newMeasureWidth);
6995
7142
  let r = m.getRect();
6996
7143
  m.offset(x - r.left, -r.centerY);
6997
7144
  x += r.width;
6998
7145
  x += m.getPostMeasureBreakWidth();
6999
7146
  });
7000
7147
  this.measures.forEach((m) => {
7001
- m.layoutConnectives(renderer);
7002
- m.layoutBeams(renderer);
7148
+ m.layoutConnectives(ctx);
7149
+ m.layoutBeams(ctx);
7003
7150
  });
7004
7151
  }
7005
7152
  updateRect() {
7006
- let left = this.measures.length > 0 ? this.measures[0].getRect().left : 0;
7007
- let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : 0;
7153
+ let left = 0;
7154
+ let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : left;
7008
7155
  let top = this.measures.length > 0 ? Math.min(...this.measures.map((m) => m.getRect().top)) : 0;
7009
7156
  let bottom = this.measures.length > 0 ? Math.max(...this.measures.map((m) => m.getRect().bottom)) : 0;
7010
7157
  this.rect = new DivRect(left, right, top, bottom);
@@ -7012,8 +7159,8 @@ var ObjScoreRow = class extends MusicObject {
7012
7159
  alignStemsToBeams() {
7013
7160
  this.measures.forEach((m) => m.alignStemsToBeams());
7014
7161
  }
7015
- layoutSetNotationLines(renderer) {
7016
- let { unitSize } = renderer;
7162
+ layoutSetNotationLines(ctx) {
7163
+ let { unitSize } = ctx;
7017
7164
  for (let i = 1; i < this.notationLines.length; i++) {
7018
7165
  let prev = this.notationLines[i - 1];
7019
7166
  let cur = this.notationLines[i];
@@ -7037,11 +7184,20 @@ var ObjScoreRow = class extends MusicObject {
7037
7184
  });
7038
7185
  });
7039
7186
  });
7187
+ this.instrumentNames.forEach((obj, i) => {
7188
+ let grp = this.instrumentLineGroups[i];
7189
+ if (obj && grp.length > 0) {
7190
+ obj.offset(
7191
+ -obj.getRect().left,
7192
+ -obj.getRect().centerY + (grp[0].getRect().top + grp[grp.length - 1].getRect().bottom) / 2
7193
+ );
7194
+ }
7195
+ });
7040
7196
  this.alignStemsToBeams();
7041
7197
  this.requestRectUpdate();
7042
7198
  }
7043
- layoutPadding(renderer) {
7044
- let p = renderer.unitSize / 2;
7199
+ layoutPadding(ctx) {
7200
+ let p = ctx.unitSize / 2;
7045
7201
  this.getRect();
7046
7202
  this.rect.left -= p;
7047
7203
  this.rect.right += p;
@@ -7056,24 +7212,38 @@ var ObjScoreRow = class extends MusicObject {
7056
7212
  this.measures.forEach((m) => m.offset(dx, dy));
7057
7213
  this.rect.offsetInPlace(dx, dy);
7058
7214
  this.notationLines.forEach((l) => l.offset(dx, dy));
7215
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.offset(dx, dy));
7059
7216
  }
7060
- draw(renderer) {
7061
- let ctx = renderer.getCanvasContext();
7062
- if (!ctx) {
7063
- return;
7064
- }
7065
- renderer.drawDebugRect(this.getRect());
7217
+ draw(ctx) {
7218
+ ctx.drawDebugRect(this.getRect());
7066
7219
  ctx.save();
7067
- ctx.rect(this.getRect().left, this.getRect().top, this.getRect().width, this.getRect().height);
7220
+ let { left, top, width, height } = this.getRect();
7221
+ ctx.rect(left, top, width, height);
7068
7222
  ctx.clip();
7069
7223
  if (this.getFirstMeasure() && (this.notationLines.length > 1 || this.notationLines[0] instanceof ObjTab)) {
7070
- let left = this.getFirstMeasure().getStaffLineLeft();
7071
- let top = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7224
+ let left2 = this.getFirstMeasure().getStaffLineLeft();
7225
+ let top2 = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7072
7226
  let bottom = Math.max(...this.notationLines.map((line) => line.getBottomLineY()));
7073
- renderer.drawLine(left, top, left, bottom);
7074
- }
7075
- this.measures.forEach((m) => m.draw(renderer));
7076
- this.notationLines.forEach((m) => m.draw(renderer));
7227
+ ctx.color("black").lineWidth(1).strokeLine(left2, top2, left2, bottom);
7228
+ }
7229
+ this.measures.forEach((m) => m.draw(ctx));
7230
+ this.notationLines.forEach((m) => m.draw(ctx));
7231
+ let grpSize = this.doc.getInstrumentGroupSize(ctx);
7232
+ this.instrumentNames.forEach((obj, i) => {
7233
+ let grp = this.instrumentLineGroups[i];
7234
+ if (grp.length > 1) {
7235
+ let r = new DivRect(
7236
+ grpSize.braceLeft,
7237
+ grpSize.braceRight,
7238
+ grp[0].getTopLineY(),
7239
+ grp[grp.length - 1].getBottomLineY()
7240
+ );
7241
+ ctx.color("brack").lineWidth(1).drawBrace(r, "left");
7242
+ }
7243
+ if (obj) {
7244
+ obj.draw(ctx);
7245
+ }
7246
+ });
7077
7247
  ctx.restore();
7078
7248
  }
7079
7249
  };
@@ -7121,24 +7291,24 @@ var ObjHeader = class extends MusicObject {
7121
7291
  }
7122
7292
  return [this];
7123
7293
  }
7124
- layoutWidth(renderer, width) {
7294
+ layoutWidth(ctx, left, right) {
7125
7295
  let top = 0;
7126
- this.rect = new DivRect(0, width, 0, 0);
7296
+ this.rect = new DivRect(left, right, 0, 0);
7127
7297
  if (this.titleText) {
7128
- this.titleText.layout(renderer);
7129
- this.titleText.offset(width / 2, top);
7298
+ this.titleText.layout(ctx);
7299
+ this.titleText.offset((left + right) / 2, top);
7130
7300
  top += this.titleText.getRect().height;
7131
7301
  this.rect.expandInPlace(this.titleText.getRect());
7132
7302
  }
7133
7303
  if (this.composerText) {
7134
- this.composerText.layout(renderer);
7135
- this.composerText.offset(width, top);
7304
+ this.composerText.layout(ctx);
7305
+ this.composerText.offset(right, top);
7136
7306
  top += this.composerText.getRect().height;
7137
7307
  this.rect.expandInPlace(this.composerText.getRect());
7138
7308
  }
7139
7309
  if (this.arrangerText) {
7140
- this.arrangerText.layout(renderer);
7141
- this.arrangerText.offset(width, top);
7310
+ this.arrangerText.layout(ctx);
7311
+ this.arrangerText.offset(right, top);
7142
7312
  top += this.arrangerText.getRect().height;
7143
7313
  this.rect.expandInPlace(this.arrangerText.getRect());
7144
7314
  }
@@ -7155,27 +7325,27 @@ var ObjHeader = class extends MusicObject {
7155
7325
  }
7156
7326
  this.rect.offsetInPlace(dx, dy);
7157
7327
  }
7158
- draw(renderer) {
7328
+ draw(ctx) {
7159
7329
  if (this.titleText) {
7160
- this.titleText.draw(renderer);
7330
+ this.titleText.draw(ctx);
7161
7331
  }
7162
7332
  if (this.composerText) {
7163
- this.composerText.draw(renderer);
7333
+ this.composerText.draw(ctx);
7164
7334
  }
7165
7335
  if (this.arrangerText) {
7166
- this.arrangerText.draw(renderer);
7336
+ this.arrangerText.draw(ctx);
7167
7337
  }
7168
7338
  }
7169
7339
  };
7170
7340
 
7171
7341
  // src/score/engine/obj-document.ts
7172
- import { Utils as Utils14 } from "@tspro/ts-utils-lib";
7342
+ import { Utils as Utils15 } from "@tspro/ts-utils-lib";
7173
7343
  import { MusicError as MusicError17, MusicErrorType as MusicErrorType17 } from "@tspro/web-music-score/core";
7174
7344
  var ObjDocument = class extends MusicObject {
7175
7345
  constructor() {
7176
7346
  super(void 0);
7177
7347
  __publicField(this, "needLayout", true);
7178
- __publicField(this, "renderer");
7348
+ __publicField(this, "ctx");
7179
7349
  __publicField(this, "rows", []);
7180
7350
  __publicField(this, "measures", []);
7181
7351
  __publicField(this, "measuresPerRow", Infinity);
@@ -7191,7 +7361,7 @@ var ObjDocument = class extends MusicObject {
7191
7361
  return this.mi;
7192
7362
  }
7193
7363
  setScoreConfiguration(config) {
7194
- if (Utils14.Is.isEnumValue(config, StaffPreset)) {
7364
+ if (Utils15.Is.isEnumValue(config, StaffPreset)) {
7195
7365
  switch (config) {
7196
7366
  default:
7197
7367
  case "treble" /* Treble */:
@@ -7219,7 +7389,7 @@ var ObjDocument = class extends MusicObject {
7219
7389
  ];
7220
7390
  break;
7221
7391
  }
7222
- } else if (Utils14.Is.isArray(config)) {
7392
+ } else if (Utils15.Is.isArray(config)) {
7223
7393
  this.curScoreConfig = config;
7224
7394
  } else {
7225
7395
  this.curScoreConfig = [config];
@@ -7280,17 +7450,17 @@ var ObjDocument = class extends MusicObject {
7280
7450
  addConnectiveProps(connectiveProps) {
7281
7451
  this.allConnectiveProps.push(connectiveProps);
7282
7452
  }
7283
- setRenderer(renderer) {
7284
- if (this.renderer === renderer) {
7453
+ setRenderContext(ctx) {
7454
+ if (this.ctx === ctx) {
7285
7455
  return;
7286
7456
  }
7287
- let prevRenderer = this.renderer;
7288
- this.renderer = renderer;
7289
- if (prevRenderer) {
7290
- prevRenderer.setDocument(void 0);
7457
+ let prevCtx = this.ctx;
7458
+ this.ctx = ctx;
7459
+ if (prevCtx) {
7460
+ prevCtx.setDocument(void 0);
7291
7461
  }
7292
- if (renderer) {
7293
- renderer.setDocument(this.mi);
7462
+ if (ctx) {
7463
+ ctx.setDocument(this.mi);
7294
7464
  }
7295
7465
  this.requestFullLayout();
7296
7466
  }
@@ -7339,13 +7509,13 @@ var ObjDocument = class extends MusicObject {
7339
7509
  requestNewRow() {
7340
7510
  this.newRowRequested = true;
7341
7511
  }
7342
- addMeasure() {
7512
+ addMeasure(measureOptions) {
7343
7513
  let lastRow = this.rows[this.rows.length - 1];
7344
7514
  if (!lastRow || this.newRowRequested && lastRow.getMeasures().length > 0 || lastRow.getMeasures().length >= this.measuresPerRow) {
7345
7515
  lastRow = this.addNewRow(lastRow);
7346
7516
  this.newRowRequested = false;
7347
7517
  }
7348
- let measure = new ObjMeasure2(lastRow);
7518
+ let measure = new ObjMeasure2(lastRow, measureOptions);
7349
7519
  this.measures.push(measure);
7350
7520
  lastRow.addMeasure(measure);
7351
7521
  this.requestLayout();
@@ -7376,9 +7546,21 @@ var ObjDocument = class extends MusicObject {
7376
7546
  this.measures.forEach((m) => m.resetPassCount());
7377
7547
  }
7378
7548
  updateCursorRect(cursorRect) {
7379
- if (this.renderer) {
7380
- this.renderer.updateCursorRect(cursorRect);
7381
- }
7549
+ if (this.ctx) {
7550
+ this.ctx.updateCursorRect(cursorRect);
7551
+ }
7552
+ }
7553
+ getInstrumentGroupSize(ctx) {
7554
+ let nameWidth = Math.max(0, ...this.rows.map((row) => row.getInstrumentNameWidth(ctx)));
7555
+ let hasName = nameWidth > 0;
7556
+ let padding = hasName ? ctx.unitSize : 0;
7557
+ let braceWidth = hasName ? ctx.unitSize * 5 : 0;
7558
+ return {
7559
+ nameLeft: 0,
7560
+ nameRight: nameWidth,
7561
+ braceLeft: nameWidth + padding,
7562
+ braceRight: nameWidth + padding + braceWidth + padding
7563
+ };
7382
7564
  }
7383
7565
  requestLayout() {
7384
7566
  this.needLayout = true;
@@ -7392,31 +7574,34 @@ var ObjDocument = class extends MusicObject {
7392
7574
  this.requestLayout();
7393
7575
  }
7394
7576
  layout() {
7577
+ var _a;
7395
7578
  if (!this.needLayout) {
7396
7579
  return;
7397
7580
  }
7398
- const { renderer } = this;
7399
- if (!renderer) {
7581
+ const { ctx } = this;
7582
+ if (!ctx) {
7400
7583
  return;
7401
7584
  }
7402
- let { unitSize } = renderer;
7585
+ let { unitSize } = ctx;
7403
7586
  this.forEachMeasure((m) => m.createBeams());
7587
+ (_a = this.getFirstMeasure()) == null ? void 0 : _a.updateRunningArguments();
7404
7588
  this.forEachMeasure((m) => m.createExtensions());
7405
7589
  this.allConnectiveProps.forEach((props) => props.removeConnectives());
7406
7590
  this.allConnectiveProps.forEach((props) => props.createConnectives());
7407
- this.rows.forEach((row) => row.resetLayoutGroups(renderer));
7408
- this.rows.forEach((row) => row.layout(renderer));
7409
- let rowWidth = Math.max(
7591
+ this.rows.forEach((row) => row.resetLayoutGroups(ctx));
7592
+ this.rows.forEach((row) => row.layout(ctx));
7593
+ let left = this.getInstrumentGroupSize(ctx).braceRight;
7594
+ let right = Math.max(
7410
7595
  DocumentSettings.DocumentMinWidth * unitSize,
7411
7596
  ...this.rows.map((row) => 1.4 * row.getMinWidth())
7412
7597
  );
7413
- this.rows.forEach((row) => row.layoutWidth(renderer, rowWidth));
7414
- this.rows.forEach((row) => row.layoutLayoutGroups(renderer));
7415
- this.rows.forEach((row) => row.layoutSetNotationLines(renderer));
7416
- this.rows.forEach((row) => row.layoutPadding(renderer));
7598
+ this.rows.forEach((row) => row.layoutWidth(ctx, left, right));
7599
+ this.rows.forEach((row) => row.layoutLayoutGroups(ctx));
7600
+ this.rows.forEach((row) => row.layoutSetNotationLines(ctx));
7601
+ this.rows.forEach((row) => row.layoutPadding(ctx));
7417
7602
  this.rect = new DivRect();
7418
7603
  if (this.header) {
7419
- this.header.layoutWidth(renderer, rowWidth);
7604
+ this.header.layoutWidth(ctx, left, right);
7420
7605
  this.rect.expandInPlace(this.header.getRect());
7421
7606
  }
7422
7607
  this.rows.forEach((row) => {
@@ -7427,13 +7612,13 @@ var ObjDocument = class extends MusicObject {
7427
7612
  this.needLayout = false;
7428
7613
  }
7429
7614
  drawContent() {
7430
- const { renderer } = this;
7431
- if (!renderer) {
7615
+ const { ctx } = this;
7616
+ if (!ctx) {
7432
7617
  return;
7433
7618
  }
7434
- this.rows.forEach((row) => row.draw(renderer));
7619
+ this.rows.forEach((row) => row.draw(ctx));
7435
7620
  if (this.header) {
7436
- this.header.draw(renderer);
7621
+ this.header.draw(ctx);
7437
7622
  }
7438
7623
  }
7439
7624
  pickStaffPosAt(x, y) {
@@ -7476,7 +7661,7 @@ var ObjDocument = class extends MusicObject {
7476
7661
  };
7477
7662
 
7478
7663
  // src/score/pub/document-builder.ts
7479
- import { BeamGrouping, KeySignature as KeySignature3, Note as Note10, NoteLength as NoteLength9, RhythmProps as RhythmProps6, Scale as Scale2, ScaleType, SymbolSet as SymbolSet2, TimeSignature as TimeSignature2, TimeSignatures, TuningNameList, validateNoteLength as validateNoteLength4, validateTupletRatio } from "@tspro/web-music-score/theory";
7664
+ import { BeamGrouping, KeySignature as KeySignature3, Note as Note10, NoteLength as NoteLength8, RhythmProps as RhythmProps6, Scale as Scale2, ScaleType, SymbolSet as SymbolSet2, TimeSignature as TimeSignature2, TimeSignatures, TuningNameList, validateNoteLength as validateNoteLength3, validateTupletRatio } from "@tspro/web-music-score/theory";
7480
7665
  import { MusicError as MusicError18, MusicErrorType as MusicErrorType18 } from "@tspro/web-music-score/core";
7481
7666
  function assertArg(condition, argName, argValue) {
7482
7667
  if (!condition) {
@@ -7492,70 +7677,89 @@ function isNote(note) {
7492
7677
  }
7493
7678
  }
7494
7679
  function isVoiceId(value) {
7495
- return Utils15.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7680
+ return Utils16.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7496
7681
  }
7497
7682
  function isStringNumber(value) {
7498
- return Utils15.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7683
+ return Utils16.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7499
7684
  }
7500
7685
  function isVerseNumber(value) {
7501
- return Utils15.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
7686
+ return Utils16.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
7502
7687
  }
7503
7688
  function assertBaseConfig(baseConfig) {
7504
- assertArg(Utils15.Is.isObject(baseConfig), "baseConfig", baseConfig);
7505
- assertArg(Utils15.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
7506
- assertArg(Utils15.Is.isUndefined(baseConfig.voiceIds) || Utils15.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => Utils15.Is.isNumber(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
7689
+ var _a;
7690
+ assertArg(Utils16.Is.isObject(baseConfig), "baseConfig", baseConfig);
7691
+ assertArg(Utils16.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
7692
+ assertArg(Utils16.Is.isUndefined(baseConfig.voiceId) || isVoiceId(baseConfig.voiceId) || Utils16.Is.isArray(baseConfig.voiceId) && baseConfig.voiceId.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceId", baseConfig.voiceId);
7693
+ if (!Utils16.Is.isUndefined(baseConfig.voiceIds)) {
7694
+ assertArg(isVoiceId(baseConfig.voiceIds) || Utils16.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
7695
+ console.warn(`Staff/tab config property 'voiceIds' is deprecated, use 'voiceId' instead.`);
7696
+ let arr = Utils16.Arr.toArray((_a = baseConfig.voiceId) != null ? _a : []);
7697
+ Utils16.Arr.toArray(baseConfig.voiceIds).forEach((voiceId) => arr.push(voiceId));
7698
+ baseConfig.voiceId = arr;
7699
+ }
7700
+ if (Utils16.Is.isArray(baseConfig.voiceId)) {
7701
+ baseConfig.voiceId = Utils16.Arr.removeDuplicates(baseConfig.voiceId);
7702
+ }
7703
+ assertArg(Utils16.Is.isStringOrUndefined(baseConfig.instrument), "baseConfig.instrument", baseConfig.instrument);
7507
7704
  }
7508
7705
  function assertStaffConfig(staffConfig) {
7509
7706
  assertBaseConfig(staffConfig);
7510
- assertArg(Utils15.Is.isObject(staffConfig), "staffConfig", staffConfig);
7707
+ assertArg(Utils16.Is.isObject(staffConfig), "staffConfig", staffConfig);
7511
7708
  assertArg(staffConfig.type === "staff", "staffConfig.type", staffConfig.type);
7512
- assertArg(Utils15.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7513
- assertArg(Utils15.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7514
- assertArg(Utils15.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7515
- assertArg(Utils15.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7516
- assertArg(Utils15.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
7517
- assertArg(Utils15.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
7709
+ assertArg(Utils16.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7710
+ assertArg(Utils16.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7711
+ assertArg(Utils16.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7712
+ assertArg(Utils16.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7713
+ assertArg(Utils16.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
7714
+ assertArg(Utils16.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
7715
+ if (!Utils16.Is.isUndefined(staffConfig.isGrand)) {
7716
+ console.warn(`Staff config property 'isGrand' is deprecated, use 'grandId' instead.`);
7717
+ }
7518
7718
  }
7519
7719
  function assertTabConfig(tabConfig) {
7520
7720
  assertBaseConfig(tabConfig);
7521
- assertArg(Utils15.Is.isObject(tabConfig), "tabConfig", tabConfig);
7721
+ assertArg(Utils16.Is.isObject(tabConfig), "tabConfig", tabConfig);
7522
7722
  assertArg(tabConfig.type === "tab", "tabConfig.type", tabConfig.type);
7523
- if (Utils15.Is.isString(tabConfig.tuning)) {
7723
+ if (Utils16.Is.isString(tabConfig.tuning)) {
7524
7724
  assertArg(TuningNameList.includes(tabConfig.tuning), "tabConfig.tuning", tabConfig.tuning);
7525
- } else if (Utils15.Is.isArray(tabConfig.tuning)) {
7725
+ } else if (Utils16.Is.isArray(tabConfig.tuning)) {
7526
7726
  assertArg(tabConfig.tuning.length === getStringNumbers().length && tabConfig.tuning.every((s) => isNote(s)), "tabConfig.tuning", tabConfig.tuning);
7527
7727
  }
7528
7728
  }
7529
7729
  function assertNoteOptions(noteOptions) {
7530
- assertArg(Utils15.Is.isObject(noteOptions), "noteOptions", noteOptions);
7531
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.dotted) || Utils15.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
7532
- assertArg(Utils15.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
7533
- assertArg(Utils15.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
7534
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.arpeggio) || Utils15.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
7535
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
7536
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
7537
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
7538
- assertArg(Utils15.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || Utils15.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
7539
- assertArg(Utils15.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7540
- assertArg(Utils15.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7730
+ assertArg(Utils16.Is.isObject(noteOptions), "noteOptions", noteOptions);
7731
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.dotted) || Utils16.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
7732
+ assertArg(Utils16.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
7733
+ assertArg(Utils16.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
7734
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.arpeggio) || Utils16.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
7735
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
7736
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
7737
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
7738
+ assertArg(Utils16.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || Utils16.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
7739
+ assertArg(Utils16.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7740
+ assertArg(Utils16.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7541
7741
  }
7542
7742
  function assertRestOptions(restOptions) {
7543
- assertArg(Utils15.Is.isObject(restOptions), "restOptions", restOptions);
7544
- assertArg(Utils15.Is.isBooleanOrUndefined(restOptions.dotted) || Utils15.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
7545
- assertArg(Utils15.Is.isStringOrUndefined(restOptions.staffPos) || Utils15.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof Note10, "restOptions.staffPos", restOptions.staffPos);
7546
- assertArg(Utils15.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
7547
- assertArg(Utils15.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
7548
- assertArg(Utils15.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
7743
+ assertArg(Utils16.Is.isObject(restOptions), "restOptions", restOptions);
7744
+ assertArg(Utils16.Is.isBooleanOrUndefined(restOptions.dotted) || Utils16.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
7745
+ assertArg(Utils16.Is.isStringOrUndefined(restOptions.staffPos) || Utils16.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof Note10, "restOptions.staffPos", restOptions.staffPos);
7746
+ assertArg(Utils16.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
7747
+ assertArg(Utils16.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
7748
+ assertArg(Utils16.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
7549
7749
  }
7550
7750
  function assertLyricsOptions(lyricsOptions) {
7551
- assertArg(Utils15.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
7552
- assertArg(Utils15.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
7553
- assertArg(Utils15.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
7751
+ assertArg(Utils16.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
7752
+ assertArg(Utils16.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
7753
+ assertArg(Utils16.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
7754
+ }
7755
+ function assertMeasureOptions(measureOptions) {
7756
+ assertArg(Utils16.Is.isObject(measureOptions), "measureOptions", measureOptions);
7757
+ assertArg(Utils16.Is.isBooleanOrUndefined(measureOptions.showNumber), "measureOptions.showNumber", measureOptions.showNumber);
7554
7758
  }
7555
7759
  function assertStaffTabOrGRoups(staffTabOrGroups) {
7556
7760
  assertArg(
7557
- Utils15.Is.isStringOrUndefined(staffTabOrGroups) || Utils15.Is.isIntegerGte(staffTabOrGroups, 0) || Utils15.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7558
- (staffTabOrGroup) => Utils15.Is.isString(staffTabOrGroup) || Utils15.Is.isIntegerGte(staffTabOrGroup, 0)
7761
+ Utils16.Is.isStringOrUndefined(staffTabOrGroups) || Utils16.Is.isIntegerGte(staffTabOrGroups, 0) || Utils16.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7762
+ (staffTabOrGroup) => Utils16.Is.isString(staffTabOrGroup) || Utils16.Is.isIntegerGte(staffTabOrGroup, 0)
7559
7763
  ),
7560
7764
  "staffTabOrGroup",
7561
7765
  staffTabOrGroups
@@ -7563,7 +7767,7 @@ function assertStaffTabOrGRoups(staffTabOrGroups) {
7563
7767
  }
7564
7768
  function isNoteLength(noteLen) {
7565
7769
  try {
7566
- validateNoteLength4(noteLen);
7770
+ validateNoteLength3(noteLen);
7567
7771
  return true;
7568
7772
  } catch (e) {
7569
7773
  return false;
@@ -7577,7 +7781,7 @@ function isTupletRatio(tupletRatio) {
7577
7781
  return false;
7578
7782
  }
7579
7783
  }
7580
- var DocumentBuilder = class {
7784
+ var _DocumentBuilder = class _DocumentBuilder {
7581
7785
  /**
7582
7786
  * Create new document builder instance.
7583
7787
  */
@@ -7587,19 +7791,19 @@ var DocumentBuilder = class {
7587
7791
  this.doc = new ObjDocument();
7588
7792
  }
7589
7793
  setScoreConfiguration(config) {
7590
- if (Utils15.Is.isEnumValue(config, StaffPreset)) {
7794
+ if (Utils16.Is.isEnumValue(config, StaffPreset)) {
7591
7795
  this.doc.setScoreConfiguration(config);
7592
- } else if (Utils15.Is.isObject(config) && config.type === "staff") {
7796
+ } else if (Utils16.Is.isObject(config) && config.type === "staff") {
7593
7797
  assertStaffConfig(config);
7594
7798
  this.doc.setScoreConfiguration(config);
7595
- } else if (Utils15.Is.isObject(config) && config.type === "tab") {
7799
+ } else if (Utils16.Is.isObject(config) && config.type === "tab") {
7596
7800
  assertTabConfig(config);
7597
7801
  this.doc.setScoreConfiguration(config);
7598
- } else if (Utils15.Is.isNonEmptyArray(config)) {
7802
+ } else if (Utils16.Is.isNonEmptyArray(config)) {
7599
7803
  config.forEach((c) => {
7600
- if (Utils15.Is.isObject(c) && c.type === "staff") {
7804
+ if (Utils16.Is.isObject(c) && c.type === "staff") {
7601
7805
  assertStaffConfig(c);
7602
- } else if (Utils15.Is.isObject(c) && c.type === "tab") {
7806
+ } else if (Utils16.Is.isObject(c) && c.type === "tab") {
7603
7807
  assertTabConfig(c);
7604
7808
  } else {
7605
7809
  assertArg(false, "config", config);
@@ -7613,7 +7817,7 @@ var DocumentBuilder = class {
7613
7817
  }
7614
7818
  getMeasure() {
7615
7819
  var _a;
7616
- return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure();
7820
+ return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure(_DocumentBuilder.DefaultMeasureOptions);
7617
7821
  }
7618
7822
  /**
7619
7823
  * Get music document after finished building.
@@ -7630,9 +7834,9 @@ var DocumentBuilder = class {
7630
7834
  * @returns - This document builder instance.
7631
7835
  */
7632
7836
  setHeader(title, composer, arranger) {
7633
- assertArg(Utils15.Is.isStringOrUndefined(title), "title", title);
7634
- assertArg(Utils15.Is.isStringOrUndefined(composer), "composer", composer);
7635
- assertArg(Utils15.Is.isStringOrUndefined(arranger), "arranger", arranger);
7837
+ assertArg(Utils16.Is.isStringOrUndefined(title), "title", title);
7838
+ assertArg(Utils16.Is.isStringOrUndefined(composer), "composer", composer);
7839
+ assertArg(Utils16.Is.isStringOrUndefined(arranger), "arranger", arranger);
7636
7840
  this.doc.setHeader(title, composer, arranger);
7637
7841
  return this;
7638
7842
  }
@@ -7642,29 +7846,32 @@ var DocumentBuilder = class {
7642
7846
  * @returns - This document builder instance.
7643
7847
  */
7644
7848
  setMeasuresPerRow(measuresPerRow) {
7645
- assertArg(Utils15.Is.isIntegerGte(measuresPerRow, 1) || Utils15.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
7849
+ assertArg(Utils16.Is.isIntegerGte(measuresPerRow, 1) || Utils16.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
7646
7850
  this.doc.setMeasuresPerRow(measuresPerRow);
7647
7851
  return this;
7648
7852
  }
7649
7853
  /**
7650
7854
  * Add new measure.
7855
+ * @param measureOptions - Measure options.
7651
7856
  * @returns - This document builder instance.
7652
7857
  */
7653
- addMeasure() {
7654
- this.doc.addMeasure();
7858
+ addMeasure(measureOptions) {
7859
+ measureOptions != null ? measureOptions : measureOptions = {};
7860
+ assertMeasureOptions(measureOptions);
7861
+ this.doc.addMeasure(measureOptions);
7655
7862
  return this;
7656
7863
  }
7657
7864
  setKeySignature(...args) {
7658
- assertArg(args[0] instanceof Scale2 || args[0] instanceof KeySignature3 || Utils15.Is.isNonEmptyString(args[0]) && (args.length === 1 || Utils15.Is.isEnumValue(args[1], ScaleType)), "keySignature", args);
7865
+ assertArg(args[0] instanceof Scale2 || args[0] instanceof KeySignature3 || Utils16.Is.isNonEmptyString(args[0]) && (args.length === 1 || Utils16.Is.isEnumValue(args[1], ScaleType)), "keySignature", args);
7659
7866
  this.getMeasure().setKeySignature(...args);
7660
7867
  return this;
7661
7868
  }
7662
7869
  setTimeSignature(...args) {
7663
7870
  if (args[0] instanceof TimeSignature2) {
7664
7871
  this.getMeasure().setTimeSignature(args[0]);
7665
- } else if (Utils15.Is.isEnumValue(args[0], TimeSignatures) && Utils15.Is.isEnumValueOrUndefined(args[1], BeamGrouping)) {
7872
+ } else if (Utils16.Is.isEnumValue(args[0], TimeSignatures) && Utils16.Is.isEnumValueOrUndefined(args[1], BeamGrouping)) {
7666
7873
  this.getMeasure().setTimeSignature(new TimeSignature2(args[0], args[1]));
7667
- } else if (Utils15.Is.isIntegerGte(args[0], 1) && Utils15.Is.isIntegerGte(args[1], 1) && Utils15.Is.isEnumValueOrUndefined(args[2], BeamGrouping)) {
7874
+ } else if (Utils16.Is.isIntegerGte(args[0], 1) && Utils16.Is.isIntegerGte(args[1], 1) && Utils16.Is.isEnumValueOrUndefined(args[2], BeamGrouping)) {
7668
7875
  this.getMeasure().setTimeSignature(new TimeSignature2(args[0], args[1], args[2]));
7669
7876
  } else {
7670
7877
  assertArg(false, "timeSignature args", args);
@@ -7672,12 +7879,12 @@ var DocumentBuilder = class {
7672
7879
  return this;
7673
7880
  }
7674
7881
  setTempo(beatsPerMinute, beatLength, dotted) {
7675
- assertArg(Utils15.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
7882
+ assertArg(Utils16.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
7676
7883
  if (beatLength === void 0) {
7677
- assertArg(Utils15.Is.isUndefined(dotted), "dotted", dotted);
7884
+ assertArg(Utils16.Is.isUndefined(dotted), "dotted", dotted);
7678
7885
  } else {
7679
- assertArg(Utils15.Is.isEnumValue(beatLength, NoteLength9) || isNoteLength(beatLength), "beatLength", beatLength);
7680
- assertArg(Utils15.Is.isBooleanOrUndefined(dotted) || Utils15.Is.isIntegerGte(dotted, 0), "dotted", dotted);
7886
+ assertArg(Utils16.Is.isEnumValue(beatLength, NoteLength8) || isNoteLength(beatLength), "beatLength", beatLength);
7887
+ assertArg(Utils16.Is.isBooleanOrUndefined(dotted) || Utils16.Is.isIntegerGte(dotted, 0), "dotted", dotted);
7681
7888
  }
7682
7889
  this.getMeasure().setTempo(beatsPerMinute, beatLength, dotted);
7683
7890
  return this;
@@ -7693,17 +7900,17 @@ var DocumentBuilder = class {
7693
7900
  addNote(voiceId, note, noteLength, noteOptions) {
7694
7901
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7695
7902
  assertArg(
7696
- note instanceof Note10 || Utils15.Is.isNonEmptyString(note) || Utils15.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils15.Is.isNonEmptyString(note2)),
7903
+ note instanceof Note10 || Utils16.Is.isNonEmptyString(note) || Utils16.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils16.Is.isNonEmptyString(note2)),
7697
7904
  "note",
7698
7905
  note
7699
7906
  );
7700
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7907
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7701
7908
  noteOptions != null ? noteOptions : noteOptions = {};
7702
7909
  assertNoteOptions(noteOptions);
7703
- if (Utils15.Is.isArray(note)) {
7910
+ if (Utils16.Is.isArray(note)) {
7704
7911
  let string = noteOptions.string;
7705
7912
  note.forEach((note2, noteId) => {
7706
- noteOptions.string = Utils15.Is.isArray(string) ? string[noteId] : string;
7913
+ noteOptions.string = Utils16.Is.isArray(string) ? string[noteId] : string;
7707
7914
  this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions);
7708
7915
  });
7709
7916
  } else {
@@ -7721,8 +7928,8 @@ var DocumentBuilder = class {
7721
7928
  */
7722
7929
  addChord(voiceId, notes, noteLength, noteOptions) {
7723
7930
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7724
- assertArg(Utils15.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils15.Is.isNonEmptyString(note)), "notes", notes);
7725
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7931
+ assertArg(Utils16.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils16.Is.isNonEmptyString(note)), "notes", notes);
7932
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7726
7933
  noteOptions != null ? noteOptions : noteOptions = {};
7727
7934
  assertNoteOptions(noteOptions);
7728
7935
  this.getMeasure().addNoteGroup(voiceId, notes, noteLength, noteOptions);
@@ -7737,7 +7944,7 @@ var DocumentBuilder = class {
7737
7944
  */
7738
7945
  addRest(voiceId, restLength, restOptions) {
7739
7946
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7740
- assertArg(Utils15.Is.isEnumValue(restLength, NoteLength9) || isNoteLength(restLength), "restLength", restLength);
7947
+ assertArg(Utils16.Is.isEnumValue(restLength, NoteLength8) || isNoteLength(restLength), "restLength", restLength);
7741
7948
  restOptions != null ? restOptions : restOptions = {};
7742
7949
  assertRestOptions(restOptions);
7743
7950
  this.getMeasure().addRest(voiceId, restLength, restOptions);
@@ -7760,24 +7967,24 @@ var DocumentBuilder = class {
7760
7967
  */
7761
7968
  addTuplet(voiceId, tupletRatio, tupletBuilder) {
7762
7969
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7763
- assertArg(Utils15.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
7764
- assertArg(isTupletRatio(tupletRatio) && Utils15.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
7970
+ assertArg(Utils16.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
7971
+ assertArg(isTupletRatio(tupletRatio) && Utils16.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
7765
7972
  let tupletSymbols = [];
7766
7973
  const helper = {
7767
7974
  addNote: (note, noteLength, noteOptions) => {
7768
7975
  assertArg(
7769
- note instanceof Note10 || Utils15.Is.isNonEmptyString(note) || Utils15.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils15.Is.isNonEmptyString(note2)),
7976
+ note instanceof Note10 || Utils16.Is.isNonEmptyString(note) || Utils16.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils16.Is.isNonEmptyString(note2)),
7770
7977
  "note",
7771
7978
  note
7772
7979
  );
7773
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7980
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7774
7981
  noteOptions != null ? noteOptions : noteOptions = {};
7775
7982
  delete noteOptions.triplet;
7776
7983
  assertNoteOptions(noteOptions);
7777
- if (Utils15.Is.isArray(note)) {
7984
+ if (Utils16.Is.isArray(note)) {
7778
7985
  let string = noteOptions.string;
7779
7986
  note.forEach((note2, noteId) => {
7780
- noteOptions.string = Utils15.Is.isArray(string) ? string[noteId] : string;
7987
+ noteOptions.string = Utils16.Is.isArray(string) ? string[noteId] : string;
7781
7988
  let s = this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions, tupletRatio);
7782
7989
  tupletSymbols.push(s);
7783
7990
  });
@@ -7788,8 +7995,8 @@ var DocumentBuilder = class {
7788
7995
  return helper;
7789
7996
  },
7790
7997
  addChord: (notes, noteLength, noteOptions) => {
7791
- assertArg(Utils15.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils15.Is.isNonEmptyString(note)), "notes", notes);
7792
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7998
+ assertArg(Utils16.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils16.Is.isNonEmptyString(note)), "notes", notes);
7999
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7793
8000
  noteOptions != null ? noteOptions : noteOptions = {};
7794
8001
  delete noteOptions.triplet;
7795
8002
  assertNoteOptions(noteOptions);
@@ -7798,7 +8005,7 @@ var DocumentBuilder = class {
7798
8005
  return helper;
7799
8006
  },
7800
8007
  addRest: (restLength, restOptions) => {
7801
- assertArg(Utils15.Is.isEnumValue(restLength, NoteLength9) || isNoteLength(restLength), "restLength", restLength);
8008
+ assertArg(Utils16.Is.isEnumValue(restLength, NoteLength8) || isNoteLength(restLength), "restLength", restLength);
7802
8009
  restOptions != null ? restOptions : restOptions = {};
7803
8010
  delete restOptions.triplet;
7804
8011
  assertRestOptions(restOptions);
@@ -7815,8 +8022,8 @@ var DocumentBuilder = class {
7815
8022
  var _a;
7816
8023
  assertStaffTabOrGRoups(staffTabOrGroups);
7817
8024
  assertArg(isVerseNumber(verse), "verse", verse);
7818
- assertArg(Utils15.Is.isEnumValue(lyricsLength, NoteLength9), "lyricsLength", lyricsLength);
7819
- assertArg(Utils15.Is.isString(lyricsText) || Utils15.Is.isArray(lyricsText) && lyricsText.every((text) => Utils15.Is.isString(text)), "lyricsText", lyricsText);
8025
+ assertArg(Utils16.Is.isEnumValue(lyricsLength, NoteLength8), "lyricsLength", lyricsLength);
8026
+ assertArg(Utils16.Is.isString(lyricsText) || Utils16.Is.isArray(lyricsText) && lyricsText.every((text) => Utils16.Is.isString(text)), "lyricsText", lyricsText);
7820
8027
  lyricsOptions != null ? lyricsOptions : lyricsOptions = {};
7821
8028
  assertLyricsOptions(lyricsOptions);
7822
8029
  if (lyricsOptions.align !== void 0) {
@@ -7824,7 +8031,7 @@ var DocumentBuilder = class {
7824
8031
  } else {
7825
8032
  (_a = lyricsOptions.align) != null ? _a : lyricsOptions.align = this.currentLyricsAlign;
7826
8033
  }
7827
- if (Utils15.Is.isArray(lyricsText)) {
8034
+ if (Utils16.Is.isArray(lyricsText)) {
7828
8035
  lyricsText.forEach((text) => this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, text, lyricsOptions));
7829
8036
  } else {
7830
8037
  this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions);
@@ -7856,7 +8063,7 @@ var DocumentBuilder = class {
7856
8063
  }
7857
8064
  addFermataInternal(staffTabOrGroups, fermata) {
7858
8065
  assertStaffTabOrGRoups(staffTabOrGroups);
7859
- assertArg(Utils15.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
8066
+ assertArg(Utils16.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
7860
8067
  this.getMeasure().addFermata(staffTabOrGroups, fermata);
7861
8068
  return this;
7862
8069
  }
@@ -7879,11 +8086,11 @@ var DocumentBuilder = class {
7879
8086
  }
7880
8087
  addNavigationInternal(staffTabOrGroups, navigation, ...args) {
7881
8088
  assertStaffTabOrGRoups(staffTabOrGroups);
7882
- assertArg(Utils15.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
8089
+ assertArg(Utils16.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
7883
8090
  if (navigation === "endRepeat" /* EndRepeat */ && args.length > 0) {
7884
- assertArg(Utils15.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
8091
+ assertArg(Utils16.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
7885
8092
  } else if (navigation === "ending" /* Ending */ && args.length > 0) {
7886
- assertArg(args.every((passage) => Utils15.Is.isIntegerGte(passage, 1)), "passages", args);
8093
+ assertArg(args.every((passage) => Utils16.Is.isIntegerGte(passage, 1)), "passages", args);
7887
8094
  }
7888
8095
  this.getMeasure().addNavigation(staffTabOrGroups, navigation, ...args);
7889
8096
  return this;
@@ -7900,8 +8107,8 @@ var DocumentBuilder = class {
7900
8107
  throw new MusicError18(MusicErrorType18.Score, `Annotation text "${text}" is not known annotation.`);
7901
8108
  }
7902
8109
  assertStaffTabOrGRoups(staffTabOrGroups);
7903
- assertArg(Utils15.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
7904
- assertArg(Utils15.Is.isNonEmptyString(text), "text", text);
8110
+ assertArg(Utils16.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
8111
+ assertArg(Utils16.Is.isNonEmptyString(text), "text", text);
7905
8112
  this.getMeasure().addAnnotation(staffTabOrGroups, annotation, text);
7906
8113
  return this;
7907
8114
  }
@@ -7921,8 +8128,8 @@ var DocumentBuilder = class {
7921
8128
  }
7922
8129
  addLabelInternal(staffTabOrGroups, label, text) {
7923
8130
  assertStaffTabOrGRoups(staffTabOrGroups);
7924
- assertArg(Utils15.Is.isEnumValue(label, Label), "label", label);
7925
- assertArg(Utils15.Is.isNonEmptyString(text), "text", text);
8131
+ assertArg(Utils16.Is.isEnumValue(label, Label), "label", label);
8132
+ assertArg(Utils16.Is.isNonEmptyString(text), "text", text);
7926
8133
  this.getMeasure().addLabel(staffTabOrGroups, label, text);
7927
8134
  return this;
7928
8135
  }
@@ -7946,21 +8153,21 @@ var DocumentBuilder = class {
7946
8153
  return this.addLabelInternal(staffTabOrGroups, label, text);
7947
8154
  }
7948
8155
  addConnective(connective, ...args) {
7949
- assertArg(Utils15.Is.isEnumValue(connective, Connective), "connective", connective);
8156
+ assertArg(Utils16.Is.isEnumValue(connective, Connective), "connective", connective);
7950
8157
  if (connective === "tie" /* Tie */) {
7951
- assertArg(Utils15.Is.isIntegerOrUndefined(args[0]) || Utils15.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
7952
- assertArg(Utils15.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8158
+ assertArg(Utils16.Is.isIntegerOrUndefined(args[0]) || Utils16.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
8159
+ assertArg(Utils16.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7953
8160
  let tieSpan = args[0];
7954
8161
  let noteAnchor = args[1];
7955
8162
  this.getMeasure().addConnective(connective, tieSpan, noteAnchor);
7956
8163
  } else if (connective === "slur" /* Slur */) {
7957
- assertArg(Utils15.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
7958
- assertArg(Utils15.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8164
+ assertArg(Utils16.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
8165
+ assertArg(Utils16.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7959
8166
  let slurSpan = args[0];
7960
8167
  let noteAnchor = args[1];
7961
8168
  this.getMeasure().addConnective(connective, slurSpan, noteAnchor);
7962
8169
  } else if (connective === "slide" /* Slide */) {
7963
- assertArg(Utils15.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
8170
+ assertArg(Utils16.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
7964
8171
  let noteAnchor = args[0];
7965
8172
  this.getMeasure().addConnective(connective, noteAnchor);
7966
8173
  }
@@ -7979,18 +8186,18 @@ var DocumentBuilder = class {
7979
8186
  * @returns - This document builder instance.
7980
8187
  */
7981
8188
  addExtension(extensionBuilder) {
7982
- assertArg(Utils15.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
8189
+ assertArg(Utils16.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
7983
8190
  let ticks = 0;
7984
8191
  let visible = true;
7985
8192
  const helper = {
7986
8193
  notes: (noteLength, noteCount) => {
7987
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7988
- assertArg(Utils15.Is.isUndefined(noteCount) || Utils15.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8194
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
8195
+ assertArg(Utils16.Is.isUndefined(noteCount) || Utils16.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
7989
8196
  ticks += RhythmProps6.get(noteLength).ticks * (noteCount != null ? noteCount : 1);
7990
8197
  return helper;
7991
8198
  },
7992
8199
  measures: (measureCount) => {
7993
- assertArg(Utils15.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8200
+ assertArg(Utils16.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
7994
8201
  ticks += this.getMeasure().getMeasureTicks() * measureCount;
7995
8202
  return helper;
7996
8203
  },
@@ -8019,13 +8226,13 @@ var DocumentBuilder = class {
8019
8226
  * @returns - This document builder instance.
8020
8227
  */
8021
8228
  addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition = "auto" /* Auto */) {
8022
- assertArg(Utils15.Is.isNonEmptyString(groupName), "groupName", groupName);
8229
+ assertArg(Utils16.Is.isNonEmptyString(groupName), "groupName", groupName);
8023
8230
  assertArg(
8024
- Utils15.Is.isNonEmptyString(staffsTabsAndGroups) || Utils15.Is.isIntegerGte(staffsTabsAndGroups, 0) || Utils15.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => Utils15.Is.isNonEmptyString(line) || Utils15.Is.isIntegerGte(line, 0)),
8231
+ Utils16.Is.isNonEmptyString(staffsTabsAndGroups) || Utils16.Is.isIntegerGte(staffsTabsAndGroups, 0) || Utils16.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => Utils16.Is.isNonEmptyString(line) || Utils16.Is.isIntegerGte(line, 0)),
8025
8232
  "staffsTabsAndGroups",
8026
8233
  staffsTabsAndGroups
8027
8234
  );
8028
- assertArg(Utils15.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8235
+ assertArg(Utils16.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8029
8236
  this.doc.addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition);
8030
8237
  return this;
8031
8238
  }
@@ -8060,7 +8267,7 @@ var DocumentBuilder = class {
8060
8267
  * @returns - This document builder instance.
8061
8268
  */
8062
8269
  completeRests(voiceId) {
8063
- assertArg(Utils15.Is.isUndefined(voiceId) || isVoiceId(voiceId) || Utils15.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8270
+ assertArg(Utils16.Is.isUndefined(voiceId) || isVoiceId(voiceId) || Utils16.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8064
8271
  this.getMeasure().completeRests(voiceId);
8065
8272
  return this;
8066
8273
  }
@@ -8072,8 +8279,8 @@ var DocumentBuilder = class {
8072
8279
  * @returns - This document builder instance.
8073
8280
  */
8074
8281
  addScaleArpeggio(scale, bottomNote, numOctaves) {
8075
- assertArg(Utils15.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8076
- assertArg(Utils15.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8282
+ assertArg(Utils16.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8283
+ assertArg(Utils16.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8077
8284
  let ts = this.getMeasure().getTimeSignature();
8078
8285
  let notes = scale.getScaleNotes(bottomNote, numOctaves);
8079
8286
  for (let i = 0; i < notes.length; i++) {
@@ -8087,6 +8294,8 @@ var DocumentBuilder = class {
8087
8294
  return this;
8088
8295
  }
8089
8296
  };
8297
+ __publicField(_DocumentBuilder, "DefaultMeasureOptions", {});
8298
+ var DocumentBuilder = _DocumentBuilder;
8090
8299
 
8091
8300
  // src/score/pub/event.ts
8092
8301
  import { MusicError as MusicError19, MusicErrorType as MusicErrorType19 } from "@tspro/web-music-score/core";
@@ -8103,32 +8312,44 @@ var ScoreStaffPosEvent = class extends ScoreEvent {
8103
8312
  /**
8104
8313
  * Create new score staff position event.
8105
8314
  * @param type - Score event type.
8106
- * @param renderer - Renderer.
8315
+ * @param renderContext - Render context.
8107
8316
  * @param scoreRow - Score row.
8108
8317
  * @param diatonicId - Diatonic id that was clicked/entered/left.
8109
8318
  */
8110
- constructor(type, renderer, scoreRow, diatonicId) {
8319
+ constructor(type, renderContext, scoreRow, diatonicId) {
8111
8320
  super(type);
8112
- this.renderer = renderer;
8321
+ this.renderContext = renderContext;
8113
8322
  this.scoreRow = scoreRow;
8114
8323
  this.diatonicId = diatonicId;
8115
8324
  }
8325
+ /**
8326
+ * @deprecated - Provided for legacy support, use renderContext instead.
8327
+ */
8328
+ get renderer() {
8329
+ return this.renderContext;
8330
+ }
8116
8331
  };
8117
8332
  var ScoreObjectEvent = class extends ScoreEvent {
8118
8333
  /**
8119
8334
  * Create new score object event.
8120
8335
  * @param type - Score event type.
8121
- * @param renderer - Renderer.
8336
+ * @param renderContext - Render context.
8122
8337
  * @param objects - Array of objects, last object in this array is the top object that was clicked/entered/left, previous objects are it's parent objects.
8123
8338
  */
8124
- constructor(type, renderer, objects) {
8339
+ constructor(type, renderContext, objects) {
8125
8340
  super(type);
8126
- this.renderer = renderer;
8341
+ this.renderContext = renderContext;
8127
8342
  this.objects = objects;
8128
8343
  if (arguments.length === 0) {
8129
8344
  throw new MusicError19(MusicErrorType19.Score, "Empty array in score object event!");
8130
8345
  }
8131
8346
  }
8347
+ /**
8348
+ * @deprecated - Provided for legacy support, use renderContext instead.
8349
+ */
8350
+ get renderer() {
8351
+ return this.renderContext;
8352
+ }
8132
8353
  /** Top object getter. */
8133
8354
  get topObject() {
8134
8355
  return this.objects[this.objects.length - 1];
@@ -8145,10 +8366,10 @@ var ScoreObjectEvent = class extends ScoreEvent {
8145
8366
 
8146
8367
  // src/score/pub/music-interface.ts
8147
8368
  import * as Audio2 from "@tspro/web-music-score/audio";
8148
- import { Utils as Utils17 } from "@tspro/ts-utils-lib";
8369
+ import { Utils as Utils18 } from "@tspro/ts-utils-lib";
8149
8370
 
8150
8371
  // src/score/pub/music-objects.ts
8151
- import { Utils as Utils16 } from "@tspro/ts-utils-lib";
8372
+ import { Utils as Utils17 } from "@tspro/ts-utils-lib";
8152
8373
  import { MusicError as MusicError20, MusicErrorType as MusicErrorType20 } from "@tspro/web-music-score/core";
8153
8374
  function assertArg2(condition, argName, argValue) {
8154
8375
  if (!condition) {
@@ -8156,7 +8377,7 @@ function assertArg2(condition, argName, argValue) {
8156
8377
  }
8157
8378
  }
8158
8379
  function isVoiceId2(value) {
8159
- return Utils16.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8380
+ return Utils17.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8160
8381
  }
8161
8382
  function getNotationLine(line) {
8162
8383
  if (line instanceof ObjStaff || line instanceof ObjTab) {
@@ -8332,7 +8553,7 @@ var _MDocument = class _MDocument extends MusicInterface6 {
8332
8553
  * @returns - Player instance.
8333
8554
  */
8334
8555
  play(playStateChangeListener) {
8335
- assertArg2(Utils16.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8556
+ assertArg2(Utils17.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8336
8557
  return new MPlayer(this, playStateChangeListener).play();
8337
8558
  }
8338
8559
  };
@@ -8362,7 +8583,7 @@ var _MEnding = class _MEnding extends MusicInterface6 {
8362
8583
  * @returns - Boolean whether this ending has asked passage number.
8363
8584
  */
8364
8585
  hasPassage(passage) {
8365
- assertArg2(Utils16.Is.isIntegerGte(passage, 1), "passage", passage);
8586
+ assertArg2(Utils17.Is.isIntegerGte(passage, 1), "passage", passage);
8366
8587
  return this.obj.hasPassage(passage);
8367
8588
  }
8368
8589
  };
@@ -9049,7 +9270,7 @@ var _MPlayer = class _MPlayer {
9049
9270
  constructor(doc, playStateChangeListener) {
9050
9271
  __publicField(this, "player");
9051
9272
  assertArg3(doc instanceof MDocument2, "doc", doc);
9052
- assertArg3(Utils17.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9273
+ assertArg3(Utils18.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9053
9274
  this.player = new Player();
9054
9275
  this.player.setDocument(doc.getMusicObject());
9055
9276
  this.player.setCursorPositionChangeListener((cursorRect) => doc.getMusicObject().updateCursorRect(cursorRect));
@@ -9093,32 +9314,32 @@ var _MPlayer = class _MPlayer {
9093
9314
  };
9094
9315
  __publicField(_MPlayer, "currentlyPlaying", /* @__PURE__ */ new Set());
9095
9316
  var MPlayer = _MPlayer;
9096
- var MRenderer2 = class {
9317
+ var MRenderContext2 = class {
9097
9318
  /**
9098
- * Create new renderer instance.
9319
+ * Create new render context instance.
9099
9320
  */
9100
9321
  constructor() {
9101
- __publicField(this, "renderer");
9102
- this.renderer = new Renderer(this);
9322
+ __publicField(this, "ctx");
9323
+ this.ctx = new RenderContext(this);
9103
9324
  }
9104
9325
  /**
9105
- * Attach music document to this renderer.
9326
+ * Attach music document to this render context.
9106
9327
  * @param doc - Music document.
9107
- * @returns - This renderer instance.
9328
+ * @returns - This render context instance.
9108
9329
  */
9109
9330
  setDocument(doc) {
9110
- assertArg3(Utils17.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9111
- this.renderer.setDocument(doc);
9331
+ assertArg3(Utils18.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9332
+ this.ctx.setDocument(doc);
9112
9333
  return this;
9113
9334
  }
9114
9335
  /**
9115
- * Set target canvas html element for this renderer.
9336
+ * Set target canvas html element for this render context.
9116
9337
  * @param canvas - HTML canvas element or element id.
9117
- * @returns - This renderer instance.
9338
+ * @returns - This render context instance.
9118
9339
  */
9119
9340
  setCanvas(canvas) {
9120
- canvas = require_t(Utils17.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
9121
- this.renderer.setCanvas(canvas);
9341
+ canvas = require_t(Utils18.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set render canvas because invalid canvas id: " + canvas : "Cannot set render canvas because given canvas is undefined.");
9342
+ this.ctx.setCanvas(canvas);
9122
9343
  return this;
9123
9344
  }
9124
9345
  /**
@@ -9126,22 +9347,22 @@ var MRenderer2 = class {
9126
9347
  * @param scoreEventListener - Score event listener.
9127
9348
  */
9128
9349
  setScoreEventListener(scoreEventListener) {
9129
- assertArg3(Utils17.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9130
- this.renderer.setScoreEventListener(scoreEventListener);
9350
+ assertArg3(Utils18.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9351
+ this.ctx.setScoreEventListener(scoreEventListener);
9131
9352
  }
9132
9353
  /**
9133
9354
  * Draw given music object hilighted.
9134
9355
  * @param obj - Music object or undefined to remove hilighting.
9135
9356
  */
9136
9357
  hilightObject(obj) {
9137
- this.renderer.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9358
+ this.ctx.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9138
9359
  }
9139
9360
  /**
9140
9361
  * Draw given staff position hilighted.
9141
9362
  * @param staffPos - Staff position (score row and diatonic id) or undefined to remove hilighting.
9142
9363
  */
9143
9364
  hilightStaffPos(staffPos) {
9144
- this.renderer.hilightStaffPos(staffPos ? {
9365
+ this.ctx.hilightStaffPos(staffPos ? {
9145
9366
  scoreRow: staffPos.scoreRow.getMusicObject(),
9146
9367
  diatonicId: staffPos.diatonicId
9147
9368
  } : void 0);
@@ -9151,13 +9372,14 @@ var MRenderer2 = class {
9151
9372
  */
9152
9373
  draw() {
9153
9374
  try {
9154
- this.renderer.draw();
9155
- } catch (e) {
9156
- console.log("Draw failed in music renderer.");
9157
- console.log(e);
9375
+ this.ctx.draw();
9376
+ } catch (err) {
9377
+ console.log("Draw failed in music render context!", err);
9158
9378
  }
9159
9379
  }
9160
9380
  };
9381
+ var MRenderer = class extends MRenderContext2 {
9382
+ };
9161
9383
  var _MPlaybackButtons = class _MPlaybackButtons {
9162
9384
  /**
9163
9385
  * Create new playback buttons helper class instance.
@@ -9200,7 +9422,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9200
9422
  * @returns
9201
9423
  */
9202
9424
  setDocument(doc) {
9203
- assertArg3(Utils17.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9425
+ assertArg3(Utils18.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9204
9426
  this.onStop();
9205
9427
  if (doc) {
9206
9428
  this.player = new MPlayer(doc, (playState) => {
@@ -9244,9 +9466,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9244
9466
  * @returns - This playback buttons class instance.
9245
9467
  */
9246
9468
  setPlayButton(btn, btnLabel) {
9247
- assertArg3(Utils17.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9469
+ assertArg3(Utils18.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9248
9470
  _MPlaybackButtons.removeOnClickListeners(this.playButton, this.onPlay);
9249
- this.playButton = require_t(Utils17.Dom.getButton(btn), "Play button required!");
9471
+ this.playButton = require_t(Utils18.Dom.getButton(btn), "Play button required!");
9250
9472
  this.playLabel = btnLabel != null ? btnLabel : "Play";
9251
9473
  _MPlaybackButtons.removeOnClickListeners(this.playButton, "all");
9252
9474
  _MPlaybackButtons.addOnClickListener(this.playButton, this.onPlay);
@@ -9260,9 +9482,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9260
9482
  * @returns - This playback buttons class instance.
9261
9483
  */
9262
9484
  setStopButton(btn, btnLabel) {
9263
- assertArg3(Utils17.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9485
+ assertArg3(Utils18.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9264
9486
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, this.onStop);
9265
- this.stopButton = require_t(Utils17.Dom.getButton(btn), "Stop button required!");
9487
+ this.stopButton = require_t(Utils18.Dom.getButton(btn), "Stop button required!");
9266
9488
  this.stopLabel = btnLabel != null ? btnLabel : "Stop";
9267
9489
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, "all");
9268
9490
  _MPlaybackButtons.addOnClickListener(this.stopButton, this.onStop);
@@ -9277,10 +9499,10 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9277
9499
  * @returns - This playback buttons class instance.
9278
9500
  */
9279
9501
  setPlayStopButton(btn, playLabel, stopLabel) {
9280
- assertArg3(Utils17.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9281
- assertArg3(Utils17.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9502
+ assertArg3(Utils18.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9503
+ assertArg3(Utils18.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9282
9504
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, this.onPlayStop);
9283
- this.playStopButton = require_t(Utils17.Dom.getButton(btn), "Play/stop button required!");
9505
+ this.playStopButton = require_t(Utils18.Dom.getButton(btn), "Play/stop button required!");
9284
9506
  this.playLabel = playLabel != null ? playLabel : "Play";
9285
9507
  this.stopLabel = stopLabel != null ? stopLabel : "Stop";
9286
9508
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, "all");
@@ -9295,9 +9517,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9295
9517
  * @returns - This playback buttons class instance.
9296
9518
  */
9297
9519
  setPauseButton(btn, btnLabel) {
9298
- assertArg3(Utils17.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9520
+ assertArg3(Utils18.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9299
9521
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, this.onPause);
9300
- this.pauseButton = require_t(Utils17.Dom.getButton(btn), "Pause button required!");
9522
+ this.pauseButton = require_t(Utils18.Dom.getButton(btn), "Pause button required!");
9301
9523
  this.pauseLabel = btnLabel != null ? btnLabel : "Pause";
9302
9524
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, "all");
9303
9525
  _MPlaybackButtons.addOnClickListener(this.pauseButton, this.onPause);
@@ -9319,7 +9541,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9319
9541
  }
9320
9542
  }
9321
9543
  static addOnClickListener(btn, onClick) {
9322
- assertArg3(Utils17.Is.isFunction(onClick), "onClick", onClick);
9544
+ assertArg3(Utils18.Is.isFunction(onClick), "onClick", onClick);
9323
9545
  btn.addEventListener("click", onClick);
9324
9546
  let clickListeners = this.savedOnClickListeners.get(btn) || [];
9325
9547
  this.savedOnClickListeners.set(btn, [...clickListeners, onClick]);
@@ -9360,7 +9582,8 @@ export {
9360
9582
  MNoteGroup,
9361
9583
  MPlaybackButtons,
9362
9584
  MPlayer,
9363
- MRenderer2 as MRenderer,
9585
+ MRenderContext2 as MRenderContext,
9586
+ MRenderer,
9364
9587
  MRest,
9365
9588
  MRhythmColumn,
9366
9589
  MScoreRow,