@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,4 +1,4 @@
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
  "use strict";
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -61,7 +61,8 @@ __export(score_exports, {
61
61
  MNoteGroup: () => MNoteGroup,
62
62
  MPlaybackButtons: () => MPlaybackButtons,
63
63
  MPlayer: () => MPlayer,
64
- MRenderer: () => MRenderer2,
64
+ MRenderContext: () => MRenderContext2,
65
+ MRenderer: () => MRenderer,
65
66
  MRest: () => MRest,
66
67
  MRhythmColumn: () => MRhythmColumn,
67
68
  MScoreRow: () => MScoreRow,
@@ -375,7 +376,7 @@ var DivRect = class _DivRect {
375
376
  };
376
377
 
377
378
  // src/score/pub/document-builder.ts
378
- var import_ts_utils_lib16 = require("@tspro/ts-utils-lib");
379
+ var import_ts_utils_lib18 = require("@tspro/ts-utils-lib");
379
380
 
380
381
  // src/score/pub/types.ts
381
382
  var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
@@ -387,10 +388,10 @@ var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
387
388
  StaffPreset3["GuitarCombined"] = "guitarCombined";
388
389
  return StaffPreset3;
389
390
  })(StaffPreset || {});
390
- var Clef = /* @__PURE__ */ ((Clef4) => {
391
- Clef4["G"] = "G";
392
- Clef4["F"] = "F";
393
- return Clef4;
391
+ var Clef = /* @__PURE__ */ ((Clef2) => {
392
+ Clef2["G"] = "G";
393
+ Clef2["F"] = "F";
394
+ return Clef2;
394
395
  })(Clef || {});
395
396
  function getVoiceIds() {
396
397
  return [0, 1, 2, 3];
@@ -586,7 +587,7 @@ var import_theory12 = require("@tspro/web-music-score/theory");
586
587
  // src/score/engine/obj-staff-and-tab.ts
587
588
  var import_theory11 = require("@tspro/web-music-score/theory");
588
589
 
589
- // src/score/engine/renderer.ts
590
+ // src/score/engine/render-context.ts
590
591
  var import_ts_utils_lib3 = require("@tspro/ts-utils-lib");
591
592
 
592
593
  // src/score/engine/settings.ts
@@ -611,6 +612,7 @@ var DocumentSettings = {
611
612
  FlagSeparation: 2,
612
613
  BeamSeparation: 1.25,
613
614
  BeamAngleFactor: 0.5,
615
+ BeamThickness: 4,
614
616
  RestDotSpace: 0.5,
615
617
  LedgerLineWidth: 3.6,
616
618
  StubTieLength: 5,
@@ -618,58 +620,58 @@ var DocumentSettings = {
618
620
  TabHeight: 20
619
621
  };
620
622
 
621
- // src/score/engine/renderer.ts
623
+ // src/score/engine/render-context.ts
622
624
  var import_core3 = require("@tspro/web-music-score/core");
623
625
 
624
- // src/score/engine/assets/treble-clef.png
625
- 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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";
626
+ // src/score/engine/assets/F-clef.png
627
+ 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==";
626
628
 
627
- // src/score/engine/assets/bass-clef.png
628
- 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==";
629
+ // src/score/engine/assets/G-clef.png
630
+ 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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";
629
631
 
630
632
  // src/theory/rhythm.ts
631
633
  var import_ts_utils_lib2 = require("@tspro/ts-utils-lib");
632
634
  var import_core2 = require("@tspro/web-music-score/core");
633
635
  var MaxTupletRatioValue = 12;
634
636
  var TicksMultiplier = 12 * 11 * 9 * 7 * 5;
635
- var NoteLength = /* @__PURE__ */ ((NoteLength10) => {
636
- NoteLength10["Whole"] = "1n";
637
- NoteLength10["WholeTriplet"] = "1t";
638
- NoteLength10["WholeDot"] = "1.";
639
- NoteLength10["Whole2Dots"] = "1..";
640
- NoteLength10["Whole12Dots"] = "1..";
641
- NoteLength10["Whole3Dots"] = "1...";
642
- NoteLength10["Whole4Dots"] = "1....";
643
- NoteLength10["Whole5Dots"] = "1.....";
644
- NoteLength10["Whole6Dots"] = "1......";
645
- NoteLength10["Half"] = "2n";
646
- NoteLength10["HalfTriplet"] = "2t";
647
- NoteLength10["HalfDot"] = "2.";
648
- NoteLength10["Half2Dots"] = "2..";
649
- NoteLength10["Half3Dots"] = "2...";
650
- NoteLength10["Half4Dots"] = "2....";
651
- NoteLength10["Half5Dots"] = "2.....";
652
- NoteLength10["Quarter"] = "4n";
653
- NoteLength10["QuarterTriplet"] = "4t";
654
- NoteLength10["QuarterDot"] = "4.";
655
- NoteLength10["Quarter2Dots"] = "4..";
656
- NoteLength10["Quarter3Dots"] = "4...";
657
- NoteLength10["Quarter4Dots"] = "4....";
658
- NoteLength10["Eighth"] = "8n";
659
- NoteLength10["EighthTriplet"] = "8t";
660
- NoteLength10["EighthDot"] = "8.";
661
- NoteLength10["Eighth2Dots"] = "8..";
662
- NoteLength10["Eighth3Dots"] = "8...";
663
- NoteLength10["Sixteenth"] = "16n";
664
- NoteLength10["SixteenthTriplet"] = "16t";
665
- NoteLength10["SixteenthDot"] = "16.";
666
- NoteLength10["Sixteenth2Dots"] = "16..";
667
- NoteLength10["ThirtySecond"] = "32n";
668
- NoteLength10["ThirtySecondTriplet"] = "32t";
669
- NoteLength10["ThirtySecondDot"] = "32.";
670
- NoteLength10["SixtyFourth"] = "64n";
671
- NoteLength10["SixtyFourthTriplet"] = "64t";
672
- return NoteLength10;
637
+ var NoteLength = /* @__PURE__ */ ((NoteLength9) => {
638
+ NoteLength9["Whole"] = "1n";
639
+ NoteLength9["WholeTriplet"] = "1t";
640
+ NoteLength9["WholeDot"] = "1.";
641
+ NoteLength9["Whole2Dots"] = "1..";
642
+ NoteLength9["Whole12Dots"] = "1..";
643
+ NoteLength9["Whole3Dots"] = "1...";
644
+ NoteLength9["Whole4Dots"] = "1....";
645
+ NoteLength9["Whole5Dots"] = "1.....";
646
+ NoteLength9["Whole6Dots"] = "1......";
647
+ NoteLength9["Half"] = "2n";
648
+ NoteLength9["HalfTriplet"] = "2t";
649
+ NoteLength9["HalfDot"] = "2.";
650
+ NoteLength9["Half2Dots"] = "2..";
651
+ NoteLength9["Half3Dots"] = "2...";
652
+ NoteLength9["Half4Dots"] = "2....";
653
+ NoteLength9["Half5Dots"] = "2.....";
654
+ NoteLength9["Quarter"] = "4n";
655
+ NoteLength9["QuarterTriplet"] = "4t";
656
+ NoteLength9["QuarterDot"] = "4.";
657
+ NoteLength9["Quarter2Dots"] = "4..";
658
+ NoteLength9["Quarter3Dots"] = "4...";
659
+ NoteLength9["Quarter4Dots"] = "4....";
660
+ NoteLength9["Eighth"] = "8n";
661
+ NoteLength9["EighthTriplet"] = "8t";
662
+ NoteLength9["EighthDot"] = "8.";
663
+ NoteLength9["Eighth2Dots"] = "8..";
664
+ NoteLength9["Eighth3Dots"] = "8...";
665
+ NoteLength9["Sixteenth"] = "16n";
666
+ NoteLength9["SixteenthTriplet"] = "16t";
667
+ NoteLength9["SixteenthDot"] = "16.";
668
+ NoteLength9["Sixteenth2Dots"] = "16..";
669
+ NoteLength9["ThirtySecond"] = "32n";
670
+ NoteLength9["ThirtySecondTriplet"] = "32t";
671
+ NoteLength9["ThirtySecondDot"] = "32.";
672
+ NoteLength9["SixtyFourth"] = "64n";
673
+ NoteLength9["SixtyFourthTriplet"] = "64t";
674
+ return NoteLength9;
673
675
  })(NoteLength || {});
674
676
  function validateNoteLength(noteLength) {
675
677
  if (import_ts_utils_lib2.Utils.Is.isEnumValue(noteLength, NoteLength)) {
@@ -876,13 +878,13 @@ __publicField(_RhythmProps, "NoteSymbolMap", /* @__PURE__ */ new Map([[1, "\u{1D
876
878
  __publicField(_RhythmProps, "cache", /* @__PURE__ */ new Map());
877
879
  var RhythmProps = _RhythmProps;
878
880
 
879
- // src/score/engine/renderer.ts
881
+ // src/score/engine/render-context.ts
880
882
  var HilightStaffPosRectColor = "#55cc55";
881
883
  var HilightObjectRectColor = "#55cc55";
882
884
  var PlayPosIndicatorColor = "#44aa44";
883
885
  var ImageAssets = /* @__PURE__ */ new Map([
884
- [0 /* TrebleClefPng */, { src: treble_clef_default }],
885
- [1 /* BassClefPng */, { src: bass_clef_default }]
886
+ [0 /* G_Clef */, { src: G_clef_default }],
887
+ [1 /* F_Clef */, { src: F_clef_default }]
886
888
  ]);
887
889
  function staffPosEquals(a, b) {
888
890
  if (!a && !b) return true;
@@ -894,14 +896,13 @@ function objectsEquals(a, b) {
894
896
  else if (!a || !b) return false;
895
897
  else return a.length === b.length && a.every((a2, i) => a2 === b[i]);
896
898
  }
897
- var Renderer = class {
899
+ var RenderContext = class {
898
900
  constructor(mi) {
899
901
  this.mi = mi;
900
902
  __publicField(this, "devicePixelRatio");
901
903
  __publicField(this, "fontSize");
902
904
  __publicField(this, "unitSize");
903
- __publicField(this, "lineWidth");
904
- __publicField(this, "beamThickness");
905
+ __publicField(this, "_lineWidth");
905
906
  __publicField(this, "scoreEventListener");
906
907
  __publicField(this, "canvas");
907
908
  __publicField(this, "ctx");
@@ -921,8 +922,7 @@ var Renderer = class {
921
922
  this.devicePixelRatio = window.devicePixelRatio;
922
923
  this.fontSize = import_ts_utils_lib3.Device.FontSize * DocumentSettings.DocumentScale * this.devicePixelRatio;
923
924
  this.unitSize = this.fontSize * 0.3;
924
- this.lineWidth = this.unitSize * 0.2;
925
- this.beamThickness = this.unitSize * 0.8;
925
+ this._lineWidth = this.unitSize * 0.2;
926
926
  ImageAssets.forEach((asset) => {
927
927
  if (asset.finished !== true) {
928
928
  const img = new Image();
@@ -968,10 +968,10 @@ var Renderer = class {
968
968
  let prevMDoc = this.mdoc;
969
969
  this.mdoc = mdoc;
970
970
  if (prevMDoc) {
971
- prevMDoc.getMusicObject().setRenderer(void 0);
971
+ prevMDoc.getMusicObject().setRenderContext(void 0);
972
972
  }
973
973
  if (mdoc) {
974
- mdoc.getMusicObject().setRenderer(this);
974
+ mdoc.getMusicObject().setRenderContext(this);
975
975
  }
976
976
  }
977
977
  setCanvas(canvas) {
@@ -1107,22 +1107,24 @@ var Renderer = class {
1107
1107
  }
1108
1108
  }
1109
1109
  draw() {
1110
- let { ctx, doc } = this;
1111
- if (!ctx || !doc) {
1112
- return;
1110
+ try {
1111
+ let { doc } = this;
1112
+ if (doc) {
1113
+ doc.layout();
1114
+ this.updateCanvasSize();
1115
+ this.clearCanvas();
1116
+ this.drawHilightStaffPosRect();
1117
+ this.drawHilightObjectRect();
1118
+ this.drawPlayCursor();
1119
+ doc.drawContent();
1120
+ }
1121
+ } catch (err) {
1122
+ console.error("Render failed!", err);
1113
1123
  }
1114
- doc.layout();
1115
- this.updateCanvasSize();
1116
- this.clearCanvas();
1117
- this.drawHilightStaffPosRect();
1118
- this.drawHilightObjectRect();
1119
- this.drawPlayCursor();
1120
- doc.drawContent();
1121
1124
  }
1122
1125
  drawHilightStaffPosRect() {
1123
- let ctx = this.getCanvasContext();
1124
1126
  let { mousePos, hilightedStaffPos, unitSize } = this;
1125
- if (!ctx || !hilightedStaffPos) {
1127
+ if (!hilightedStaffPos) {
1126
1128
  return;
1127
1129
  }
1128
1130
  let { scoreRow, diatonicId } = hilightedStaffPos;
@@ -1130,26 +1132,25 @@ var Renderer = class {
1130
1132
  if (!staff) {
1131
1133
  return;
1132
1134
  }
1133
- ctx.fillStyle = HilightStaffPosRectColor;
1134
- ctx.fillRect(0, staff.getDiatonicIdY(diatonicId) - unitSize, ctx.canvas.width, 2 * unitSize);
1135
+ this.fillColor(HilightStaffPosRectColor);
1136
+ this.fillRect(staff.row.getRect().left, staff.getDiatonicIdY(diatonicId) - unitSize, staff.row.getRect().width, 2 * unitSize);
1135
1137
  if (mousePos !== void 0) {
1136
1138
  this.drawLedgerLines(staff, diatonicId, mousePos.x);
1137
1139
  }
1138
1140
  }
1139
1141
  drawHilightObjectRect() {
1140
- let ctx = this.getCanvasContext();
1141
1142
  let { hilightedObj } = this;
1142
- if (!ctx || !hilightedObj) {
1143
+ if (!hilightedObj) {
1143
1144
  return;
1144
1145
  }
1145
1146
  let rect = hilightedObj.getRect();
1146
- ctx.strokeStyle = HilightObjectRectColor;
1147
- ctx.strokeRect(rect.left, rect.top, rect.width, rect.height);
1147
+ this.lineColor(HilightObjectRectColor);
1148
+ this.strokeRect(rect.left, rect.top, rect.width, rect.height);
1148
1149
  }
1149
1150
  drawPlayCursor() {
1150
- let { cursorRect: r, lineWidth } = this;
1151
+ let { cursorRect: r } = this;
1151
1152
  if (r) {
1152
- this.drawLine(r.centerX, r.top, r.centerX, r.bottom, PlayPosIndicatorColor, lineWidth * 2);
1153
+ this.color(PlayPosIndicatorColor).lineWidth(2).strokeLine(r.centerX, r.top, r.centerX, r.bottom);
1153
1154
  }
1154
1155
  }
1155
1156
  txFromScreenCoord(screenCoord) {
@@ -1158,75 +1159,13 @@ var Renderer = class {
1158
1159
  txToScreenCoord(coord) {
1159
1160
  return coord.div(this.devicePixelRatio);
1160
1161
  }
1161
- getCanvasContext() {
1162
- return this.ctx;
1163
- }
1164
1162
  clearCanvas() {
1165
- let ctx = this.getCanvasContext();
1166
- if (ctx) {
1167
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
1168
- }
1169
- }
1170
- getTextWidth(text, font) {
1171
- let ctx = this.getCanvasContext();
1172
- if (ctx) {
1173
- let savedFont = ctx.font;
1174
- ctx.font = font;
1175
- let metrics = ctx.measureText(text);
1176
- ctx.font = savedFont;
1177
- return metrics.width;
1178
- } else {
1179
- return import_ts_utils_lib3.Utils.Dom.getCanvasTextWidth(text, font);
1180
- }
1163
+ var _a;
1164
+ (_a = this.ctx) == null ? void 0 : _a.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
1181
1165
  }
1182
1166
  drawDebugRect(r) {
1183
- if (!DebugSettings.DrawDebugRects) {
1184
- return;
1185
- }
1186
- let ctx = this.getCanvasContext();
1187
- if (ctx) {
1188
- ctx.lineWidth = 1;
1189
- ctx.strokeStyle = "red";
1190
- ctx.beginPath();
1191
- ctx.rect(r.left, r.top, r.right - r.left, r.bottom - r.top);
1192
- ctx.stroke();
1193
- }
1194
- }
1195
- fillCircle(x, y, radius, color) {
1196
- let ctx = this.getCanvasContext();
1197
- if (ctx) {
1198
- if (color !== void 0) {
1199
- ctx.fillStyle = color;
1200
- }
1201
- ctx.beginPath();
1202
- ctx.arc(x, y, radius, 0, 2 * Math.PI);
1203
- ctx.fill();
1204
- }
1205
- }
1206
- drawLine(startX, startY, endX, endY, color, lineWidth) {
1207
- let ctx = this.getCanvasContext();
1208
- if (ctx) {
1209
- ctx.strokeStyle = color != null ? color : "black";
1210
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
1211
- ctx.beginPath();
1212
- ctx.moveTo(startX, startY);
1213
- ctx.lineTo(endX, endY);
1214
- ctx.stroke();
1215
- }
1216
- }
1217
- drawPartialLine(startX, startY, endX, endY, startT, endT, color, lineWidth) {
1218
- let ctx = this.getCanvasContext();
1219
- if (ctx) {
1220
- let x1 = startX + (endX - startX) * startT;
1221
- let y1 = startY + (endY - startY) * startT;
1222
- let x2 = startX + (endX - startX) * endT;
1223
- let y2 = startY + (endY - startY) * endT;
1224
- ctx.strokeStyle = color != null ? color : "black";
1225
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
1226
- ctx.beginPath();
1227
- ctx.moveTo(x1, y1);
1228
- ctx.lineTo(x2, y2);
1229
- ctx.stroke();
1167
+ if (DebugSettings.DrawDebugRects) {
1168
+ this.color("red").lineWidth(1).strokeRect(r.left, r.top, r.width, r.height);
1230
1169
  }
1231
1170
  }
1232
1171
  drawLedgerLines(staff, diatonicId, x) {
@@ -1236,14 +1175,14 @@ var Renderer = class {
1236
1175
  for (let lineDiatonicId = staff.topLineDiatonicId + 2; lineDiatonicId <= diatonicId; lineDiatonicId += 2) {
1237
1176
  if (staff.containsDiatonicId(lineDiatonicId)) {
1238
1177
  let y = staff.getDiatonicIdY(lineDiatonicId);
1239
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1178
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1240
1179
  }
1241
1180
  }
1242
1181
  } else if (diatonicId <= staff.bottomLineDiatonicId - 2) {
1243
1182
  for (let lineDiatonicId = staff.bottomLineDiatonicId - 2; lineDiatonicId >= diatonicId; lineDiatonicId -= 2) {
1244
1183
  if (staff.containsDiatonicId(lineDiatonicId)) {
1245
1184
  let y = staff.getDiatonicIdY(lineDiatonicId);
1246
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1185
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1247
1186
  }
1248
1187
  }
1249
1188
  }
@@ -1279,44 +1218,38 @@ var Renderer = class {
1279
1218
  }
1280
1219
  return new DivRect(-leftw, 0, rightw, -toph, 0, bottomh);
1281
1220
  }
1282
- drawRest(restSize, x, y, color) {
1283
- let ctx = this.getCanvasContext();
1284
- if (!ctx) {
1285
- return;
1286
- }
1287
- let { unitSize, lineWidth } = this;
1221
+ drawRest(restSize, x, y) {
1222
+ let { unitSize } = this;
1288
1223
  let { flagCount } = NoteLengthProps.get(validateNoteLength(restSize + "n"));
1289
- ctx.strokeStyle = ctx.fillStyle = color;
1290
- ctx.lineWidth = lineWidth;
1291
1224
  if (NoteLengthProps.equals(restSize, "1n" /* Whole */)) {
1292
- ctx.fillRect(x - unitSize, y, unitSize * 2, unitSize);
1225
+ this.fillRect(x - unitSize, y, unitSize * 2, unitSize);
1293
1226
  } else if (NoteLengthProps.equals(restSize, "2n" /* Half */)) {
1294
- ctx.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
1227
+ this.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
1295
1228
  } else if (NoteLengthProps.equals(restSize, "4n" /* Quarter */)) {
1296
- ctx.beginPath();
1297
- ctx.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
1298
- ctx.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
1299
- ctx.quadraticCurveTo(
1229
+ this.beginPath();
1230
+ this.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
1231
+ this.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
1232
+ this.quadraticCurveTo(
1300
1233
  x - unitSize * 0.8,
1301
1234
  y - unitSize * 0.5,
1302
1235
  x + unitSize * 1,
1303
1236
  y + unitSize * 1.5
1304
1237
  );
1305
- ctx.lineTo(x - unitSize * 1, y - unitSize * 0.75);
1306
- ctx.quadraticCurveTo(
1238
+ this.lineTo(x - unitSize * 1, y - unitSize * 0.75);
1239
+ this.quadraticCurveTo(
1307
1240
  x + unitSize * 0.2,
1308
1241
  y - unitSize * 1.5,
1309
1242
  x - unitSize * 0.6,
1310
1243
  y - unitSize * 3.2
1311
1244
  );
1312
- ctx.moveTo(x + unitSize * 1, y + unitSize * 1.5);
1313
- ctx.quadraticCurveTo(
1245
+ this.moveTo(x + unitSize * 1, y + unitSize * 1.5);
1246
+ this.quadraticCurveTo(
1314
1247
  x - unitSize * 0.8,
1315
1248
  y + unitSize * 1,
1316
1249
  x - unitSize * 0.2,
1317
1250
  y + unitSize * 2.8
1318
1251
  );
1319
- ctx.bezierCurveTo(
1252
+ this.bezierCurveTo(
1320
1253
  x - unitSize * 1.8,
1321
1254
  y + unitSize * 1.5,
1322
1255
  x - unitSize * 0.6,
@@ -1324,46 +1257,42 @@ var Renderer = class {
1324
1257
  x + unitSize * 0.9,
1325
1258
  y + unitSize * 1.5
1326
1259
  );
1327
- ctx.fill();
1328
- ctx.stroke();
1260
+ this.fill();
1261
+ this.stroke();
1329
1262
  } else if (flagCount > 0) {
1330
1263
  let adj = 1 - flagCount % 2;
1331
1264
  let fx = (p) => x + (-p * 0.25 + 0.5) * unitSize;
1332
1265
  let fy = (p) => y + (p + adj) * unitSize;
1333
- ctx.beginPath();
1334
- ctx.moveTo(fx(1 + flagCount), fy(1 + flagCount));
1335
- ctx.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
1336
- ctx.stroke();
1266
+ this.beginPath();
1267
+ this.moveTo(fx(1 + flagCount), fy(1 + flagCount));
1268
+ this.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
1269
+ this.stroke();
1337
1270
  for (let i = 0; i < flagCount; i++) {
1338
1271
  let t = flagCount - i * 2;
1339
- ctx.beginPath();
1340
- ctx.moveTo(fx(t - 2.5), fy(t - 2.5));
1341
- ctx.quadraticCurveTo(
1272
+ this.beginPath();
1273
+ this.moveTo(fx(t - 2.5), fy(t - 2.5));
1274
+ this.quadraticCurveTo(
1342
1275
  fx(t - 0.5) + unitSize * 0.25,
1343
1276
  fy(t - 1.5),
1344
1277
  fx(t - 1.5) - unitSize * 1.5,
1345
1278
  fy(t - 1.5)
1346
1279
  );
1347
- ctx.stroke();
1348
- ctx.beginPath();
1349
- ctx.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
1350
- ctx.fill();
1280
+ this.stroke();
1281
+ this.beginPath();
1282
+ this.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
1283
+ this.fill();
1351
1284
  }
1352
1285
  }
1353
1286
  }
1354
1287
  drawFlag(rect, dir) {
1355
- let ctx = this.getCanvasContext();
1356
- if (!ctx) {
1357
- return;
1358
- }
1359
1288
  let left = rect.left;
1360
1289
  let right = rect.right;
1361
1290
  let width = right - left;
1362
1291
  let top = dir === "up" ? rect.top : rect.bottom;
1363
1292
  let bottom = dir === "up" ? rect.bottom : rect.top;
1364
- ctx.beginPath();
1365
- ctx.moveTo(left, top);
1366
- ctx.bezierCurveTo(
1293
+ this.beginPath();
1294
+ this.moveTo(left, top);
1295
+ this.bezierCurveTo(
1367
1296
  left,
1368
1297
  top * 0.75 + bottom * 0.25,
1369
1298
  left + width * 1.5,
@@ -1371,16 +1300,178 @@ var Renderer = class {
1371
1300
  left + width * 0.5,
1372
1301
  bottom
1373
1302
  );
1374
- ctx.stroke();
1303
+ this.stroke();
1304
+ }
1305
+ color(color) {
1306
+ if (this.ctx) this.ctx.strokeStyle = this.ctx.fillStyle = color;
1307
+ return this;
1308
+ }
1309
+ lineColor(color) {
1310
+ if (this.ctx) this.ctx.strokeStyle = color;
1311
+ return this;
1312
+ }
1313
+ fillColor(color) {
1314
+ if (this.ctx) this.ctx.fillStyle = color;
1315
+ return this;
1316
+ }
1317
+ lineWidth(lineWidth) {
1318
+ if (this.ctx) this.ctx.lineWidth = this._lineWidth * (lineWidth != null ? lineWidth : 1);
1319
+ return this;
1320
+ }
1321
+ font(font) {
1322
+ if (this.ctx) this.ctx.font = font;
1323
+ return this;
1324
+ }
1325
+ beginPath() {
1326
+ if (this.ctx) this.ctx.beginPath();
1327
+ return this;
1328
+ }
1329
+ stroke() {
1330
+ if (this.ctx) this.ctx.stroke();
1331
+ return this;
1332
+ }
1333
+ fill() {
1334
+ if (this.ctx) this.ctx.fill();
1335
+ return this;
1336
+ }
1337
+ moveTo(x, y) {
1338
+ if (this.ctx) this.ctx.moveTo(x, y);
1339
+ return this;
1340
+ }
1341
+ lineTo(x, y) {
1342
+ if (this.ctx) this.ctx.lineTo(x, y);
1343
+ return this;
1344
+ }
1345
+ bezierCurveTo(x1, y1, x2, y2, x3, y3) {
1346
+ if (this.ctx) this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
1347
+ return this;
1348
+ }
1349
+ quadraticCurveTo(x1, y1, x2, y2) {
1350
+ if (this.ctx) this.ctx.quadraticCurveTo(x1, y1, x2, y2);
1351
+ return this;
1352
+ }
1353
+ fillRect(x, y, w, h) {
1354
+ if (this.ctx) this.ctx.fillRect(x, y, w, h);
1355
+ return this;
1356
+ }
1357
+ setLineDash(pattern) {
1358
+ if (this.ctx) this.ctx.setLineDash(pattern);
1359
+ return this;
1360
+ }
1361
+ drawImage(img, x, y, w, h) {
1362
+ if (this.ctx) this.ctx.drawImage(img, x, y, w, h);
1363
+ return this;
1364
+ }
1365
+ ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle) {
1366
+ if (this.ctx) this.ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle);
1367
+ return this;
1368
+ }
1369
+ clip() {
1370
+ if (this.ctx) this.ctx.clip();
1371
+ return this;
1372
+ }
1373
+ save() {
1374
+ if (this.ctx) this.ctx.save();
1375
+ return this;
1376
+ }
1377
+ restore() {
1378
+ if (this.ctx) this.ctx.restore();
1379
+ return this;
1380
+ }
1381
+ rect(x, y, w, h) {
1382
+ if (this.ctx) this.ctx.rect(x, y, w, h);
1383
+ return this;
1384
+ }
1385
+ scale(x, y) {
1386
+ if (this.ctx) this.ctx.scale(x, y);
1387
+ return this;
1388
+ }
1389
+ strokeRect(x, y, w, h) {
1390
+ if (this.ctx) this.ctx.strokeRect(x, y, w, h);
1391
+ return this;
1392
+ }
1393
+ fillText(text, x, y) {
1394
+ if (this.ctx) this.ctx.fillText(text, x, y);
1395
+ return this;
1396
+ }
1397
+ getTextWidth(text, font) {
1398
+ if (this.ctx) {
1399
+ let savedFont = this.ctx.font;
1400
+ this.ctx.font = font;
1401
+ let metrics = this.ctx.measureText(text);
1402
+ this.ctx.font = savedFont;
1403
+ return metrics.width;
1404
+ } else {
1405
+ return import_ts_utils_lib3.Utils.Dom.getCanvasTextWidth(text, font);
1406
+ }
1407
+ }
1408
+ arc(x, y, radius, startRadians, endRadians) {
1409
+ var _a;
1410
+ (_a = this.ctx) == null ? void 0 : _a.arc(x, y, radius, startRadians, endRadians);
1411
+ }
1412
+ fillCircle(x, y, radius) {
1413
+ if (this.ctx) {
1414
+ this.ctx.beginPath();
1415
+ this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
1416
+ this.ctx.fill();
1417
+ }
1418
+ }
1419
+ strokeLine(startX, startY, endX, endY) {
1420
+ if (this.ctx) {
1421
+ this.ctx.beginPath();
1422
+ this.ctx.moveTo(startX, startY);
1423
+ this.ctx.lineTo(endX, endY);
1424
+ this.ctx.stroke();
1425
+ }
1426
+ }
1427
+ strokePartialLine(startX, startY, endX, endY, startT, endT) {
1428
+ let x1 = startX + (endX - startX) * startT;
1429
+ let y1 = startY + (endY - startY) * startT;
1430
+ let x2 = startX + (endX - startX) * endT;
1431
+ let y2 = startY + (endY - startY) * endT;
1432
+ if (this.ctx) {
1433
+ this.ctx.beginPath();
1434
+ this.ctx.moveTo(x1, y1);
1435
+ this.ctx.lineTo(x2, y2);
1436
+ this.ctx.stroke();
1437
+ }
1438
+ }
1439
+ drawBrace(rect, side) {
1440
+ if (this.ctx) {
1441
+ let { left, right, width, top, bottom, centerY } = rect;
1442
+ if (side === "right") {
1443
+ [left, right, width] = [right, left, -width];
1444
+ }
1445
+ this.ctx.beginPath();
1446
+ this.ctx.moveTo(right, top);
1447
+ this.ctx.bezierCurveTo(
1448
+ left + width * 0.1,
1449
+ top,
1450
+ left + width * 0.8,
1451
+ centerY,
1452
+ left,
1453
+ centerY
1454
+ );
1455
+ this.ctx.moveTo(right, bottom);
1456
+ this.ctx.bezierCurveTo(
1457
+ left + width * 0.1,
1458
+ bottom,
1459
+ left + width * 0.8,
1460
+ centerY,
1461
+ left,
1462
+ centerY
1463
+ );
1464
+ this.ctx.stroke();
1465
+ }
1375
1466
  }
1376
1467
  };
1377
1468
 
1378
1469
  // src/score/engine/obj-staff-and-tab.ts
1379
1470
  var import_core16 = require("@tspro/web-music-score/core");
1380
- var import_ts_utils_lib14 = require("@tspro/ts-utils-lib");
1471
+ var import_ts_utils_lib15 = require("@tspro/ts-utils-lib");
1381
1472
 
1382
1473
  // src/score/engine/obj-measure.ts
1383
- var import_ts_utils_lib13 = require("@tspro/ts-utils-lib");
1474
+ var import_ts_utils_lib14 = require("@tspro/ts-utils-lib");
1384
1475
  var import_theory9 = require("@tspro/web-music-score/theory");
1385
1476
  var import_theory10 = require("@tspro/web-music-score/theory");
1386
1477
 
@@ -1426,9 +1517,9 @@ var ObjImage = class extends MusicObject {
1426
1517
  pick(x, y) {
1427
1518
  return this.rect.contains(x, y) ? [this] : [];
1428
1519
  }
1429
- layout(renderer) {
1520
+ layout(ctx) {
1430
1521
  let { anchorX, anchorY, image, imageScale } = this;
1431
- let { unitSize } = renderer;
1522
+ let { unitSize } = ctx;
1432
1523
  try {
1433
1524
  let w = image.naturalWidth * imageScale * unitSize;
1434
1525
  let h = image.naturalHeight * imageScale * unitSize;
@@ -1440,17 +1531,10 @@ var ObjImage = class extends MusicObject {
1440
1531
  offset(dx, dy) {
1441
1532
  this.rect.offsetInPlace(dx, dy);
1442
1533
  }
1443
- draw(renderer) {
1444
- let ctx = renderer.getCanvasContext();
1445
- if (!ctx) {
1446
- return;
1447
- }
1534
+ draw(ctx) {
1448
1535
  let r = this.rect;
1449
- renderer.drawDebugRect(r);
1450
- try {
1451
- ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1452
- } catch (err) {
1453
- }
1536
+ ctx.drawDebugRect(r);
1537
+ ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1454
1538
  }
1455
1539
  };
1456
1540
 
@@ -1471,8 +1555,8 @@ var ObjAccidental = class extends MusicObject {
1471
1555
  pick(x, y) {
1472
1556
  return this.rect.contains(x, y) ? [this] : [];
1473
1557
  }
1474
- layout(renderer) {
1475
- let { unitSize } = renderer;
1558
+ layout(ctx) {
1559
+ let { unitSize } = ctx;
1476
1560
  switch (this.accidental) {
1477
1561
  case -2:
1478
1562
  this.rect = DivRect.createSections(unitSize * 1.25, unitSize * 1.25, unitSize * 4, unitSize * 1.2);
@@ -1496,34 +1580,23 @@ var ObjAccidental = class extends MusicObject {
1496
1580
  offset(dx, dy) {
1497
1581
  this.rect.offsetInPlace(dx, dy);
1498
1582
  }
1499
- draw(renderer) {
1500
- let ctx = renderer.getCanvasContext();
1501
- if (!ctx) {
1502
- return;
1503
- }
1504
- renderer.drawDebugRect(this.rect);
1505
- let { unitSize, lineWidth } = renderer;
1583
+ draw(ctx) {
1584
+ ctx.drawDebugRect(this.rect);
1585
+ let { unitSize } = ctx;
1506
1586
  let { accidental } = this;
1507
1587
  let x = this.rect.centerX;
1508
1588
  let y = this.rect.centerY;
1509
- ctx.strokeStyle = ctx.fillStyle = this.color;
1510
- function draw_b(x2, y2) {
1511
- if (ctx) {
1512
- ctx.lineWidth = lineWidth;
1513
- ctx.beginPath();
1514
- ctx.moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4);
1515
- ctx.lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1);
1516
- ctx.bezierCurveTo(
1517
- x2 + unitSize * 0.75,
1518
- y2 - unitSize * 0,
1519
- x2 + unitSize * 0.75,
1520
- y2 - unitSize * 2.2,
1521
- x2 - unitSize * 0.75,
1522
- y2 - unitSize * 0.5
1523
- );
1524
- ctx.stroke();
1525
- }
1526
- }
1589
+ ctx.color(this.color);
1590
+ const draw_b = (x2, y2) => {
1591
+ ctx.lineWidth(1).beginPath().moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4).lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1).bezierCurveTo(
1592
+ x2 + unitSize * 0.75,
1593
+ y2 - unitSize * 0,
1594
+ x2 + unitSize * 0.75,
1595
+ y2 - unitSize * 2.2,
1596
+ x2 - unitSize * 0.75,
1597
+ y2 - unitSize * 0.5
1598
+ ).stroke();
1599
+ };
1527
1600
  if (accidental === -2) {
1528
1601
  draw_b(x - unitSize * 0.5, y);
1529
1602
  draw_b(x + unitSize * 0.5, y);
@@ -1531,47 +1604,11 @@ var ObjAccidental = class extends MusicObject {
1531
1604
  draw_b(x, y);
1532
1605
  }
1533
1606
  if (accidental === 0) {
1534
- ctx.beginPath();
1535
- ctx.lineWidth = lineWidth;
1536
- ctx.moveTo(x - unitSize * 0.5, y - unitSize * 2.2);
1537
- ctx.lineTo(x - unitSize * 0.5, y + unitSize * 1);
1538
- ctx.moveTo(x + unitSize * 0.5, y + unitSize * 2.2);
1539
- ctx.lineTo(x + unitSize * 0.5, y - unitSize * 1);
1540
- ctx.stroke();
1541
- ctx.beginPath();
1542
- ctx.lineWidth = lineWidth * 2;
1543
- ctx.moveTo(x - unitSize * 0.5, y + unitSize * 1);
1544
- ctx.lineTo(x + unitSize * 0.5, y + unitSize * 0.6);
1545
- ctx.moveTo(x + unitSize * 0.5, y - unitSize * 1);
1546
- ctx.lineTo(x - unitSize * 0.5, y - unitSize * 0.6);
1547
- ctx.stroke();
1607
+ 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();
1548
1608
  } else if (accidental === 1) {
1549
- ctx.lineWidth = lineWidth;
1550
- ctx.beginPath();
1551
- ctx.moveTo(x - unitSize * 0.3, y - unitSize * 1.6);
1552
- ctx.lineTo(x - unitSize * 0.3, y + unitSize * 2);
1553
- ctx.moveTo(x + unitSize * 0.3, y - unitSize * 2);
1554
- ctx.lineTo(x + unitSize * 0.3, y + unitSize * 1.6);
1555
- ctx.stroke();
1556
- ctx.lineWidth = lineWidth * 2;
1557
- ctx.beginPath();
1558
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.5);
1559
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.9);
1560
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.9);
1561
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.5);
1562
- ctx.stroke();
1609
+ 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();
1563
1610
  } else if (accidental === 2) {
1564
- ctx.lineWidth = lineWidth;
1565
- ctx.beginPath();
1566
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.75);
1567
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.75);
1568
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.75);
1569
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.75);
1570
- ctx.stroke();
1571
- ctx.fillRect(x - unitSize * 1, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1572
- ctx.fillRect(x + unitSize * 0.3, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1573
- ctx.fillRect(x - unitSize * 1, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1574
- ctx.fillRect(x + unitSize * 0.3, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1611
+ 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);
1575
1612
  }
1576
1613
  }
1577
1614
  };
@@ -1637,13 +1674,13 @@ var ObjText = class extends MusicObject {
1637
1674
  pick(x, y) {
1638
1675
  return this.rect.contains(x, y) ? [this] : [];
1639
1676
  }
1640
- layout(renderer) {
1677
+ layout(ctx) {
1641
1678
  let { scale, anchorX, anchorY, bold, italic } = this;
1642
- let fontSize = renderer.fontSize * scale;
1679
+ let fontSize = ctx.fontSize * scale;
1643
1680
  this.font = (italic ? "italic " : "") + (bold ? "bold " : "") + fontSize + "px Times New Roman";
1644
- this.lineWidths = this.textLines.map((text) => renderer.getTextWidth(text, this.font));
1681
+ this.lineWidths = this.textLines.map((text) => ctx.getTextWidth(text, this.font));
1645
1682
  this.lineHeight = fontSize;
1646
- let p = this.padding * renderer.unitSize;
1683
+ let p = this.padding * ctx.unitSize;
1647
1684
  let w = p + Math.max(...this.lineWidths) + p;
1648
1685
  let h = p + this.lineHeight * this.textLines.length + p;
1649
1686
  if (this.boxed === "square" || this.boxed === "circle") {
@@ -1654,19 +1691,14 @@ var ObjText = class extends MusicObject {
1654
1691
  offset(dx, dy) {
1655
1692
  this.rect.offsetInPlace(dx, dy);
1656
1693
  }
1657
- draw(renderer) {
1658
- const ctx = renderer.getCanvasContext();
1659
- if (!ctx) {
1660
- return;
1661
- }
1662
- renderer.drawDebugRect(this.rect);
1663
- ctx.lineWidth = renderer.lineWidth;
1664
- ctx.strokeStyle = ctx.fillStyle = this.color;
1665
- ctx.font = this.font;
1694
+ draw(ctx) {
1695
+ var _a;
1696
+ ctx.drawDebugRect(this.rect);
1697
+ ctx.lineWidth(1).font(this.font);
1666
1698
  let { rect, padding, lineHeight, lineWidths, anchorX, anchorY, italic } = this;
1667
1699
  if (this.bgcolor !== void 0) {
1668
1700
  ctx.save();
1669
- ctx.fillStyle = this.bgcolor;
1701
+ ctx.fillColor((_a = this.bgcolor) != null ? _a : "black");
1670
1702
  ctx.beginPath();
1671
1703
  ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
1672
1704
  ctx.fill();
@@ -1674,10 +1706,11 @@ var ObjText = class extends MusicObject {
1674
1706
  }
1675
1707
  let lineCount = this.textLines.length;
1676
1708
  let textHeight = lineCount * lineHeight;
1677
- let fixY = -lineHeight * (italic ? 0.25 : 0.175);
1678
- let p = padding * renderer.unitSize;
1709
+ let fixY = -lineHeight * (italic ? 0.25 : 0.2);
1710
+ let p = padding * ctx.unitSize;
1679
1711
  let centerX = (rect.left + p) * (1 - anchorX) + (rect.right - p) * anchorX;
1680
1712
  let centerY = (rect.top + p) * (1 - anchorY) + (rect.bottom - p) * anchorY;
1713
+ ctx.color(this.color);
1681
1714
  this.textLines.forEach((textLine, i) => {
1682
1715
  let x = centerX - lineWidths[i] * anchorX;
1683
1716
  let y = centerY - textHeight * anchorY + lineHeight * (i + 1) + fixY;
@@ -1723,9 +1756,9 @@ var ObjStaffSignature = class extends MusicObject {
1723
1756
  getMusicInterface() {
1724
1757
  return this.mi;
1725
1758
  }
1726
- updateClefImage(renderer, showClef) {
1759
+ updateClefImage(ctx, showClef) {
1727
1760
  if (showClef) {
1728
- let img = renderer.getImageAsset(this.staff.clefImageAsset);
1761
+ let img = ctx.getImageAsset(this.staff.clefImageAsset);
1729
1762
  this.clefImage = img ? new ObjImage(this, img, 0, 0.5, 0.1) : void 0;
1730
1763
  this.eightBelowClef = this.clefImage && this.staff.isOctaveDown ? new ObjText(this, "8", 0.5, 0) : void 0;
1731
1764
  } else {
@@ -1856,29 +1889,29 @@ var ObjStaffSignature = class extends MusicObject {
1856
1889
  }
1857
1890
  return [this];
1858
1891
  }
1859
- layout(renderer) {
1892
+ layout(ctx) {
1860
1893
  var _a, _b, _c, _d, _e, _f;
1861
- let { unitSize } = renderer;
1894
+ let { unitSize } = ctx;
1862
1895
  let { staff } = this;
1863
1896
  let paddingX = unitSize;
1864
1897
  let x = 0;
1865
1898
  this.rect = new DivRect();
1866
1899
  if (this.clefImage) {
1867
1900
  x += paddingX;
1868
- this.clefImage.layout(renderer);
1901
+ this.clefImage.layout(ctx);
1869
1902
  this.clefImage.offset(x, staff.getDiatonicIdY(staff.clefLineDiatonicId));
1870
1903
  this.rect.expandInPlace(this.clefImage.getRect());
1871
1904
  x = this.rect.right;
1872
1905
  if (this.eightBelowClef) {
1873
1906
  let r = this.clefImage.getRect();
1874
- this.eightBelowClef.layout(renderer);
1907
+ this.eightBelowClef.layout(ctx);
1875
1908
  this.eightBelowClef.offset(r.left + r.width / 2, Math.max(r.centerY + r.height * 0.3, staff.getBottomLineY()));
1876
1909
  this.rect.expandInPlace(this.eightBelowClef.getRect());
1877
1910
  }
1878
1911
  }
1879
1912
  if (this.measureNumber) {
1880
- this.measureNumber.layout(renderer);
1881
- let y = this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY();
1913
+ this.measureNumber.layout(ctx);
1914
+ let y = Math.min(staff.getTopLineY(), this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY());
1882
1915
  this.measureNumber.offset(0, y);
1883
1916
  this.rect.expandInPlace(this.measureNumber.getRect());
1884
1917
  x = Math.max(x, this.rect.right);
@@ -1886,7 +1919,7 @@ var ObjStaffSignature = class extends MusicObject {
1886
1919
  if (this.ksNeutralizeAccidentals.length > 0) {
1887
1920
  x += paddingX;
1888
1921
  this.ksNeutralizeAccidentals.forEach((objAcc) => {
1889
- objAcc.layout(renderer);
1922
+ objAcc.layout(ctx);
1890
1923
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1891
1924
  this.rect.expandInPlace(objAcc.getRect());
1892
1925
  x = this.rect.right;
@@ -1895,15 +1928,15 @@ var ObjStaffSignature = class extends MusicObject {
1895
1928
  if (this.ksNewAccidentals) {
1896
1929
  x += paddingX;
1897
1930
  this.ksNewAccidentals.forEach((objAcc) => {
1898
- objAcc.layout(renderer);
1931
+ objAcc.layout(ctx);
1899
1932
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1900
1933
  this.rect.expandInPlace(objAcc.getRect());
1901
1934
  x = this.rect.right;
1902
1935
  });
1903
1936
  }
1904
1937
  let right = x;
1905
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
1906
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
1938
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
1939
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1907
1940
  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);
1908
1941
  if (this.beatCountText) {
1909
1942
  this.beatCountText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.middleLineDiatonicId + 2));
@@ -1922,7 +1955,7 @@ var ObjStaffSignature = class extends MusicObject {
1922
1955
  ...this.ksNeutralizeAccidentals.map((o) => o.getRect().top),
1923
1956
  ...this.ksNewAccidentals.map((o) => o.getRect().top)
1924
1957
  );
1925
- this.tempoText.layout(renderer);
1958
+ this.tempoText.layout(ctx);
1926
1959
  this.tempoText.offset(x, tempoBottom);
1927
1960
  this.rect.expandInPlace(this.tempoText.getRect());
1928
1961
  }
@@ -1940,16 +1973,16 @@ var ObjStaffSignature = class extends MusicObject {
1940
1973
  (_f = this.tempoText) == null ? void 0 : _f.offset(dx, dy);
1941
1974
  this.rect.offsetInPlace(dx, dy);
1942
1975
  }
1943
- draw(renderer) {
1976
+ draw(ctx) {
1944
1977
  var _a, _b, _c, _d, _e, _f;
1945
- (_a = this.clefImage) == null ? void 0 : _a.draw(renderer);
1946
- (_b = this.eightBelowClef) == null ? void 0 : _b.draw(renderer);
1947
- (_c = this.measureNumber) == null ? void 0 : _c.draw(renderer);
1948
- this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(renderer));
1949
- this.ksNewAccidentals.forEach((acc) => acc.draw(renderer));
1950
- (_d = this.beatCountText) == null ? void 0 : _d.draw(renderer);
1951
- (_e = this.beatSizeText) == null ? void 0 : _e.draw(renderer);
1952
- (_f = this.tempoText) == null ? void 0 : _f.draw(renderer);
1978
+ (_a = this.clefImage) == null ? void 0 : _a.draw(ctx);
1979
+ (_b = this.eightBelowClef) == null ? void 0 : _b.draw(ctx);
1980
+ (_c = this.measureNumber) == null ? void 0 : _c.draw(ctx);
1981
+ this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(ctx));
1982
+ this.ksNewAccidentals.forEach((acc) => acc.draw(ctx));
1983
+ (_d = this.beatCountText) == null ? void 0 : _d.draw(ctx);
1984
+ (_e = this.beatSizeText) == null ? void 0 : _e.draw(ctx);
1985
+ (_f = this.tempoText) == null ? void 0 : _f.draw(ctx);
1953
1986
  }
1954
1987
  };
1955
1988
  var ObjTabSignature = class extends MusicObject {
@@ -2024,22 +2057,22 @@ var ObjTabSignature = class extends MusicObject {
2024
2057
  }
2025
2058
  return [this];
2026
2059
  }
2027
- layout(renderer) {
2060
+ layout(ctx) {
2028
2061
  var _a, _b, _c, _d, _e, _f;
2029
- let { unitSize } = renderer;
2062
+ let { unitSize } = ctx;
2030
2063
  let { tab } = this;
2031
2064
  let paddingX = unitSize;
2032
2065
  let x = 0;
2033
2066
  let topLineY = tab.getTopLineY();
2034
2067
  this.rect = new DivRect();
2035
2068
  if (this.measureNumber) {
2036
- this.measureNumber.layout(renderer);
2069
+ this.measureNumber.layout(ctx);
2037
2070
  this.measureNumber.offset(0, topLineY);
2038
2071
  this.rect.expandInPlace(this.measureNumber.getRect());
2039
2072
  x = Math.max(x, this.rect.right);
2040
2073
  }
2041
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
2042
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
2074
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
2075
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
2043
2076
  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);
2044
2077
  if (this.beatCountText) {
2045
2078
  this.beatCountText.offset(0 + tsWidth / 2 + paddingX, tab.getRect().centerY - this.beatCountText.getRect().bottomh);
@@ -2050,7 +2083,7 @@ var ObjTabSignature = class extends MusicObject {
2050
2083
  this.rect.expandInPlace(this.beatSizeText.getRect());
2051
2084
  }
2052
2085
  if (this.tempoText) {
2053
- this.tempoText.layout(renderer);
2086
+ this.tempoText.layout(ctx);
2054
2087
  this.tempoText.offset(x + unitSize * 2, topLineY);
2055
2088
  this.rect.expandInPlace(this.tempoText.getRect());
2056
2089
  }
@@ -2064,12 +2097,12 @@ var ObjTabSignature = class extends MusicObject {
2064
2097
  (_d = this.tempoText) == null ? void 0 : _d.offset(dx, dy);
2065
2098
  this.rect.offsetInPlace(dx, dy);
2066
2099
  }
2067
- draw(renderer) {
2100
+ draw(ctx) {
2068
2101
  var _a, _b, _c, _d;
2069
- (_a = this.measureNumber) == null ? void 0 : _a.draw(renderer);
2070
- (_b = this.beatCountText) == null ? void 0 : _b.draw(renderer);
2071
- (_c = this.beatSizeText) == null ? void 0 : _c.draw(renderer);
2072
- (_d = this.tempoText) == null ? void 0 : _d.draw(renderer);
2102
+ (_a = this.measureNumber) == null ? void 0 : _a.draw(ctx);
2103
+ (_b = this.beatCountText) == null ? void 0 : _b.draw(ctx);
2104
+ (_c = this.beatSizeText) == null ? void 0 : _c.draw(ctx);
2105
+ (_d = this.tempoText) == null ? void 0 : _d.draw(ctx);
2073
2106
  }
2074
2107
  };
2075
2108
 
@@ -2102,8 +2135,8 @@ var ObjArpeggio = class extends MusicObject {
2102
2135
  pick(x, y) {
2103
2136
  return this.rect.contains(x, y) ? [this] : [];
2104
2137
  }
2105
- layout(renderer) {
2106
- let { unitSize } = renderer;
2138
+ layout(ctx) {
2139
+ let { unitSize } = ctx;
2107
2140
  this.topArrowHeight = this.arpeggioDir === "up" /* Up */ ? unitSize : 0;
2108
2141
  this.bottomArrowHeight = this.arpeggioDir === "down" /* Down */ ? unitSize : 0;
2109
2142
  let top = this.line.getTopLineY();
@@ -2117,16 +2150,11 @@ var ObjArpeggio = class extends MusicObject {
2117
2150
  offset(dx, dy) {
2118
2151
  this.rect.offsetInPlace(dx, dy);
2119
2152
  }
2120
- draw(renderer) {
2121
- let ctx = renderer.getCanvasContext();
2122
- if (!ctx) {
2123
- return;
2124
- }
2125
- let { lineWidth } = renderer;
2153
+ draw(ctx) {
2126
2154
  let { rect, topArrowHeight, bottomArrowHeight } = this;
2127
- renderer.drawDebugRect(this.rect);
2128
- ctx.strokeStyle = ctx.fillStyle = this.color;
2129
- ctx.lineWidth = lineWidth * 2;
2155
+ ctx.drawDebugRect(this.rect);
2156
+ ctx.color(this.color);
2157
+ ctx.lineWidth(2);
2130
2158
  ctx.beginPath();
2131
2159
  for (let i = 0, y = rect.top + topArrowHeight; i < this.numCycles; i++, y += this.cycleHeight) {
2132
2160
  ctx.moveTo(rect.centerX, y);
@@ -2193,40 +2221,33 @@ var ObjStaffRest = class extends MusicObject {
2193
2221
  this.dotRects.forEach((r) => this.rect.expandInPlace(r));
2194
2222
  }
2195
2223
  };
2196
- var ObjRest = class extends MusicObject {
2224
+ var _ObjRest = class _ObjRest extends MusicObject {
2197
2225
  constructor(col, voiceId, noteLength, options, tupletRatio) {
2198
- var _a, _b;
2226
+ var _a, _b, _c, _d;
2199
2227
  super(col);
2200
2228
  this.col = col;
2201
2229
  this.voiceId = voiceId;
2202
- __publicField(this, "ownStemDir");
2203
- __publicField(this, "ownDiatonicId");
2230
+ this.options = options;
2204
2231
  __publicField(this, "color");
2205
2232
  __publicField(this, "hide");
2206
2233
  __publicField(this, "oldStyleTriplet");
2207
2234
  __publicField(this, "rhythmProps");
2235
+ __publicField(this, "setDiatonicId");
2236
+ __publicField(this, "runningDiatonicId");
2237
+ // Staff position of rest.
2238
+ __publicField(this, "runningStemDir");
2208
2239
  __publicField(this, "beamGroup");
2209
2240
  __publicField(this, "staffObjects", []);
2210
2241
  __publicField(this, "mi");
2211
- let diatonicId = getDiatonicIdFromStaffPos(options == null ? void 0 : options.staffPos);
2212
- if (diatonicId !== void 0) {
2213
- let hasStaff = this.row.hasStaff;
2214
- let staff2 = this.row.getStaff(diatonicId);
2215
- if (hasStaff && !staff2) {
2216
- throw new import_core6.MusicError(import_core6.MusicErrorType.Score, "Rest staffPos is out of staff boundaries!");
2217
- }
2218
- }
2219
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, diatonicId);
2220
- this.ownStemDir = this.measure.updateOwnStemDir(
2221
- this
2222
- /*, options?.stem*/
2223
- );
2224
- let staff = this.row.getStaff(this.ownDiatonicId);
2225
- if (staff && staff.isSpace(this.ownDiatonicId)) {
2226
- this.ownDiatonicId += this.ownDiatonicId >= staff.middleLineDiatonicId ? 1 : -1;
2227
- }
2228
- this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
2229
- this.hide = (_b = options == null ? void 0 : options.hide) != null ? _b : false;
2242
+ this.setDiatonicId = (_b = getDiatonicIdFromStaffPos((_a = this.options) == null ? void 0 : _a.staffPos)) != null ? _b : _ObjRest.UndefinedDiatonicId;
2243
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(this.voiceId));
2244
+ if (this.setDiatonicId !== _ObjRest.UndefinedDiatonicId && staves.length > 0 && staves[0].isSpace(this.setDiatonicId)) {
2245
+ this.setDiatonicId += this.setDiatonicId >= staves[0].middleLineDiatonicId ? 1 : -1;
2246
+ }
2247
+ this.runningDiatonicId = this.setDiatonicId;
2248
+ this.runningStemDir = "up" /* Up */;
2249
+ this.color = (_c = options == null ? void 0 : options.color) != null ? _c : "black";
2250
+ this.hide = (_d = options == null ? void 0 : options.hide) != null ? _d : false;
2230
2251
  this.oldStyleTriplet = tupletRatio === void 0 && ((options == null ? void 0 : options.triplet) === true || import_theory3.NoteLengthProps.get(noteLength).isTriplet);
2231
2252
  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;
2232
2253
  this.rhythmProps = import_theory3.RhythmProps.get(noteLength, dotCount, (tupletRatio != null ? tupletRatio : this.oldStyleTriplet) ? import_theory3.Tuplet.Triplet : void 0);
@@ -2247,8 +2268,27 @@ var ObjRest = class extends MusicObject {
2247
2268
  get noteLength() {
2248
2269
  return this.rhythmProps.noteLength;
2249
2270
  }
2271
+ getDiatonicId(staff) {
2272
+ if (this.runningDiatonicId === _ObjRest.UndefinedDiatonicId) {
2273
+ if (staff) {
2274
+ if (import_theory3.NoteLengthProps.equals(this.noteLength, "1n")) {
2275
+ return staff.middleLineDiatonicId + 2;
2276
+ } else {
2277
+ return staff.middleLineDiatonicId;
2278
+ }
2279
+ } else {
2280
+ return import_theory3.Note.getNote("G4").diatonicId;
2281
+ }
2282
+ } else {
2283
+ return this.runningDiatonicId;
2284
+ }
2285
+ }
2250
2286
  get stemDir() {
2251
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
2287
+ return this.runningStemDir;
2288
+ }
2289
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
2290
+ this.runningDiatonicId = diatonicId;
2291
+ this.runningStemDir = stemDir;
2252
2292
  }
2253
2293
  getStaticObjects(line) {
2254
2294
  let staticObjects = [];
@@ -2320,28 +2360,28 @@ var ObjRest = class extends MusicObject {
2320
2360
  }
2321
2361
  updateAccidentalState(accState) {
2322
2362
  }
2323
- layout(renderer, accState) {
2363
+ layout(ctx, accState) {
2324
2364
  this.requestRectUpdate();
2325
2365
  this.staffObjects.length = 0;
2326
2366
  if (this.hide) {
2327
2367
  return;
2328
2368
  }
2329
- let { unitSize } = renderer;
2330
- let { ownDiatonicId } = this;
2369
+ let { unitSize } = ctx;
2331
2370
  let { noteSize, dotCount } = this.rhythmProps;
2332
2371
  this.row.getStaves().forEach((staff) => {
2333
- if (!staff.containsDiatonicId(ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2372
+ let diatonicId = this.getDiatonicId(staff);
2373
+ if (!staff.containsDiatonicId(diatonicId) || !staff.containsVoiceId(this.voiceId)) {
2334
2374
  return;
2335
2375
  }
2336
2376
  let obj = new ObjStaffRest(staff, this);
2337
- obj.restRect = renderer.getRestRect(noteSize);
2377
+ obj.restRect = ctx.getRestRect(noteSize);
2338
2378
  for (let i = 0; i < dotCount; i++) {
2339
2379
  let dotWidth = DocumentSettings.DotSize * unitSize;
2340
2380
  let dotX = obj.restRect.rightw + (DocumentSettings.RestDotSpace + DocumentSettings.DotSize * unitSize) + i * DocumentSettings.DotSize * unitSize * 1.5;
2341
2381
  let dotY = this.getRestDotVerticalDisplacement(noteSize) * unitSize;
2342
2382
  obj.dotRects.push(DivRect.createCentered(dotX, dotY, dotWidth, dotWidth));
2343
2383
  }
2344
- obj.offset(0, staff.getDiatonicIdY(ownDiatonicId));
2384
+ obj.offset(0, staff.getDiatonicIdY(diatonicId));
2345
2385
  this.staffObjects.push(obj);
2346
2386
  });
2347
2387
  }
@@ -2361,48 +2401,41 @@ var ObjRest = class extends MusicObject {
2361
2401
  this.staffObjects.forEach((s) => s.offset(dx, 0));
2362
2402
  this.requestRectUpdate();
2363
2403
  }
2364
- draw(renderer) {
2365
- let ctx = renderer.getCanvasContext();
2366
- if (!ctx || this.staffObjects.length === 0) {
2404
+ draw(ctx) {
2405
+ if (this.staffObjects.length === 0) {
2367
2406
  return;
2368
2407
  }
2369
- renderer.drawDebugRect(this.getRect());
2370
- let { lineWidth } = renderer;
2371
- let { color } = this;
2408
+ ctx.drawDebugRect(this.getRect());
2372
2409
  let { noteSize } = this.rhythmProps;
2373
- ctx.strokeStyle = ctx.fillStyle = color;
2374
- ctx.lineWidth = lineWidth;
2410
+ ctx.color(this.color).lineWidth(1);
2375
2411
  this.staffObjects.forEach((obj) => {
2376
2412
  let { dotRects, restRect } = obj;
2377
2413
  let x = restRect.centerX;
2378
2414
  let y = restRect.centerY;
2379
- renderer.drawRest(noteSize, x, y, color);
2380
- dotRects.forEach((r) => {
2381
- renderer.fillCircle(r.centerX, r.centerY, r.width / 2);
2382
- });
2415
+ ctx.drawRest(noteSize, x, y);
2416
+ dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
2383
2417
  });
2384
2418
  }
2385
2419
  };
2420
+ __publicField(_ObjRest, "UndefinedDiatonicId", Infinity);
2421
+ var ObjRest = _ObjRest;
2386
2422
 
2387
2423
  // src/score/engine/obj-note-group.ts
2388
2424
  var import_ts_utils_lib4 = require("@tspro/ts-utils-lib");
2389
2425
  var import_theory4 = require("@tspro/web-music-score/theory");
2390
2426
  var import_core7 = require("@tspro/web-music-score/core");
2391
- function getStem(stem) {
2392
- return import_ts_utils_lib4.Utils.Is.isEnumValue(stem, Stem) ? stem : void 0;
2393
- }
2394
2427
  function getArpeggio(a) {
2395
2428
  return import_ts_utils_lib4.Utils.Is.isEnumValue(a, Arpeggio) ? a : a === true ? "up" /* Up */ : void 0;
2396
2429
  }
2397
- function sortNoteStringData(notes, strings) {
2430
+ function sortNotesAndStrings(notes, strings) {
2398
2431
  let stringArr = import_ts_utils_lib4.Utils.Arr.isArray(strings) ? strings : strings !== void 0 ? [strings] : [];
2399
2432
  let noteStringData = notes.map((note, i) => {
2400
2433
  return { note, string: stringArr[i] };
2401
2434
  });
2402
2435
  noteStringData = import_ts_utils_lib4.Utils.Arr.removeDuplicatesCmp(noteStringData, (a, b) => import_theory4.Note.equals(a.note, b.note)).sort((a, b) => import_theory4.Note.compareFunc(a.note, b.note));
2403
2436
  return {
2404
- notes: noteStringData.map((e) => e.note),
2405
- strings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2437
+ sortedNotes: noteStringData.map((e) => e.note),
2438
+ sortedStrings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2406
2439
  };
2407
2440
  }
2408
2441
  var ObjStaffNoteGroup = class extends MusicObject {
@@ -2474,7 +2507,6 @@ var ObjTabNoteGroup = class extends MusicObject {
2474
2507
  this.noteGroup = noteGroup;
2475
2508
  __publicField(this, "fretNumbers", []);
2476
2509
  __publicField(this, "mi");
2477
- tab.addObject(this);
2478
2510
  this.mi = new MTabNoteGroup(this);
2479
2511
  }
2480
2512
  getMusicInterface() {
@@ -2500,12 +2532,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2500
2532
  this.col = col;
2501
2533
  this.voiceId = voiceId;
2502
2534
  this.notes = notes;
2503
- __publicField(this, "minDiatonicId");
2504
- __publicField(this, "maxDiatonicId");
2505
- __publicField(this, "ownDiatonicId");
2535
+ this.options = options;
2536
+ __publicField(this, "setDiatonicId");
2537
+ __publicField(this, "setStringsNumbers");
2538
+ __publicField(this, "runningDiatonicId");
2506
2539
  // Average diatonicId of notes.
2507
- __publicField(this, "ownStemDir");
2508
- __publicField(this, "ownString");
2540
+ __publicField(this, "runningStemDir");
2541
+ __publicField(this, "runningStringNumbers");
2509
2542
  __publicField(this, "color");
2510
2543
  __publicField(this, "staccato");
2511
2544
  __publicField(this, "diamond");
@@ -2523,13 +2556,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2523
2556
  if (!import_ts_utils_lib4.Utils.Is.isIntegerGte(notes.length, 1)) {
2524
2557
  throw new import_core7.MusicError(import_core7.MusicErrorType.Score, "Cannot create note group object because notes array is empty.");
2525
2558
  }
2526
- let noteStringData = sortNoteStringData(notes, options == null ? void 0 : options.string);
2527
- this.notes = noteStringData.notes;
2528
- this.minDiatonicId = this.notes[0].diatonicId;
2529
- this.maxDiatonicId = this.notes[this.notes.length - 1].diatonicId;
2530
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, Math.round((this.minDiatonicId + this.maxDiatonicId) / 2));
2531
- this.ownStemDir = this.measure.updateOwnStemDir(this, getStem(options == null ? void 0 : options.stem));
2532
- this.ownString = this.measure.updateOwnString(this, noteStringData.strings);
2559
+ let { sortedNotes, sortedStrings } = sortNotesAndStrings(notes, options == null ? void 0 : options.string);
2560
+ this.notes = sortedNotes;
2561
+ this.setStringsNumbers = sortedStrings;
2562
+ this.setDiatonicId = Math.round((this.minDiatonicId + this.maxDiatonicId) / 2);
2563
+ this.runningDiatonicId = this.setDiatonicId;
2564
+ this.runningStemDir = "up" /* Up */;
2565
+ this.runningStringNumbers = [];
2533
2566
  this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
2534
2567
  this.staccato = (_b = options == null ? void 0 : options.staccato) != null ? _b : false;
2535
2568
  this.diamond = (_c = options == null ? void 0 : options.diamond) != null ? _c : false;
@@ -2551,11 +2584,20 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2551
2584
  get row() {
2552
2585
  return this.col.row;
2553
2586
  }
2587
+ get minDiatonicId() {
2588
+ return this.notes[0].diatonicId;
2589
+ }
2590
+ get maxDiatonicId() {
2591
+ return this.notes[this.notes.length - 1].diatonicId;
2592
+ }
2593
+ getDiatonicId(staff) {
2594
+ return this.runningDiatonicId;
2595
+ }
2554
2596
  get stemDir() {
2555
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
2597
+ return this.runningStemDir;
2556
2598
  }
2557
2599
  enableConnective(line) {
2558
- return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.ownDiatonicId));
2600
+ return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.runningDiatonicId));
2559
2601
  }
2560
2602
  startConnective(connectiveProps) {
2561
2603
  if (!this.row.hasStaff && connectiveProps.connective === "tie" /* Tie */) {
@@ -2566,6 +2608,11 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2566
2608
  this.startConnnectives.push(connectiveProps);
2567
2609
  this.doc.addConnectiveProps(connectiveProps);
2568
2610
  }
2611
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
2612
+ this.runningDiatonicId = diatonicId === ObjRest.UndefinedDiatonicId ? this.setDiatonicId : diatonicId;
2613
+ this.runningStemDir = stemDir;
2614
+ this.runningStringNumbers = stringNumbers;
2615
+ }
2569
2616
  getStaticObjects(line) {
2570
2617
  let staticObjects = [];
2571
2618
  this.staffObjects.forEach((obj) => {
@@ -2605,12 +2652,12 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2605
2652
  return this.notes[0];
2606
2653
  }
2607
2654
  getConnectiveAnchorPoint(connectiveProps, line, noteIndex, noteAnchor, side) {
2655
+ var _a;
2608
2656
  if (line instanceof ObjStaff) {
2609
- let staff = line;
2610
2657
  if (noteIndex < 0 || noteIndex >= this.notes.length) {
2611
2658
  throw new import_core7.MusicError(import_core7.MusicErrorType.Score, "Invalid noteIndex: " + noteIndex);
2612
2659
  }
2613
- let obj = this.staffObjects.find((obj2) => obj2.staff === staff);
2660
+ let obj = this.staffObjects.find((obj2) => obj2.staff === line);
2614
2661
  if (!obj || noteIndex < 0 || noteIndex >= obj.noteHeadRects.length) {
2615
2662
  let r = this.getRect();
2616
2663
  return { x: r.centerX, y: r.bottom };
@@ -2658,11 +2705,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2658
2705
  default:
2659
2706
  throw new import_core7.MusicError(import_core7.MusicErrorType.Score, "Invalid noteAnchor: " + noteAnchor);
2660
2707
  }
2661
- } else {
2662
- let tab = line;
2663
- let obj = this.tabObjects.find((obj2) => obj2.tab === tab);
2664
- let fretNumber = obj == null ? void 0 : obj.fretNumbers[noteIndex];
2665
- if (!obj || !fretNumber) {
2708
+ } else if (line instanceof ObjTab) {
2709
+ let fretNumber = (_a = this.tabObjects.find((obj) => obj.tab === line)) == null ? void 0 : _a.fretNumbers[noteIndex];
2710
+ if (!fretNumber) {
2666
2711
  return { x: 0, y: 0 };
2667
2712
  }
2668
2713
  let r = fretNumber.getRect();
@@ -2670,26 +2715,29 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2670
2715
  let y;
2671
2716
  let s = 0.9;
2672
2717
  if (connectiveProps.connective === "slide" /* Slide */) {
2673
- let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(obj, 0);
2674
- let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(obj, 0);
2718
+ let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(line, 0);
2719
+ let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(line, 0);
2675
2720
  let slideUp = leftFretNumber === void 0 || rightFretNumber === void 0 || leftFretNumber <= rightFretNumber;
2676
2721
  if (side === "left") {
2677
- y = slideUp ? r.centerY + r.bottomh * s : r.centerY - r.toph * s;
2722
+ y = (slideUp ? r.centerY + r.bottomh : r.centerY - r.toph) * s;
2678
2723
  } else {
2679
- y = slideUp ? r.centerY - r.toph * s : r.centerY + r.bottomh * s;
2724
+ y = (slideUp ? r.centerY - r.toph : r.centerY + r.bottomh) * s;
2680
2725
  }
2681
2726
  } else {
2682
2727
  y = r.centerY + r.bottomh * s;
2683
2728
  }
2684
2729
  return { x, y };
2730
+ } else {
2731
+ return { x: 0, y: 0 };
2685
2732
  }
2686
2733
  }
2687
2734
  getFretNumberString(noteIndex) {
2688
- return this.ownString[noteIndex];
2735
+ return this.runningStringNumbers[noteIndex];
2689
2736
  }
2690
- getFretNumber(tabObj, noteIndex) {
2691
- let fretNumber = tabObj.fretNumbers[noteIndex];
2692
- return fretNumber === void 0 ? void 0 : +fretNumber.getText();
2737
+ getFretNumber(tab, noteIndex) {
2738
+ let tabObj = this.tabObjects.find((o) => o.tab === tab);
2739
+ let fretNumber = tabObj == null ? void 0 : tabObj.fretNumbers[noteIndex];
2740
+ return fretNumber ? parseInt(fretNumber.getText()) : void 0;
2693
2741
  }
2694
2742
  getNextNoteGroup() {
2695
2743
  let voiceNoteGroups = this.measure.getVoiceSymbols(this.voiceId).filter((s) => s instanceof _ObjNoteGroup);
@@ -2752,8 +2800,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2752
2800
  return { staff, x, y, stemHeight };
2753
2801
  });
2754
2802
  }
2755
- getStemHeight(renderer) {
2756
- let { unitSize } = renderer;
2803
+ getStemHeight(ctx) {
2804
+ let { unitSize } = ctx;
2757
2805
  let { flagCount, hasStem } = this.rhythmProps;
2758
2806
  if (hasStem) {
2759
2807
  let addY = this.hasBeamCount() ? DocumentSettings.BeamSeparation : DocumentSettings.FlagSeparation;
@@ -2816,9 +2864,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2816
2864
  }
2817
2865
  });
2818
2866
  }
2819
- layout(renderer, accState) {
2867
+ layout(ctx, accState) {
2820
2868
  this.requestRectUpdate();
2821
- let { unitSize } = renderer;
2869
+ let { unitSize } = ctx;
2822
2870
  let { row, stemDir } = this;
2823
2871
  let { dotCount, flagCount, hasStem } = this.rhythmProps;
2824
2872
  let dotWidth = DocumentSettings.DotSize * unitSize;
@@ -2826,7 +2874,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2826
2874
  let noteHeadHeight = (this.diamond ? DocumentSettings.DiamondNoteHeadSize : DocumentSettings.NoteHeadHeight) * unitSize;
2827
2875
  this.staffObjects.length = 0;
2828
2876
  row.getStaves().forEach((staff) => {
2829
- if (!staff.containsDiatonicId(this.ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2877
+ if (!staff.containsDiatonicId(this.runningDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2830
2878
  return;
2831
2879
  }
2832
2880
  let obj = new ObjStaffNoteGroup(staff, this);
@@ -2849,7 +2897,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2849
2897
  if (accState.needAccidental(note)) {
2850
2898
  let acc = obj.accidentals[noteIndex] = new ObjAccidental(this, note.diatonicId, note.accidental, this.color);
2851
2899
  if (acc) {
2852
- acc.layout(renderer);
2900
+ acc.layout(ctx);
2853
2901
  acc.offset(-noteHeadRect.leftw - unitSize * DocumentSettings.NoteAccSpace - acc.getRect().rightw, noteY);
2854
2902
  }
2855
2903
  noteStaff.addObject(acc);
@@ -2880,7 +2928,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2880
2928
  let bottomNoteY = obj.noteHeadRects[0].centerY;
2881
2929
  let topNoteY = obj.noteHeadRects[obj.noteHeadRects.length - 1].centerY;
2882
2930
  let stemX = stemDir === "up" /* Up */ ? noteHeadWidth / 2 : -noteHeadWidth / 2;
2883
- let stemHeight = this.getStemHeight(renderer);
2931
+ let stemHeight = this.getStemHeight(ctx);
2884
2932
  let stemTipY = stemDir === "up" /* Up */ ? topNoteY - stemHeight : bottomNoteY + stemHeight;
2885
2933
  let stemBaseY = stemDir === "up" /* Up */ ? bottomNoteY : topNoteY;
2886
2934
  if (hasStem) {
@@ -2907,20 +2955,21 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2907
2955
  }
2908
2956
  let obj = new ObjTabNoteGroup(tab, this);
2909
2957
  this.notes.forEach((note, noteIndex) => {
2910
- if (this.ownString[noteIndex] !== void 0) {
2911
- let stringId = this.ownString[noteIndex] - 1;
2912
- let fretId = note.chromaticId - tab.getTuningStrings()[stringId].chromaticId;
2958
+ let stringNumber = this.runningStringNumbers[noteIndex];
2959
+ if (import_ts_utils_lib4.Utils.Is.isIntegerBetween(stringNumber, 1, 6)) {
2960
+ let fretId = note.chromaticId - tab.getTuningStrings()[stringNumber - 1].chromaticId;
2913
2961
  let color = fretId < 0 ? "red" : "black";
2914
2962
  let fretNumber = new ObjText(this, { text: String(fretId), color, bgcolor: "white" }, 0.5, 0.5);
2915
- obj.fretNumbers.push(fretNumber);
2916
- fretNumber.layout(renderer);
2963
+ fretNumber.layout(ctx);
2917
2964
  let x = this.col.getRect().centerX;
2918
- let y = tab.getStringY(stringId);
2965
+ let y = tab.getStringY(stringNumber - 1);
2919
2966
  fretNumber.offset(x, y);
2967
+ obj.fretNumbers.push(fretNumber);
2920
2968
  }
2921
2969
  });
2922
2970
  if (obj.fretNumbers.length > 0) {
2923
2971
  this.tabObjects.push(obj);
2972
+ tab.addObject(obj);
2924
2973
  }
2925
2974
  });
2926
2975
  }
@@ -2948,19 +2997,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2948
2997
  this.tabObjects.forEach((obj) => obj.offset(dx, 0));
2949
2998
  this.requestRectUpdate();
2950
2999
  }
2951
- draw(renderer) {
2952
- const ctx = renderer.getCanvasContext();
2953
- if (!ctx) {
2954
- return;
2955
- }
2956
- renderer.drawDebugRect(this.getRect());
2957
- let { lineWidth } = renderer;
2958
- let { color, stemDir } = this;
3000
+ draw(ctx) {
3001
+ ctx.drawDebugRect(this.getRect());
3002
+ let { stemDir } = this;
2959
3003
  let { isSolidNoteHead } = this.rhythmProps;
2960
3004
  this.staffObjects.forEach((obj) => {
2961
- obj.accidentals.forEach((d) => d.draw(renderer));
2962
- ctx.strokeStyle = ctx.fillStyle = color;
2963
- ctx.lineWidth = lineWidth;
3005
+ obj.accidentals.forEach((d) => d.draw(ctx));
3006
+ ctx.color(this.color);
3007
+ ctx.lineWidth(1);
2964
3008
  obj.noteHeadRects.forEach((r) => {
2965
3009
  if (this.diamond) {
2966
3010
  if (isSolidNoteHead) {
@@ -2973,14 +3017,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2973
3017
  ctx.fill();
2974
3018
  } else {
2975
3019
  ctx.beginPath();
2976
- ctx.lineWidth = lineWidth * 2.5;
3020
+ ctx.lineWidth(2.5);
2977
3021
  ctx.moveTo(r.centerX, r.top);
2978
3022
  ctx.lineTo(r.right, r.centerY);
2979
3023
  ctx.moveTo(r.left, r.centerY);
2980
3024
  ctx.lineTo(r.centerX, r.bottom);
2981
3025
  ctx.stroke();
2982
3026
  ctx.beginPath();
2983
- ctx.lineWidth = lineWidth;
3027
+ ctx.lineWidth(1);
2984
3028
  ctx.moveTo(r.right, r.centerY);
2985
3029
  ctx.lineTo(r.centerX, r.bottom);
2986
3030
  ctx.moveTo(r.centerX, r.top);
@@ -2997,16 +3041,16 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2997
3041
  }
2998
3042
  }
2999
3043
  });
3000
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
3044
+ obj.dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
3001
3045
  if (obj.stemTip && obj.stemBase) {
3002
3046
  ctx.beginPath();
3003
3047
  ctx.moveTo(obj.stemBase.centerX, obj.stemBase.centerY);
3004
3048
  ctx.lineTo(obj.stemTip.centerX, obj.stemTip.centerY);
3005
3049
  ctx.stroke();
3006
3050
  }
3007
- obj.flagRects.forEach((rect) => renderer.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
3051
+ obj.flagRects.forEach((rect) => ctx.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
3008
3052
  });
3009
- this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(renderer)));
3053
+ this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(ctx)));
3010
3054
  }
3011
3055
  getDotVerticalDisplacement(staff, diatonicId, stemDir) {
3012
3056
  if (staff.isLine(diatonicId)) {
@@ -3032,87 +3076,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
3032
3076
 
3033
3077
  // src/score/engine/obj-rhythm-column.ts
3034
3078
  var import_core8 = require("@tspro/web-music-score/core");
3035
-
3036
- // src/score/engine/obj-lyrics.ts
3037
3079
  var import_ts_utils_lib5 = require("@tspro/ts-utils-lib");
3038
- var LyricsContainer = class {
3039
- constructor(col, lyricsLength) {
3040
- this.col = col;
3041
- __publicField(this, "lyricsObjects", []);
3042
- __publicField(this, "rhythmProps");
3043
- this.rhythmProps = RhythmProps.get(lyricsLength);
3044
- }
3045
- addLyricsObject(lyricsObj) {
3046
- var _a;
3047
- this.lyricsObjects.push(lyricsObj);
3048
- (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
3049
- }
3050
- };
3051
- var ObjLyrics = class extends MusicObject {
3052
- constructor(col, verse, line, vpos, lyricsText, lyricsOptions) {
3053
- super(col);
3054
- this.col = col;
3055
- this.verse = verse;
3056
- this.line = line;
3057
- this.vpos = vpos;
3058
- __publicField(this, "nextLyricsObject");
3059
- __publicField(this, "color", "black");
3060
- __publicField(this, "hyphen");
3061
- __publicField(this, "text");
3062
- __publicField(this, "mi");
3063
- let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
3064
- this.hyphen = import_ts_utils_lib5.Utils.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
3065
- this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
3066
- this.rect = new DivRect();
3067
- this.mi = new MLyrics(this);
3068
- }
3069
- getMusicInterface() {
3070
- return this.mi;
3071
- }
3072
- get measure() {
3073
- return this.col.measure;
3074
- }
3075
- getText() {
3076
- return this.text.getText();
3077
- }
3078
- setNextLyricsObject(lyricsObj) {
3079
- this.nextLyricsObject = lyricsObj;
3080
- }
3081
- pick(x, y) {
3082
- return this.rect.contains(x, y) ? [this] : [];
3083
- }
3084
- layout(renderer) {
3085
- this.text.layout(renderer);
3086
- this.rect = this.text.getRect().copy();
3087
- }
3088
- offset(dx, dy) {
3089
- this.text.offset(dx, dy);
3090
- this.rect.offsetInPlace(dx, dy);
3091
- }
3092
- draw(renderer) {
3093
- var _a;
3094
- this.text.draw(renderer);
3095
- const ctx = renderer.getCanvasContext();
3096
- if (ctx && this.hyphen !== void 0) {
3097
- let l = this.getRect();
3098
- let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
3099
- let hyphenw = renderer.unitSize * 1.5;
3100
- let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
3101
- let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
3102
- if (w > 0) {
3103
- ctx.lineWidth = renderer.lineWidth;
3104
- ctx.strokeStyle = ctx.fillStyle = this.color;
3105
- let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
3106
- let cy = (l.top + l.bottom) / 2;
3107
- ctx.moveTo(cx - w / 2, cy);
3108
- ctx.lineTo(cx + w / 2, cy);
3109
- ctx.stroke();
3110
- }
3111
- }
3112
- }
3113
- };
3114
-
3115
- // src/score/engine/obj-rhythm-column.ts
3116
3080
  var noteHeadDataCompareFunc = (a, b) => {
3117
3081
  let cmp = import_theory5.Note.compareFunc(a.note, b.note);
3118
3082
  if (cmp === 0) {
@@ -3126,7 +3090,7 @@ var ObjRhythmColumn = class extends MusicObject {
3126
3090
  this.measure = measure;
3127
3091
  this.positionTicks = positionTicks;
3128
3092
  __publicField(this, "voiceSymbol", []);
3129
- __publicField(this, "lyricsContainers", []);
3093
+ __publicField(this, "lyricsObject", new import_ts_utils_lib5.Map3());
3130
3094
  __publicField(this, "minDiatonicId");
3131
3095
  __publicField(this, "maxDiatonicId");
3132
3096
  __publicField(this, "staffMinDiatonicId", /* @__PURE__ */ new Map());
@@ -3236,8 +3200,11 @@ var ObjRhythmColumn = class extends MusicObject {
3236
3200
  validateVoiceId(voiceId);
3237
3201
  this.voiceSymbol[voiceId] = symbol;
3238
3202
  if (symbol instanceof ObjRest && !symbol.hide) {
3239
- this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(this.minDiatonicId, symbol.ownDiatonicId);
3240
- this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(this.maxDiatonicId, symbol.ownDiatonicId);
3203
+ this.row.getStaves().forEach((staff) => {
3204
+ let diatonicId = symbol.getDiatonicId(staff);
3205
+ this.minDiatonicId = this.minDiatonicId === void 0 ? diatonicId : Math.min(this.minDiatonicId, diatonicId);
3206
+ this.maxDiatonicId = this.maxDiatonicId === void 0 ? diatonicId : Math.max(this.maxDiatonicId, diatonicId);
3207
+ });
3241
3208
  } else if (symbol instanceof ObjNoteGroup) {
3242
3209
  this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.notes[0].diatonicId : Math.min(this.minDiatonicId, symbol.notes[0].diatonicId);
3243
3210
  this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.notes[symbol.notes.length - 1].diatonicId : Math.max(this.maxDiatonicId, symbol.notes[symbol.notes.length - 1].diatonicId);
@@ -3252,18 +3219,11 @@ var ObjRhythmColumn = class extends MusicObject {
3252
3219
  getVoiceSymbol(voiceId) {
3253
3220
  return this.voiceSymbol[voiceId];
3254
3221
  }
3255
- getLyricsContainerDatas() {
3256
- return this.lyricsContainers;
3222
+ getLyricsObject(verse, line, vpos) {
3223
+ return this.lyricsObject.get(verse, line, vpos);
3257
3224
  }
3258
- getLyricsContainer(verse, line, vpos, lyricsLength) {
3259
- let data = this.lyricsContainers.find((data2) => data2.verse === verse && data2.line === line && data2.vpos === vpos);
3260
- if (data === void 0 && lyricsLength !== void 0) {
3261
- data = { lyricsContainer: new LyricsContainer(this, (0, import_theory5.validateNoteLength)(lyricsLength)), verse, line, vpos };
3262
- this.lyricsContainers.push(data);
3263
- this.requestLayout();
3264
- this.requestRectUpdate();
3265
- }
3266
- return data == null ? void 0 : data.lyricsContainer;
3225
+ addLyricsObject(lyricsObj) {
3226
+ this.lyricsObject.set(lyricsObj.verse, lyricsObj.line, lyricsObj.vpos, lyricsObj);
3267
3227
  }
3268
3228
  getMinWidth() {
3269
3229
  let maxNoteSize = Math.max(...this.voiceSymbol.map((s) => s.rhythmProps.noteSize));
@@ -3374,19 +3334,19 @@ var ObjRhythmColumn = class extends MusicObject {
3374
3334
  this.measure.requestLayout();
3375
3335
  }
3376
3336
  }
3377
- layout(renderer, accState) {
3337
+ layout(ctx, accState) {
3378
3338
  if (!this.needLayout) {
3379
3339
  return;
3380
3340
  }
3381
3341
  this.requestRectUpdate();
3382
3342
  this.rect = new DivRect();
3383
3343
  let { row } = this;
3384
- let { unitSize } = renderer;
3344
+ let { unitSize } = ctx;
3385
3345
  let halfMinWidth = this.getMinWidth() * unitSize / 2;
3386
3346
  let leftw = halfMinWidth;
3387
3347
  let rightw = halfMinWidth;
3388
3348
  this.voiceSymbol.forEach((symbol) => {
3389
- symbol.layout(renderer, accState);
3349
+ symbol.layout(ctx, accState);
3390
3350
  let r = symbol.getRect();
3391
3351
  leftw = Math.max(leftw, r.leftw);
3392
3352
  rightw = Math.max(rightw, r.rightw);
@@ -3395,7 +3355,7 @@ var ObjRhythmColumn = class extends MusicObject {
3395
3355
  let arpeggioWidth = 0;
3396
3356
  this.arpeggios = row.getNotationLines().map((line) => {
3397
3357
  let arpeggio = new ObjArpeggio(this, line, this.getArpeggioDir());
3398
- arpeggio.layout(renderer);
3358
+ arpeggio.layout(ctx);
3399
3359
  arpeggio.offset(-leftw - arpeggio.getRect().right, line.getRect().centerY - arpeggio.getRect().centerY);
3400
3360
  arpeggioWidth = Math.max(arpeggioWidth, arpeggio.getRect().width);
3401
3361
  line.addObject(arpeggio);
@@ -3425,8 +3385,9 @@ var ObjRhythmColumn = class extends MusicObject {
3425
3385
  minDiatonicId = minDiatonicId === void 0 ? symbol.minDiatonicId : Math.min(minDiatonicId, symbol.minDiatonicId);
3426
3386
  maxDiatonicId = maxDiatonicId === void 0 ? symbol.maxDiatonicId : Math.max(maxDiatonicId, symbol.maxDiatonicId);
3427
3387
  } else if (symbol instanceof ObjRest) {
3428
- minDiatonicId = minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(minDiatonicId, symbol.ownDiatonicId);
3429
- maxDiatonicId = maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(maxDiatonicId, symbol.ownDiatonicId);
3388
+ let diatonicId = symbol.getDiatonicId(staff);
3389
+ minDiatonicId = minDiatonicId === void 0 ? diatonicId : Math.min(minDiatonicId, diatonicId);
3390
+ maxDiatonicId = maxDiatonicId === void 0 ? diatonicId : Math.max(maxDiatonicId, diatonicId);
3430
3391
  }
3431
3392
  }
3432
3393
  });
@@ -3460,23 +3421,23 @@ var ObjRhythmColumn = class extends MusicObject {
3460
3421
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
3461
3422
  this.rect.offsetInPlace(dx, dy);
3462
3423
  }
3463
- draw(renderer) {
3424
+ draw(ctx) {
3464
3425
  this.row.getStaves().forEach((staff) => {
3465
3426
  let minDiatonicId = this.staffMinDiatonicId.get(staff);
3466
3427
  let maxDiatonicId = this.staffMaxDiatonicId.get(staff);
3467
3428
  if (minDiatonicId !== void 0) {
3468
- renderer.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3429
+ ctx.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3469
3430
  }
3470
3431
  if (maxDiatonicId !== void 0) {
3471
- renderer.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3432
+ ctx.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3472
3433
  }
3473
3434
  });
3474
3435
  this.voiceSymbol.forEach((symbol) => {
3475
3436
  if (symbol) {
3476
- symbol.draw(renderer);
3437
+ symbol.draw(ctx);
3477
3438
  }
3478
3439
  });
3479
- this.arpeggios.forEach((arpeggio) => arpeggio.draw(renderer));
3440
+ this.arpeggios.forEach((arpeggio) => arpeggio.draw(ctx));
3480
3441
  }
3481
3442
  };
3482
3443
 
@@ -3524,13 +3485,13 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3524
3485
  pick(x, y) {
3525
3486
  return this.rect.contains(x, y) ? [this] : [];
3526
3487
  }
3527
- layout(renderer) {
3488
+ layout(ctx) {
3528
3489
  switch (this.text) {
3529
3490
  case _ObjSpecialText.Coda: {
3530
3491
  let codaSym = this.components[0];
3531
3492
  let codaText = this.components[1];
3532
- codaSym.layout(renderer);
3533
- codaText.layout(renderer);
3493
+ codaSym.layout(ctx);
3494
+ codaText.layout(ctx);
3534
3495
  codaSym.offset(0, (codaText.getRect().top + codaText.getRect().bottom) / 2);
3535
3496
  codaText.offset(codaSym.getRect().right, 0);
3536
3497
  this.rect = new DivRect(
@@ -3546,8 +3507,8 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3546
3507
  case _ObjSpecialText.toCoda: {
3547
3508
  let toCodaText = this.components[0];
3548
3509
  let codaSym = this.components[1];
3549
- toCodaText.layout(renderer);
3550
- codaSym.layout(renderer);
3510
+ toCodaText.layout(ctx);
3511
+ codaSym.layout(ctx);
3551
3512
  codaSym.offset(0, (toCodaText.getRect().top + toCodaText.getRect().bottom) / 2);
3552
3513
  toCodaText.offset(codaSym.getRect().left, 0);
3553
3514
  this.rect = new DivRect(
@@ -3562,7 +3523,7 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3562
3523
  }
3563
3524
  default: {
3564
3525
  let text = this.components[0];
3565
- text.layout(renderer);
3526
+ text.layout(ctx);
3566
3527
  this.rect = text.getRect().copy();
3567
3528
  break;
3568
3529
  }
@@ -3572,9 +3533,9 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3572
3533
  this.components.forEach((c) => c.offset(dx, dy));
3573
3534
  this.rect.offsetInPlace(dx, dy);
3574
3535
  }
3575
- draw(renderer) {
3576
- renderer.drawDebugRect(this.rect);
3577
- this.components.forEach((c) => c.draw(renderer));
3536
+ draw(ctx) {
3537
+ ctx.drawDebugRect(this.rect);
3538
+ this.components.forEach((c) => c.draw(ctx));
3578
3539
  }
3579
3540
  };
3580
3541
  __publicField(_ObjSpecialText, "toCoda", "\u{1D10C} toCoda");
@@ -4036,6 +3997,10 @@ var Player = class _Player {
4036
3997
  return;
4037
3998
  }
4038
3999
  const col = this.playerColumnSequence[this.playPos];
4000
+ if (!col) {
4001
+ this.stop();
4002
+ return;
4003
+ }
4039
4004
  const getDuration = (ticks, tempo2) => {
4040
4005
  let seconds = calcTicksDuration(ticks, tempo2);
4041
4006
  return Math.max(0, seconds);
@@ -4120,6 +4085,9 @@ var Player = class _Player {
4120
4085
  return void 0;
4121
4086
  }
4122
4087
  let col = this.playerColumnSequence[this.playPos];
4088
+ if (!col) {
4089
+ return void 0;
4090
+ }
4123
4091
  let measure = col.measure;
4124
4092
  let x = col.getRect().centerX;
4125
4093
  let top = measure.row.getRect().top;
@@ -4134,8 +4102,8 @@ var ObjStaffTabBarLine = class extends MusicObject {
4134
4102
  super(line);
4135
4103
  this.barLine = barLine;
4136
4104
  this.line = line;
4137
- __publicField(this, "lineRects", []);
4138
- __publicField(this, "dotRects", []);
4105
+ __publicField(this, "verticalLines", []);
4106
+ __publicField(this, "dots", []);
4139
4107
  __publicField(this, "mi");
4140
4108
  line.addObject(this);
4141
4109
  this.mi = new MStaffTabBarLine(this);
@@ -4150,8 +4118,11 @@ var ObjStaffTabBarLine = class extends MusicObject {
4150
4118
  this.rect = r;
4151
4119
  }
4152
4120
  offset(dx, dy) {
4153
- this.lineRects.forEach((r) => r.offsetInPlace(dx, dy));
4154
- this.dotRects.forEach((r) => r.offsetInPlace(dx, dy));
4121
+ this.verticalLines.forEach((l) => l.left += dx);
4122
+ this.dots.forEach((d) => {
4123
+ d.x += dx;
4124
+ d.y += dy;
4125
+ });
4155
4126
  this.rect.offsetInPlace(dx, dy);
4156
4127
  }
4157
4128
  };
@@ -4160,6 +4131,7 @@ var ObjBarLine = class extends MusicObject {
4160
4131
  super(measure);
4161
4132
  this.measure = measure;
4162
4133
  __publicField(this, "staffTabObjects", []);
4134
+ __publicField(this, "staffTabObjectGroups", []);
4163
4135
  __publicField(this, "barLineType", 0 /* None */);
4164
4136
  }
4165
4137
  pick(x, y) {
@@ -4174,14 +4146,14 @@ var ObjBarLine = class extends MusicObject {
4174
4146
  }
4175
4147
  return [this];
4176
4148
  }
4177
- layout(renderer) {
4149
+ layout(ctx) {
4178
4150
  this.requestRectUpdate();
4179
4151
  this.staffTabObjects.length = 0;
4180
4152
  this.barLineType = this.solveBarLineType();
4181
- let { unitSize, lineWidth } = renderer;
4153
+ let { unitSize, _lineWidth } = ctx;
4182
4154
  let { measure, barLineType } = this;
4183
4155
  let { row } = measure;
4184
- let thinW = lineWidth;
4156
+ let thinW = _lineWidth;
4185
4157
  let thicW = 0.7 * unitSize;
4186
4158
  let spaceW = 0.7 * unitSize;
4187
4159
  let dotW = DocumentSettings.DotSize * unitSize;
@@ -4191,13 +4163,13 @@ var ObjBarLine = class extends MusicObject {
4191
4163
  let lineCenterY;
4192
4164
  let lineDotOff;
4193
4165
  let top, bottom;
4194
- const addRect = (left, width) => {
4195
- obj.lineRects.push(new DivRect(left, left + width / 2, left + width, top, 0, bottom));
4166
+ const addVerticalLine = (left, width) => {
4167
+ obj.verticalLines.push({ left, width });
4196
4168
  };
4197
- const addDots = (cx) => {
4169
+ const addDotPair = (cx) => {
4198
4170
  for (let i = -1; i <= 1; i += 2) {
4199
4171
  let y = lineCenterY + i * lineDotOff;
4200
- obj.dotRects.push(new DivRect(cx - dotRadius, cx, cx + dotRadius, y - dotRadius, y, y + dotRadius));
4172
+ obj.dots.push({ x: cx, y, r: dotRadius });
4201
4173
  }
4202
4174
  };
4203
4175
  if (line instanceof ObjStaff) {
@@ -4215,41 +4187,44 @@ var ObjBarLine = class extends MusicObject {
4215
4187
  break;
4216
4188
  case 1 /* Single */:
4217
4189
  obj.setRect(new DivRect(-thinW, 0, 0, top, 0, bottom));
4218
- addRect(-thinW, thinW);
4190
+ addVerticalLine(-thinW, thinW);
4219
4191
  break;
4220
4192
  case 2 /* Double */:
4221
4193
  obj.setRect(new DivRect(-thinW - spaceW - thinW, 0, 0, top, 0, bottom));
4222
- addRect(-thinW - spaceW - thinW, thinW);
4223
- addRect(-thinW, thinW);
4194
+ addVerticalLine(-thinW - spaceW - thinW, thinW);
4195
+ addVerticalLine(-thinW, thinW);
4224
4196
  break;
4225
4197
  case 3 /* EndSong */:
4226
4198
  obj.setRect(new DivRect(-thicW - spaceW - thinW, 0, 0, top, 0, bottom));
4227
- addRect(-thinW - spaceW - thicW, thinW);
4228
- addRect(-thicW, thicW);
4199
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
4200
+ addVerticalLine(-thicW, thicW);
4229
4201
  break;
4230
4202
  case 4 /* StartRepeat */:
4231
4203
  obj.setRect(new DivRect(0, 0, thicW + spaceW + thinW + spaceW + dotW, top, 0, bottom));
4232
- addRect(0, thicW);
4233
- addRect(thicW + spaceW, thinW);
4234
- addDots(thicW + spaceW + thinW + spaceW + dotRadius);
4204
+ addVerticalLine(0, thicW);
4205
+ addVerticalLine(thicW + spaceW, thinW);
4206
+ addDotPair(thicW + spaceW + thinW + spaceW + dotRadius);
4235
4207
  break;
4236
4208
  case 5 /* EndRepeat */:
4237
4209
  obj.setRect(new DivRect(-thicW - spaceW - thinW - spaceW - dotW, 0, 0, top, 0, bottom));
4238
- addRect(-thinW - spaceW - thicW, thinW);
4239
- addRect(-thicW, thicW);
4240
- addDots(-thinW - spaceW - thicW - spaceW - dotRadius);
4210
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
4211
+ addVerticalLine(-thicW, thicW);
4212
+ addDotPair(-thinW - spaceW - thicW - spaceW - dotRadius);
4241
4213
  break;
4242
4214
  case 6 /* EndStartRepeat */:
4243
4215
  obj.setRect(new DivRect(-dotW - spaceW - thinW - spaceW - thicW / 2, 0, thicW / 2 + spaceW + thinW + spaceW + dotW, top, 0, bottom));
4244
- addRect(-thicW / 2, thicW);
4245
- addRect(-thicW / 2 - spaceW - thinW, thinW);
4246
- addRect(thicW / 2 + spaceW, thinW);
4247
- addDots(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
4248
- addDots(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
4216
+ addVerticalLine(-thicW / 2, thicW);
4217
+ addVerticalLine(-thicW / 2 - spaceW - thinW, thinW);
4218
+ addVerticalLine(thicW / 2 + spaceW, thinW);
4219
+ addDotPair(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
4220
+ addDotPair(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
4249
4221
  break;
4250
4222
  }
4251
4223
  this.staffTabObjects.push(obj);
4252
4224
  });
4225
+ this.staffTabObjectGroups = row.getInstrumentLineGroups().map(
4226
+ (lines) => lines.map((line) => this.staffTabObjects.find((obj) => obj.line === line)).filter((obj) => obj !== void 0)
4227
+ );
4253
4228
  }
4254
4229
  updateRect() {
4255
4230
  if (this.staffTabObjects.length > 0) {
@@ -4265,16 +4240,19 @@ var ObjBarLine = class extends MusicObject {
4265
4240
  this.staffTabObjects.forEach((obj) => obj.offset(dx, 0));
4266
4241
  this.requestRectUpdate();
4267
4242
  }
4268
- draw(renderer) {
4269
- const ctx = renderer.getCanvasContext();
4270
- if (!ctx || this.barLineType === 0 /* None */) {
4243
+ draw(ctx) {
4244
+ if (this.barLineType === 0 /* None */) {
4271
4245
  return;
4272
4246
  }
4273
- renderer.drawDebugRect(this.getRect());
4274
- ctx.strokeStyle = ctx.fillStyle = "black";
4275
- this.staffTabObjects.forEach((obj) => {
4276
- obj.lineRects.forEach((r) => ctx.fillRect(r.left, r.top, r.width, r.height));
4277
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
4247
+ ctx.drawDebugRect(this.getRect());
4248
+ ctx.color("black");
4249
+ this.staffTabObjectGroups.forEach((objs) => {
4250
+ if (objs.length > 0) {
4251
+ objs.forEach((obj) => obj.dots.forEach((d) => ctx.fillCircle(d.x, d.y, d.r)));
4252
+ let top = objs[0].getRect().top;
4253
+ let height = objs[objs.length - 1].getRect().bottom - top;
4254
+ objs[0].verticalLines.forEach((vline) => ctx.fillRect(vline.left, top, vline.width, height));
4255
+ }
4278
4256
  });
4279
4257
  }
4280
4258
  };
@@ -4380,14 +4358,14 @@ var ObjEnding = class extends MusicObject {
4380
4358
  pick(x, y) {
4381
4359
  return this.rect.contains(x, y) ? [this] : [];
4382
4360
  }
4383
- layout(renderer) {
4361
+ layout(ctx) {
4384
4362
  this.rect = new DivRect();
4385
4363
  this.shapeRects = [this.rect.copy()];
4386
4364
  }
4387
- layoutFitToMeasure(renderer) {
4388
- let { unitSize } = renderer;
4365
+ layoutFitToMeasure(ctx) {
4366
+ let { unitSize } = ctx;
4389
4367
  let { measure } = this;
4390
- this.endingText.layout(renderer);
4368
+ this.endingText.layout(ctx);
4391
4369
  let textRect = this.endingText.getRect();
4392
4370
  let measureContent = measure.getColumnsContentRect();
4393
4371
  let endingHeight = textRect.height;
@@ -4405,16 +4383,10 @@ var ObjEnding = class extends MusicObject {
4405
4383
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
4406
4384
  this.rect.offsetInPlace(dx, dy);
4407
4385
  }
4408
- draw(renderer) {
4409
- let ctx = renderer.getCanvasContext();
4410
- if (!ctx) {
4411
- return;
4412
- }
4413
- let { lineWidth } = renderer;
4386
+ draw(ctx) {
4414
4387
  let { rect } = this;
4415
- renderer.drawDebugRect(this.rect);
4416
- ctx.strokeStyle = ctx.fillStyle = "black";
4417
- ctx.lineWidth = lineWidth;
4388
+ ctx.drawDebugRect(this.rect);
4389
+ ctx.color("black").lineWidth(1);
4418
4390
  ctx.beginPath();
4419
4391
  ctx.moveTo(rect.left, rect.bottom);
4420
4392
  ctx.lineTo(rect.left, rect.top);
@@ -4423,7 +4395,7 @@ var ObjEnding = class extends MusicObject {
4423
4395
  ctx.lineTo(rect.right, rect.bottom);
4424
4396
  }
4425
4397
  ctx.stroke();
4426
- this.endingText.draw(renderer);
4398
+ this.endingText.draw(ctx);
4427
4399
  }
4428
4400
  };
4429
4401
 
@@ -4498,6 +4470,12 @@ var ObjStaffBeamGroup = class extends MusicObject {
4498
4470
  }
4499
4471
  }
4500
4472
  };
4473
+ var InvalidBeamGroup = class {
4474
+ constructor(beamGroup, message) {
4475
+ this.beamGroup = beamGroup;
4476
+ this.message = message;
4477
+ }
4478
+ };
4501
4479
  var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4502
4480
  constructor(symbols, tupletRatio) {
4503
4481
  super(symbols[0].measure);
@@ -4538,10 +4516,30 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4538
4516
  let first = i === 0;
4539
4517
  let last = i === this.symbols.length - 1;
4540
4518
  if (first && sym.getRightBeamCount() === 0 || last && sym.getLeftBeamCount() === 0 || !first && !last && (sym.getLeftBeamCount() === 0 || sym.getRightBeamCount() === 0)) {
4541
- this.detach();
4519
+ throw new InvalidBeamGroup(this, "Beam has zero left or right beam count!");
4542
4520
  }
4543
4521
  });
4544
4522
  }
4523
+ if (symbols.some((symbol) => symbol.voiceId !== symbols[0].voiceId)) {
4524
+ if (this.type === 0 /* RegularBeam */) {
4525
+ throw new InvalidBeamGroup(this, "Beam symbols have different voiceId.");
4526
+ } else {
4527
+ throw new import_core11.MusicError(import_core11.MusicErrorType.Score, `Tuplet symbols have different voiceId.`);
4528
+ }
4529
+ }
4530
+ symbols[0].row.getStaves().forEach((staff) => {
4531
+ if (staff.getActualStaff(symbols[0].getDiatonicId(staff)) && staff.containsVoiceId(symbols[0].voiceId)) {
4532
+ symbols.forEach((sym) => {
4533
+ let actualStaff = staff.getActualStaff(sym.getDiatonicId(staff));
4534
+ if (!actualStaff || !actualStaff.containsVoiceId(sym.voiceId)) {
4535
+ throw new InvalidBeamGroup(this, "Some of beam or tuplet symbols are not visible!");
4536
+ }
4537
+ });
4538
+ }
4539
+ });
4540
+ }
4541
+ get stemDir() {
4542
+ return this.symbols[0].stemDir;
4545
4543
  }
4546
4544
  get showTupletRatio() {
4547
4545
  var _a;
@@ -4549,26 +4547,54 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4549
4547
  }
4550
4548
  static createBeam(noteGroups) {
4551
4549
  if (noteGroups.length > 1 && noteGroups.every((ng) => !ng.hasTuplet())) {
4552
- new _ObjBeamGroup(noteGroups, void 0);
4550
+ try {
4551
+ new _ObjBeamGroup(noteGroups, void 0);
4552
+ return true;
4553
+ } catch (err) {
4554
+ if (err instanceof InvalidBeamGroup) {
4555
+ err.beamGroup.detach();
4556
+ } else {
4557
+ throw err;
4558
+ }
4559
+ }
4553
4560
  }
4561
+ return false;
4554
4562
  }
4555
4563
  static createOldStyleTriplet(symbols) {
4556
- let s2 = symbols.slice(0, 2);
4557
- let n2 = s2.map((s) => s.rhythmProps.noteSize);
4558
- if (s2.length === 2 && s2.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && (n2[0] * 2 === n2[1] || n2[1] * 2 === n2[0])) {
4559
- new _ObjBeamGroup(s2, import_theory7.Tuplet.Triplet);
4560
- return 2;
4561
- }
4562
- let s3 = symbols.slice(0, 3);
4563
- let n3 = s3.map((s) => s.rhythmProps.noteSize);
4564
- if (s3.length === 3 && s3.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && n3.every((n) => n === n3[0])) {
4565
- new _ObjBeamGroup(s3, import_theory7.Tuplet.Triplet);
4566
- return 3;
4564
+ try {
4565
+ let s2 = symbols.slice(0, 2);
4566
+ let n2 = s2.map((s) => s.rhythmProps.noteSize);
4567
+ if (s2.length === 2 && s2.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && (n2[0] * 2 === n2[1] || n2[1] * 2 === n2[0])) {
4568
+ new _ObjBeamGroup(s2, import_theory7.Tuplet.Triplet);
4569
+ return 2;
4570
+ }
4571
+ let s3 = symbols.slice(0, 3);
4572
+ let n3 = s3.map((s) => s.rhythmProps.noteSize);
4573
+ if (s3.length === 3 && s3.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && n3.every((n) => n === n3[0])) {
4574
+ new _ObjBeamGroup(s3, import_theory7.Tuplet.Triplet);
4575
+ return 3;
4576
+ }
4577
+ } catch (err) {
4578
+ if (err instanceof InvalidBeamGroup) {
4579
+ console.error(err.message);
4580
+ err.beamGroup.detach();
4581
+ } else {
4582
+ throw err;
4583
+ }
4567
4584
  }
4568
4585
  return 0;
4569
4586
  }
4570
4587
  static createTuplet(symbols, tupletRatio) {
4571
- new _ObjBeamGroup(symbols, tupletRatio);
4588
+ try {
4589
+ new _ObjBeamGroup(symbols, tupletRatio);
4590
+ } catch (err) {
4591
+ if (err instanceof InvalidBeamGroup) {
4592
+ console.error(err.message);
4593
+ err.beamGroup.detach();
4594
+ } else {
4595
+ throw err;
4596
+ }
4597
+ }
4572
4598
  }
4573
4599
  getMusicInterface() {
4574
4600
  return this.mi;
@@ -4610,22 +4636,18 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4610
4636
  getLastSymbol() {
4611
4637
  return this.symbols[this.symbols.length - 1];
4612
4638
  }
4613
- get stemDir() {
4614
- return this.symbols[0].ownStemDir;
4639
+ get color() {
4640
+ return this.symbols[0].color;
4615
4641
  }
4616
- layout(renderer) {
4642
+ layout(ctx) {
4617
4643
  this.requestRectUpdate();
4618
4644
  this.staffObjects.length = 0;
4619
4645
  let symbols = this.getSymbols();
4620
4646
  if (symbols.length === 0) {
4621
4647
  return;
4622
4648
  }
4623
- let voiceId = symbols[0].voiceId;
4624
- if (symbols.some((symbol) => symbol.voiceId !== voiceId)) {
4625
- return;
4626
- }
4627
- let { unitSize } = renderer;
4628
- let { stemDir } = this;
4649
+ let { unitSize } = ctx;
4650
+ let { stemDir, type } = this;
4629
4651
  let symbolsBeamCoords = symbols.map((s) => s.getBeamCoords());
4630
4652
  symbolsBeamCoords[0].map((s) => s == null ? void 0 : s.staff).forEach((mainStaff, index) => {
4631
4653
  var _a, _b;
@@ -4661,7 +4683,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4661
4683
  }
4662
4684
  let leftStemHeight = (_a = symbolStemHeight[0]) != null ? _a : 0;
4663
4685
  let rightStemHeight = (_b = symbolStemHeight[symbolStemHeight.length - 1]) != null ? _b : 0;
4664
- if (this.type !== 2 /* TupletGroup */) {
4686
+ if (type !== 2 /* TupletGroup */) {
4665
4687
  let leftDy = leftStemHeight < rightStemHeight ? Math.sqrt(rightStemHeight - leftStemHeight) : 0;
4666
4688
  let rightDy = rightStemHeight < leftStemHeight ? Math.sqrt(leftStemHeight - rightStemHeight) : 0;
4667
4689
  if (stemDir === "up" /* Up */) {
@@ -4699,21 +4721,21 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4699
4721
  rightY += raiseBeamY;
4700
4722
  symbolY = symbolY.map((y) => y === void 0 ? void 0 : y + raiseBeamY);
4701
4723
  let obj = new ObjStaffBeamGroup(mainStaff, this);
4702
- if (this.type === 2 /* TupletGroup */) {
4724
+ if (type === 2 /* TupletGroup */) {
4703
4725
  let ef = unitSize / (rightX - leftX);
4704
4726
  let l = import_ts_utils_lib9.Utils.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, -ef);
4705
4727
  let r = import_ts_utils_lib9.Utils.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, 1 + ef);
4706
4728
  obj.points.push(new BeamPoint(leftStaff, this, leftSymbol, l.x, l.y));
4707
4729
  obj.points.push(new BeamPoint(rightStaff, this, rightSymbol, r.x, r.y));
4708
4730
  obj.tupletNumberOffsetY = 0;
4709
- } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TupletBeam */) {
4731
+ } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4710
4732
  raiseBeamY *= 0.5;
4711
- let { beamThickness } = renderer;
4733
+ let beamThickness = ctx._lineWidth * DocumentSettings.BeamThickness;
4712
4734
  const beamHeight = (i) => {
4713
4735
  let sym = symbols[i];
4714
4736
  if (sym instanceof ObjNoteGroup) {
4715
4737
  let beamCount = sym instanceof ObjNoteGroup ? Math.max(sym.getLeftBeamCount(), sym.getRightBeamCount()) : 0;
4716
- return DocumentSettings.BeamSeparation * unitSize * (this.stemDir === "up" /* Up */ ? beamCount - 1 : 0);
4738
+ return DocumentSettings.BeamSeparation * unitSize * (stemDir === "up" /* Up */ ? beamCount - 1 : 0);
4717
4739
  } else {
4718
4740
  return 0;
4719
4741
  }
@@ -4724,8 +4746,16 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4724
4746
  let symY = symbolY[i];
4725
4747
  if (symStaff && symX !== void 0 && symY !== void 0) {
4726
4748
  let pt = new BeamPoint(symStaff, this, sym, symX, symY);
4727
- pt.topBeamsHeight = beamThickness / 2 + (stemDir === "down" /* Down */ ? beamHeight(i) : 0);
4728
- pt.bottomBeamsHeight = beamThickness / 2 + (stemDir === "up" /* Up */ ? beamHeight(i) : 0);
4749
+ switch (stemDir) {
4750
+ case "up" /* Up */:
4751
+ pt.topBeamsHeight = beamThickness / 2;
4752
+ pt.bottomBeamsHeight = beamThickness / 2 + beamHeight(i);
4753
+ break;
4754
+ case "down" /* Down */:
4755
+ pt.topBeamsHeight = beamThickness / 2 + beamHeight(i);
4756
+ pt.bottomBeamsHeight = beamThickness / 2;
4757
+ break;
4758
+ }
4729
4759
  obj.points.push(pt);
4730
4760
  }
4731
4761
  });
@@ -4733,7 +4763,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4733
4763
  }
4734
4764
  if (this.isTuplet()) {
4735
4765
  obj.tupletNumber = new ObjText(this, this.getTupletRatioText(), 0.5, 0.5);
4736
- obj.tupletNumber.layout(renderer);
4766
+ obj.tupletNumber.layout(ctx);
4737
4767
  obj.tupletNumber.offset((leftX + rightX) / 2, (leftY + rightY) / 2 + obj.tupletNumberOffsetY);
4738
4768
  }
4739
4769
  if (obj.points.length >= 2) {
@@ -4776,55 +4806,56 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4776
4806
  this.staffObjects.forEach((obj) => obj.offset(dx, 0));
4777
4807
  this.requestRectUpdate();
4778
4808
  }
4779
- draw(renderer) {
4780
- let { unitSize, beamThickness, lineWidth } = renderer;
4781
- let color = "black";
4782
- this.staffObjects.forEach((obj) => {
4783
- if (this.type === 2 /* TupletGroup */) {
4784
- let l = obj.points[0];
4785
- let r = obj.points[obj.points.length - 1];
4786
- if (l && r) {
4787
- let tf = obj.tupletNumber ? obj.tupletNumber.getRect().width / (r.x - l.x) * 1.2 : 0;
4788
- let lc = import_ts_utils_lib9.Utils.Math.interpolateCoord(l.x, l.y, r.x, r.y, 0.5 - tf / 2);
4789
- let rc = import_ts_utils_lib9.Utils.Math.interpolateCoord(l.x, l.y, r.x, r.y, 0.5 + tf / 2);
4790
- let tipH = this.stemDir === "up" /* Up */ ? unitSize : -unitSize;
4791
- renderer.drawLine(l.x, l.y, lc.x, lc.y, color, lineWidth);
4792
- renderer.drawLine(rc.x, rc.y, r.x, r.y, color, lineWidth);
4793
- renderer.drawLine(l.x, l.y, l.x, l.y + tipH, color, lineWidth);
4794
- renderer.drawLine(r.x, r.y, r.x, r.y + tipH, color, lineWidth);
4809
+ draw(ctx) {
4810
+ let { unitSize } = ctx;
4811
+ let { stemDir, color, type } = this;
4812
+ if (type === 2 /* TupletGroup */) {
4813
+ ctx.color(color).lineWidth(1);
4814
+ let tipHeight = (stemDir === "up" /* Up */ ? 1 : -1) * unitSize;
4815
+ this.staffObjects.forEach((obj) => {
4816
+ let { x: lx, y: ly } = obj.points[0];
4817
+ let { x: rx, y: ry } = obj.points[obj.points.length - 1];
4818
+ if (obj.tupletNumber) {
4819
+ let tf = obj.tupletNumber.getRect().width / (rx - lx) * 1.2;
4820
+ let lc = import_ts_utils_lib9.Utils.Math.interpolateCoord(lx, ly, rx, ry, 0.5 - tf / 2);
4821
+ let rc = import_ts_utils_lib9.Utils.Math.interpolateCoord(lx, ly, rx, ry, 0.5 + tf / 2);
4822
+ ctx.strokeLine(lx, ly, lc.x, lc.y);
4823
+ ctx.strokeLine(rc.x, rc.y, rx, ry);
4824
+ } else {
4825
+ ctx.strokeLine(lx, ly, rx, ry);
4795
4826
  }
4796
- } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TupletBeam */) {
4797
- let beamSeparation = DocumentSettings.BeamSeparation * unitSize * (this.stemDir === "up" /* Up */ ? 1 : -1);
4827
+ ctx.strokeLine(lx, ly, lx, ly + tipHeight);
4828
+ ctx.strokeLine(rx, ry, rx, ry + tipHeight);
4829
+ });
4830
+ } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4831
+ ctx.color(color).lineWidth(DocumentSettings.BeamThickness);
4832
+ this.staffObjects.forEach((obj) => {
4798
4833
  let noteGroupPoints = obj.points.filter((p) => p.symbol instanceof ObjNoteGroup);
4834
+ let { x: lx, y: ly } = noteGroupPoints[0];
4835
+ let { x: rx, y: ry } = noteGroupPoints[noteGroupPoints.length - 1];
4836
+ let beamSeparation = DocumentSettings.BeamSeparation * unitSize * (stemDir === "up" /* Up */ ? 1 : -1) * (1 + 0.5 * Math.abs(Math.atan2(ry - ly, rx - lx)));
4799
4837
  for (let i = 0; i < noteGroupPoints.length - 1; i++) {
4800
- let left = noteGroupPoints[i];
4801
- let right = noteGroupPoints[i + 1];
4802
- if (!(left.symbol instanceof ObjNoteGroup && right.symbol instanceof ObjNoteGroup)) {
4803
- continue;
4804
- }
4805
- let leftBeamCount = left.symbol.getRightBeamCount();
4806
- let rightBeamCount = right.symbol.getLeftBeamCount();
4807
- let lx = left.x;
4808
- let ly = left.y;
4809
- let rx = right.x;
4810
- let ry = right.y;
4811
- let dy = beamSeparation * (1 + 0.5 * Math.abs(Math.atan2(ry - ly, rx - lx)));
4838
+ let { x: lx2, y: ly2, symbol: lsymbol } = noteGroupPoints[i];
4839
+ let { x: rx2, y: ry2, symbol: rsymbol } = noteGroupPoints[i + 1];
4840
+ let leftBeamCount = lsymbol.getRightBeamCount();
4841
+ let rightBeamCount = rsymbol.getLeftBeamCount();
4812
4842
  for (let beamId = 0; beamId < Math.max(leftBeamCount, rightBeamCount); beamId++) {
4813
4843
  if (beamId < leftBeamCount && beamId < rightBeamCount) {
4814
- renderer.drawLine(lx, ly, rx, ry, color, beamThickness);
4844
+ ctx.strokeLine(lx2, ly2, rx2, ry2);
4815
4845
  } else if (leftBeamCount > rightBeamCount) {
4816
- renderer.drawPartialLine(lx, ly, rx, ry, 0, 0.25, color, beamThickness);
4846
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0, 0.25);
4817
4847
  } else if (rightBeamCount > leftBeamCount) {
4818
- renderer.drawPartialLine(lx, ly, rx, ry, 0.75, 1, color, beamThickness);
4848
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0.75, 1);
4819
4849
  }
4820
- ly += dy;
4821
- ry += dy;
4850
+ ly2 += beamSeparation;
4851
+ ry2 += beamSeparation;
4822
4852
  }
4823
4853
  }
4824
- }
4825
- if (obj.tupletNumber) {
4826
- obj.tupletNumber.draw(renderer);
4827
- }
4854
+ });
4855
+ }
4856
+ this.staffObjects.forEach((obj) => {
4857
+ var _a;
4858
+ return (_a = obj.tupletNumber) == null ? void 0 : _a.draw(ctx);
4828
4859
  });
4829
4860
  }
4830
4861
  setBeamCounts() {
@@ -4924,8 +4955,8 @@ var ObjFermata = class extends MusicObject {
4924
4955
  pick(x, y) {
4925
4956
  return this.rect.contains(x, y) ? [this] : [];
4926
4957
  }
4927
- layout(renderer) {
4928
- let { unitSize } = renderer;
4958
+ layout(ctx) {
4959
+ let { unitSize } = ctx;
4929
4960
  let width = unitSize * 4;
4930
4961
  let height = unitSize * 3;
4931
4962
  this.rect = new DivRect(-width / 2, width / 2, -height, 0);
@@ -4933,12 +4964,8 @@ var ObjFermata = class extends MusicObject {
4933
4964
  offset(dx, dy) {
4934
4965
  this.rect.offsetInPlace(dx, dy);
4935
4966
  }
4936
- draw(renderer) {
4937
- let ctx = renderer.getCanvasContext();
4938
- if (!ctx) {
4939
- return;
4940
- }
4941
- let { lineWidth, unitSize } = renderer;
4967
+ draw(ctx) {
4968
+ let { unitSize } = ctx;
4942
4969
  let upsideDown = this.pos === 1 /* Below */;
4943
4970
  let dy = (upsideDown ? unitSize : -unitSize) * 0.7;
4944
4971
  let left = this.rect.left;
@@ -4946,9 +4973,8 @@ var ObjFermata = class extends MusicObject {
4946
4973
  let top = (upsideDown ? this.rect.bottom : this.rect.top) + dy;
4947
4974
  let bottom = (upsideDown ? this.rect.top : this.rect.bottom) + dy;
4948
4975
  let height = bottom - top;
4949
- renderer.drawDebugRect(this.rect);
4950
- ctx.strokeStyle = ctx.fillStyle = this.color;
4951
- ctx.lineWidth = lineWidth;
4976
+ ctx.drawDebugRect(this.rect);
4977
+ ctx.color("black").lineWidth(1);
4952
4978
  ctx.beginPath();
4953
4979
  ctx.moveTo(left, bottom);
4954
4980
  ctx.bezierCurveTo(left, top, right, top, right, bottom);
@@ -4956,7 +4982,7 @@ var ObjFermata = class extends MusicObject {
4956
4982
  ctx.stroke();
4957
4983
  ctx.fill();
4958
4984
  let r = height / 6;
4959
- renderer.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
4985
+ ctx.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
4960
4986
  }
4961
4987
  };
4962
4988
 
@@ -4999,8 +5025,8 @@ var ObjExtensionLine = class extends MusicObject {
4999
5025
  return this.rightObj.getRect().centerX;
5000
5026
  }
5001
5027
  }
5002
- layoutFitToMeasure(renderer) {
5003
- let { unitSize } = renderer;
5028
+ layoutFitToMeasure(ctx) {
5029
+ let { unitSize } = ctx;
5004
5030
  let lineLeft = this.getLineLeft();
5005
5031
  let lineRight = this.getLineRight();
5006
5032
  let lineRectH = unitSize;
@@ -5009,27 +5035,24 @@ var ObjExtensionLine = class extends MusicObject {
5009
5035
  pick(x, y) {
5010
5036
  return this.rect.contains(x, y) ? [this] : [];
5011
5037
  }
5012
- layout(renderer) {
5038
+ layout(ctx) {
5013
5039
  this.rect = new DivRect();
5014
5040
  }
5015
5041
  offset(dx, dy) {
5016
5042
  this.rect.offsetInPlace(dx, dy);
5017
5043
  }
5018
- draw(renderer) {
5019
- let ctx = renderer.getCanvasContext();
5020
- if (!ctx) {
5021
- return;
5022
- }
5044
+ draw(ctx) {
5023
5045
  let { rect } = this;
5024
5046
  if (this.extension.getLineStyle() === "dashed") {
5025
5047
  ctx.setLineDash([7, 3]);
5026
5048
  }
5027
- renderer.drawLine(rect.left, rect.centerY, rect.right, rect.centerY, "black", renderer.lineWidth);
5049
+ ctx.color("black").lineWidth(1);
5050
+ ctx.strokeLine(rect.left, rect.centerY, rect.right, rect.centerY);
5028
5051
  ctx.setLineDash([]);
5029
5052
  let tails = this.extension.getTails();
5030
5053
  if (tails.length > 0 && this === tails[tails.length - 1]) {
5031
- let tipH = rect.centerY > this.line.getRect().centerY ? -renderer.unitSize : renderer.unitSize;
5032
- renderer.drawLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH, "black", renderer.lineWidth);
5054
+ let tipH = rect.centerY > this.line.getRect().centerY ? -ctx.unitSize : ctx.unitSize;
5055
+ ctx.strokeLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH);
5033
5056
  }
5034
5057
  }
5035
5058
  };
@@ -5045,9 +5068,9 @@ var import_ts_utils_lib10 = require("@tspro/ts-utils-lib");
5045
5068
  var import_core12 = require("@tspro/web-music-score/core");
5046
5069
  var ObjConnective = class extends MusicObject {
5047
5070
  constructor(connectiveProps, line, measure, leftNoteGroup, leftNoteId, ...args) {
5071
+ var _a;
5048
5072
  super(measure);
5049
5073
  this.connectiveProps = connectiveProps;
5050
- this.line = line;
5051
5074
  this.measure = measure;
5052
5075
  __publicField(this, "lx", 0);
5053
5076
  __publicField(this, "ly", 0);
@@ -5058,12 +5081,14 @@ var ObjConnective = class extends MusicObject {
5058
5081
  __publicField(this, "cp2x", 0);
5059
5082
  __publicField(this, "cp2y", 0);
5060
5083
  __publicField(this, "arcHeight", 0);
5084
+ __publicField(this, "line");
5061
5085
  __publicField(this, "leftNoteGroup");
5062
5086
  __publicField(this, "leftNoteId");
5063
5087
  __publicField(this, "rightNoteGroup");
5064
5088
  __publicField(this, "rightNoteId");
5065
5089
  __publicField(this, "tieType");
5066
5090
  __publicField(this, "mi");
5091
+ this.line = (_a = this.measure.row.findMatchingLine(line)) != null ? _a : line;
5067
5092
  this.leftNoteGroup = leftNoteGroup;
5068
5093
  this.leftNoteId = leftNoteId;
5069
5094
  if (args[0] instanceof ObjNoteGroup && typeof args[1] === "number") {
@@ -5087,8 +5112,8 @@ var ObjConnective = class extends MusicObject {
5087
5112
  pick(x, y) {
5088
5113
  return this.rect.contains(x, y) ? [this] : [];
5089
5114
  }
5090
- layout(renderer) {
5091
- let { unitSize } = renderer;
5115
+ layout(ctx) {
5116
+ let { unitSize } = ctx;
5092
5117
  let { measure, line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId, connectiveProps } = this;
5093
5118
  let { noteAnchor, arcDir } = connectiveProps;
5094
5119
  let { row } = measure;
@@ -5164,11 +5189,7 @@ var ObjConnective = class extends MusicObject {
5164
5189
  this.cp2y += dy;
5165
5190
  this.rect.offsetInPlace(dx, dy);
5166
5191
  }
5167
- draw(renderer) {
5168
- let ctx = renderer.getCanvasContext();
5169
- if (!ctx) {
5170
- return;
5171
- }
5192
+ draw(ctx) {
5172
5193
  if (this.rightNoteGroup === void 0) {
5173
5194
  } else if (this.leftNoteGroup.measure === this.rightNoteGroup.measure) {
5174
5195
  } else if (this.leftNoteGroup.row.getNextRow() === this.rightNoteGroup.row) {
@@ -5177,12 +5198,11 @@ var ObjConnective = class extends MusicObject {
5177
5198
  return;
5178
5199
  }
5179
5200
  let { rect } = this;
5180
- let { lineWidth } = renderer;
5181
- renderer.drawDebugRect(rect);
5182
- let t = lineWidth * 1.5;
5183
- let s = lineWidth * 0.25;
5184
- ctx.strokeStyle = ctx.fillStyle = "black";
5185
- ctx.lineWidth = lineWidth;
5201
+ let { _lineWidth } = ctx;
5202
+ ctx.drawDebugRect(rect);
5203
+ let t = _lineWidth * 1.5;
5204
+ let s = _lineWidth * 0.25;
5205
+ ctx.color("black").lineWidth(1);
5186
5206
  if (this.arcHeight === 0) {
5187
5207
  ctx.beginPath();
5188
5208
  ctx.moveTo(this.lx, this.ly);
@@ -5232,7 +5252,7 @@ var ConnectiveProps = class {
5232
5252
  return false;
5233
5253
  }
5234
5254
  }
5235
- computeParams() {
5255
+ computeParams(line) {
5236
5256
  let { stemDir } = this.noteGroups[0];
5237
5257
  let { hasStem } = this.noteGroups[0].rhythmProps;
5238
5258
  if (this.noteAnchor === "stemTip" /* StemTip */) {
@@ -5249,9 +5269,8 @@ var ConnectiveProps = class {
5249
5269
  this.noteAnchor = "below" /* Below */;
5250
5270
  }
5251
5271
  } else if (this.noteAnchor === "center" /* Center */) {
5252
- let { row } = this.noteGroups[0].measure;
5253
- let diatonicId = this.noteGroups[0].ownDiatonicId;
5254
- let staff = row.getStaff(diatonicId);
5272
+ let staff = line instanceof ObjStaff ? line : void 0;
5273
+ let diatonicId = this.noteGroups[0].getDiatonicId(staff);
5255
5274
  this.arcDir = !staff || diatonicId < staff.middleLineDiatonicId ? "down" : "up";
5256
5275
  } else if (this.noteAnchor === "above" /* Above */) {
5257
5276
  this.arcDir = "up";
@@ -5267,68 +5286,73 @@ var ConnectiveProps = class {
5267
5286
  this.noteGroups.length = 1;
5268
5287
  }
5269
5288
  createConnectives() {
5289
+ if (this.noteGroups.length === 0) {
5290
+ return;
5291
+ }
5270
5292
  this.getStartNoteGroup().collectConnectiveProps();
5271
- this.computeParams();
5272
5293
  let { connective, span } = this;
5273
- if (connective === "tie" /* Tie */) {
5274
- if (import_ts_utils_lib11.Utils.Is.isEnumValue(span, TieType)) {
5275
- let leftNoteGroup = this.noteGroups[0];
5276
- for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
5277
- this.createObjConnectiveWithTieType(leftNoteGroup, noteId, span);
5294
+ this.noteGroups[0].row.getNotationLines().forEach((line) => {
5295
+ this.computeParams(line);
5296
+ if (connective === "tie" /* Tie */) {
5297
+ if (import_ts_utils_lib11.Utils.Is.isEnumValue(span, TieType)) {
5298
+ let leftNoteGroup = this.noteGroups[0];
5299
+ for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
5300
+ this.createObjConnectiveWithTieType(line, leftNoteGroup, noteId, span);
5301
+ }
5302
+ } else if (this.noteGroups.length >= 2) {
5303
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
5304
+ let leftNoteGroup = this.noteGroups[i];
5305
+ let rightNoteGroup = this.noteGroups[i + 1];
5306
+ leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
5307
+ let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => import_theory8.Note.equals(rightNote, leftNote));
5308
+ if (rightNoteId >= 0) {
5309
+ this.createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
5310
+ }
5311
+ });
5312
+ }
5278
5313
  }
5279
- } else if (this.noteGroups.length >= 2) {
5280
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
5281
- let leftNoteGroup = this.noteGroups[i];
5282
- let rightNoteGroup = this.noteGroups[i + 1];
5283
- leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
5284
- let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => import_theory8.Note.equals(rightNote, leftNote));
5285
- if (rightNoteId >= 0) {
5286
- this.createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
5287
- }
5288
- });
5314
+ } else if (connective === "slur" /* Slur */) {
5315
+ if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
5316
+ let leftNoteGroup = this.noteGroups[0];
5317
+ let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
5318
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
5289
5319
  }
5290
- }
5291
- } else if (connective === "slur" /* Slur */) {
5292
- if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
5293
- let leftNoteGroup = this.noteGroups[0];
5294
- let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
5295
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
5296
- }
5297
- } else if (connective === "slide" /* Slide */) {
5298
- if (this.noteGroups.length >= 2) {
5299
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
5300
- let leftNoteGroup = this.noteGroups[i];
5301
- let rightNoteGroup = this.noteGroups[i + 1];
5302
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
5320
+ } else if (connective === "slide" /* Slide */) {
5321
+ if (this.noteGroups.length >= 2) {
5322
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
5323
+ let leftNoteGroup = this.noteGroups[i];
5324
+ let rightNoteGroup = this.noteGroups[i + 1];
5325
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
5326
+ }
5303
5327
  }
5304
5328
  }
5305
- }
5329
+ });
5306
5330
  }
5307
- createObjConnectiveWithTieType(leftNoteGroup, leftNoteId, tieType) {
5308
- leftNoteGroup.row.getNotationLines().filter((line) => leftNoteGroup.enableConnective(line)).forEach((line) => {
5309
- if (line instanceof ObjStaff) {
5331
+ createObjConnectiveWithTieType(line, leftNoteGroup, leftNoteId, tieType) {
5332
+ if (!leftNoteGroup.enableConnective(line)) {
5333
+ return;
5334
+ } else if (line instanceof ObjStaff) {
5335
+ new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5336
+ } else if (line instanceof ObjTab) {
5337
+ let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
5338
+ if (leftString !== void 0) {
5310
5339
  new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5311
- } else {
5312
- let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
5313
- if (leftString !== void 0) {
5314
- new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5315
- }
5316
5340
  }
5317
- });
5341
+ }
5318
5342
  }
5319
- createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
5343
+ createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
5320
5344
  const addConnective = (measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2) => {
5321
- measure.row.getNotationLines().filter((line) => leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line)).forEach((line) => {
5322
- if (line instanceof ObjStaff) {
5345
+ if (!(leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line))) {
5346
+ return;
5347
+ } else if (line instanceof ObjStaff) {
5348
+ new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5349
+ } else if (line instanceof ObjTab) {
5350
+ let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
5351
+ let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
5352
+ if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
5323
5353
  new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5324
- } else {
5325
- let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
5326
- let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
5327
- if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
5328
- new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5329
- }
5330
5354
  }
5331
- });
5355
+ }
5332
5356
  };
5333
5357
  if (leftNoteGroup.measure === rightNoteGroup.measure) {
5334
5358
  addConnective(leftNoteGroup.measure, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
@@ -5341,18 +5365,84 @@ var ConnectiveProps = class {
5341
5365
  }
5342
5366
  };
5343
5367
 
5344
- // src/score/engine/obj-tab-rhythm.ts
5368
+ // src/score/engine/obj-lyrics.ts
5345
5369
  var import_ts_utils_lib12 = require("@tspro/ts-utils-lib");
5370
+ var ObjLyrics = class extends MusicObject {
5371
+ constructor(col, verse, line, vpos, lyricsLength, lyricsText, lyricsOptions) {
5372
+ super(col);
5373
+ this.col = col;
5374
+ this.verse = verse;
5375
+ this.line = line;
5376
+ this.vpos = vpos;
5377
+ __publicField(this, "nextLyricsObject");
5378
+ __publicField(this, "rhythmProps");
5379
+ __publicField(this, "color", "black");
5380
+ __publicField(this, "hyphen");
5381
+ __publicField(this, "text");
5382
+ __publicField(this, "mi");
5383
+ this.rhythmProps = RhythmProps.get(lyricsLength);
5384
+ let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
5385
+ this.hyphen = import_ts_utils_lib12.Utils.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
5386
+ this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
5387
+ this.rect = new DivRect();
5388
+ this.mi = new MLyrics(this);
5389
+ }
5390
+ getMusicInterface() {
5391
+ return this.mi;
5392
+ }
5393
+ get measure() {
5394
+ return this.col.measure;
5395
+ }
5396
+ getText() {
5397
+ return this.text.getText();
5398
+ }
5399
+ setNextLyricsObject(lyricsObj) {
5400
+ this.nextLyricsObject = lyricsObj;
5401
+ }
5402
+ pick(x, y) {
5403
+ return this.rect.contains(x, y) ? [this] : [];
5404
+ }
5405
+ layout(ctx) {
5406
+ this.text.layout(ctx);
5407
+ this.rect = this.text.getRect().copy();
5408
+ }
5409
+ offset(dx, dy) {
5410
+ this.text.offset(dx, dy);
5411
+ this.rect.offsetInPlace(dx, dy);
5412
+ }
5413
+ draw(ctx) {
5414
+ var _a;
5415
+ this.text.draw(ctx);
5416
+ if (this.hyphen !== void 0) {
5417
+ ctx.color(this.color).lineWidth(1);
5418
+ let l = this.getRect();
5419
+ let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
5420
+ let hyphenw = ctx.unitSize * 1.5;
5421
+ let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
5422
+ let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
5423
+ if (w > 0) {
5424
+ let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
5425
+ let cy = (l.top + l.bottom) / 2;
5426
+ ctx.moveTo(cx - w / 2, cy);
5427
+ ctx.lineTo(cx + w / 2, cy);
5428
+ ctx.stroke();
5429
+ }
5430
+ }
5431
+ }
5432
+ };
5433
+
5434
+ // src/score/engine/obj-tab-rhythm.ts
5435
+ var import_ts_utils_lib13 = require("@tspro/ts-utils-lib");
5346
5436
  var ObjTabRhythm = class extends MusicObject {
5347
5437
  constructor(measure, tab) {
5348
5438
  super(measure);
5349
5439
  this.measure = measure;
5350
5440
  this.tab = tab;
5351
- __publicField(this, "voiceIds");
5441
+ __publicField(this, "voiceId");
5352
5442
  __publicField(this, "mi");
5353
5443
  // Keep non-static
5354
5444
  __publicField(this, "tupletPartsTextObjMap", /* @__PURE__ */ new Map());
5355
- this.voiceIds = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5445
+ this.voiceId = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5356
5446
  this.rect = new DivRect();
5357
5447
  this.mi = new MTabRhythm(this);
5358
5448
  }
@@ -5362,17 +5452,17 @@ var ObjTabRhythm = class extends MusicObject {
5362
5452
  pick(x, y) {
5363
5453
  return this.rect.contains(x, y) ? [this] : [];
5364
5454
  }
5365
- layout(renderer) {
5455
+ layout(ctx) {
5366
5456
  let columns = this.measure.getColumns();
5367
- let numColsInVoiceId = getVoiceIds().map((voiceId) => import_ts_utils_lib12.Utils.Math.sum(columns.map((col) => col.getVoiceSymbol(voiceId) ? 1 : 0)));
5368
- this.voiceIds.sort((a, b) => import_ts_utils_lib12.Utils.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5457
+ let numColsInVoiceId = getVoiceIds().map((voiceId) => import_ts_utils_lib13.Utils.Math.sum(columns.map((col) => col.getVoiceSymbol(voiceId) ? 1 : 0)));
5458
+ this.voiceId.sort((a, b) => import_ts_utils_lib13.Utils.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5369
5459
  this.rect = new DivRect();
5370
5460
  }
5371
5461
  hasTuplets() {
5372
5462
  return this.measure.getBeamGroups().some((beamGroup) => beamGroup.isTuplet());
5373
5463
  }
5374
- layoutFitToMeasure(renderer) {
5375
- let { unitSize, fontSize } = renderer;
5464
+ layoutFitToMeasure(ctx) {
5465
+ let { unitSize, fontSize } = ctx;
5376
5466
  let { measure } = this;
5377
5467
  let { left, right } = measure.getColumnsContentRect();
5378
5468
  let stemHeight = unitSize * 5;
@@ -5386,13 +5476,10 @@ var ObjTabRhythm = class extends MusicObject {
5386
5476
  offset(dx, dy) {
5387
5477
  this.rect.offsetInPlace(dx, dy);
5388
5478
  }
5389
- draw(renderer) {
5390
- const ctx = renderer.getCanvasContext();
5391
- if (!ctx) {
5392
- return;
5393
- }
5394
- renderer.drawDebugRect(this.rect);
5395
- let { unitSize, lineWidth, fontSize } = renderer;
5479
+ draw(ctx) {
5480
+ ctx.drawDebugRect(this.rect);
5481
+ ctx.color("black").lineWidth(1);
5482
+ let { unitSize, fontSize } = ctx;
5396
5483
  let flagSize = unitSize;
5397
5484
  let dotSpace = unitSize;
5398
5485
  let dotWidth = unitSize * 0.25;
@@ -5402,7 +5489,7 @@ var ObjTabRhythm = class extends MusicObject {
5402
5489
  let columns = this.measure.getColumns();
5403
5490
  for (let colId = 0; colId < columns.length; colId++) {
5404
5491
  let cur = columns[colId];
5405
- let curVoiceSymbol = this.voiceIds.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5492
+ let curVoiceSymbol = this.voiceId.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5406
5493
  if (!curVoiceSymbol) {
5407
5494
  continue;
5408
5495
  }
@@ -5414,16 +5501,17 @@ var ObjTabRhythm = class extends MusicObject {
5414
5501
  let colX = sym.col.getRect().centerX;
5415
5502
  if (sym instanceof ObjNoteGroup) {
5416
5503
  if (sym.rhythmProps.noteSize >= 2) {
5417
- let stemThickness = sym.rhythmProps.noteSize === 4 ? lineWidth * 2 : lineWidth;
5418
- renderer.drawLine(colX, stemBottom, colX, stemTop, "black", stemThickness);
5504
+ ctx.lineWidth(sym.rhythmProps.noteSize === 4 ? 2 : 1);
5505
+ ctx.strokeLine(colX, stemBottom, colX, stemTop);
5419
5506
  }
5507
+ ctx.lineWidth(1);
5420
5508
  if (symbols.length === 1) {
5421
5509
  for (let i = 0; i < sym.rhythmProps.flagCount; i++) {
5422
- renderer.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5510
+ ctx.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5423
5511
  }
5424
5512
  }
5425
5513
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5426
- renderer.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5514
+ ctx.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5427
5515
  }
5428
5516
  } else if (sym instanceof ObjRest) {
5429
5517
  let cx = colX;
@@ -5431,11 +5519,11 @@ var ObjTabRhythm = class extends MusicObject {
5431
5519
  let scale = 0.65;
5432
5520
  ctx.save();
5433
5521
  ctx.scale(scale, scale);
5434
- renderer.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale, "black");
5522
+ ctx.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale);
5435
5523
  ctx.restore();
5436
5524
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5437
5525
  cx += dotSpace * 1.5;
5438
- renderer.fillCircle(cx, cy + dotSpace, dotWidth);
5526
+ ctx.fillCircle(cx, cy + dotSpace, dotWidth);
5439
5527
  }
5440
5528
  }
5441
5529
  if (nextSym) {
@@ -5446,16 +5534,18 @@ var ObjTabRhythm = class extends MusicObject {
5446
5534
  let leftBeamCount = left.hasTuplet() ? 1 : left instanceof ObjNoteGroup ? left.getRightBeamCount() : 1;
5447
5535
  let rightBeamCount = right.hasTuplet() ? 1 : right instanceof ObjNoteGroup ? right.getLeftBeamCount() : 1;
5448
5536
  let maxBeamCount = Math.max(leftBeamCount, rightBeamCount);
5537
+ ctx.lineWidth(2);
5449
5538
  for (let i = 0; i < maxBeamCount; i++) {
5450
5539
  let leftT = rightBeamCount > leftBeamCount && i >= leftBeamCount ? 0.75 : 0;
5451
5540
  let rightT = leftBeamCount > rightBeamCount && i >= rightBeamCount ? 0.25 : 1;
5452
- renderer.drawPartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT, "black", lineWidth * 2);
5541
+ ctx.strokePartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT);
5453
5542
  }
5543
+ ctx.lineWidth(1);
5454
5544
  for (let i = 0; i < left.rhythmProps.dotCount; i++) {
5455
- renderer.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5545
+ ctx.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5456
5546
  }
5457
5547
  for (let i = 0; i < right.rhythmProps.dotCount; i++) {
5458
- renderer.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5548
+ ctx.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5459
5549
  }
5460
5550
  }
5461
5551
  if (beamGroup && beamGroup.isTuplet()) {
@@ -5464,11 +5554,11 @@ var ObjTabRhythm = class extends MusicObject {
5464
5554
  let textObj = this.tupletPartsTextObjMap.get(text);
5465
5555
  if (!textObj) {
5466
5556
  this.tupletPartsTextObjMap.set(text, textObj = new ObjText(this, { text, scale: 0.75 }, 0.5, 0.5));
5467
- textObj.layout(renderer);
5557
+ textObj.layout(ctx);
5468
5558
  }
5469
5559
  textObj.offset(-textObj.getRect().centerX, -textObj.getRect().centerY);
5470
5560
  textObj.offset(cx, stemTop - fontSize / 2);
5471
- textObj.draw(renderer);
5561
+ textObj.draw(ctx);
5472
5562
  }
5473
5563
  if (symbols.length > 1) {
5474
5564
  colId = columns.indexOf(symbols[symbols.length - 1].col);
@@ -5493,7 +5583,7 @@ function getExtensionTicks(extensionLength) {
5493
5583
  if (typeof extensionLength === "string") {
5494
5584
  extensionLength = [extensionLength];
5495
5585
  }
5496
- if (import_ts_utils_lib13.Utils.Is.isArray(extensionLength)) {
5586
+ if (import_ts_utils_lib14.Utils.Is.isArray(extensionLength)) {
5497
5587
  let totalTicks = 0;
5498
5588
  for (let i = 0; i < extensionLength.length; ) {
5499
5589
  let str = extensionLength[i];
@@ -5528,9 +5618,10 @@ function getVerseLayoutGroupId(verse) {
5528
5618
  }
5529
5619
  }
5530
5620
  var _ObjMeasure = class _ObjMeasure extends MusicObject {
5531
- constructor(row) {
5621
+ constructor(row, options) {
5532
5622
  super(row);
5533
5623
  this.row = row;
5624
+ this.options = options;
5534
5625
  __publicField(this, "prevMeasure");
5535
5626
  __publicField(this, "nextMeasure");
5536
5627
  __publicField(this, "keySignature", (0, import_theory9.getDefaultKeySignature)());
@@ -5552,9 +5643,6 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5552
5643
  __publicField(this, "leftSolidAreaWidth", 0);
5553
5644
  __publicField(this, "minColumnsAreaWidth", 0);
5554
5645
  __publicField(this, "rightSolidAreaWidth", 0);
5555
- __publicField(this, "useDiatonicId", []);
5556
- __publicField(this, "useStemDir", []);
5557
- __publicField(this, "useString", []);
5558
5646
  __publicField(this, "voiceSymbols", []);
5559
5647
  __publicField(this, "lastAddedRhythmColumn");
5560
5648
  __publicField(this, "lastAddedRhythmSymbol");
@@ -5571,7 +5659,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5571
5659
  // play twice.
5572
5660
  __publicField(this, "endRepeatPlayCountText");
5573
5661
  __publicField(this, "staticObjectsCache", /* @__PURE__ */ new Map());
5574
- __publicField(this, "lyricsObjectsCache", /* @__PURE__ */ new Map());
5662
+ __publicField(this, "lyricsObjectsCache", new import_ts_utils_lib14.Map3());
5575
5663
  __publicField(this, "mi");
5576
5664
  this.mi = new MMeasure(this);
5577
5665
  this.prevMeasure = row.doc.getLastMeasure();
@@ -5609,54 +5697,67 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5609
5697
  getPassCount() {
5610
5698
  return this.passCount;
5611
5699
  }
5612
- updateOwnDiatonicId(voiceId, setDiatonicId) {
5613
- if (typeof setDiatonicId == "number") {
5614
- this.useDiatonicId[voiceId] = setDiatonicId;
5615
- } else if (this.useDiatonicId[voiceId] === void 0) {
5616
- let prevMeasure = this.getPrevMeasure();
5617
- if (prevMeasure && prevMeasure.useDiatonicId[voiceId] !== void 0) {
5618
- this.useDiatonicId[voiceId] = prevMeasure.useDiatonicId[voiceId];
5619
- }
5620
- }
5621
- let diatonicId = this.useDiatonicId[voiceId];
5622
- if (diatonicId === void 0) {
5623
- if (this.row.hasStaff) {
5624
- diatonicId = this.row.getTopStaff().middleLineDiatonicId;
5625
- } else {
5626
- diatonicId = import_theory9.Note.getNote("C4").diatonicId;
5627
- }
5628
- }
5629
- return this.useDiatonicId[voiceId] = import_theory9.Note.validateDiatonicId(diatonicId);
5630
- }
5631
- updateOwnStemDir(symbol, setStemDir) {
5632
- var _a, _b;
5633
- let { voiceId } = symbol;
5634
- if (setStemDir !== void 0) {
5635
- this.useStemDir[voiceId] = setStemDir;
5636
- } else if (this.useStemDir[voiceId] === void 0) {
5637
- this.useStemDir[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useStemDir[voiceId]) != null ? _b : "auto" /* Auto */;
5638
- }
5639
- let stemDir = this.useStemDir[voiceId];
5640
- if (stemDir === "auto" /* Auto */ || stemDir === void 0) {
5641
- let staff = this.row.getStaff(symbol.ownDiatonicId);
5642
- if (staff) {
5643
- return symbol.ownDiatonicId > staff.middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */;
5644
- } else {
5645
- return "up" /* Up */;
5646
- }
5647
- } else {
5648
- return stemDir;
5649
- }
5650
- }
5651
- updateOwnString(symbol, setString) {
5652
- var _a, _b;
5653
- let { voiceId } = symbol;
5654
- if (setString !== void 0) {
5655
- this.useString[voiceId] = setString;
5656
- } else if (this.useString[voiceId] === void 0) {
5657
- this.useString[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useString[voiceId]) != null ? _b : [];
5658
- }
5659
- return this.useString[voiceId];
5700
+ updateRunningArguments(runningArgs) {
5701
+ var _a;
5702
+ runningArgs != null ? runningArgs : runningArgs = [];
5703
+ let numVoices = import_ts_utils_lib14.Utils.Math.sum(getVoiceIds().map((voiceId) => this.getVoiceSymbols(voiceId).length > 0 ? 1 : 0));
5704
+ getVoiceIds().forEach((voiceId) => {
5705
+ var _a2;
5706
+ const getDefaultDiatonicId = () => {
5707
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(voiceId));
5708
+ let tabs = this.row.getTabs().filter((tab) => tab.containsVoiceId(voiceId));
5709
+ return staves.length > 0 ? staves[0].middleLineDiatonicId : tabs.length > 0 ? tabs[0].getTuningStrings()[3].diatonicId : import_theory9.Note.getNote("G4").diatonicId;
5710
+ };
5711
+ const getDefaultStemDir = () => "auto" /* Auto */;
5712
+ const getDefaultStringNumbers = () => [];
5713
+ let args = (_a2 = runningArgs[voiceId]) != null ? _a2 : runningArgs[voiceId] = {
5714
+ diatonicId: getDefaultDiatonicId(),
5715
+ stemDir: getDefaultStemDir(),
5716
+ stringNumbers: getDefaultStringNumbers()
5717
+ };
5718
+ this.getVoiceSymbols(voiceId).forEach((sym, symId, symArr) => {
5719
+ var _a3, _b;
5720
+ if (sym.setDiatonicId === ObjRest.UndefinedDiatonicId) {
5721
+ if (numVoices < 2) {
5722
+ args.diatonicId = ObjRest.UndefinedDiatonicId;
5723
+ }
5724
+ } else {
5725
+ args.diatonicId = sym.setDiatonicId;
5726
+ }
5727
+ if (sym instanceof ObjNoteGroup) {
5728
+ if (sym.setStringsNumbers) {
5729
+ args.stringNumbers = sym.setStringsNumbers;
5730
+ }
5731
+ switch ((_a3 = sym.options) == null ? void 0 : _a3.stem) {
5732
+ case "up" /* Up */:
5733
+ case "up":
5734
+ args.stemDir = "up" /* Up */;
5735
+ break;
5736
+ case "down" /* Down */:
5737
+ case "down":
5738
+ args.stemDir = "down" /* Down */;
5739
+ break;
5740
+ case "auto" /* Auto */:
5741
+ case "auto":
5742
+ args.stemDir = "auto" /* Auto */;
5743
+ break;
5744
+ }
5745
+ }
5746
+ let beamSymbols = (_b = sym.getBeamGroup()) == null ? void 0 : _b.getSymbols();
5747
+ let setStemDir;
5748
+ if (beamSymbols === void 0) {
5749
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir([sym]) : args.stemDir;
5750
+ } else {
5751
+ if (sym === beamSymbols[0]) {
5752
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir(beamSymbols) : args.stemDir;
5753
+ } else {
5754
+ setStemDir = beamSymbols[0].stemDir;
5755
+ }
5756
+ }
5757
+ sym.updateRunningArguments(args.diatonicId, setStemDir, args.stringNumbers);
5758
+ });
5759
+ });
5760
+ (_a = this.getNextMeasure()) == null ? void 0 : _a.updateRunningArguments(runningArgs);
5660
5761
  }
5661
5762
  pick(x, y) {
5662
5763
  if (!this.getRect().contains(x, y)) {
@@ -5758,7 +5859,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5758
5859
  this.alterKeySignature = args[0];
5759
5860
  } else if (args[0] instanceof import_theory9.Scale) {
5760
5861
  this.alterKeySignature = args[0];
5761
- } else if (import_ts_utils_lib13.Utils.Is.isNonEmptyString(args[0])) {
5862
+ } else if (import_ts_utils_lib14.Utils.Is.isNonEmptyString(args[0])) {
5762
5863
  if (args.length === 1) {
5763
5864
  this.alterKeySignature = (0, import_theory9.getScale)(args[0]);
5764
5865
  } else if (args.length === 2) {
@@ -5869,7 +5970,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5869
5970
  let grp = this.doc.getStaffGroup(staffTabOrGroup);
5870
5971
  if (grp && !prevGroups.includes(staffTabOrGroup)) {
5871
5972
  let curGroups = [...prevGroups, staffTabOrGroup];
5872
- (import_ts_utils_lib13.Utils.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5973
+ (import_ts_utils_lib14.Utils.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5873
5974
  switch (grp.verticalPosition) {
5874
5975
  case "above" /* Above */:
5875
5976
  addToStaffTabOrGroup(staffTabOrGroup2, 0 /* Above */, curGroups);
@@ -5896,7 +5997,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5896
5997
  } else {
5897
5998
  addToStaffTabOrGroup(0, defaultVerticalPos);
5898
5999
  }
5899
- } else if (import_ts_utils_lib13.Utils.Is.isArray(staffTabOrGroups)) {
6000
+ } else if (import_ts_utils_lib14.Utils.Is.isArray(staffTabOrGroups)) {
5900
6001
  staffTabOrGroups.forEach((staffTabOrGroup) => addToStaffTabOrGroup(staffTabOrGroup, defaultVerticalPos));
5901
6002
  } else {
5902
6003
  addToStaffTabOrGroup(staffTabOrGroups, defaultVerticalPos);
@@ -5980,7 +6081,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5980
6081
  case "endRepeat" /* EndRepeat */:
5981
6082
  if (args.length === 0) {
5982
6083
  this.endRepeatPlayCount = 2;
5983
- } else if (import_ts_utils_lib13.Utils.Is.isIntegerGte(args[0], 2)) {
6084
+ } else if (import_ts_utils_lib14.Utils.Is.isIntegerGte(args[0], 2)) {
5984
6085
  this.endRepeatPlayCount = args[0];
5985
6086
  } else {
5986
6087
  throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Invalid end repeat play count (should be 2 or greater integer): " + args[0]);
@@ -6067,15 +6168,15 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6067
6168
  throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Connective can be added to note group only.");
6068
6169
  }
6069
6170
  if (connective === "tie" /* Tie */) {
6070
- let tieSpan = import_ts_utils_lib13.Utils.Is.isInteger(args[0]) || import_ts_utils_lib13.Utils.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
6071
- let noteAnchor = import_ts_utils_lib13.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6171
+ let tieSpan = import_ts_utils_lib14.Utils.Is.isInteger(args[0]) || import_ts_utils_lib14.Utils.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
6172
+ let noteAnchor = import_ts_utils_lib14.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6072
6173
  anchor.startConnective(new ConnectiveProps("tie" /* Tie */, tieSpan, noteAnchor, anchor));
6073
6174
  } else if (connective === "slur" /* Slur */) {
6074
- let slurSpan = import_ts_utils_lib13.Utils.Is.isInteger(args[0]) ? args[0] : 2;
6075
- let noteAnchor = import_ts_utils_lib13.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6175
+ let slurSpan = import_ts_utils_lib14.Utils.Is.isInteger(args[0]) ? args[0] : 2;
6176
+ let noteAnchor = import_ts_utils_lib14.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6076
6177
  anchor.startConnective(new ConnectiveProps("slur" /* Slur */, slurSpan, noteAnchor, anchor));
6077
6178
  } else if (connective === "slide" /* Slide */) {
6078
- let noteAnchor = import_ts_utils_lib13.Utils.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : "auto" /* Auto */;
6179
+ let noteAnchor = import_ts_utils_lib14.Utils.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : "auto" /* Auto */;
6079
6180
  anchor.startConnective(new ConnectiveProps("slide" /* Slide */, 2, noteAnchor, anchor));
6080
6181
  }
6081
6182
  }
@@ -6157,16 +6258,15 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6157
6258
  }
6158
6259
  addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions) {
6159
6260
  this.forEachStaffGroup(staffTabOrGroups, 1 /* Below */, (line, vpos) => {
6261
+ var _a;
6160
6262
  let col = this.getRhythmColumn({ verse, line, vpos });
6161
- let lyricsContainer = col.getLyricsContainer(verse, line, vpos, (0, import_theory9.validateNoteLength)(lyricsLength));
6162
- if (lyricsContainer) {
6163
- let lyricsObj = new ObjLyrics(col, verse, line, vpos, lyricsText, lyricsOptions);
6164
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6165
- lyricsArr.push(lyricsObj);
6166
- lyricsArr.sort((a, b) => import_ts_utils_lib13.Utils.Math.cmp(a.col.positionTicks, b.col.positionTicks));
6167
- lyricsContainer.addLyricsObject(lyricsObj);
6168
- this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
6169
- }
6263
+ let lyricsObj = new ObjLyrics(col, verse, line, vpos, (0, import_theory9.validateNoteLength)(lyricsLength), lyricsText, lyricsOptions);
6264
+ col.addLyricsObject(lyricsObj);
6265
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
6266
+ lyricsArr.push(lyricsObj);
6267
+ lyricsArr.sort((a, b) => import_ts_utils_lib14.Utils.Math.cmp(a.col.positionTicks, b.col.positionTicks));
6268
+ (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
6269
+ this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
6170
6270
  this.lastAddedRhythmColumn = col;
6171
6271
  });
6172
6272
  }
@@ -6179,7 +6279,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6179
6279
  let positionTicks = 0;
6180
6280
  for (let i = this.columns.length - 1; i >= 0 && positionTicks === 0; i--) {
6181
6281
  let col = this.columns[i];
6182
- let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsContainer(arg.verse, arg.line, arg.vpos);
6282
+ let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsObject(arg.verse, arg.line, arg.vpos);
6183
6283
  if (symbol) {
6184
6284
  positionTicks = col.positionTicks + symbol.rhythmProps.ticks;
6185
6285
  }
@@ -6247,31 +6347,21 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6247
6347
  return this.barLineRight.getRect().centerX;
6248
6348
  }
6249
6349
  getLyricsObjects(line, vpos, verse) {
6250
- let vposMap = this.lyricsObjectsCache.get(line);
6251
- if (vposMap === void 0) {
6252
- vposMap = /* @__PURE__ */ new Map();
6253
- this.lyricsObjectsCache.set(line, vposMap);
6254
- }
6255
- let verseMap = vposMap.get(vpos);
6256
- if (verseMap === void 0) {
6257
- verseMap = /* @__PURE__ */ new Map();
6258
- vposMap.set(vpos, verseMap);
6350
+ let lyricsObjs = this.lyricsObjectsCache.get(line, vpos, verse);
6351
+ if (!lyricsObjs) {
6352
+ this.lyricsObjectsCache.set(line, vpos, verse, lyricsObjs = []);
6259
6353
  }
6260
- let lyricsArr = verseMap.get(verse);
6261
- if (lyricsArr === void 0) {
6262
- lyricsArr = [];
6263
- verseMap.set(verse, lyricsArr);
6264
- }
6265
- return lyricsArr;
6354
+ return lyricsObjs;
6266
6355
  }
6267
6356
  getPrevLyricsObject(lyricsObj) {
6268
6357
  var _a;
6269
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6358
+ let { line, verse, vpos } = lyricsObj;
6359
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
6270
6360
  let i = lyricsArr.indexOf(lyricsObj);
6271
6361
  if (i > 0) {
6272
6362
  return lyricsArr[i - 1];
6273
6363
  } else if (i === 0) {
6274
- let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6364
+ let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(line, vpos, verse);
6275
6365
  if (lyricsArr2 && lyricsArr2.length > 0) {
6276
6366
  return lyricsArr2[lyricsArr2.length - 1];
6277
6367
  }
@@ -6385,24 +6475,26 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6385
6475
  let beamGroupSize = ts.beamGroupSizes[groupId];
6386
6476
  let beamGroupSizeList = [beamGroupSize];
6387
6477
  if (beamGroupSize.length > 1) {
6388
- beamGroupSizeList.unshift([import_ts_utils_lib13.Utils.Math.sum(beamGroupSize)]);
6478
+ beamGroupSizeList.unshift([import_ts_utils_lib14.Utils.Math.sum(beamGroupSize)]);
6389
6479
  }
6390
- let beamsCreated = false;
6480
+ let beamCreated = false;
6391
6481
  let groupStartTicksSave = groupStartTicks;
6392
- while (beamGroupSizeList.length > 0 && !beamsCreated) {
6482
+ while (beamGroupSizeList.length > 0 && !beamCreated) {
6393
6483
  let beamGroupSize2 = beamGroupSizeList.shift();
6394
6484
  groupStartTicks = groupStartTicksSave;
6395
6485
  beamGroupSize2.forEach((beamGroupSize3) => {
6396
6486
  let beamGroupTicks = beamGroupSize3 * import_theory9.NoteLengthProps.get("8n").ticks;
6487
+ let groupEndTicks = groupStartTicks + beamGroupTicks;
6397
6488
  let groupSymbols = symbols.filter((symbol) => {
6398
6489
  let symbolStartTicks = upBeatStartTicks + symbol.col.positionTicks;
6399
- let symbolTicks = symbol.rhythmProps.ticks;
6400
- return symbolStartTicks >= groupStartTicks && symbolStartTicks + symbolTicks <= groupStartTicks + beamGroupTicks;
6490
+ let symbolEndTicks = symbolStartTicks + symbol.rhythmProps.ticks;
6491
+ return symbolStartTicks >= groupStartTicks && symbolEndTicks <= groupEndTicks;
6401
6492
  });
6402
- let groupNotesTicks = import_ts_utils_lib13.Utils.Math.sum(groupSymbols.map((sym) => sym.rhythmProps.ticks));
6403
- if (groupNotesTicks === beamGroupTicks && groupSymbols.every((n) => n instanceof ObjNoteGroup) && (groupSymbols.every((n) => n.rhythmProps.flagCount === 1) || beamGroupSizeList.length === 0)) {
6404
- ObjBeamGroup.createBeam(groupSymbols);
6405
- beamsCreated = true;
6493
+ let groupSymbolsTicks = import_ts_utils_lib14.Utils.Math.sum(groupSymbols.map((sym) => sym.rhythmProps.ticks));
6494
+ if (groupSymbolsTicks === beamGroupTicks && groupSymbols.every((n) => n instanceof ObjNoteGroup) && (groupSymbols.every((n) => n.rhythmProps.flagCount === 1) || beamGroupSizeList.length === 0)) {
6495
+ if (ObjBeamGroup.createBeam(groupSymbols)) {
6496
+ beamCreated = true;
6497
+ }
6406
6498
  }
6407
6499
  groupStartTicks += beamGroupTicks;
6408
6500
  });
@@ -6432,7 +6524,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6432
6524
  this.completeRests(getVoiceIds().filter((id) => this.getConsumedTicks(id) > 0));
6433
6525
  }
6434
6526
  return;
6435
- } else if (import_ts_utils_lib13.Utils.Is.isArray(voiceId)) {
6527
+ } else if (import_ts_utils_lib14.Utils.Is.isArray(voiceId)) {
6436
6528
  voiceId.forEach((id) => this.completeRests(id));
6437
6529
  return;
6438
6530
  } else {
@@ -6462,20 +6554,20 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6462
6554
  this.row.requestLayout();
6463
6555
  }
6464
6556
  }
6465
- layout(renderer) {
6557
+ layout(ctx) {
6466
6558
  var _a;
6467
6559
  if (!this.needLayout) {
6468
6560
  return;
6469
6561
  }
6470
6562
  this.staticObjectsCache.clear();
6471
6563
  this.requestRectUpdate();
6472
- let { unitSize } = renderer;
6564
+ let { unitSize } = ctx;
6473
6565
  this.postMeasureBreakWidth = this.hasPostMeasureBreak() ? DocumentSettings.PostMeasureBreakWidth * unitSize : 0;
6474
6566
  let isFirstMeasureInRow = this === this.row.getFirstMeasure();
6475
6567
  let isAfterMeasureBreak = ((_a = this.getPrevMeasure()) == null ? void 0 : _a.hasPostMeasureBreak()) === true;
6476
6568
  this.tabStringNotesWidth = isFirstMeasureInRow && this.row.hasTab ? unitSize * 4 : 0;
6477
6569
  let showClef = isFirstMeasureInRow || isAfterMeasureBreak;
6478
- let showMeasureNumber = isFirstMeasureInRow && !this.row.isFirstRow();
6570
+ let showMeasureNumber = this.options.showNumber === false ? false : this.options.showNumber === true || isFirstMeasureInRow && !this.row.isFirstRow();
6479
6571
  let showKeySignature = isFirstMeasureInRow || isAfterMeasureBreak || !!this.alterKeySignature;
6480
6572
  let showTimeSignature = !!this.alterTimeSignature;
6481
6573
  let showTempo = !!this.alterTempo;
@@ -6485,12 +6577,12 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6485
6577
  let oldSignature = this.signatures.filter((s) => s instanceof ObjStaffSignature).find((s) => s.staff === line);
6486
6578
  let signature = oldSignature != null ? oldSignature : new ObjStaffSignature(this, line);
6487
6579
  signature.staff.addObject(signature);
6488
- signature.updateClefImage(renderer, showClef);
6580
+ signature.updateClefImage(ctx, showClef);
6489
6581
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6490
6582
  signature.updateKeySignature(showKeySignature);
6491
6583
  signature.updateTimeSignature(showTimeSignature);
6492
6584
  signature.updateTempo(showTempo && lineId === 0);
6493
- signature.layout(renderer);
6585
+ signature.layout(ctx);
6494
6586
  this.signatures.push(signature);
6495
6587
  } else if (line instanceof ObjTab && (showMeasureNumber || showTimeSignature || showTempo)) {
6496
6588
  let oldSignature = this.signatures.filter((s) => s instanceof ObjTabSignature).find((s) => s.tab === line);
@@ -6499,7 +6591,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6499
6591
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6500
6592
  signature.updateTimeSignature(showTimeSignature);
6501
6593
  signature.updateTempo(showTempo && lineId === 0);
6502
- signature.layout(renderer);
6594
+ signature.layout(ctx);
6503
6595
  this.signatures.push(signature);
6504
6596
  }
6505
6597
  });
@@ -6509,29 +6601,29 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6509
6601
  for (let stringId = 0; stringId < 6; stringId++) {
6510
6602
  let note = tab.getTuningStrings()[stringId].format(import_theory9.PitchNotation.Helmholtz, import_theory9.SymbolSet.Unicode);
6511
6603
  let obj = new ObjText(this, { text: note, scale: 0.8 }, 1, 0.5);
6512
- obj.layout(renderer);
6604
+ obj.layout(ctx);
6513
6605
  obj.offset(this.tabStringNotesWidth * 0.8, tab.getStringY(stringId));
6514
6606
  this.tabStringNotes.push(obj);
6515
6607
  tab.addObject(obj);
6516
6608
  }
6517
6609
  });
6518
6610
  }
6519
- this.barLineLeft.layout(renderer);
6611
+ this.barLineLeft.layout(ctx);
6520
6612
  const accState = new AccidentalState(this);
6521
- this.columns.forEach((col) => col.layout(renderer, accState));
6522
- this.barLineRight.layout(renderer);
6613
+ this.columns.forEach((col) => col.layout(ctx, accState));
6614
+ this.barLineRight.layout(ctx);
6523
6615
  if (this.endRepeatPlayCountText) {
6524
- this.endRepeatPlayCountText.layout(renderer);
6616
+ this.endRepeatPlayCountText.layout(ctx);
6525
6617
  }
6526
- this.layoutObjects.forEach((layoutObj) => layoutObj.layout(renderer));
6527
- let padding = renderer.unitSize;
6618
+ this.layoutObjects.forEach((layoutObj) => layoutObj.layout(ctx));
6619
+ let padding = ctx.unitSize;
6528
6620
  this.leftSolidAreaWidth = this.tabStringNotesWidth + Math.max(0, ...this.signatures.map((signature) => signature.getRect().width)) + this.barLineLeft.getRect().width + padding;
6529
6621
  this.rightSolidAreaWidth = padding + this.barLineRight.getRect().width;
6530
6622
  this.minColumnsAreaWidth = 0;
6531
6623
  this.columns.forEach((col) => this.minColumnsAreaWidth += col.getRect().width);
6532
6624
  this.minColumnsAreaWidth = Math.max(this.minColumnsAreaWidth, _ObjMeasure.MinFlexContentWidth * unitSize);
6533
6625
  }
6534
- layoutWidth(renderer, width) {
6626
+ layoutWidth(ctx, width) {
6535
6627
  if (!this.needLayout) {
6536
6628
  return;
6537
6629
  }
@@ -6555,7 +6647,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6555
6647
  let columnsAreaLeft = this.rect.left + this.leftSolidAreaWidth;
6556
6648
  let columnsAreaRight = this.rect.right - this.rightSolidAreaWidth;
6557
6649
  let columnsAreaWidth = columnsAreaRight - columnsAreaLeft;
6558
- let columnsWidth = import_ts_utils_lib13.Utils.Math.sum(this.columns.map((col) => col.getRect().width));
6650
+ let columnsWidth = import_ts_utils_lib14.Utils.Math.sum(this.columns.map((col) => col.getRect().width));
6559
6651
  let columnScale = columnsAreaWidth / columnsWidth;
6560
6652
  let columnLeft = columnsAreaLeft;
6561
6653
  this.columns.forEach((col) => {
@@ -6565,22 +6657,22 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6565
6657
  columnLeft += rect.width * columnScale;
6566
6658
  });
6567
6659
  }
6568
- layoutConnectives(renderer) {
6660
+ layoutConnectives(ctx) {
6569
6661
  if (!this.needLayout) {
6570
6662
  return;
6571
6663
  }
6572
6664
  this.connectives.forEach((connective) => {
6573
- connective.layout(renderer);
6665
+ connective.layout(ctx);
6574
6666
  this.rect.top = Math.min(this.rect.top, connective.getRect().top);
6575
6667
  this.rect.bottom = Math.max(this.rect.bottom, connective.getRect().bottom);
6576
6668
  });
6577
6669
  }
6578
- layoutBeams(renderer) {
6670
+ layoutBeams(ctx) {
6579
6671
  if (!this.needLayout) {
6580
6672
  return;
6581
6673
  }
6582
6674
  this.beamGroups.forEach((beamGroup) => {
6583
- beamGroup.layout(renderer);
6675
+ beamGroup.layout(ctx);
6584
6676
  this.rect.top = Math.min(this.rect.top, beamGroup.getRect().top);
6585
6677
  this.rect.bottom = Math.max(this.rect.bottom, beamGroup.getRect().bottom);
6586
6678
  });
@@ -6640,13 +6732,13 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6640
6732
  this.rect.offsetInPlace(dx, dy);
6641
6733
  this.requestRectUpdate();
6642
6734
  }
6643
- draw(renderer) {
6644
- renderer.drawDebugRect(this.getRect());
6735
+ draw(ctx) {
6736
+ ctx.drawDebugRect(this.getRect());
6645
6737
  let left = this.getStaffLineLeft();
6646
6738
  let right = this.getStaffLineRight();
6647
- const drawLine = (y) => renderer.drawLine(left, y, right, y);
6648
- let { row } = this;
6649
- row.getNotationLines().forEach((line) => {
6739
+ ctx.color("black").lineWidth(1);
6740
+ const drawLine = (y) => ctx.strokeLine(left, y, right, y);
6741
+ this.row.getNotationLines().forEach((line) => {
6650
6742
  if (line instanceof ObjStaff) {
6651
6743
  for (let p = line.bottomLineDiatonicId; p <= line.topLineDiatonicId; p += 2) {
6652
6744
  drawLine(line.getDiatonicIdY(p));
@@ -6657,17 +6749,17 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6657
6749
  }
6658
6750
  }
6659
6751
  });
6660
- this.signatures.forEach((signature) => signature.draw(renderer));
6661
- this.tabStringNotes.forEach((obj) => obj.draw(renderer));
6662
- this.barLineLeft.draw(renderer);
6663
- this.columns.forEach((col) => col.draw(renderer));
6664
- this.barLineRight.draw(renderer);
6752
+ this.signatures.forEach((signature) => signature.draw(ctx));
6753
+ this.tabStringNotes.forEach((obj) => obj.draw(ctx));
6754
+ this.barLineLeft.draw(ctx);
6755
+ this.columns.forEach((col) => col.draw(ctx));
6756
+ this.barLineRight.draw(ctx);
6665
6757
  if (this.endRepeatPlayCountText) {
6666
- this.endRepeatPlayCountText.draw(renderer);
6758
+ this.endRepeatPlayCountText.draw(ctx);
6667
6759
  }
6668
- this.connectives.forEach((connective) => connective.draw(renderer));
6669
- this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(renderer));
6670
- this.beamGroups.forEach((beam) => beam.draw(renderer));
6760
+ this.connectives.forEach((connective) => connective.draw(ctx));
6761
+ this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(ctx));
6762
+ this.beamGroups.forEach((beam) => beam.draw(ctx));
6671
6763
  }
6672
6764
  };
6673
6765
  __publicField(_ObjMeasure, "MinFlexContentWidth", 10);
@@ -6737,11 +6829,11 @@ var LayoutObjectWrapper = class {
6737
6829
  isPositionResolved() {
6738
6830
  return this.positionResolved;
6739
6831
  }
6740
- resolveClosestToStaffY(renderer) {
6832
+ resolveClosestToStaffY(ctx) {
6741
6833
  let { musicObj, measure, verticalPos, line } = this;
6742
6834
  let lineTop = line.getTopLineY();
6743
6835
  let lineBottom = line.getBottomLineY();
6744
- let linePadding = renderer.unitSize * 2;
6836
+ let linePadding = ctx.unitSize * 2;
6745
6837
  let y = verticalPos === 1 /* Below */ ? lineBottom + linePadding + musicObj.getRect().toph : lineTop - linePadding - musicObj.getRect().bottomh;
6746
6838
  let staticObjects = measure.getStaticObjects(line);
6747
6839
  let objShapeRects = musicObj.getShapeRects();
@@ -6764,7 +6856,7 @@ var LayoutObjectWrapper = class {
6764
6856
  return void 0;
6765
6857
  }
6766
6858
  }
6767
- layout(renderer) {
6859
+ layout(ctx) {
6768
6860
  this.line.addObject(this);
6769
6861
  }
6770
6862
  offset(dx, dy) {
@@ -6799,20 +6891,21 @@ var LayoutGroup = class {
6799
6891
  }
6800
6892
  });
6801
6893
  }
6802
- clearPositionAndLayout(renderer) {
6894
+ clearPositionAndLayout(ctx) {
6803
6895
  this.layoutObjectTable.forEach((layoutObjects) => {
6804
6896
  layoutObjects.forEach((layoutObj) => {
6805
6897
  layoutObj.clearPositionResolved();
6806
- layoutObj.musicObj.layout(renderer);
6898
+ layoutObj.musicObj.layout(ctx);
6807
6899
  });
6808
6900
  });
6809
6901
  }
6810
6902
  };
6811
6903
 
6812
6904
  // src/score/engine/obj-staff-and-tab.ts
6813
- var ObjNotationLine4 = class extends MusicObject {
6814
- constructor(parent) {
6815
- super(parent);
6905
+ var ObjNotationLine5 = class extends MusicObject {
6906
+ constructor(row) {
6907
+ super(row);
6908
+ this.row = row;
6816
6909
  __publicField(this, "objects", []);
6817
6910
  __publicField(this, "layoutGroups", []);
6818
6911
  }
@@ -6829,18 +6922,18 @@ var ObjNotationLine4 = class extends MusicObject {
6829
6922
  }
6830
6923
  return layoutGroup;
6831
6924
  }
6832
- resetLayoutGroups(renderer) {
6925
+ resetLayoutGroups(ctx) {
6833
6926
  this.layoutGroups.forEach((layoutGroup) => {
6834
6927
  if (layoutGroup) {
6835
- layoutGroup.clearPositionAndLayout(renderer);
6928
+ layoutGroup.clearPositionAndLayout(ctx);
6836
6929
  }
6837
6930
  });
6838
6931
  }
6839
- layoutLayoutGroups(renderer) {
6932
+ layoutLayoutGroups(ctx) {
6840
6933
  this.layoutGroups.forEach((layoutGroup) => {
6841
6934
  if (layoutGroup) {
6842
- this.layoutLayoutGroup(renderer, layoutGroup, 0 /* Above */);
6843
- this.layoutLayoutGroup(renderer, layoutGroup, 1 /* Below */);
6935
+ this.layoutLayoutGroup(ctx, layoutGroup, 0 /* Above */);
6936
+ this.layoutLayoutGroup(ctx, layoutGroup, 1 /* Below */);
6844
6937
  }
6845
6938
  });
6846
6939
  }
@@ -6851,42 +6944,42 @@ var ObjNotationLine4 = class extends MusicObject {
6851
6944
  layoutObj.offset(0, y - layoutObj.getRect().centerY);
6852
6945
  layoutObj.setPositionResolved();
6853
6946
  }
6854
- alignObjectsY(renderer, layoutObjArr) {
6947
+ alignObjectsY(ctx, layoutObjArr) {
6855
6948
  layoutObjArr = layoutObjArr.filter((layoutObj) => !layoutObj.isPositionResolved());
6856
6949
  let rowY;
6857
6950
  layoutObjArr.forEach((layoutObj) => {
6858
- let y = layoutObj.resolveClosestToStaffY(renderer);
6951
+ let y = layoutObj.resolveClosestToStaffY(ctx);
6859
6952
  rowY = layoutObj.verticalPos === 1 /* Below */ ? Math.max(y, rowY != null ? rowY : y) : Math.min(y, rowY != null ? rowY : y);
6860
6953
  });
6861
6954
  layoutObjArr.forEach((layoutObj) => this.setObjectY(layoutObj, rowY));
6862
6955
  }
6863
- layoutLayoutGroup(renderer, layoutGroup, verticalPos) {
6956
+ layoutLayoutGroup(ctx, layoutGroup, verticalPos) {
6864
6957
  let rowLayoutObjs = layoutGroup.getLayoutObjects(verticalPos).filter((layoutObj) => !layoutObj.isPositionResolved());
6865
6958
  rowLayoutObjs.forEach((layoutObj) => {
6866
6959
  let { musicObj, anchor } = layoutObj;
6867
6960
  if (musicObj instanceof ObjEnding || musicObj instanceof ObjExtensionLine || musicObj instanceof ObjTabRhythm) {
6868
- musicObj.layoutFitToMeasure(renderer);
6961
+ musicObj.layoutFitToMeasure(ctx);
6869
6962
  } else {
6870
6963
  musicObj.offset(anchor.getRect().centerX - musicObj.getRect().centerX, 0);
6871
6964
  }
6872
6965
  });
6873
6966
  if (layoutGroup.rowAlign) {
6874
- this.alignObjectsY(renderer, rowLayoutObjs);
6967
+ this.alignObjectsY(ctx, rowLayoutObjs);
6875
6968
  } else {
6876
6969
  rowLayoutObjs.forEach((layoutObj) => {
6877
6970
  let link = layoutObj.musicObj.getLink();
6878
6971
  if (link && link.getHead() === layoutObj.musicObj) {
6879
6972
  let objectParts = [link.getHead(), ...link.getTails()];
6880
6973
  let layoutObjs = rowLayoutObjs.filter((layoutObj2) => objectParts.some((o) => o === layoutObj2.musicObj));
6881
- this.alignObjectsY(renderer, layoutObjs);
6974
+ this.alignObjectsY(ctx, layoutObjs);
6882
6975
  } else {
6883
- this.alignObjectsY(renderer, [layoutObj]);
6976
+ this.alignObjectsY(ctx, [layoutObj]);
6884
6977
  }
6885
6978
  });
6886
6979
  }
6887
6980
  }
6888
6981
  };
6889
- var ObjStaff = class extends ObjNotationLine4 {
6982
+ var ObjStaff = class extends ObjNotationLine5 {
6890
6983
  constructor(row, staffConfig, id) {
6891
6984
  super(row);
6892
6985
  this.row = row;
@@ -6905,11 +6998,11 @@ var ObjStaff = class extends ObjNotationLine4 {
6905
6998
  __publicField(this, "mi");
6906
6999
  const getDiatonicId = (noteName, isOctaveDown) => import_theory11.Note.getNote(noteName).diatonicId - (isOctaveDown ? 7 : 0);
6907
7000
  if (staffConfig.clef === "G" /* G */) {
6908
- this.clefImageAsset = 0 /* TrebleClefPng */;
7001
+ this.clefImageAsset = 0 /* G_Clef */;
6909
7002
  this.clefLineDiatonicId = getDiatonicId("G4", staffConfig.isOctaveDown === true);
6910
7003
  this.middleLineDiatonicId = this.clefLineDiatonicId + 2;
6911
7004
  } else if (staffConfig.clef === "F" /* F */) {
6912
- this.clefImageAsset = 1 /* BassClefPng */;
7005
+ this.clefImageAsset = 1 /* F_Clef */;
6913
7006
  this.clefLineDiatonicId = getDiatonicId("F3", staffConfig.isOctaveDown === true);
6914
7007
  this.middleLineDiatonicId = this.clefLineDiatonicId - 2;
6915
7008
  } else {
@@ -6931,6 +7024,9 @@ var ObjStaff = class extends ObjNotationLine4 {
6931
7024
  var _a;
6932
7025
  return (_a = this.staffConfig.name) != null ? _a : "";
6933
7026
  }
7027
+ getConfig() {
7028
+ return this.staffConfig;
7029
+ }
6934
7030
  getTopLineY() {
6935
7031
  return this.topLineY;
6936
7032
  }
@@ -6984,7 +7080,7 @@ var ObjStaff = class extends ObjNotationLine4 {
6984
7080
  return diatonicId % 2 !== this.middleLineDiatonicId % 2;
6985
7081
  }
6986
7082
  containsVoiceId(voiceId) {
6987
- return !this.staffConfig.voiceIds || this.staffConfig.voiceIds.includes(voiceId);
7083
+ return import_ts_utils_lib15.Utils.Is.isUndefined(this.staffConfig.voiceId) || import_ts_utils_lib15.Utils.Arr.toArray(this.staffConfig.voiceId).includes(voiceId);
6988
7084
  }
6989
7085
  calcTop() {
6990
7086
  let top = this.topLineY;
@@ -7007,16 +7103,16 @@ var ObjStaff = class extends ObjNotationLine4 {
7007
7103
  return bottom;
7008
7104
  }
7009
7105
  pick(x, y) {
7010
- return [this];
7106
+ return this.getRect().contains(x, y) ? [this] : [];
7011
7107
  }
7012
- layoutHeight(renderer) {
7013
- let { unitSize } = renderer;
7108
+ layoutHeight(ctx) {
7109
+ let { unitSize } = ctx;
7014
7110
  let h = unitSize * DocumentSettings.StaffHeight;
7015
7111
  this.topLineY = -h / 2;
7016
7112
  this.bottomLineY = h / 2;
7017
7113
  this.rect = new DivRect(0, 0, this.topLineY, this.bottomLineY);
7018
7114
  }
7019
- layoutWidth(renderer) {
7115
+ layoutWidth(ctx) {
7020
7116
  this.rect.left = this.row.getRect().left;
7021
7117
  this.rect.right = this.row.getRect().right;
7022
7118
  }
@@ -7032,10 +7128,10 @@ var ObjStaff = class extends ObjNotationLine4 {
7032
7128
  });
7033
7129
  this.rect.offsetInPlace(dx, dy);
7034
7130
  }
7035
- draw(renderer) {
7131
+ draw(ctx) {
7036
7132
  }
7037
7133
  };
7038
- var ObjTab = class extends ObjNotationLine4 {
7134
+ var ObjTab = class extends ObjNotationLine5 {
7039
7135
  constructor(row, tabConfig, id) {
7040
7136
  super(row);
7041
7137
  this.row = row;
@@ -7046,7 +7142,7 @@ var ObjTab = class extends ObjNotationLine4 {
7046
7142
  __publicField(this, "tuningName");
7047
7143
  __publicField(this, "tuningStrings");
7048
7144
  __publicField(this, "mi");
7049
- if (import_ts_utils_lib14.Utils.Is.isArray(tabConfig.tuning)) {
7145
+ if (import_ts_utils_lib15.Utils.Is.isArray(tabConfig.tuning)) {
7050
7146
  this.tuningName = void 0;
7051
7147
  this.tuningStrings = tabConfig.tuning.map((noteName) => import_theory11.Note.getNote(noteName)).reverse();
7052
7148
  } else if (typeof tabConfig.tuning === "string") {
@@ -7065,6 +7161,9 @@ var ObjTab = class extends ObjNotationLine4 {
7065
7161
  var _a;
7066
7162
  return (_a = this.tabConfig.name) != null ? _a : "";
7067
7163
  }
7164
+ getConfig() {
7165
+ return this.tabConfig;
7166
+ }
7068
7167
  getTuningName() {
7069
7168
  return this.tuningName;
7070
7169
  }
@@ -7094,7 +7193,7 @@ var ObjTab = class extends ObjNotationLine4 {
7094
7193
  return this.bottom;
7095
7194
  }
7096
7195
  containsVoiceId(voiceId) {
7097
- return !this.tabConfig.voiceIds || this.tabConfig.voiceIds.includes(voiceId);
7196
+ return import_ts_utils_lib15.Utils.Is.isUndefined(this.tabConfig.voiceId) || import_ts_utils_lib15.Utils.Arr.toArray(this.tabConfig.voiceId).includes(voiceId);
7098
7197
  }
7099
7198
  containsDiatonicId(diatonicId) {
7100
7199
  return true;
@@ -7110,16 +7209,16 @@ var ObjTab = class extends ObjNotationLine4 {
7110
7209
  return bottom;
7111
7210
  }
7112
7211
  pick(x, y) {
7113
- return [this];
7212
+ return this.getRect().contains(x, y) ? [this] : [];
7114
7213
  }
7115
- layoutHeight(renderer) {
7116
- let { unitSize } = renderer;
7214
+ layoutHeight(ctx) {
7215
+ let { unitSize } = ctx;
7117
7216
  let h = unitSize * DocumentSettings.TabHeight;
7118
7217
  this.top = -h / 2;
7119
7218
  this.bottom = h / 2;
7120
7219
  this.rect = new DivRect(0, 0, this.top, this.bottom);
7121
7220
  }
7122
- layoutWidth(renderer) {
7221
+ layoutWidth(ctx) {
7123
7222
  this.rect.left = this.row.getRect().left;
7124
7223
  this.rect.right = this.row.getRect().right;
7125
7224
  }
@@ -7135,12 +7234,13 @@ var ObjTab = class extends ObjNotationLine4 {
7135
7234
  });
7136
7235
  this.rect.offsetInPlace(dx, dy);
7137
7236
  }
7138
- draw(renderer) {
7237
+ draw(ctx) {
7139
7238
  }
7140
7239
  };
7141
7240
 
7142
7241
  // src/score/engine/obj-score-row.ts
7143
7242
  var import_core17 = require("@tspro/web-music-score/core");
7243
+ var import_ts_utils_lib16 = require("@tspro/ts-utils-lib");
7144
7244
  var ObjScoreRow = class extends MusicObject {
7145
7245
  constructor(doc, prevRow, scoreConfig) {
7146
7246
  super(doc);
@@ -7150,14 +7250,30 @@ var ObjScoreRow = class extends MusicObject {
7150
7250
  __publicField(this, "nextRow");
7151
7251
  __publicField(this, "minWidth", 0);
7152
7252
  __publicField(this, "notationLines");
7253
+ __publicField(this, "instrumentLineGroups");
7153
7254
  __publicField(this, "staves");
7154
7255
  __publicField(this, "tabs");
7256
+ __publicField(this, "instrumentNames");
7155
7257
  __publicField(this, "measures", []);
7156
7258
  __publicField(this, "needLayout", true);
7157
7259
  __publicField(this, "mi");
7158
7260
  this.notationLines = this.createNotationLines();
7159
7261
  this.staves = this.notationLines.filter((line) => line instanceof ObjStaff);
7160
7262
  this.tabs = this.notationLines.filter((line) => line instanceof ObjTab);
7263
+ let lineGroups = [];
7264
+ for (let i = 0; i < this.notationLines.length; i++) {
7265
+ let line = this.notationLines[i];
7266
+ let prevGroup = lineGroups[lineGroups.length - 1];
7267
+ if (prevGroup === void 0 || prevGroup[0].getConfig().instrument === void 0 || prevGroup[0].getConfig().instrument !== line.getConfig().instrument) {
7268
+ lineGroups.push([line]);
7269
+ } else {
7270
+ prevGroup.push(line);
7271
+ }
7272
+ }
7273
+ this.instrumentLineGroups = lineGroups;
7274
+ this.instrumentNames = this.instrumentLineGroups.map((lines) => {
7275
+ return lines.length > 0 && import_ts_utils_lib16.Utils.Is.isNonEmptyString(lines[0].getConfig().instrument) ? new ObjText(this, String(lines[0].getConfig().instrument), 0, 0.5) : void 0;
7276
+ });
7161
7277
  if (this.prevRow) {
7162
7278
  this.prevRow.nextRow = this;
7163
7279
  }
@@ -7181,6 +7297,14 @@ var ObjScoreRow = class extends MusicObject {
7181
7297
  getNotationLines() {
7182
7298
  return this.notationLines;
7183
7299
  }
7300
+ getInstrumentLineGroups() {
7301
+ return this.instrumentLineGroups;
7302
+ }
7303
+ findMatchingLine(line) {
7304
+ return line.row === this ? line : this.notationLines.find(
7305
+ (curLine) => import_ts_utils_lib16.Utils.Obj.deepEqual(line.row.scoreConfig, curLine.row.scoreConfig) && line.id === curLine.id || import_ts_utils_lib16.Utils.Is.isNonEmptyString(line.getConfig().name) && line.getConfig().name === curLine.getConfig().name && line.getConfig().type === curLine.getConfig().type
7306
+ );
7307
+ }
7184
7308
  getStaves() {
7185
7309
  return this.staves;
7186
7310
  }
@@ -7219,13 +7343,14 @@ var ObjScoreRow = class extends MusicObject {
7219
7343
  }
7220
7344
  return void 0;
7221
7345
  }
7222
- resetLayoutGroups(renderer) {
7223
- this.notationLines.forEach((line) => line.resetLayoutGroups(renderer));
7346
+ resetLayoutGroups(ctx) {
7347
+ this.notationLines.forEach((line) => line.resetLayoutGroups(ctx));
7224
7348
  }
7225
- layoutLayoutGroups(renderer) {
7226
- this.notationLines.forEach((line) => line.layoutLayoutGroups(renderer));
7349
+ layoutLayoutGroups(ctx) {
7350
+ this.notationLines.forEach((line) => line.layoutLayoutGroups(ctx));
7227
7351
  }
7228
7352
  pick(x, y) {
7353
+ var _a, _b;
7229
7354
  if (!this.getRect().contains(x, y)) {
7230
7355
  return [];
7231
7356
  }
@@ -7235,6 +7360,12 @@ var ObjScoreRow = class extends MusicObject {
7235
7360
  return [this, ...arr];
7236
7361
  }
7237
7362
  }
7363
+ for (let i = 0; i < this.instrumentNames.length; i++) {
7364
+ let arr = (_b = (_a = this.instrumentNames[i]) == null ? void 0 : _a.pick(x, y)) != null ? _b : [];
7365
+ if (arr.length > 0) {
7366
+ return [this, ...arr];
7367
+ }
7368
+ }
7238
7369
  for (let i = 0; i < this.notationLines.length; i++) {
7239
7370
  let arr = this.notationLines[i].pick(x, y);
7240
7371
  if (arr.length > 0) {
@@ -7286,61 +7417,78 @@ var ObjScoreRow = class extends MusicObject {
7286
7417
  getMinWidth() {
7287
7418
  return this.minWidth;
7288
7419
  }
7420
+ solveAutoStemDir(symbols) {
7421
+ if (symbols.length === 0) {
7422
+ return "up" /* Up */;
7423
+ } else {
7424
+ let voiceId = symbols[0].voiceId;
7425
+ let noteGroupDiatonicIds = symbols.filter((sym) => sym instanceof ObjNoteGroup).map((n) => n.setDiatonicId);
7426
+ let restDiatonicIds = symbols.filter((sym) => sym instanceof ObjRest && sym.setDiatonicId !== ObjRest.UndefinedDiatonicId).map((r) => r.setDiatonicId);
7427
+ if (noteGroupDiatonicIds.length === 0 && restDiatonicIds.length === 0) {
7428
+ return "up" /* Up */;
7429
+ }
7430
+ let diatonicIds = noteGroupDiatonicIds.length > 0 ? noteGroupDiatonicIds : restDiatonicIds;
7431
+ let avgDiatonicId = Math.floor(import_ts_utils_lib16.Utils.Math.avg(...diatonicIds));
7432
+ let staves = this.getStaves().filter((staff) => staff.containsVoiceId(voiceId) && staff.containsDiatonicId(avgDiatonicId));
7433
+ return staves.length > 0 ? avgDiatonicId >= staves[0].middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */ : "up" /* Up */;
7434
+ }
7435
+ }
7436
+ getInstrumentNameWidth(ctx) {
7437
+ return Math.max(0, ...this.instrumentNames.map((obj) => obj ? obj.getRect().width : 0));
7438
+ }
7289
7439
  requestLayout() {
7290
7440
  if (!this.needLayout) {
7291
7441
  this.needLayout = true;
7292
7442
  this.doc.requestLayout();
7293
7443
  }
7294
7444
  }
7295
- layout(renderer) {
7445
+ layout(ctx) {
7296
7446
  if (!this.needLayout) {
7297
7447
  return;
7298
7448
  }
7299
7449
  this.requestRectUpdate();
7450
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.layout(ctx));
7300
7451
  this.notationLines.forEach((line) => {
7301
7452
  line.removeObjects();
7302
- line.layoutHeight(renderer);
7453
+ line.layoutHeight(ctx);
7303
7454
  });
7304
- this.rect = new DivRect(0, 0, 0, 0);
7305
7455
  this.minWidth = 0;
7306
7456
  this.measures.forEach((m) => {
7307
- m.layout(renderer);
7457
+ m.layout(ctx);
7308
7458
  this.minWidth += m.getMinWidth();
7309
7459
  this.minWidth += m.getPostMeasureBreakWidth();
7310
7460
  });
7311
7461
  }
7312
- layoutWidth(renderer, width) {
7462
+ layoutWidth(ctx, left, right) {
7313
7463
  if (!this.needLayout) {
7314
7464
  return;
7315
7465
  }
7316
- let rowWidth = Math.max(width, this.minWidth);
7317
- this.rect.centerX = this.rect.left + rowWidth / 2;
7318
- this.rect.right = this.rect.left + rowWidth;
7319
- this.notationLines.forEach((line) => line.layoutWidth(renderer));
7320
- let targetColumnsAreaWidth = rowWidth;
7466
+ this.rect = new DivRect(0, right, 0, 0);
7467
+ this.notationLines.forEach((line) => line.layoutWidth(ctx));
7468
+ let targetColumnsAreaWidth = right - left;
7321
7469
  let minColumnsAreaWidth = 0;
7322
7470
  this.measures.forEach((m) => {
7323
7471
  targetColumnsAreaWidth -= m.getSolidAreaWidth() + m.getPostMeasureBreakWidth();
7324
7472
  minColumnsAreaWidth += m.getMinColumnsAreaWidth();
7325
7473
  });
7326
7474
  let columnsAreaScale = targetColumnsAreaWidth / minColumnsAreaWidth;
7327
- let x = 0;
7475
+ let x = this.doc.getInstrumentGroupSize(ctx).braceRight;
7328
7476
  this.measures.forEach((m) => {
7329
7477
  let newMeasureWidth = m.getSolidAreaWidth() + m.getMinColumnsAreaWidth() * columnsAreaScale;
7330
- m.layoutWidth(renderer, newMeasureWidth);
7478
+ m.layoutWidth(ctx, newMeasureWidth);
7331
7479
  let r = m.getRect();
7332
7480
  m.offset(x - r.left, -r.centerY);
7333
7481
  x += r.width;
7334
7482
  x += m.getPostMeasureBreakWidth();
7335
7483
  });
7336
7484
  this.measures.forEach((m) => {
7337
- m.layoutConnectives(renderer);
7338
- m.layoutBeams(renderer);
7485
+ m.layoutConnectives(ctx);
7486
+ m.layoutBeams(ctx);
7339
7487
  });
7340
7488
  }
7341
7489
  updateRect() {
7342
- let left = this.measures.length > 0 ? this.measures[0].getRect().left : 0;
7343
- let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : 0;
7490
+ let left = 0;
7491
+ let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : left;
7344
7492
  let top = this.measures.length > 0 ? Math.min(...this.measures.map((m) => m.getRect().top)) : 0;
7345
7493
  let bottom = this.measures.length > 0 ? Math.max(...this.measures.map((m) => m.getRect().bottom)) : 0;
7346
7494
  this.rect = new DivRect(left, right, top, bottom);
@@ -7348,8 +7496,8 @@ var ObjScoreRow = class extends MusicObject {
7348
7496
  alignStemsToBeams() {
7349
7497
  this.measures.forEach((m) => m.alignStemsToBeams());
7350
7498
  }
7351
- layoutSetNotationLines(renderer) {
7352
- let { unitSize } = renderer;
7499
+ layoutSetNotationLines(ctx) {
7500
+ let { unitSize } = ctx;
7353
7501
  for (let i = 1; i < this.notationLines.length; i++) {
7354
7502
  let prev = this.notationLines[i - 1];
7355
7503
  let cur = this.notationLines[i];
@@ -7373,11 +7521,20 @@ var ObjScoreRow = class extends MusicObject {
7373
7521
  });
7374
7522
  });
7375
7523
  });
7524
+ this.instrumentNames.forEach((obj, i) => {
7525
+ let grp = this.instrumentLineGroups[i];
7526
+ if (obj && grp.length > 0) {
7527
+ obj.offset(
7528
+ -obj.getRect().left,
7529
+ -obj.getRect().centerY + (grp[0].getRect().top + grp[grp.length - 1].getRect().bottom) / 2
7530
+ );
7531
+ }
7532
+ });
7376
7533
  this.alignStemsToBeams();
7377
7534
  this.requestRectUpdate();
7378
7535
  }
7379
- layoutPadding(renderer) {
7380
- let p = renderer.unitSize / 2;
7536
+ layoutPadding(ctx) {
7537
+ let p = ctx.unitSize / 2;
7381
7538
  this.getRect();
7382
7539
  this.rect.left -= p;
7383
7540
  this.rect.right += p;
@@ -7392,24 +7549,38 @@ var ObjScoreRow = class extends MusicObject {
7392
7549
  this.measures.forEach((m) => m.offset(dx, dy));
7393
7550
  this.rect.offsetInPlace(dx, dy);
7394
7551
  this.notationLines.forEach((l) => l.offset(dx, dy));
7552
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.offset(dx, dy));
7395
7553
  }
7396
- draw(renderer) {
7397
- let ctx = renderer.getCanvasContext();
7398
- if (!ctx) {
7399
- return;
7400
- }
7401
- renderer.drawDebugRect(this.getRect());
7554
+ draw(ctx) {
7555
+ ctx.drawDebugRect(this.getRect());
7402
7556
  ctx.save();
7403
- ctx.rect(this.getRect().left, this.getRect().top, this.getRect().width, this.getRect().height);
7557
+ let { left, top, width, height } = this.getRect();
7558
+ ctx.rect(left, top, width, height);
7404
7559
  ctx.clip();
7405
7560
  if (this.getFirstMeasure() && (this.notationLines.length > 1 || this.notationLines[0] instanceof ObjTab)) {
7406
- let left = this.getFirstMeasure().getStaffLineLeft();
7407
- let top = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7561
+ let left2 = this.getFirstMeasure().getStaffLineLeft();
7562
+ let top2 = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7408
7563
  let bottom = Math.max(...this.notationLines.map((line) => line.getBottomLineY()));
7409
- renderer.drawLine(left, top, left, bottom);
7410
- }
7411
- this.measures.forEach((m) => m.draw(renderer));
7412
- this.notationLines.forEach((m) => m.draw(renderer));
7564
+ ctx.color("black").lineWidth(1).strokeLine(left2, top2, left2, bottom);
7565
+ }
7566
+ this.measures.forEach((m) => m.draw(ctx));
7567
+ this.notationLines.forEach((m) => m.draw(ctx));
7568
+ let grpSize = this.doc.getInstrumentGroupSize(ctx);
7569
+ this.instrumentNames.forEach((obj, i) => {
7570
+ let grp = this.instrumentLineGroups[i];
7571
+ if (grp.length > 1) {
7572
+ let r = new DivRect(
7573
+ grpSize.braceLeft,
7574
+ grpSize.braceRight,
7575
+ grp[0].getTopLineY(),
7576
+ grp[grp.length - 1].getBottomLineY()
7577
+ );
7578
+ ctx.color("brack").lineWidth(1).drawBrace(r, "left");
7579
+ }
7580
+ if (obj) {
7581
+ obj.draw(ctx);
7582
+ }
7583
+ });
7413
7584
  ctx.restore();
7414
7585
  }
7415
7586
  };
@@ -7457,24 +7628,24 @@ var ObjHeader = class extends MusicObject {
7457
7628
  }
7458
7629
  return [this];
7459
7630
  }
7460
- layoutWidth(renderer, width) {
7631
+ layoutWidth(ctx, left, right) {
7461
7632
  let top = 0;
7462
- this.rect = new DivRect(0, width, 0, 0);
7633
+ this.rect = new DivRect(left, right, 0, 0);
7463
7634
  if (this.titleText) {
7464
- this.titleText.layout(renderer);
7465
- this.titleText.offset(width / 2, top);
7635
+ this.titleText.layout(ctx);
7636
+ this.titleText.offset((left + right) / 2, top);
7466
7637
  top += this.titleText.getRect().height;
7467
7638
  this.rect.expandInPlace(this.titleText.getRect());
7468
7639
  }
7469
7640
  if (this.composerText) {
7470
- this.composerText.layout(renderer);
7471
- this.composerText.offset(width, top);
7641
+ this.composerText.layout(ctx);
7642
+ this.composerText.offset(right, top);
7472
7643
  top += this.composerText.getRect().height;
7473
7644
  this.rect.expandInPlace(this.composerText.getRect());
7474
7645
  }
7475
7646
  if (this.arrangerText) {
7476
- this.arrangerText.layout(renderer);
7477
- this.arrangerText.offset(width, top);
7647
+ this.arrangerText.layout(ctx);
7648
+ this.arrangerText.offset(right, top);
7478
7649
  top += this.arrangerText.getRect().height;
7479
7650
  this.rect.expandInPlace(this.arrangerText.getRect());
7480
7651
  }
@@ -7491,27 +7662,27 @@ var ObjHeader = class extends MusicObject {
7491
7662
  }
7492
7663
  this.rect.offsetInPlace(dx, dy);
7493
7664
  }
7494
- draw(renderer) {
7665
+ draw(ctx) {
7495
7666
  if (this.titleText) {
7496
- this.titleText.draw(renderer);
7667
+ this.titleText.draw(ctx);
7497
7668
  }
7498
7669
  if (this.composerText) {
7499
- this.composerText.draw(renderer);
7670
+ this.composerText.draw(ctx);
7500
7671
  }
7501
7672
  if (this.arrangerText) {
7502
- this.arrangerText.draw(renderer);
7673
+ this.arrangerText.draw(ctx);
7503
7674
  }
7504
7675
  }
7505
7676
  };
7506
7677
 
7507
7678
  // src/score/engine/obj-document.ts
7508
- var import_ts_utils_lib15 = require("@tspro/ts-utils-lib");
7679
+ var import_ts_utils_lib17 = require("@tspro/ts-utils-lib");
7509
7680
  var import_core18 = require("@tspro/web-music-score/core");
7510
7681
  var ObjDocument = class extends MusicObject {
7511
7682
  constructor() {
7512
7683
  super(void 0);
7513
7684
  __publicField(this, "needLayout", true);
7514
- __publicField(this, "renderer");
7685
+ __publicField(this, "ctx");
7515
7686
  __publicField(this, "rows", []);
7516
7687
  __publicField(this, "measures", []);
7517
7688
  __publicField(this, "measuresPerRow", Infinity);
@@ -7527,7 +7698,7 @@ var ObjDocument = class extends MusicObject {
7527
7698
  return this.mi;
7528
7699
  }
7529
7700
  setScoreConfiguration(config) {
7530
- if (import_ts_utils_lib15.Utils.Is.isEnumValue(config, StaffPreset)) {
7701
+ if (import_ts_utils_lib17.Utils.Is.isEnumValue(config, StaffPreset)) {
7531
7702
  switch (config) {
7532
7703
  default:
7533
7704
  case "treble" /* Treble */:
@@ -7555,7 +7726,7 @@ var ObjDocument = class extends MusicObject {
7555
7726
  ];
7556
7727
  break;
7557
7728
  }
7558
- } else if (import_ts_utils_lib15.Utils.Is.isArray(config)) {
7729
+ } else if (import_ts_utils_lib17.Utils.Is.isArray(config)) {
7559
7730
  this.curScoreConfig = config;
7560
7731
  } else {
7561
7732
  this.curScoreConfig = [config];
@@ -7616,17 +7787,17 @@ var ObjDocument = class extends MusicObject {
7616
7787
  addConnectiveProps(connectiveProps) {
7617
7788
  this.allConnectiveProps.push(connectiveProps);
7618
7789
  }
7619
- setRenderer(renderer) {
7620
- if (this.renderer === renderer) {
7790
+ setRenderContext(ctx) {
7791
+ if (this.ctx === ctx) {
7621
7792
  return;
7622
7793
  }
7623
- let prevRenderer = this.renderer;
7624
- this.renderer = renderer;
7625
- if (prevRenderer) {
7626
- prevRenderer.setDocument(void 0);
7794
+ let prevCtx = this.ctx;
7795
+ this.ctx = ctx;
7796
+ if (prevCtx) {
7797
+ prevCtx.setDocument(void 0);
7627
7798
  }
7628
- if (renderer) {
7629
- renderer.setDocument(this.mi);
7799
+ if (ctx) {
7800
+ ctx.setDocument(this.mi);
7630
7801
  }
7631
7802
  this.requestFullLayout();
7632
7803
  }
@@ -7675,13 +7846,13 @@ var ObjDocument = class extends MusicObject {
7675
7846
  requestNewRow() {
7676
7847
  this.newRowRequested = true;
7677
7848
  }
7678
- addMeasure() {
7849
+ addMeasure(measureOptions) {
7679
7850
  let lastRow = this.rows[this.rows.length - 1];
7680
7851
  if (!lastRow || this.newRowRequested && lastRow.getMeasures().length > 0 || lastRow.getMeasures().length >= this.measuresPerRow) {
7681
7852
  lastRow = this.addNewRow(lastRow);
7682
7853
  this.newRowRequested = false;
7683
7854
  }
7684
- let measure = new ObjMeasure2(lastRow);
7855
+ let measure = new ObjMeasure2(lastRow, measureOptions);
7685
7856
  this.measures.push(measure);
7686
7857
  lastRow.addMeasure(measure);
7687
7858
  this.requestLayout();
@@ -7712,9 +7883,21 @@ var ObjDocument = class extends MusicObject {
7712
7883
  this.measures.forEach((m) => m.resetPassCount());
7713
7884
  }
7714
7885
  updateCursorRect(cursorRect) {
7715
- if (this.renderer) {
7716
- this.renderer.updateCursorRect(cursorRect);
7717
- }
7886
+ if (this.ctx) {
7887
+ this.ctx.updateCursorRect(cursorRect);
7888
+ }
7889
+ }
7890
+ getInstrumentGroupSize(ctx) {
7891
+ let nameWidth = Math.max(0, ...this.rows.map((row) => row.getInstrumentNameWidth(ctx)));
7892
+ let hasName = nameWidth > 0;
7893
+ let padding = hasName ? ctx.unitSize : 0;
7894
+ let braceWidth = hasName ? ctx.unitSize * 5 : 0;
7895
+ return {
7896
+ nameLeft: 0,
7897
+ nameRight: nameWidth,
7898
+ braceLeft: nameWidth + padding,
7899
+ braceRight: nameWidth + padding + braceWidth + padding
7900
+ };
7718
7901
  }
7719
7902
  requestLayout() {
7720
7903
  this.needLayout = true;
@@ -7728,31 +7911,34 @@ var ObjDocument = class extends MusicObject {
7728
7911
  this.requestLayout();
7729
7912
  }
7730
7913
  layout() {
7914
+ var _a;
7731
7915
  if (!this.needLayout) {
7732
7916
  return;
7733
7917
  }
7734
- const { renderer } = this;
7735
- if (!renderer) {
7918
+ const { ctx } = this;
7919
+ if (!ctx) {
7736
7920
  return;
7737
7921
  }
7738
- let { unitSize } = renderer;
7922
+ let { unitSize } = ctx;
7739
7923
  this.forEachMeasure((m) => m.createBeams());
7924
+ (_a = this.getFirstMeasure()) == null ? void 0 : _a.updateRunningArguments();
7740
7925
  this.forEachMeasure((m) => m.createExtensions());
7741
7926
  this.allConnectiveProps.forEach((props) => props.removeConnectives());
7742
7927
  this.allConnectiveProps.forEach((props) => props.createConnectives());
7743
- this.rows.forEach((row) => row.resetLayoutGroups(renderer));
7744
- this.rows.forEach((row) => row.layout(renderer));
7745
- let rowWidth = Math.max(
7928
+ this.rows.forEach((row) => row.resetLayoutGroups(ctx));
7929
+ this.rows.forEach((row) => row.layout(ctx));
7930
+ let left = this.getInstrumentGroupSize(ctx).braceRight;
7931
+ let right = Math.max(
7746
7932
  DocumentSettings.DocumentMinWidth * unitSize,
7747
7933
  ...this.rows.map((row) => 1.4 * row.getMinWidth())
7748
7934
  );
7749
- this.rows.forEach((row) => row.layoutWidth(renderer, rowWidth));
7750
- this.rows.forEach((row) => row.layoutLayoutGroups(renderer));
7751
- this.rows.forEach((row) => row.layoutSetNotationLines(renderer));
7752
- this.rows.forEach((row) => row.layoutPadding(renderer));
7935
+ this.rows.forEach((row) => row.layoutWidth(ctx, left, right));
7936
+ this.rows.forEach((row) => row.layoutLayoutGroups(ctx));
7937
+ this.rows.forEach((row) => row.layoutSetNotationLines(ctx));
7938
+ this.rows.forEach((row) => row.layoutPadding(ctx));
7753
7939
  this.rect = new DivRect();
7754
7940
  if (this.header) {
7755
- this.header.layoutWidth(renderer, rowWidth);
7941
+ this.header.layoutWidth(ctx, left, right);
7756
7942
  this.rect.expandInPlace(this.header.getRect());
7757
7943
  }
7758
7944
  this.rows.forEach((row) => {
@@ -7763,13 +7949,13 @@ var ObjDocument = class extends MusicObject {
7763
7949
  this.needLayout = false;
7764
7950
  }
7765
7951
  drawContent() {
7766
- const { renderer } = this;
7767
- if (!renderer) {
7952
+ const { ctx } = this;
7953
+ if (!ctx) {
7768
7954
  return;
7769
7955
  }
7770
- this.rows.forEach((row) => row.draw(renderer));
7956
+ this.rows.forEach((row) => row.draw(ctx));
7771
7957
  if (this.header) {
7772
- this.header.draw(renderer);
7958
+ this.header.draw(ctx);
7773
7959
  }
7774
7960
  }
7775
7961
  pickStaffPosAt(x, y) {
@@ -7828,70 +8014,89 @@ function isNote(note) {
7828
8014
  }
7829
8015
  }
7830
8016
  function isVoiceId(value) {
7831
- return import_ts_utils_lib16.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8017
+ return import_ts_utils_lib18.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7832
8018
  }
7833
8019
  function isStringNumber(value) {
7834
- return import_ts_utils_lib16.Utils.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
8020
+ return import_ts_utils_lib18.Utils.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7835
8021
  }
7836
8022
  function isVerseNumber(value) {
7837
- return import_ts_utils_lib16.Utils.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
8023
+ return import_ts_utils_lib18.Utils.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
7838
8024
  }
7839
8025
  function assertBaseConfig(baseConfig) {
7840
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(baseConfig), "baseConfig", baseConfig);
7841
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
7842
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(baseConfig.voiceIds) || import_ts_utils_lib16.Utils.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => import_ts_utils_lib16.Utils.Is.isNumber(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
8026
+ var _a;
8027
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(baseConfig), "baseConfig", baseConfig);
8028
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
8029
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(baseConfig.voiceId) || isVoiceId(baseConfig.voiceId) || import_ts_utils_lib18.Utils.Is.isArray(baseConfig.voiceId) && baseConfig.voiceId.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceId", baseConfig.voiceId);
8030
+ if (!import_ts_utils_lib18.Utils.Is.isUndefined(baseConfig.voiceIds)) {
8031
+ assertArg(isVoiceId(baseConfig.voiceIds) || import_ts_utils_lib18.Utils.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
8032
+ console.warn(`Staff/tab config property 'voiceIds' is deprecated, use 'voiceId' instead.`);
8033
+ let arr = import_ts_utils_lib18.Utils.Arr.toArray((_a = baseConfig.voiceId) != null ? _a : []);
8034
+ import_ts_utils_lib18.Utils.Arr.toArray(baseConfig.voiceIds).forEach((voiceId) => arr.push(voiceId));
8035
+ baseConfig.voiceId = arr;
8036
+ }
8037
+ if (import_ts_utils_lib18.Utils.Is.isArray(baseConfig.voiceId)) {
8038
+ baseConfig.voiceId = import_ts_utils_lib18.Utils.Arr.removeDuplicates(baseConfig.voiceId);
8039
+ }
8040
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(baseConfig.instrument), "baseConfig.instrument", baseConfig.instrument);
7843
8041
  }
7844
8042
  function assertStaffConfig(staffConfig) {
7845
8043
  assertBaseConfig(staffConfig);
7846
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(staffConfig), "staffConfig", staffConfig);
8044
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(staffConfig), "staffConfig", staffConfig);
7847
8045
  assertArg(staffConfig.type === "staff", "staffConfig.type", staffConfig.type);
7848
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7849
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7850
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7851
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7852
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
7853
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
8046
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
8047
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
8048
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
8049
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
8050
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
8051
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
8052
+ if (!import_ts_utils_lib18.Utils.Is.isUndefined(staffConfig.isGrand)) {
8053
+ console.warn(`Staff config property 'isGrand' is deprecated, use 'grandId' instead.`);
8054
+ }
7854
8055
  }
7855
8056
  function assertTabConfig(tabConfig) {
7856
8057
  assertBaseConfig(tabConfig);
7857
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(tabConfig), "tabConfig", tabConfig);
8058
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(tabConfig), "tabConfig", tabConfig);
7858
8059
  assertArg(tabConfig.type === "tab", "tabConfig.type", tabConfig.type);
7859
- if (import_ts_utils_lib16.Utils.Is.isString(tabConfig.tuning)) {
8060
+ if (import_ts_utils_lib18.Utils.Is.isString(tabConfig.tuning)) {
7860
8061
  assertArg(import_theory13.TuningNameList.includes(tabConfig.tuning), "tabConfig.tuning", tabConfig.tuning);
7861
- } else if (import_ts_utils_lib16.Utils.Is.isArray(tabConfig.tuning)) {
8062
+ } else if (import_ts_utils_lib18.Utils.Is.isArray(tabConfig.tuning)) {
7862
8063
  assertArg(tabConfig.tuning.length === getStringNumbers().length && tabConfig.tuning.every((s) => isNote(s)), "tabConfig.tuning", tabConfig.tuning);
7863
8064
  }
7864
8065
  }
7865
8066
  function assertNoteOptions(noteOptions) {
7866
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(noteOptions), "noteOptions", noteOptions);
7867
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.dotted) || import_ts_utils_lib16.Utils.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
7868
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
7869
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
7870
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.arpeggio) || import_ts_utils_lib16.Utils.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
7871
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
7872
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
7873
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
7874
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || import_ts_utils_lib16.Utils.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
7875
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7876
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
8067
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(noteOptions), "noteOptions", noteOptions);
8068
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.dotted) || import_ts_utils_lib18.Utils.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
8069
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
8070
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
8071
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.arpeggio) || import_ts_utils_lib18.Utils.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
8072
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
8073
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
8074
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
8075
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || import_ts_utils_lib18.Utils.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
8076
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
8077
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7877
8078
  }
7878
8079
  function assertRestOptions(restOptions) {
7879
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(restOptions), "restOptions", restOptions);
7880
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(restOptions.dotted) || import_ts_utils_lib16.Utils.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
7881
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(restOptions.staffPos) || import_ts_utils_lib16.Utils.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof import_theory13.Note, "restOptions.staffPos", restOptions.staffPos);
7882
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
7883
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
7884
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
8080
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(restOptions), "restOptions", restOptions);
8081
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(restOptions.dotted) || import_ts_utils_lib18.Utils.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
8082
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(restOptions.staffPos) || import_ts_utils_lib18.Utils.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof import_theory13.Note, "restOptions.staffPos", restOptions.staffPos);
8083
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
8084
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
8085
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
7885
8086
  }
7886
8087
  function assertLyricsOptions(lyricsOptions) {
7887
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
7888
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
7889
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
8088
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
8089
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
8090
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
8091
+ }
8092
+ function assertMeasureOptions(measureOptions) {
8093
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(measureOptions), "measureOptions", measureOptions);
8094
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(measureOptions.showNumber), "measureOptions.showNumber", measureOptions.showNumber);
7890
8095
  }
7891
8096
  function assertStaffTabOrGRoups(staffTabOrGroups) {
7892
8097
  assertArg(
7893
- import_ts_utils_lib16.Utils.Is.isStringOrUndefined(staffTabOrGroups) || import_ts_utils_lib16.Utils.Is.isIntegerGte(staffTabOrGroups, 0) || import_ts_utils_lib16.Utils.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7894
- (staffTabOrGroup) => import_ts_utils_lib16.Utils.Is.isString(staffTabOrGroup) || import_ts_utils_lib16.Utils.Is.isIntegerGte(staffTabOrGroup, 0)
8098
+ import_ts_utils_lib18.Utils.Is.isStringOrUndefined(staffTabOrGroups) || import_ts_utils_lib18.Utils.Is.isIntegerGte(staffTabOrGroups, 0) || import_ts_utils_lib18.Utils.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
8099
+ (staffTabOrGroup) => import_ts_utils_lib18.Utils.Is.isString(staffTabOrGroup) || import_ts_utils_lib18.Utils.Is.isIntegerGte(staffTabOrGroup, 0)
7895
8100
  ),
7896
8101
  "staffTabOrGroup",
7897
8102
  staffTabOrGroups
@@ -7913,7 +8118,7 @@ function isTupletRatio(tupletRatio) {
7913
8118
  return false;
7914
8119
  }
7915
8120
  }
7916
- var DocumentBuilder = class {
8121
+ var _DocumentBuilder = class _DocumentBuilder {
7917
8122
  /**
7918
8123
  * Create new document builder instance.
7919
8124
  */
@@ -7923,19 +8128,19 @@ var DocumentBuilder = class {
7923
8128
  this.doc = new ObjDocument();
7924
8129
  }
7925
8130
  setScoreConfiguration(config) {
7926
- if (import_ts_utils_lib16.Utils.Is.isEnumValue(config, StaffPreset)) {
8131
+ if (import_ts_utils_lib18.Utils.Is.isEnumValue(config, StaffPreset)) {
7927
8132
  this.doc.setScoreConfiguration(config);
7928
- } else if (import_ts_utils_lib16.Utils.Is.isObject(config) && config.type === "staff") {
8133
+ } else if (import_ts_utils_lib18.Utils.Is.isObject(config) && config.type === "staff") {
7929
8134
  assertStaffConfig(config);
7930
8135
  this.doc.setScoreConfiguration(config);
7931
- } else if (import_ts_utils_lib16.Utils.Is.isObject(config) && config.type === "tab") {
8136
+ } else if (import_ts_utils_lib18.Utils.Is.isObject(config) && config.type === "tab") {
7932
8137
  assertTabConfig(config);
7933
8138
  this.doc.setScoreConfiguration(config);
7934
- } else if (import_ts_utils_lib16.Utils.Is.isNonEmptyArray(config)) {
8139
+ } else if (import_ts_utils_lib18.Utils.Is.isNonEmptyArray(config)) {
7935
8140
  config.forEach((c) => {
7936
- if (import_ts_utils_lib16.Utils.Is.isObject(c) && c.type === "staff") {
8141
+ if (import_ts_utils_lib18.Utils.Is.isObject(c) && c.type === "staff") {
7937
8142
  assertStaffConfig(c);
7938
- } else if (import_ts_utils_lib16.Utils.Is.isObject(c) && c.type === "tab") {
8143
+ } else if (import_ts_utils_lib18.Utils.Is.isObject(c) && c.type === "tab") {
7939
8144
  assertTabConfig(c);
7940
8145
  } else {
7941
8146
  assertArg(false, "config", config);
@@ -7949,7 +8154,7 @@ var DocumentBuilder = class {
7949
8154
  }
7950
8155
  getMeasure() {
7951
8156
  var _a;
7952
- return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure();
8157
+ return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure(_DocumentBuilder.DefaultMeasureOptions);
7953
8158
  }
7954
8159
  /**
7955
8160
  * Get music document after finished building.
@@ -7966,9 +8171,9 @@ var DocumentBuilder = class {
7966
8171
  * @returns - This document builder instance.
7967
8172
  */
7968
8173
  setHeader(title, composer, arranger) {
7969
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(title), "title", title);
7970
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(composer), "composer", composer);
7971
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(arranger), "arranger", arranger);
8174
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(title), "title", title);
8175
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(composer), "composer", composer);
8176
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(arranger), "arranger", arranger);
7972
8177
  this.doc.setHeader(title, composer, arranger);
7973
8178
  return this;
7974
8179
  }
@@ -7978,29 +8183,32 @@ var DocumentBuilder = class {
7978
8183
  * @returns - This document builder instance.
7979
8184
  */
7980
8185
  setMeasuresPerRow(measuresPerRow) {
7981
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(measuresPerRow, 1) || import_ts_utils_lib16.Utils.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
8186
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(measuresPerRow, 1) || import_ts_utils_lib18.Utils.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
7982
8187
  this.doc.setMeasuresPerRow(measuresPerRow);
7983
8188
  return this;
7984
8189
  }
7985
8190
  /**
7986
8191
  * Add new measure.
8192
+ * @param measureOptions - Measure options.
7987
8193
  * @returns - This document builder instance.
7988
8194
  */
7989
- addMeasure() {
7990
- this.doc.addMeasure();
8195
+ addMeasure(measureOptions) {
8196
+ measureOptions != null ? measureOptions : measureOptions = {};
8197
+ assertMeasureOptions(measureOptions);
8198
+ this.doc.addMeasure(measureOptions);
7991
8199
  return this;
7992
8200
  }
7993
8201
  setKeySignature(...args) {
7994
- assertArg(args[0] instanceof import_theory13.Scale || args[0] instanceof import_theory13.KeySignature || import_ts_utils_lib16.Utils.Is.isNonEmptyString(args[0]) && (args.length === 1 || import_ts_utils_lib16.Utils.Is.isEnumValue(args[1], import_theory13.ScaleType)), "keySignature", args);
8202
+ assertArg(args[0] instanceof import_theory13.Scale || args[0] instanceof import_theory13.KeySignature || import_ts_utils_lib18.Utils.Is.isNonEmptyString(args[0]) && (args.length === 1 || import_ts_utils_lib18.Utils.Is.isEnumValue(args[1], import_theory13.ScaleType)), "keySignature", args);
7995
8203
  this.getMeasure().setKeySignature(...args);
7996
8204
  return this;
7997
8205
  }
7998
8206
  setTimeSignature(...args) {
7999
8207
  if (args[0] instanceof import_theory13.TimeSignature) {
8000
8208
  this.getMeasure().setTimeSignature(args[0]);
8001
- } else if (import_ts_utils_lib16.Utils.Is.isEnumValue(args[0], import_theory13.TimeSignatures) && import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[1], import_theory13.BeamGrouping)) {
8209
+ } else if (import_ts_utils_lib18.Utils.Is.isEnumValue(args[0], import_theory13.TimeSignatures) && import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[1], import_theory13.BeamGrouping)) {
8002
8210
  this.getMeasure().setTimeSignature(new import_theory13.TimeSignature(args[0], args[1]));
8003
- } else if (import_ts_utils_lib16.Utils.Is.isIntegerGte(args[0], 1) && import_ts_utils_lib16.Utils.Is.isIntegerGte(args[1], 1) && import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[2], import_theory13.BeamGrouping)) {
8211
+ } else if (import_ts_utils_lib18.Utils.Is.isIntegerGte(args[0], 1) && import_ts_utils_lib18.Utils.Is.isIntegerGte(args[1], 1) && import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[2], import_theory13.BeamGrouping)) {
8004
8212
  this.getMeasure().setTimeSignature(new import_theory13.TimeSignature(args[0], args[1], args[2]));
8005
8213
  } else {
8006
8214
  assertArg(false, "timeSignature args", args);
@@ -8008,12 +8216,12 @@ var DocumentBuilder = class {
8008
8216
  return this;
8009
8217
  }
8010
8218
  setTempo(beatsPerMinute, beatLength, dotted) {
8011
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
8219
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
8012
8220
  if (beatLength === void 0) {
8013
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(dotted), "dotted", dotted);
8221
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(dotted), "dotted", dotted);
8014
8222
  } else {
8015
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(beatLength, import_theory13.NoteLength) || isNoteLength(beatLength), "beatLength", beatLength);
8016
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(dotted) || import_ts_utils_lib16.Utils.Is.isIntegerGte(dotted, 0), "dotted", dotted);
8223
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(beatLength, import_theory13.NoteLength) || isNoteLength(beatLength), "beatLength", beatLength);
8224
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(dotted) || import_ts_utils_lib18.Utils.Is.isIntegerGte(dotted, 0), "dotted", dotted);
8017
8225
  }
8018
8226
  this.getMeasure().setTempo(beatsPerMinute, beatLength, dotted);
8019
8227
  return this;
@@ -8029,17 +8237,17 @@ var DocumentBuilder = class {
8029
8237
  addNote(voiceId, note, noteLength, noteOptions) {
8030
8238
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8031
8239
  assertArg(
8032
- note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib16.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note2)),
8240
+ note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib18.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note2)),
8033
8241
  "note",
8034
8242
  note
8035
8243
  );
8036
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8244
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8037
8245
  noteOptions != null ? noteOptions : noteOptions = {};
8038
8246
  assertNoteOptions(noteOptions);
8039
- if (import_ts_utils_lib16.Utils.Is.isArray(note)) {
8247
+ if (import_ts_utils_lib18.Utils.Is.isArray(note)) {
8040
8248
  let string = noteOptions.string;
8041
8249
  note.forEach((note2, noteId) => {
8042
- noteOptions.string = import_ts_utils_lib16.Utils.Is.isArray(string) ? string[noteId] : string;
8250
+ noteOptions.string = import_ts_utils_lib18.Utils.Is.isArray(string) ? string[noteId] : string;
8043
8251
  this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions);
8044
8252
  });
8045
8253
  } else {
@@ -8057,8 +8265,8 @@ var DocumentBuilder = class {
8057
8265
  */
8058
8266
  addChord(voiceId, notes, noteLength, noteOptions) {
8059
8267
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8060
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note)), "notes", notes);
8061
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8268
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note)), "notes", notes);
8269
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8062
8270
  noteOptions != null ? noteOptions : noteOptions = {};
8063
8271
  assertNoteOptions(noteOptions);
8064
8272
  this.getMeasure().addNoteGroup(voiceId, notes, noteLength, noteOptions);
@@ -8073,7 +8281,7 @@ var DocumentBuilder = class {
8073
8281
  */
8074
8282
  addRest(voiceId, restLength, restOptions) {
8075
8283
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8076
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8284
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8077
8285
  restOptions != null ? restOptions : restOptions = {};
8078
8286
  assertRestOptions(restOptions);
8079
8287
  this.getMeasure().addRest(voiceId, restLength, restOptions);
@@ -8096,24 +8304,24 @@ var DocumentBuilder = class {
8096
8304
  */
8097
8305
  addTuplet(voiceId, tupletRatio, tupletBuilder) {
8098
8306
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8099
- assertArg(import_ts_utils_lib16.Utils.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
8100
- assertArg(isTupletRatio(tupletRatio) && import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
8307
+ assertArg(import_ts_utils_lib18.Utils.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
8308
+ assertArg(isTupletRatio(tupletRatio) && import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
8101
8309
  let tupletSymbols = [];
8102
8310
  const helper = {
8103
8311
  addNote: (note, noteLength, noteOptions) => {
8104
8312
  assertArg(
8105
- note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib16.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note2)),
8313
+ note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib18.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note2)),
8106
8314
  "note",
8107
8315
  note
8108
8316
  );
8109
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8317
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8110
8318
  noteOptions != null ? noteOptions : noteOptions = {};
8111
8319
  delete noteOptions.triplet;
8112
8320
  assertNoteOptions(noteOptions);
8113
- if (import_ts_utils_lib16.Utils.Is.isArray(note)) {
8321
+ if (import_ts_utils_lib18.Utils.Is.isArray(note)) {
8114
8322
  let string = noteOptions.string;
8115
8323
  note.forEach((note2, noteId) => {
8116
- noteOptions.string = import_ts_utils_lib16.Utils.Is.isArray(string) ? string[noteId] : string;
8324
+ noteOptions.string = import_ts_utils_lib18.Utils.Is.isArray(string) ? string[noteId] : string;
8117
8325
  let s = this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions, tupletRatio);
8118
8326
  tupletSymbols.push(s);
8119
8327
  });
@@ -8124,8 +8332,8 @@ var DocumentBuilder = class {
8124
8332
  return helper;
8125
8333
  },
8126
8334
  addChord: (notes, noteLength, noteOptions) => {
8127
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note)), "notes", notes);
8128
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8335
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note)), "notes", notes);
8336
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8129
8337
  noteOptions != null ? noteOptions : noteOptions = {};
8130
8338
  delete noteOptions.triplet;
8131
8339
  assertNoteOptions(noteOptions);
@@ -8134,7 +8342,7 @@ var DocumentBuilder = class {
8134
8342
  return helper;
8135
8343
  },
8136
8344
  addRest: (restLength, restOptions) => {
8137
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8345
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8138
8346
  restOptions != null ? restOptions : restOptions = {};
8139
8347
  delete restOptions.triplet;
8140
8348
  assertRestOptions(restOptions);
@@ -8151,8 +8359,8 @@ var DocumentBuilder = class {
8151
8359
  var _a;
8152
8360
  assertStaffTabOrGRoups(staffTabOrGroups);
8153
8361
  assertArg(isVerseNumber(verse), "verse", verse);
8154
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(lyricsLength, import_theory13.NoteLength), "lyricsLength", lyricsLength);
8155
- assertArg(import_ts_utils_lib16.Utils.Is.isString(lyricsText) || import_ts_utils_lib16.Utils.Is.isArray(lyricsText) && lyricsText.every((text) => import_ts_utils_lib16.Utils.Is.isString(text)), "lyricsText", lyricsText);
8362
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(lyricsLength, import_theory13.NoteLength), "lyricsLength", lyricsLength);
8363
+ assertArg(import_ts_utils_lib18.Utils.Is.isString(lyricsText) || import_ts_utils_lib18.Utils.Is.isArray(lyricsText) && lyricsText.every((text) => import_ts_utils_lib18.Utils.Is.isString(text)), "lyricsText", lyricsText);
8156
8364
  lyricsOptions != null ? lyricsOptions : lyricsOptions = {};
8157
8365
  assertLyricsOptions(lyricsOptions);
8158
8366
  if (lyricsOptions.align !== void 0) {
@@ -8160,7 +8368,7 @@ var DocumentBuilder = class {
8160
8368
  } else {
8161
8369
  (_a = lyricsOptions.align) != null ? _a : lyricsOptions.align = this.currentLyricsAlign;
8162
8370
  }
8163
- if (import_ts_utils_lib16.Utils.Is.isArray(lyricsText)) {
8371
+ if (import_ts_utils_lib18.Utils.Is.isArray(lyricsText)) {
8164
8372
  lyricsText.forEach((text) => this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, text, lyricsOptions));
8165
8373
  } else {
8166
8374
  this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions);
@@ -8192,7 +8400,7 @@ var DocumentBuilder = class {
8192
8400
  }
8193
8401
  addFermataInternal(staffTabOrGroups, fermata) {
8194
8402
  assertStaffTabOrGRoups(staffTabOrGroups);
8195
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
8403
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
8196
8404
  this.getMeasure().addFermata(staffTabOrGroups, fermata);
8197
8405
  return this;
8198
8406
  }
@@ -8215,11 +8423,11 @@ var DocumentBuilder = class {
8215
8423
  }
8216
8424
  addNavigationInternal(staffTabOrGroups, navigation, ...args) {
8217
8425
  assertStaffTabOrGRoups(staffTabOrGroups);
8218
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
8426
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
8219
8427
  if (navigation === "endRepeat" /* EndRepeat */ && args.length > 0) {
8220
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
8428
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
8221
8429
  } else if (navigation === "ending" /* Ending */ && args.length > 0) {
8222
- assertArg(args.every((passage) => import_ts_utils_lib16.Utils.Is.isIntegerGte(passage, 1)), "passages", args);
8430
+ assertArg(args.every((passage) => import_ts_utils_lib18.Utils.Is.isIntegerGte(passage, 1)), "passages", args);
8223
8431
  }
8224
8432
  this.getMeasure().addNavigation(staffTabOrGroups, navigation, ...args);
8225
8433
  return this;
@@ -8236,8 +8444,8 @@ var DocumentBuilder = class {
8236
8444
  throw new import_core19.MusicError(import_core19.MusicErrorType.Score, `Annotation text "${text}" is not known annotation.`);
8237
8445
  }
8238
8446
  assertStaffTabOrGRoups(staffTabOrGroups);
8239
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
8240
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(text), "text", text);
8447
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
8448
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(text), "text", text);
8241
8449
  this.getMeasure().addAnnotation(staffTabOrGroups, annotation, text);
8242
8450
  return this;
8243
8451
  }
@@ -8257,8 +8465,8 @@ var DocumentBuilder = class {
8257
8465
  }
8258
8466
  addLabelInternal(staffTabOrGroups, label, text) {
8259
8467
  assertStaffTabOrGRoups(staffTabOrGroups);
8260
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(label, Label), "label", label);
8261
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(text), "text", text);
8468
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(label, Label), "label", label);
8469
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(text), "text", text);
8262
8470
  this.getMeasure().addLabel(staffTabOrGroups, label, text);
8263
8471
  return this;
8264
8472
  }
@@ -8282,21 +8490,21 @@ var DocumentBuilder = class {
8282
8490
  return this.addLabelInternal(staffTabOrGroups, label, text);
8283
8491
  }
8284
8492
  addConnective(connective, ...args) {
8285
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(connective, Connective), "connective", connective);
8493
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(connective, Connective), "connective", connective);
8286
8494
  if (connective === "tie" /* Tie */) {
8287
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerOrUndefined(args[0]) || import_ts_utils_lib16.Utils.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
8288
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8495
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerOrUndefined(args[0]) || import_ts_utils_lib18.Utils.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
8496
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8289
8497
  let tieSpan = args[0];
8290
8498
  let noteAnchor = args[1];
8291
8499
  this.getMeasure().addConnective(connective, tieSpan, noteAnchor);
8292
8500
  } else if (connective === "slur" /* Slur */) {
8293
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
8294
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8501
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
8502
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8295
8503
  let slurSpan = args[0];
8296
8504
  let noteAnchor = args[1];
8297
8505
  this.getMeasure().addConnective(connective, slurSpan, noteAnchor);
8298
8506
  } else if (connective === "slide" /* Slide */) {
8299
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
8507
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
8300
8508
  let noteAnchor = args[0];
8301
8509
  this.getMeasure().addConnective(connective, noteAnchor);
8302
8510
  }
@@ -8315,18 +8523,18 @@ var DocumentBuilder = class {
8315
8523
  * @returns - This document builder instance.
8316
8524
  */
8317
8525
  addExtension(extensionBuilder) {
8318
- assertArg(import_ts_utils_lib16.Utils.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
8526
+ assertArg(import_ts_utils_lib18.Utils.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
8319
8527
  let ticks = 0;
8320
8528
  let visible = true;
8321
8529
  const helper = {
8322
8530
  notes: (noteLength, noteCount) => {
8323
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8324
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteCount) || import_ts_utils_lib16.Utils.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8531
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8532
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteCount) || import_ts_utils_lib18.Utils.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8325
8533
  ticks += import_theory13.RhythmProps.get(noteLength).ticks * (noteCount != null ? noteCount : 1);
8326
8534
  return helper;
8327
8535
  },
8328
8536
  measures: (measureCount) => {
8329
- assertArg(import_ts_utils_lib16.Utils.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8537
+ assertArg(import_ts_utils_lib18.Utils.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8330
8538
  ticks += this.getMeasure().getMeasureTicks() * measureCount;
8331
8539
  return helper;
8332
8540
  },
@@ -8355,13 +8563,13 @@ var DocumentBuilder = class {
8355
8563
  * @returns - This document builder instance.
8356
8564
  */
8357
8565
  addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition = "auto" /* Auto */) {
8358
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(groupName), "groupName", groupName);
8566
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(groupName), "groupName", groupName);
8359
8567
  assertArg(
8360
- import_ts_utils_lib16.Utils.Is.isNonEmptyString(staffsTabsAndGroups) || import_ts_utils_lib16.Utils.Is.isIntegerGte(staffsTabsAndGroups, 0) || import_ts_utils_lib16.Utils.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => import_ts_utils_lib16.Utils.Is.isNonEmptyString(line) || import_ts_utils_lib16.Utils.Is.isIntegerGte(line, 0)),
8568
+ import_ts_utils_lib18.Utils.Is.isNonEmptyString(staffsTabsAndGroups) || import_ts_utils_lib18.Utils.Is.isIntegerGte(staffsTabsAndGroups, 0) || import_ts_utils_lib18.Utils.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => import_ts_utils_lib18.Utils.Is.isNonEmptyString(line) || import_ts_utils_lib18.Utils.Is.isIntegerGte(line, 0)),
8361
8569
  "staffsTabsAndGroups",
8362
8570
  staffsTabsAndGroups
8363
8571
  );
8364
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8572
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8365
8573
  this.doc.addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition);
8366
8574
  return this;
8367
8575
  }
@@ -8396,7 +8604,7 @@ var DocumentBuilder = class {
8396
8604
  * @returns - This document builder instance.
8397
8605
  */
8398
8606
  completeRests(voiceId) {
8399
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(voiceId) || isVoiceId(voiceId) || import_ts_utils_lib16.Utils.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8607
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(voiceId) || isVoiceId(voiceId) || import_ts_utils_lib18.Utils.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8400
8608
  this.getMeasure().completeRests(voiceId);
8401
8609
  return this;
8402
8610
  }
@@ -8408,8 +8616,8 @@ var DocumentBuilder = class {
8408
8616
  * @returns - This document builder instance.
8409
8617
  */
8410
8618
  addScaleArpeggio(scale, bottomNote, numOctaves) {
8411
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8412
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8619
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8620
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8413
8621
  let ts = this.getMeasure().getTimeSignature();
8414
8622
  let notes = scale.getScaleNotes(bottomNote, numOctaves);
8415
8623
  for (let i = 0; i < notes.length; i++) {
@@ -8423,6 +8631,8 @@ var DocumentBuilder = class {
8423
8631
  return this;
8424
8632
  }
8425
8633
  };
8634
+ __publicField(_DocumentBuilder, "DefaultMeasureOptions", {});
8635
+ var DocumentBuilder = _DocumentBuilder;
8426
8636
 
8427
8637
  // src/score/pub/event.ts
8428
8638
  var import_core20 = require("@tspro/web-music-score/core");
@@ -8439,32 +8649,44 @@ var ScoreStaffPosEvent = class extends ScoreEvent {
8439
8649
  /**
8440
8650
  * Create new score staff position event.
8441
8651
  * @param type - Score event type.
8442
- * @param renderer - Renderer.
8652
+ * @param renderContext - Render context.
8443
8653
  * @param scoreRow - Score row.
8444
8654
  * @param diatonicId - Diatonic id that was clicked/entered/left.
8445
8655
  */
8446
- constructor(type, renderer, scoreRow, diatonicId) {
8656
+ constructor(type, renderContext, scoreRow, diatonicId) {
8447
8657
  super(type);
8448
- this.renderer = renderer;
8658
+ this.renderContext = renderContext;
8449
8659
  this.scoreRow = scoreRow;
8450
8660
  this.diatonicId = diatonicId;
8451
8661
  }
8662
+ /**
8663
+ * @deprecated - Provided for legacy support, use renderContext instead.
8664
+ */
8665
+ get renderer() {
8666
+ return this.renderContext;
8667
+ }
8452
8668
  };
8453
8669
  var ScoreObjectEvent = class extends ScoreEvent {
8454
8670
  /**
8455
8671
  * Create new score object event.
8456
8672
  * @param type - Score event type.
8457
- * @param renderer - Renderer.
8673
+ * @param renderContext - Render context.
8458
8674
  * @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.
8459
8675
  */
8460
- constructor(type, renderer, objects) {
8676
+ constructor(type, renderContext, objects) {
8461
8677
  super(type);
8462
- this.renderer = renderer;
8678
+ this.renderContext = renderContext;
8463
8679
  this.objects = objects;
8464
8680
  if (arguments.length === 0) {
8465
8681
  throw new import_core20.MusicError(import_core20.MusicErrorType.Score, "Empty array in score object event!");
8466
8682
  }
8467
8683
  }
8684
+ /**
8685
+ * @deprecated - Provided for legacy support, use renderContext instead.
8686
+ */
8687
+ get renderer() {
8688
+ return this.renderContext;
8689
+ }
8468
8690
  /** Top object getter. */
8469
8691
  get topObject() {
8470
8692
  return this.objects[this.objects.length - 1];
@@ -8481,10 +8703,10 @@ var ScoreObjectEvent = class extends ScoreEvent {
8481
8703
 
8482
8704
  // src/score/pub/music-interface.ts
8483
8705
  var Audio2 = __toESM(require("@tspro/web-music-score/audio"));
8484
- var import_ts_utils_lib18 = require("@tspro/ts-utils-lib");
8706
+ var import_ts_utils_lib20 = require("@tspro/ts-utils-lib");
8485
8707
 
8486
8708
  // src/score/pub/music-objects.ts
8487
- var import_ts_utils_lib17 = require("@tspro/ts-utils-lib");
8709
+ var import_ts_utils_lib19 = require("@tspro/ts-utils-lib");
8488
8710
  var import_core21 = require("@tspro/web-music-score/core");
8489
8711
  function assertArg2(condition, argName, argValue) {
8490
8712
  if (!condition) {
@@ -8492,7 +8714,7 @@ function assertArg2(condition, argName, argValue) {
8492
8714
  }
8493
8715
  }
8494
8716
  function isVoiceId2(value) {
8495
- return import_ts_utils_lib17.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8717
+ return import_ts_utils_lib19.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8496
8718
  }
8497
8719
  function getNotationLine(line) {
8498
8720
  if (line instanceof ObjStaff || line instanceof ObjTab) {
@@ -8668,7 +8890,7 @@ var _MDocument = class _MDocument extends MusicInterface6 {
8668
8890
  * @returns - Player instance.
8669
8891
  */
8670
8892
  play(playStateChangeListener) {
8671
- assertArg2(import_ts_utils_lib17.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8893
+ assertArg2(import_ts_utils_lib19.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8672
8894
  return new MPlayer(this, playStateChangeListener).play();
8673
8895
  }
8674
8896
  };
@@ -8698,7 +8920,7 @@ var _MEnding = class _MEnding extends MusicInterface6 {
8698
8920
  * @returns - Boolean whether this ending has asked passage number.
8699
8921
  */
8700
8922
  hasPassage(passage) {
8701
- assertArg2(import_ts_utils_lib17.Utils.Is.isIntegerGte(passage, 1), "passage", passage);
8923
+ assertArg2(import_ts_utils_lib19.Utils.Is.isIntegerGte(passage, 1), "passage", passage);
8702
8924
  return this.obj.hasPassage(passage);
8703
8925
  }
8704
8926
  };
@@ -9385,7 +9607,7 @@ var _MPlayer = class _MPlayer {
9385
9607
  constructor(doc, playStateChangeListener) {
9386
9608
  __publicField(this, "player");
9387
9609
  assertArg3(doc instanceof MDocument2, "doc", doc);
9388
- assertArg3(import_ts_utils_lib18.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9610
+ assertArg3(import_ts_utils_lib20.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9389
9611
  this.player = new Player();
9390
9612
  this.player.setDocument(doc.getMusicObject());
9391
9613
  this.player.setCursorPositionChangeListener((cursorRect) => doc.getMusicObject().updateCursorRect(cursorRect));
@@ -9429,32 +9651,32 @@ var _MPlayer = class _MPlayer {
9429
9651
  };
9430
9652
  __publicField(_MPlayer, "currentlyPlaying", /* @__PURE__ */ new Set());
9431
9653
  var MPlayer = _MPlayer;
9432
- var MRenderer2 = class {
9654
+ var MRenderContext2 = class {
9433
9655
  /**
9434
- * Create new renderer instance.
9656
+ * Create new render context instance.
9435
9657
  */
9436
9658
  constructor() {
9437
- __publicField(this, "renderer");
9438
- this.renderer = new Renderer(this);
9659
+ __publicField(this, "ctx");
9660
+ this.ctx = new RenderContext(this);
9439
9661
  }
9440
9662
  /**
9441
- * Attach music document to this renderer.
9663
+ * Attach music document to this render context.
9442
9664
  * @param doc - Music document.
9443
- * @returns - This renderer instance.
9665
+ * @returns - This render context instance.
9444
9666
  */
9445
9667
  setDocument(doc) {
9446
- assertArg3(import_ts_utils_lib18.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9447
- this.renderer.setDocument(doc);
9668
+ assertArg3(import_ts_utils_lib20.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9669
+ this.ctx.setDocument(doc);
9448
9670
  return this;
9449
9671
  }
9450
9672
  /**
9451
- * Set target canvas html element for this renderer.
9673
+ * Set target canvas html element for this render context.
9452
9674
  * @param canvas - HTML canvas element or element id.
9453
- * @returns - This renderer instance.
9675
+ * @returns - This render context instance.
9454
9676
  */
9455
9677
  setCanvas(canvas) {
9456
- canvas = require_t(import_ts_utils_lib18.Utils.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
9457
- this.renderer.setCanvas(canvas);
9678
+ canvas = require_t(import_ts_utils_lib20.Utils.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set render canvas because invalid canvas id: " + canvas : "Cannot set render canvas because given canvas is undefined.");
9679
+ this.ctx.setCanvas(canvas);
9458
9680
  return this;
9459
9681
  }
9460
9682
  /**
@@ -9462,22 +9684,22 @@ var MRenderer2 = class {
9462
9684
  * @param scoreEventListener - Score event listener.
9463
9685
  */
9464
9686
  setScoreEventListener(scoreEventListener) {
9465
- assertArg3(import_ts_utils_lib18.Utils.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9466
- this.renderer.setScoreEventListener(scoreEventListener);
9687
+ assertArg3(import_ts_utils_lib20.Utils.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9688
+ this.ctx.setScoreEventListener(scoreEventListener);
9467
9689
  }
9468
9690
  /**
9469
9691
  * Draw given music object hilighted.
9470
9692
  * @param obj - Music object or undefined to remove hilighting.
9471
9693
  */
9472
9694
  hilightObject(obj) {
9473
- this.renderer.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9695
+ this.ctx.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9474
9696
  }
9475
9697
  /**
9476
9698
  * Draw given staff position hilighted.
9477
9699
  * @param staffPos - Staff position (score row and diatonic id) or undefined to remove hilighting.
9478
9700
  */
9479
9701
  hilightStaffPos(staffPos) {
9480
- this.renderer.hilightStaffPos(staffPos ? {
9702
+ this.ctx.hilightStaffPos(staffPos ? {
9481
9703
  scoreRow: staffPos.scoreRow.getMusicObject(),
9482
9704
  diatonicId: staffPos.diatonicId
9483
9705
  } : void 0);
@@ -9487,13 +9709,14 @@ var MRenderer2 = class {
9487
9709
  */
9488
9710
  draw() {
9489
9711
  try {
9490
- this.renderer.draw();
9491
- } catch (e) {
9492
- console.log("Draw failed in music renderer.");
9493
- console.log(e);
9712
+ this.ctx.draw();
9713
+ } catch (err) {
9714
+ console.log("Draw failed in music render context!", err);
9494
9715
  }
9495
9716
  }
9496
9717
  };
9718
+ var MRenderer = class extends MRenderContext2 {
9719
+ };
9497
9720
  var _MPlaybackButtons = class _MPlaybackButtons {
9498
9721
  /**
9499
9722
  * Create new playback buttons helper class instance.
@@ -9536,7 +9759,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9536
9759
  * @returns
9537
9760
  */
9538
9761
  setDocument(doc) {
9539
- assertArg3(import_ts_utils_lib18.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9762
+ assertArg3(import_ts_utils_lib20.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9540
9763
  this.onStop();
9541
9764
  if (doc) {
9542
9765
  this.player = new MPlayer(doc, (playState) => {
@@ -9580,9 +9803,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9580
9803
  * @returns - This playback buttons class instance.
9581
9804
  */
9582
9805
  setPlayButton(btn, btnLabel) {
9583
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9806
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9584
9807
  _MPlaybackButtons.removeOnClickListeners(this.playButton, this.onPlay);
9585
- this.playButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Play button required!");
9808
+ this.playButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Play button required!");
9586
9809
  this.playLabel = btnLabel != null ? btnLabel : "Play";
9587
9810
  _MPlaybackButtons.removeOnClickListeners(this.playButton, "all");
9588
9811
  _MPlaybackButtons.addOnClickListener(this.playButton, this.onPlay);
@@ -9596,9 +9819,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9596
9819
  * @returns - This playback buttons class instance.
9597
9820
  */
9598
9821
  setStopButton(btn, btnLabel) {
9599
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9822
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9600
9823
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, this.onStop);
9601
- this.stopButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Stop button required!");
9824
+ this.stopButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Stop button required!");
9602
9825
  this.stopLabel = btnLabel != null ? btnLabel : "Stop";
9603
9826
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, "all");
9604
9827
  _MPlaybackButtons.addOnClickListener(this.stopButton, this.onStop);
@@ -9613,10 +9836,10 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9613
9836
  * @returns - This playback buttons class instance.
9614
9837
  */
9615
9838
  setPlayStopButton(btn, playLabel, stopLabel) {
9616
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9617
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9839
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9840
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9618
9841
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, this.onPlayStop);
9619
- this.playStopButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Play/stop button required!");
9842
+ this.playStopButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Play/stop button required!");
9620
9843
  this.playLabel = playLabel != null ? playLabel : "Play";
9621
9844
  this.stopLabel = stopLabel != null ? stopLabel : "Stop";
9622
9845
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, "all");
@@ -9631,9 +9854,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9631
9854
  * @returns - This playback buttons class instance.
9632
9855
  */
9633
9856
  setPauseButton(btn, btnLabel) {
9634
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9857
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9635
9858
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, this.onPause);
9636
- this.pauseButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Pause button required!");
9859
+ this.pauseButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Pause button required!");
9637
9860
  this.pauseLabel = btnLabel != null ? btnLabel : "Pause";
9638
9861
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, "all");
9639
9862
  _MPlaybackButtons.addOnClickListener(this.pauseButton, this.onPause);
@@ -9655,7 +9878,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9655
9878
  }
9656
9879
  }
9657
9880
  static addOnClickListener(btn, onClick) {
9658
- assertArg3(import_ts_utils_lib18.Utils.Is.isFunction(onClick), "onClick", onClick);
9881
+ assertArg3(import_ts_utils_lib20.Utils.Is.isFunction(onClick), "onClick", onClick);
9659
9882
  btn.addEventListener("click", onClick);
9660
9883
  let clickListeners = this.savedOnClickListeners.get(btn) || [];
9661
9884
  this.savedOnClickListeners.set(btn, [...clickListeners, onClick]);
@@ -9697,6 +9920,7 @@ var import_core23 = require("@tspro/web-music-score/core");
9697
9920
  MNoteGroup,
9698
9921
  MPlaybackButtons,
9699
9922
  MPlayer,
9923
+ MRenderContext,
9700
9924
  MRenderer,
9701
9925
  MRest,
9702
9926
  MRhythmColumn,