@coderline/alphatab 1.3.0-alpha.136 → 1.3.0-alpha.140

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.
package/dist/alphaTab.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * alphaTab v1.3.0-alpha.136 (develop, build 136)
2
+ * alphaTab v1.3.0-alpha.140 (develop, build 140)
3
3
  *
4
4
  * Copyright © 2021, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -138,7 +138,7 @@
138
138
  })(exports.AlphaTabErrorType || (exports.AlphaTabErrorType = {}));
139
139
  class AlphaTabError extends Error {
140
140
  constructor(type, message = "", inner) {
141
- super(message);
141
+ super(message !== null && message !== void 0 ? message : "");
142
142
  this.type = type;
143
143
  this.inner = inner !== null && inner !== void 0 ? inner : null;
144
144
  Object.setPrototypeOf(this, AlphaTabError.prototype);
@@ -150,8 +150,8 @@
150
150
  * binary data does not contain a reader compatible structure.
151
151
  */
152
152
  class UnsupportedFormatError extends AlphaTabError {
153
- constructor(message = 'Unsupported format', inner = null) {
154
- super(exports.AlphaTabErrorType.Format, message);
153
+ constructor(message = null, inner = null) {
154
+ super(exports.AlphaTabErrorType.Format, message !== null && message !== void 0 ? message : 'Unsupported format');
155
155
  this.inner = inner;
156
156
  Object.setPrototypeOf(this, UnsupportedFormatError.prototype);
157
157
  }
@@ -202,6 +202,7 @@
202
202
  * Automations are used to change the behaviour of a song.
203
203
  * @cloneable
204
204
  * @json
205
+ * @json_strict
205
206
  */
206
207
  class Automation {
207
208
  constructor() {
@@ -330,6 +331,7 @@
330
331
  /**
331
332
  * A bar is a single block within a track, also known as Measure.
332
333
  * @json
334
+ * @json_strict
333
335
  */
334
336
  class Bar {
335
337
  constructor() {
@@ -391,11 +393,11 @@
391
393
  voice.index = this.voices.length;
392
394
  this.voices.push(voice);
393
395
  }
394
- finish(settings) {
396
+ finish(settings, sharedDataBag) {
395
397
  this.isMultiVoice = false;
396
398
  for (let i = 0, j = this.voices.length; i < j; i++) {
397
399
  let voice = this.voices[i];
398
- voice.finish(settings);
400
+ voice.finish(settings, sharedDataBag);
399
401
  if (i > 0 && !voice.isEmpty) {
400
402
  this.isMultiVoice = true;
401
403
  }
@@ -475,6 +477,7 @@
475
477
  * describe WhammyBar and String Bending effects.
476
478
  * @cloneable
477
479
  * @json
480
+ * @json_strict
478
481
  */
479
482
  class BendPoint {
480
483
  /**
@@ -1742,6 +1745,7 @@
1742
1745
  /**
1743
1746
  * Describes an instrument articulation which is used for percussions.
1744
1747
  * @json
1748
+ * @json_strict
1745
1749
  */
1746
1750
  class InstrumentArticulation {
1747
1751
  constructor(elementType = "", staffLine = 0, outputMidiNumber = 0, noteHeadDefault = MusicFontSymbol.None, noteHeadHalf = MusicFontSymbol.None, noteHeadWhole = MusicFontSymbol.None, techniqueSymbol = MusicFontSymbol.None, techniqueSymbolPlacement = TextBaseline.Middle) {
@@ -1963,12 +1967,23 @@
1963
1967
  [34, new InstrumentArticulation("snare", 3, 38, MusicFontSymbol.NoteheadBlack, MusicFontSymbol.NoteheadBlack, MusicFontSymbol.NoteheadBlack)]
1964
1968
  ]);
1965
1969
 
1970
+ class NoteIdBag {
1971
+ constructor() {
1972
+ this.tieDestinationNoteId = -1;
1973
+ this.tieOriginNoteId = -1;
1974
+ this.slurDestinationNoteId = -1;
1975
+ this.slurOriginNoteId = -1;
1976
+ this.hammerPullDestinationNoteId = -1;
1977
+ this.hammerPullOriginNoteId = -1;
1978
+ }
1979
+ }
1966
1980
  /**
1967
1981
  * A note is a single played sound on a fretted instrument.
1968
1982
  * It consists of a fret offset and a string on which the note is played on.
1969
1983
  * It also can be modified by a lot of different effects.
1970
1984
  * @cloneable
1971
1985
  * @json
1986
+ * @json_strict
1972
1987
  */
1973
1988
  class Note {
1974
1989
  constructor() {
@@ -2009,7 +2024,7 @@
2009
2024
  * @clone_add addBendPoint
2010
2025
  * @json_add addBendPoint
2011
2026
  */
2012
- this.bendPoints = [];
2027
+ this.bendPoints = null;
2013
2028
  /**
2014
2029
  * Gets or sets the bend point with the highest bend value.
2015
2030
  * @clone_ignore
@@ -2147,25 +2162,33 @@
2147
2162
  */
2148
2163
  this.isHammerPullOrigin = false;
2149
2164
  /**
2150
- * Gets the origin note id of the hammeron/pull-off of this note.
2165
+ * Gets the origin of the hammeron/pulloff of this note.
2166
+ * @clone_ignore
2167
+ * @json_ignore
2151
2168
  */
2152
- this.hammerPullOriginNoteId = -1;
2169
+ this.hammerPullOrigin = null;
2153
2170
  /**
2154
- * Gets the destination note id of the hammeron/pull-off of this note.
2171
+ * Gets the destination for the hammeron/pullof started by this note.
2172
+ * @clone_ignore
2173
+ * @json_ignore
2155
2174
  */
2156
- this.hammerPullDestinationNoteId = -1;
2175
+ this.hammerPullDestination = null;
2157
2176
  /**
2158
2177
  * Gets or sets whether this note finishes a slur.
2159
2178
  */
2160
2179
  this.isSlurDestination = false;
2161
2180
  /**
2162
- * Gets the note id where the slur of this note starts.
2181
+ * Gets or sets the note where the slur of this note starts.
2182
+ * @clone_ignore
2183
+ * @json_ignore
2163
2184
  */
2164
- this.slurOriginNoteId = -1;
2185
+ this.slurOrigin = null;
2165
2186
  /**
2166
- * Gets or sets the note id where the slur of this note ends.
2187
+ * Gets or sets the note where the slur of this note ends.
2188
+ * @clone_ignore
2189
+ * @json_ignore
2167
2190
  */
2168
- this.slurDestinationNoteId = -1;
2191
+ this.slurDestination = null;
2169
2192
  /**
2170
2193
  * Gets or sets the harmonic type applied to this note.
2171
2194
  */
@@ -2231,13 +2254,17 @@
2231
2254
  */
2232
2255
  this.vibrato = VibratoType.None;
2233
2256
  /**
2234
- * Gets the origin note id of the tied if this note is tied.
2257
+ * Gets the origin of the tied if this note is tied.
2258
+ * @clone_ignore
2259
+ * @json_ignore
2235
2260
  */
2236
- this.tieOriginNoteId = -1;
2261
+ this.tieOrigin = null;
2237
2262
  /**
2238
- * Gets the desination note id of the tie.
2263
+ * Gets the desination of the tie.
2264
+ * @clone_ignore
2265
+ * @json_ignore
2239
2266
  */
2240
- this.tieDestinationNoteId = -1;
2267
+ this.tieDestination = null;
2241
2268
  /**
2242
2269
  * Gets or sets whether this note is ends a tied note.
2243
2270
  */
@@ -2294,9 +2321,10 @@
2294
2321
  * @json_ignore
2295
2322
  */
2296
2323
  this.effectSlurDestination = null;
2324
+ this._noteIdBag = null;
2297
2325
  }
2298
2326
  get hasBend() {
2299
- return this.bendType !== BendType.None;
2327
+ return this.bendPoints !== null && this.bendType !== BendType.None;
2300
2328
  }
2301
2329
  get isStringed() {
2302
2330
  return this.string >= 0;
@@ -2324,50 +2352,14 @@
2324
2352
  get isHammerPullDestination() {
2325
2353
  return !!this.hammerPullOrigin;
2326
2354
  }
2327
- /**
2328
- * Gets the origin of the hammeron/pulloff of this note.
2329
- */
2330
- get hammerPullOrigin() {
2331
- return this.hammerPullOriginNoteId === -1 ? null : this.beat.voice.bar.staff.track.score.getNoteById(this.hammerPullOriginNoteId);
2332
- }
2333
- /**
2334
- * Gets the destination for the hammeron/pullof started by this note.
2335
- */
2336
- get hammerPullDestination() {
2337
- return this.hammerPullDestinationNoteId === -1 ? null : this.beat.voice.bar.staff.track.score.getNoteById(this.hammerPullDestinationNoteId);
2338
- }
2339
2355
  get isSlurOrigin() {
2340
2356
  return !!this.slurDestination;
2341
2357
  }
2342
- /**
2343
- * Gets or sets the note where the slur of this note starts.
2344
- */
2345
- get slurOrigin() {
2346
- return this.slurOriginNoteId === -1 ? null : this.beat.voice.bar.staff.track.score.getNoteById(this.slurOriginNoteId);
2347
- }
2348
- /**
2349
- * Gets or sets the note where the slur of this note ends.
2350
- */
2351
- get slurDestination() {
2352
- return this.slurDestinationNoteId === -1 ? null : this.beat.voice.bar.staff.track.score.getNoteById(this.slurDestinationNoteId);
2353
- }
2354
2358
  get isHarmonic() {
2355
2359
  return this.harmonicType !== HarmonicType.None;
2356
2360
  }
2357
- /**
2358
- * Gets the origin of the tied if this note is tied.
2359
- */
2360
- get tieOrigin() {
2361
- return this.tieOriginNoteId === -1 ? null : this.beat.voice.bar.staff.track.score.getNoteById(this.tieOriginNoteId);
2362
- }
2363
- /**
2364
- * Gets the desination of the tie.
2365
- */
2366
- get tieDestination() {
2367
- return this.tieDestinationNoteId === -1 ? null : this.beat.voice.bar.staff.track.score.getNoteById(this.tieDestinationNoteId);
2368
- }
2369
2361
  get isTieOrigin() {
2370
- return this.tieDestinationNoteId !== -1;
2362
+ return this.tieDestination !== null;
2371
2363
  }
2372
2364
  get trillFret() {
2373
2365
  return this.trillValue - this.stringTuning;
@@ -2568,7 +2560,12 @@
2568
2560
  return false;
2569
2561
  }
2570
2562
  addBendPoint(point) {
2571
- this.bendPoints.push(point);
2563
+ let points = this.bendPoints;
2564
+ if (points === null) {
2565
+ points = [];
2566
+ this.bendPoints = points;
2567
+ }
2568
+ points.push(point);
2572
2569
  if (!this.maxBendPoint || point.value > this.maxBendPoint.value) {
2573
2570
  this.maxBendPoint = point;
2574
2571
  }
@@ -2576,12 +2573,12 @@
2576
2573
  this.bendType = BendType.Custom;
2577
2574
  }
2578
2575
  }
2579
- finish(settings) {
2576
+ finish(settings, sharedDataBag) {
2580
2577
  let nextNoteOnLine = new Lazy(() => Note.nextNoteOnSameLine(this));
2581
2578
  let isSongBook = settings && settings.notation.notationMode === exports.NotationMode.SongBook;
2582
2579
  // connect ties
2583
2580
  if (this.isTieDestination) {
2584
- this.chain();
2581
+ this.chain(sharedDataBag);
2585
2582
  // implicit let ring
2586
2583
  if (isSongBook && this.tieOrigin && this.tieOrigin.isLetRing) {
2587
2584
  this.isLetRing = true;
@@ -2615,8 +2612,8 @@
2615
2612
  this.isHammerPullOrigin = false;
2616
2613
  }
2617
2614
  else {
2618
- this.hammerPullDestinationNoteId = hammerPullDestination.id;
2619
- hammerPullDestination.hammerPullOriginNoteId = this.id;
2615
+ this.hammerPullDestination = hammerPullDestination;
2616
+ hammerPullDestination.hammerPullOrigin = this;
2620
2617
  }
2621
2618
  }
2622
2619
  // set slides
@@ -2654,14 +2651,15 @@
2654
2651
  }
2655
2652
  // try to detect what kind of bend was used and cleans unneeded points if required
2656
2653
  // Guitar Pro 6 and above (gpif.xml) uses exactly 4 points to define all bends
2657
- if (this.bendPoints.length > 0 && this.bendType === BendType.Custom) {
2654
+ const points = this.bendPoints;
2655
+ if (points != null && points.length > 0 && this.bendType === BendType.Custom) {
2658
2656
  let isContinuedBend = this.isTieDestination && this.tieOrigin.hasBend;
2659
2657
  this.isContinuedBend = isContinuedBend;
2660
- if (this.bendPoints.length === 4) {
2661
- let origin = this.bendPoints[0];
2662
- let middle1 = this.bendPoints[1];
2663
- let middle2 = this.bendPoints[2];
2664
- let destination = this.bendPoints[3];
2658
+ if (points.length === 4) {
2659
+ let origin = points[0];
2660
+ let middle1 = points[1];
2661
+ let middle2 = points[2];
2662
+ let destination = points[3];
2665
2663
  // the middle points are used for holds, anything else is a new feature we do not support yet
2666
2664
  if (middle1.value === middle2.value) {
2667
2665
  // bend higher?
@@ -2671,26 +2669,26 @@
2671
2669
  }
2672
2670
  else if (!isContinuedBend && origin.value > 0) {
2673
2671
  this.bendType = BendType.PrebendBend;
2674
- this.bendPoints.splice(2, 1);
2675
- this.bendPoints.splice(1, 1);
2672
+ points.splice(2, 1);
2673
+ points.splice(1, 1);
2676
2674
  }
2677
2675
  else {
2678
2676
  this.bendType = BendType.Bend;
2679
- this.bendPoints.splice(2, 1);
2680
- this.bendPoints.splice(1, 1);
2677
+ points.splice(2, 1);
2678
+ points.splice(1, 1);
2681
2679
  }
2682
2680
  }
2683
2681
  else if (destination.value < origin.value) {
2684
2682
  // origin must be > 0 otherwise it's no release, we cannot bend negative
2685
2683
  if (isContinuedBend) {
2686
2684
  this.bendType = BendType.Release;
2687
- this.bendPoints.splice(2, 1);
2688
- this.bendPoints.splice(1, 1);
2685
+ points.splice(2, 1);
2686
+ points.splice(1, 1);
2689
2687
  }
2690
2688
  else {
2691
2689
  this.bendType = BendType.PrebendRelease;
2692
- this.bendPoints.splice(2, 1);
2693
- this.bendPoints.splice(1, 1);
2690
+ points.splice(2, 1);
2691
+ points.splice(1, 1);
2694
2692
  }
2695
2693
  }
2696
2694
  else {
@@ -2699,13 +2697,13 @@
2699
2697
  }
2700
2698
  else if (origin.value > 0 && !isContinuedBend) {
2701
2699
  this.bendType = BendType.Prebend;
2702
- this.bendPoints.splice(2, 1);
2703
- this.bendPoints.splice(1, 1);
2700
+ points.splice(2, 1);
2701
+ points.splice(1, 1);
2704
2702
  }
2705
2703
  else {
2706
2704
  this.bendType = BendType.Hold;
2707
- this.bendPoints.splice(2, 1);
2708
- this.bendPoints.splice(1, 1);
2705
+ points.splice(2, 1);
2706
+ points.splice(1, 1);
2709
2707
  }
2710
2708
  }
2711
2709
  }
@@ -2713,9 +2711,9 @@
2713
2711
  Logger.warning('Model', 'Unsupported bend type detected, fallback to custom', null);
2714
2712
  }
2715
2713
  }
2716
- else if (this.bendPoints.length === 2) {
2717
- let origin = this.bendPoints[0];
2718
- let destination = this.bendPoints[1];
2714
+ else if (points.length === 2) {
2715
+ let origin = points[0];
2716
+ let destination = points[1];
2719
2717
  // bend higher?
2720
2718
  if (destination.value > origin.value) {
2721
2719
  if (!isContinuedBend && origin.value > 0) {
@@ -2739,7 +2737,7 @@
2739
2737
  }
2740
2738
  }
2741
2739
  }
2742
- else if (this.bendPoints.length === 0) {
2740
+ else if (points === null || points.length === 0) {
2743
2741
  this.bendType = BendType.None;
2744
2742
  }
2745
2743
  // initial bend pitch offsets and forced accidentals don't play well together
@@ -2835,35 +2833,134 @@
2835
2833
  }
2836
2834
  return null;
2837
2835
  }
2838
- chain() {
2839
- this.beat.voice.bar.staff.track.score.registerNote(this);
2840
- if (!this.isTieDestination) {
2841
- return;
2842
- }
2843
- let tieOrigin;
2844
- if (this.tieOriginNoteId === -1) {
2845
- tieOrigin = Note.findTieOrigin(this);
2846
- this.tieOriginNoteId = tieOrigin ? tieOrigin.id : -1;
2836
+ chain(sharedDataBag) {
2837
+ // if we have some IDs from a serialization flow,
2838
+ // we need to lookup/register the notes correctly
2839
+ if (this._noteIdBag != null) {
2840
+ // get or create lookup
2841
+ let noteIdLookup;
2842
+ if (sharedDataBag.has(Note.NoteIdLookupKey)) {
2843
+ noteIdLookup = sharedDataBag.get(Note.NoteIdLookupKey);
2844
+ }
2845
+ else {
2846
+ noteIdLookup = new Map();
2847
+ sharedDataBag.set(Note.NoteIdLookupKey, noteIdLookup);
2848
+ }
2849
+ // if this note is a source note for any effect, remember it for later
2850
+ // the destination note will look it up for linking
2851
+ if (this._noteIdBag.hammerPullDestinationNoteId !== -1 ||
2852
+ this._noteIdBag.tieDestinationNoteId !== -1 ||
2853
+ this._noteIdBag.slurDestinationNoteId !== -1) {
2854
+ noteIdLookup.set(this.id, this);
2855
+ }
2856
+ // on any effect destiniation, lookup the origin which should already be
2857
+ // registered
2858
+ if (this._noteIdBag.hammerPullOriginNoteId !== -1) {
2859
+ this.hammerPullOrigin = noteIdLookup.get(this._noteIdBag.hammerPullOriginNoteId);
2860
+ this.hammerPullOrigin.hammerPullDestination = this;
2861
+ }
2862
+ if (this._noteIdBag.tieOriginNoteId !== -1) {
2863
+ this.tieOrigin = noteIdLookup.get(this._noteIdBag.tieOriginNoteId);
2864
+ this.tieOrigin.tieDestination = this;
2865
+ }
2866
+ if (this._noteIdBag.slurOriginNoteId !== -1) {
2867
+ this.slurOrigin = noteIdLookup.get(this._noteIdBag.slurOriginNoteId);
2868
+ this.slurOrigin.slurDestination = this;
2869
+ }
2870
+ this._noteIdBag = null; // not needed anymore
2847
2871
  }
2848
2872
  else {
2849
- tieOrigin = this.tieOrigin;
2873
+ if (!this.isTieDestination && this.tieOrigin == null) {
2874
+ return;
2875
+ }
2876
+ let tieOrigin = Note.findTieOrigin(this);
2877
+ if (!tieOrigin) {
2878
+ this.isTieDestination = false;
2879
+ }
2880
+ else {
2881
+ tieOrigin.tieDestination = this;
2882
+ this.tieOrigin = tieOrigin;
2883
+ this.fret = tieOrigin.fret;
2884
+ this.octave = tieOrigin.octave;
2885
+ this.tone = tieOrigin.tone;
2886
+ if (tieOrigin.hasBend) {
2887
+ this.bendOrigin = this.tieOrigin;
2888
+ }
2889
+ }
2890
+ }
2891
+ }
2892
+ /**
2893
+ * @internal
2894
+ */
2895
+ toJson(o) {
2896
+ // inject linked note ids into JSON
2897
+ if (this.tieDestination !== null) {
2898
+ o.set("tiedestinationnoteid", this.tieDestination.id);
2850
2899
  }
2851
- if (!tieOrigin) {
2852
- this.isTieDestination = false;
2900
+ if (this.tieOrigin !== null) {
2901
+ o.set("tieoriginnoteid", this.tieOrigin.id);
2853
2902
  }
2854
- else {
2855
- tieOrigin.tieDestinationNoteId = this.id;
2856
- this.fret = tieOrigin.fret;
2857
- this.octave = tieOrigin.octave;
2858
- this.tone = tieOrigin.tone;
2859
- if (tieOrigin.hasBend) {
2860
- this.bendOrigin = this.tieOrigin;
2861
- }
2903
+ if (this.slurDestination !== null) {
2904
+ o.set("slurdestinationnoteid", this.slurDestination.id);
2905
+ }
2906
+ if (this.slurOrigin !== null) {
2907
+ o.set("sluroriginnoteid", this.slurOrigin.id);
2908
+ }
2909
+ if (this.hammerPullOrigin !== null) {
2910
+ o.set("hammerpulloriginnoteid", this.hammerPullOrigin.id);
2911
+ }
2912
+ if (this.hammerPullDestination !== null) {
2913
+ o.set("hammerpulldestinationnoteid", this.hammerPullDestination.id);
2862
2914
  }
2863
2915
  }
2916
+ /**
2917
+ * @internal
2918
+ */
2919
+ setProperty(property, v) {
2920
+ switch (property) {
2921
+ case "tiedestinationnoteid":
2922
+ if (this._noteIdBag == null) {
2923
+ this._noteIdBag = new NoteIdBag();
2924
+ }
2925
+ this._noteIdBag.tieDestinationNoteId = v;
2926
+ return true;
2927
+ case "tieoriginnoteid":
2928
+ if (this._noteIdBag == null) {
2929
+ this._noteIdBag = new NoteIdBag();
2930
+ }
2931
+ this._noteIdBag.tieOriginNoteId = v;
2932
+ return true;
2933
+ case "slurdestinationnoteid":
2934
+ if (this._noteIdBag == null) {
2935
+ this._noteIdBag = new NoteIdBag();
2936
+ }
2937
+ this._noteIdBag.slurDestinationNoteId = v;
2938
+ return true;
2939
+ case "sluroriginnoteid":
2940
+ if (this._noteIdBag == null) {
2941
+ this._noteIdBag = new NoteIdBag();
2942
+ }
2943
+ this._noteIdBag.slurOriginNoteId = v;
2944
+ return true;
2945
+ case "hammerpulloriginnoteid":
2946
+ if (this._noteIdBag == null) {
2947
+ this._noteIdBag = new NoteIdBag();
2948
+ }
2949
+ this._noteIdBag.hammerPullOriginNoteId = v;
2950
+ return true;
2951
+ case "hammerpulldestinationnoteid":
2952
+ if (this._noteIdBag == null) {
2953
+ this._noteIdBag = new NoteIdBag();
2954
+ }
2955
+ this._noteIdBag.hammerPullDestinationNoteId = v;
2956
+ return true;
2957
+ }
2958
+ return false;
2959
+ }
2864
2960
  }
2865
2961
  Note.GlobalNoteId = 0;
2866
- Note.MaxOffsetForSameLineSearch = 3;
2962
+ Note.MaxOffsetForSameLineSearch = 3;
2963
+ Note.NoteIdLookupKey = "NoteIdLookup";
2867
2964
 
2868
2965
  /**
2869
2966
  * Represents a list of beats that are grouped within the same tuplet.
@@ -3009,9 +3106,11 @@
3009
3106
  clone.bendType = original.bendType;
3010
3107
  clone.bendStyle = original.bendStyle;
3011
3108
  clone.isContinuedBend = original.isContinuedBend;
3012
- clone.bendPoints = [];
3013
- for (const i of original.bendPoints) {
3014
- clone.addBendPoint(BendPointCloner.clone(i));
3109
+ if (original.bendPoints) {
3110
+ clone.bendPoints = [];
3111
+ for (const i of original.bendPoints) {
3112
+ clone.addBendPoint(BendPointCloner.clone(i));
3113
+ }
3015
3114
  }
3016
3115
  clone.fret = original.fret;
3017
3116
  clone.string = original.string;
@@ -3021,11 +3120,7 @@
3021
3120
  clone.isVisible = original.isVisible;
3022
3121
  clone.isLeftHandTapped = original.isLeftHandTapped;
3023
3122
  clone.isHammerPullOrigin = original.isHammerPullOrigin;
3024
- clone.hammerPullOriginNoteId = original.hammerPullOriginNoteId;
3025
- clone.hammerPullDestinationNoteId = original.hammerPullDestinationNoteId;
3026
3123
  clone.isSlurDestination = original.isSlurDestination;
3027
- clone.slurOriginNoteId = original.slurOriginNoteId;
3028
- clone.slurDestinationNoteId = original.slurDestinationNoteId;
3029
3124
  clone.harmonicType = original.harmonicType;
3030
3125
  clone.harmonicValue = original.harmonicValue;
3031
3126
  clone.isGhost = original.isGhost;
@@ -3036,8 +3131,6 @@
3036
3131
  clone.slideInType = original.slideInType;
3037
3132
  clone.slideOutType = original.slideOutType;
3038
3133
  clone.vibrato = original.vibrato;
3039
- clone.tieOriginNoteId = original.tieOriginNoteId;
3040
- clone.tieDestinationNoteId = original.tieDestinationNoteId;
3041
3134
  clone.isTieDestination = original.isTieDestination;
3042
3135
  clone.leftHandFinger = original.leftHandFinger;
3043
3136
  clone.rightHandFinger = original.rightHandFinger;
@@ -3098,9 +3191,11 @@
3098
3191
  clone.tupletNumerator = original.tupletNumerator;
3099
3192
  clone.isContinuedWhammy = original.isContinuedWhammy;
3100
3193
  clone.whammyBarType = original.whammyBarType;
3101
- clone.whammyBarPoints = [];
3102
- for (const i of original.whammyBarPoints) {
3103
- clone.addWhammyBarPoint(BendPointCloner.clone(i));
3194
+ if (original.whammyBarPoints) {
3195
+ clone.whammyBarPoints = [];
3196
+ for (const i of original.whammyBarPoints) {
3197
+ clone.addWhammyBarPoint(BendPointCloner.clone(i));
3198
+ }
3104
3199
  }
3105
3200
  clone.vibrato = original.vibrato;
3106
3201
  clone.chordId = original.chordId;
@@ -3178,6 +3273,7 @@
3178
3273
  * A beat is a single block within a bar. A beat is a combination
3179
3274
  * of several notes played at the same time.
3180
3275
  * @json
3276
+ * @json_strict
3181
3277
  * @cloneable
3182
3278
  */
3183
3279
  class Beat {
@@ -3352,7 +3448,7 @@
3352
3448
  * @json_add addWhammyBarPoint
3353
3449
  * @clone_add addWhammyBarPoint
3354
3450
  */
3355
- this.whammyBarPoints = [];
3451
+ this.whammyBarPoints = null;
3356
3452
  /**
3357
3453
  * Gets or sets the highest point with for the highest whammy bar value.
3358
3454
  * @json_ignore
@@ -3473,13 +3569,13 @@
3473
3569
  !(this.tupletDenominator === 1 && this.tupletNumerator === 1));
3474
3570
  }
3475
3571
  get hasWhammyBar() {
3476
- return this.whammyBarType !== WhammyType.None;
3572
+ return this.whammyBarPoints !== null && this.whammyBarType !== WhammyType.None;
3477
3573
  }
3478
3574
  get hasChord() {
3479
3575
  return !!this.chordId;
3480
3576
  }
3481
3577
  get chord() {
3482
- return this.chordId ? this.voice.bar.staff.chords.get(this.chordId) : null;
3578
+ return this.chordId ? this.voice.bar.staff.getChord(this.chordId) : null;
3483
3579
  }
3484
3580
  get isTremolo() {
3485
3581
  return !!this.tremoloSpeed;
@@ -3494,7 +3590,12 @@
3494
3590
  return !!this.effectSlurOrigin;
3495
3591
  }
3496
3592
  addWhammyBarPoint(point) {
3497
- this.whammyBarPoints.push(point);
3593
+ let points = this.whammyBarPoints;
3594
+ if (points === null) {
3595
+ points = [];
3596
+ this.whammyBarPoints = points;
3597
+ }
3598
+ points.push(point);
3498
3599
  if (!this.maxWhammyPoint || point.value > this.maxWhammyPoint.value) {
3499
3600
  this.maxWhammyPoint = point;
3500
3601
  }
@@ -3507,16 +3608,17 @@
3507
3608
  }
3508
3609
  removeWhammyBarPoint(index) {
3509
3610
  // check index
3510
- if (index < 0 || index >= this.whammyBarPoints.length) {
3611
+ const points = this.whammyBarPoints;
3612
+ if (points === null || index < 0 || index >= points.length) {
3511
3613
  return;
3512
3614
  }
3513
3615
  // remove point
3514
- this.whammyBarPoints.splice(index, 1);
3515
- let point = this.whammyBarPoints[index];
3616
+ points.splice(index, 1);
3617
+ let point = points[index];
3516
3618
  // update maxWhammy point if required
3517
3619
  if (point === this.maxWhammyPoint) {
3518
3620
  this.maxWhammyPoint = null;
3519
- for (let currentPoint of this.whammyBarPoints) {
3621
+ for (let currentPoint of points) {
3520
3622
  if (!this.maxWhammyPoint || currentPoint.value > this.maxWhammyPoint.value) {
3521
3623
  this.maxWhammyPoint = currentPoint;
3522
3624
  }
@@ -3524,7 +3626,7 @@
3524
3626
  }
3525
3627
  if (point === this.minWhammyPoint) {
3526
3628
  this.minWhammyPoint = null;
3527
- for (let currentPoint of this.whammyBarPoints) {
3629
+ for (let currentPoint of points) {
3528
3630
  if (!this.minWhammyPoint || currentPoint.value < this.minWhammyPoint.value) {
3529
3631
  this.minWhammyPoint = currentPoint;
3530
3632
  }
@@ -3619,7 +3721,7 @@
3619
3721
  this.tupletGroup = currentTupletGroup;
3620
3722
  }
3621
3723
  }
3622
- finish(settings) {
3724
+ finish(settings, sharedDataBag) {
3623
3725
  if (this.getAutomation(AutomationType.Instrument) === null &&
3624
3726
  this.index === 0 &&
3625
3727
  this.voice.index === 0 &&
@@ -3658,7 +3760,7 @@
3658
3760
  for (let i = 0, j = this.notes.length; i < j; i++) {
3659
3761
  let note = this.notes[i];
3660
3762
  note.dynamics = this.dynamics;
3661
- note.finish(settings);
3763
+ note.finish(settings, sharedDataBag);
3662
3764
  if (note.isLetRing) {
3663
3765
  this.isLetRing = true;
3664
3766
  }
@@ -3749,17 +3851,18 @@
3749
3851
  }
3750
3852
  // try to detect what kind of bend was used and cleans unneeded points if required
3751
3853
  // Guitar Pro 6 and above (gpif.xml) uses exactly 4 points to define all whammys
3752
- if (this.whammyBarPoints.length > 0 && this.whammyBarType === WhammyType.Custom) {
3854
+ const points = this.whammyBarPoints;
3855
+ if (points !== null && points.length > 0 && this.whammyBarType === WhammyType.Custom) {
3753
3856
  if (displayMode === exports.NotationMode.SongBook) {
3754
3857
  this.whammyStyle = isGradual ? BendStyle.Gradual : BendStyle.Fast;
3755
3858
  }
3756
3859
  let isContinuedWhammy = !!this.previousBeat && this.previousBeat.hasWhammyBar;
3757
3860
  this.isContinuedWhammy = isContinuedWhammy;
3758
- if (this.whammyBarPoints.length === 4) {
3759
- let origin = this.whammyBarPoints[0];
3760
- let middle1 = this.whammyBarPoints[1];
3761
- let middle2 = this.whammyBarPoints[2];
3762
- let destination = this.whammyBarPoints[3];
3861
+ if (points.length === 4) {
3862
+ let origin = points[0];
3863
+ let middle1 = points[1];
3864
+ let middle2 = points[2];
3865
+ let destination = points[3];
3763
3866
  // the middle points are used for holds, anything else is a new feature we do not support yet
3764
3867
  if (middle1.value === middle2.value) {
3765
3868
  // constant decrease or increase
@@ -3771,14 +3874,14 @@
3771
3874
  else {
3772
3875
  this.whammyBarType = WhammyType.Dive;
3773
3876
  }
3774
- this.whammyBarPoints.splice(2, 1);
3775
- this.whammyBarPoints.splice(1, 1);
3877
+ points.splice(2, 1);
3878
+ points.splice(1, 1);
3776
3879
  }
3777
3880
  else if ((origin.value > middle1.value && middle1.value < destination.value) ||
3778
3881
  (origin.value < middle1.value && middle1.value > destination.value)) {
3779
3882
  this.whammyBarType = WhammyType.Dip;
3780
3883
  if (middle1.offset === middle2.offset || displayMode === exports.NotationMode.SongBook) {
3781
- this.whammyBarPoints.splice(2, 1);
3884
+ points.splice(2, 1);
3782
3885
  }
3783
3886
  }
3784
3887
  else if (origin.value === middle1.value && middle1.value === destination.value) {
@@ -3788,8 +3891,8 @@
3788
3891
  else {
3789
3892
  this.whammyBarType = WhammyType.Hold;
3790
3893
  }
3791
- this.whammyBarPoints.splice(2, 1);
3792
- this.whammyBarPoints.splice(1, 1);
3894
+ points.splice(2, 1);
3895
+ points.splice(1, 1);
3793
3896
  }
3794
3897
  else {
3795
3898
  Logger.warning('Model', 'Unsupported whammy type detected, fallback to custom', null);
@@ -3813,17 +3916,17 @@
3813
3916
  // remove bend on cloned note
3814
3917
  cloneNote.bendType = BendType.None;
3815
3918
  cloneNote.maxBendPoint = null;
3816
- cloneNote.bendPoints = [];
3919
+ cloneNote.bendPoints = null;
3817
3920
  cloneNote.bendStyle = BendStyle.Default;
3818
3921
  cloneNote.id = Note.GlobalNoteId++;
3819
3922
  // fix ties
3820
3923
  if (note.isTieOrigin) {
3821
- cloneNote.tieDestinationNoteId = note.tieDestination.id;
3822
- note.tieDestination.tieOriginNoteId = cloneNote.id;
3924
+ cloneNote.tieDestination = note.tieDestination;
3925
+ note.tieDestination.tieOrigin = cloneNote;
3823
3926
  }
3824
3927
  if (note.isTieDestination) {
3825
- cloneNote.tieOriginNoteId = note.tieOrigin ? note.tieOrigin.id : -1;
3826
- note.tieOrigin.tieDestinationNoteId = cloneNote.id;
3928
+ cloneNote.tieOrigin = note.tieOrigin ? note.tieOrigin : null;
3929
+ note.tieOrigin.tieDestination = cloneNote;
3827
3930
  }
3828
3931
  // if the note has a bend which is continued on the next note
3829
3932
  // we need to convert this note into a hold bend
@@ -3876,16 +3979,17 @@
3876
3979
  hasNoteOnString(noteString) {
3877
3980
  return this.noteStringLookup.has(noteString);
3878
3981
  }
3982
+ // TODO: can be likely eliminated
3879
3983
  getNoteWithRealValue(noteRealValue) {
3880
3984
  if (this.noteValueLookup.has(noteRealValue)) {
3881
3985
  return this.noteValueLookup.get(noteRealValue);
3882
3986
  }
3883
3987
  return null;
3884
3988
  }
3885
- chain() {
3989
+ chain(sharedDataBag) {
3886
3990
  for (const n of this.notes) {
3887
3991
  this.noteValueLookup.set(n.realValue, n);
3888
- n.chain();
3992
+ n.chain(sharedDataBag);
3889
3993
  }
3890
3994
  }
3891
3995
  }
@@ -3896,6 +4000,7 @@
3896
4000
  /**
3897
4001
  * A chord definition.
3898
4002
  * @json
4003
+ * @json_strict
3899
4004
  */
3900
4005
  class Chord {
3901
4006
  constructor() {
@@ -4188,6 +4293,7 @@
4188
4293
  * The MasterBar stores information about a bar which affects
4189
4294
  * all tracks.
4190
4295
  * @json
4296
+ * @json_strict
4191
4297
  */
4192
4298
  class MasterBar {
4193
4299
  constructor() {
@@ -4257,8 +4363,9 @@
4257
4363
  this.tempoAutomation = null;
4258
4364
  /**
4259
4365
  * Gets or sets the fermatas for this bar. The key is the offset of the fermata in midi ticks.
4366
+ * @json_add addFermata
4260
4367
  */
4261
- this.fermata = new Map();
4368
+ this.fermata = null;
4262
4369
  /**
4263
4370
  * The timeline position of the voice within the whole score. (unit: midi ticks)
4264
4371
  */
@@ -4300,7 +4407,12 @@
4300
4407
  * @param fermata The fermata.
4301
4408
  */
4302
4409
  addFermata(offset, fermata) {
4303
- this.fermata.set(offset, fermata);
4410
+ let fermataMap = this.fermata;
4411
+ if (fermataMap === null) {
4412
+ fermataMap = new Map();
4413
+ this.fermata = fermataMap;
4414
+ }
4415
+ fermataMap.set(offset, fermata);
4304
4416
  }
4305
4417
  /**
4306
4418
  * Gets the fermata for a given beat.
@@ -4308,8 +4420,12 @@
4308
4420
  * @returns
4309
4421
  */
4310
4422
  getFermata(beat) {
4311
- if (this.fermata.has(beat.playbackStart)) {
4312
- return this.fermata.get(beat.playbackStart);
4423
+ const fermataMap = this.fermata;
4424
+ if (fermataMap === null) {
4425
+ return null;
4426
+ }
4427
+ if (fermataMap.has(beat.playbackStart)) {
4428
+ return fermataMap.get(beat.playbackStart);
4313
4429
  }
4314
4430
  return null;
4315
4431
  }
@@ -4320,6 +4436,7 @@
4320
4436
  * This class represents the rendering stylesheet.
4321
4437
  * It contains settings which control the display of the score when rendered.
4322
4438
  * @json
4439
+ * @json_strict
4323
4440
  */
4324
4441
  class RenderStylesheet {
4325
4442
  constructor() {
@@ -4382,10 +4499,10 @@
4382
4499
  * model. It stores the basic information of
4383
4500
  * a song and stores the sub components.
4384
4501
  * @json
4502
+ * @json_strict
4385
4503
  */
4386
4504
  class Score {
4387
4505
  constructor() {
4388
- this._noteByIdLookup = new Map();
4389
4506
  this._currentRepeatGroup = new RepeatGroup();
4390
4507
  /**
4391
4508
  * The album of this song.
@@ -4485,25 +4602,18 @@
4485
4602
  this.tracks.push(track);
4486
4603
  }
4487
4604
  finish(settings) {
4488
- this._noteByIdLookup.clear();
4605
+ const sharedDataBag = new Map();
4489
4606
  for (let i = 0, j = this.tracks.length; i < j; i++) {
4490
- this.tracks[i].finish(settings);
4607
+ this.tracks[i].finish(settings, sharedDataBag);
4491
4608
  }
4492
4609
  }
4493
- registerNote(note) {
4494
- this._noteByIdLookup.set(note.id, note);
4495
- }
4496
- getNoteById(noteId) {
4497
- return this._noteByIdLookup.has(noteId)
4498
- ? this._noteByIdLookup.get(noteId)
4499
- : null;
4500
- }
4501
4610
  }
4502
4611
 
4503
4612
  /**
4504
4613
  * This public class is used to describe the beginning of a
4505
4614
  * section within a song. It acts like a marker.
4506
4615
  * @json
4616
+ * @json_strict
4507
4617
  */
4508
4618
  class Section {
4509
4619
  constructor() {
@@ -4576,50 +4686,48 @@
4576
4686
  }
4577
4687
  static fromJson(v) {
4578
4688
  switch (typeof v) {
4579
- case 'number':
4580
- {
4581
- const c = new Color(0, 0, 0, 0);
4582
- c.raw = v;
4583
- c.updateRgba();
4584
- return c;
4689
+ case 'number': {
4690
+ const c = new Color(0, 0, 0, 0);
4691
+ c.raw = v;
4692
+ c.updateRgba();
4693
+ return c;
4694
+ }
4695
+ case 'string': {
4696
+ const json = v;
4697
+ if (json.startsWith('#')) {
4698
+ if (json.length === 4) {
4699
+ // #RGB
4700
+ return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17);
4701
+ }
4702
+ if (json.length === 5) {
4703
+ // #RGBA
4704
+ return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17, parseInt(json.substring(4, 1), 16) * 17);
4705
+ }
4706
+ if (json.length === 7) {
4707
+ // #RRGGBB
4708
+ return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16));
4709
+ }
4710
+ if (json.length === 9) {
4711
+ // #RRGGBBAA
4712
+ return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16), parseInt(json.substring(7, 2), 16));
4713
+ }
4585
4714
  }
4586
- case 'string':
4587
- {
4588
- const json = v;
4589
- if (json.startsWith('#')) {
4590
- if (json.length === 4) {
4591
- // #RGB
4592
- return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17);
4593
- }
4594
- if (json.length === 5) {
4595
- // #RGBA
4596
- return new Color(parseInt(json.substring(1, 1), 16) * 17, parseInt(json.substring(2, 1), 16) * 17, parseInt(json.substring(3, 1), 16) * 17, parseInt(json.substring(4, 1), 16) * 17);
4597
- }
4598
- if (json.length === 7) {
4599
- // #RRGGBB
4600
- return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16));
4601
- }
4602
- if (json.length === 9) {
4603
- // #RRGGBBAA
4604
- return new Color(parseInt(json.substring(1, 2), 16), parseInt(json.substring(3, 2), 16), parseInt(json.substring(5, 2), 16), parseInt(json.substring(7, 2), 16));
4605
- }
4715
+ else if (json.startsWith('rgba') || json.startsWith('rgb')) {
4716
+ const start = json.indexOf('(');
4717
+ const end = json.lastIndexOf(')');
4718
+ if (start === -1 || end === -1) {
4719
+ throw new FormatError('No values specified for rgb/rgba function');
4606
4720
  }
4607
- else if (json.startsWith('rgba') || json.startsWith('rgb')) {
4608
- const start = json.indexOf('(');
4609
- const end = json.lastIndexOf(')');
4610
- if (start === -1 || end === -1) {
4611
- throw new FormatError('No values specified for rgb/rgba function');
4612
- }
4613
- const numbers = json.substring(start + 1, end).split(',');
4614
- if (numbers.length === 3) {
4615
- return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]));
4616
- }
4617
- if (numbers.length === 4) {
4618
- return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]), parseFloat(numbers[3]) * 255);
4619
- }
4721
+ const numbers = json.substring(start + 1, end).split(',');
4722
+ if (numbers.length === 3) {
4723
+ return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]));
4724
+ }
4725
+ if (numbers.length === 4) {
4726
+ return new Color(parseInt(numbers[0]), parseInt(numbers[1]), parseInt(numbers[2]), parseFloat(numbers[3]) * 255);
4620
4727
  }
4621
- return null;
4622
4728
  }
4729
+ return null;
4730
+ }
4623
4731
  }
4624
4732
  throw new FormatError('Unsupported format for color');
4625
4733
  }
@@ -4633,6 +4741,7 @@
4633
4741
  * This public class stores the midi specific information of a track needed
4634
4742
  * for playback.
4635
4743
  * @json
4744
+ * @json_strict
4636
4745
  */
4637
4746
  class PlaybackInformation {
4638
4747
  constructor() {
@@ -4674,6 +4783,7 @@
4674
4783
  /**
4675
4784
  * This public class represents a predefined string tuning.
4676
4785
  * @json
4786
+ * @json_strict
4677
4787
  */
4678
4788
  class Tuning {
4679
4789
  /**
@@ -4829,6 +4939,7 @@
4829
4939
  * This class describes a single staff within a track. There are instruments like pianos
4830
4940
  * where a single track can contain multiple staffs.
4831
4941
  * @json
4942
+ * @json_strict
4832
4943
  */
4833
4944
  class Staff {
4834
4945
  constructor() {
@@ -4846,7 +4957,7 @@
4846
4957
  * Gets or sets a list of all chords defined for this staff. {@link Beat.chordId} refers to entries in this lookup.
4847
4958
  * @json_add addChord
4848
4959
  */
4849
- this.chords = new Map();
4960
+ this.chords = null;
4850
4961
  /**
4851
4962
  * Gets or sets the fret on which a capo is set.
4852
4963
  */
@@ -4900,15 +5011,28 @@
4900
5011
  get isStringed() {
4901
5012
  return this.stringTuning.tunings.length > 0;
4902
5013
  }
4903
- finish(settings) {
5014
+ finish(settings, sharedDataBag) {
4904
5015
  this.stringTuning.finish();
4905
5016
  for (let i = 0, j = this.bars.length; i < j; i++) {
4906
- this.bars[i].finish(settings);
5017
+ this.bars[i].finish(settings, sharedDataBag);
4907
5018
  }
4908
5019
  }
4909
5020
  addChord(chordId, chord) {
4910
5021
  chord.staff = this;
4911
- this.chords.set(chordId, chord);
5022
+ let chordMap = this.chords;
5023
+ if (chordMap === null) {
5024
+ chordMap = new Map();
5025
+ this.chords = chordMap;
5026
+ }
5027
+ chordMap.set(chordId, chord);
5028
+ }
5029
+ hasChord(chordId) {
5030
+ var _a, _b;
5031
+ return (_b = (_a = this.chords) === null || _a === void 0 ? void 0 : _a.has(chordId)) !== null && _b !== void 0 ? _b : false;
5032
+ }
5033
+ getChord(chordId) {
5034
+ var _a, _b;
5035
+ return (_b = (_a = this.chords) === null || _a === void 0 ? void 0 : _a.get(chordId)) !== null && _b !== void 0 ? _b : null;
4912
5036
  }
4913
5037
  addBar(bar) {
4914
5038
  let bars = this.bars;
@@ -4926,6 +5050,7 @@
4926
5050
  * This public class describes a single track or instrument of score.
4927
5051
  * It is bascially a list of staffs containing individual music notation kinds.
4928
5052
  * @json
5053
+ * @json_strict
4929
5054
  */
4930
5055
  class Track {
4931
5056
  constructor() {
@@ -4971,7 +5096,7 @@
4971
5096
  staff.track = this;
4972
5097
  this.staves.push(staff);
4973
5098
  }
4974
- finish(settings) {
5099
+ finish(settings, sharedDataBag) {
4975
5100
  if (!this.shortName) {
4976
5101
  this.shortName = this.name;
4977
5102
  if (this.shortName.length > Track.ShortNameMaxLength) {
@@ -4979,7 +5104,7 @@
4979
5104
  }
4980
5105
  }
4981
5106
  for (let i = 0, j = this.staves.length; i < j; i++) {
4982
- this.staves[i].finish(settings);
5107
+ this.staves[i].finish(settings, sharedDataBag);
4983
5108
  }
4984
5109
  }
4985
5110
  applyLyrics(lyrics) {
@@ -5017,6 +5142,7 @@
5017
5142
  * A voice represents a group of beats
5018
5143
  * that can be played during a bar.
5019
5144
  * @json
5145
+ * @json_strict
5020
5146
  */
5021
5147
  class Voice$1 {
5022
5148
  constructor() {
@@ -5057,7 +5183,7 @@
5057
5183
  this.isEmpty = false;
5058
5184
  }
5059
5185
  }
5060
- chain(beat) {
5186
+ chain(beat, sharedDataBag) {
5061
5187
  if (!this.bar) {
5062
5188
  return;
5063
5189
  }
@@ -5075,7 +5201,7 @@
5075
5201
  beat.nextBeat.previousBeat = beat;
5076
5202
  }
5077
5203
  }
5078
- beat.chain();
5204
+ beat.chain(sharedDataBag);
5079
5205
  }
5080
5206
  addGraceBeat(beat) {
5081
5207
  if (this.beats.length === 0) {
@@ -5097,13 +5223,13 @@
5097
5223
  }
5098
5224
  return null;
5099
5225
  }
5100
- finish(settings) {
5226
+ finish(settings, sharedDataBag) {
5101
5227
  this._beatLookup = new Map();
5102
5228
  let currentGraceGroup = null;
5103
5229
  for (let index = 0; index < this.beats.length; index++) {
5104
5230
  let beat = this.beats[index];
5105
5231
  beat.index = index;
5106
- this.chain(beat);
5232
+ this.chain(beat, sharedDataBag);
5107
5233
  if (beat.graceType === GraceType.None) {
5108
5234
  beat.graceGroup = currentGraceGroup;
5109
5235
  if (currentGraceGroup) {
@@ -5123,7 +5249,7 @@
5123
5249
  for (let i = 0; i < this.beats.length; i++) {
5124
5250
  let beat = this.beats[i];
5125
5251
  beat.index = i;
5126
- beat.finish(settings);
5252
+ beat.finish(settings, sharedDataBag);
5127
5253
  // if this beat is a non-grace but has grace notes
5128
5254
  // we need to first steal the duration from the right beat
5129
5255
  // and place the grace beats correctly
@@ -5209,7 +5335,18 @@
5209
5335
  }
5210
5336
  Voice$1._globalBarId = 0;
5211
5337
 
5338
+ /**
5339
+ * @target web
5340
+ */
5212
5341
  class TypeConversions {
5342
+ static float64ToBytes(v) {
5343
+ TypeConversions._dataView.setFloat64(0, v, true);
5344
+ return this._conversionByteArray;
5345
+ }
5346
+ static bytesToFloat64(bytes) {
5347
+ TypeConversions._conversionByteArray.set(bytes, 0);
5348
+ throw TypeConversions._dataView.getFloat64(0, true);
5349
+ }
5213
5350
  static uint16ToInt16(v) {
5214
5351
  TypeConversions._dataView.setUint16(0, v, true);
5215
5352
  return TypeConversions._dataView.getInt16(0, true);
@@ -5236,6 +5373,7 @@
5236
5373
  }
5237
5374
  }
5238
5375
  TypeConversions._conversionBuffer = new ArrayBuffer(8);
5376
+ TypeConversions._conversionByteArray = new Uint8Array(TypeConversions._conversionBuffer);
5239
5377
  TypeConversions._dataView = new DataView(TypeConversions._conversionBuffer);
5240
5378
 
5241
5379
  class IOHelper {
@@ -5374,30 +5512,29 @@
5374
5512
  return decoder.encode(str);
5375
5513
  }
5376
5514
  static writeInt32BE(o, v) {
5377
- o.writeByte((v >> 24) & 0xFF);
5378
- o.writeByte((v >> 16) & 0xFF);
5379
- o.writeByte((v >> 8) & 0xFF);
5380
- o.writeByte((v >> 0) & 0xFF);
5515
+ o.writeByte((v >> 24) & 0xff);
5516
+ o.writeByte((v >> 16) & 0xff);
5517
+ o.writeByte((v >> 8) & 0xff);
5518
+ o.writeByte((v >> 0) & 0xff);
5381
5519
  }
5382
5520
  static writeInt32LE(o, v) {
5383
- o.writeByte((v >> 0) & 0xFF);
5384
- o.writeByte((v >> 8) & 0xFF);
5385
- o.writeByte((v >> 16) & 0xFF);
5386
- o.writeByte((v >> 24) & 0xFF);
5521
+ o.writeByte((v >> 0) & 0xff);
5522
+ o.writeByte((v >> 8) & 0xff);
5523
+ o.writeByte((v >> 16) & 0xff);
5524
+ o.writeByte((v >> 24) & 0xff);
5387
5525
  }
5388
5526
  static writeUInt16LE(o, v) {
5389
- o.writeByte((v >> 0) & 0xFF);
5390
- o.writeByte((v >> 8) & 0xFF);
5527
+ o.writeByte((v >> 0) & 0xff);
5528
+ o.writeByte((v >> 8) & 0xff);
5391
5529
  }
5392
5530
  static writeInt16LE(o, v) {
5393
- o.writeByte((v >> 0) & 0xFF);
5394
- o.writeByte((v >> 8) & 0xFF);
5531
+ o.writeByte((v >> 0) & 0xff);
5532
+ o.writeByte((v >> 8) & 0xff);
5395
5533
  }
5396
5534
  }
5397
5535
 
5398
5536
  class ByteBuffer {
5399
5537
  constructor() {
5400
- this._capacity = 0;
5401
5538
  this.length = 0;
5402
5539
  this.position = 0;
5403
5540
  }
@@ -5413,14 +5550,12 @@
5413
5550
  static withCapacity(capacity) {
5414
5551
  let buffer = new ByteBuffer();
5415
5552
  buffer._buffer = new Uint8Array(capacity);
5416
- buffer._capacity = capacity;
5417
5553
  return buffer;
5418
5554
  }
5419
5555
  static fromBuffer(data) {
5420
5556
  let buffer = new ByteBuffer();
5421
5557
  buffer._buffer = data;
5422
5558
  buffer.length = data.length;
5423
- buffer._capacity = buffer.length;
5424
5559
  return buffer;
5425
5560
  }
5426
5561
  static fromString(contents) {
@@ -5433,18 +5568,6 @@
5433
5568
  skip(offset) {
5434
5569
  this.position += offset;
5435
5570
  }
5436
- setCapacity(value) {
5437
- if (value !== this._capacity) {
5438
- if (value > 0) {
5439
- let newBuffer = new Uint8Array(value);
5440
- if (this.length > 0) {
5441
- newBuffer.set(this._buffer.subarray(0, 0 + this.length), 0);
5442
- }
5443
- this._buffer = newBuffer;
5444
- }
5445
- this._capacity = value;
5446
- }
5447
- }
5448
5571
  readByte() {
5449
5572
  let n = this.length - this.position;
5450
5573
  if (n <= 0) {
@@ -5460,53 +5583,43 @@
5460
5583
  if (n <= 0) {
5461
5584
  return 0;
5462
5585
  }
5463
- if (n <= 8) {
5464
- let byteCount = n;
5465
- while (--byteCount >= 0) {
5466
- buffer[offset + byteCount] = this._buffer[this.position + byteCount];
5467
- }
5468
- }
5469
- else {
5470
- buffer.set(this._buffer.subarray(this.position, this.position + n), offset);
5471
- }
5586
+ buffer.set(this._buffer.subarray(this.position, this.position + n), offset);
5472
5587
  this.position += n;
5473
5588
  return n;
5474
5589
  }
5475
5590
  writeByte(value) {
5476
- let buffer = new Uint8Array(1);
5477
- buffer[0] = value;
5478
- this.write(buffer, 0, 1);
5591
+ let i = this.position + 1;
5592
+ this.ensureCapacity(i);
5593
+ this._buffer[this.position] = value & 0xFF;
5594
+ if (i > this.length) {
5595
+ this.length = i;
5596
+ }
5597
+ this.position = i;
5479
5598
  }
5480
5599
  write(buffer, offset, count) {
5481
5600
  let i = this.position + count;
5601
+ this.ensureCapacity(i);
5602
+ let count1 = Math.min(count, buffer.length - offset);
5603
+ this._buffer.set(buffer.subarray(offset, offset + count1), this.position);
5482
5604
  if (i > this.length) {
5483
- if (i > this._capacity) {
5484
- this.ensureCapacity(i);
5485
- }
5486
5605
  this.length = i;
5487
5606
  }
5488
- if (count <= 8 && buffer !== this._buffer) {
5489
- let byteCount = count;
5490
- while (--byteCount >= 0) {
5491
- this._buffer[this.position + byteCount] = buffer[offset + byteCount];
5492
- }
5493
- }
5494
- else {
5495
- let count1 = Math.min(count, buffer.length - offset);
5496
- this._buffer.set(buffer.subarray(offset, offset + count1), this.position);
5497
- }
5498
5607
  this.position = i;
5499
5608
  }
5500
5609
  ensureCapacity(value) {
5501
- if (value > this._capacity) {
5610
+ if (value > this._buffer.length) {
5502
5611
  let newCapacity = value;
5503
5612
  if (newCapacity < 256) {
5504
5613
  newCapacity = 256;
5505
5614
  }
5506
- if (newCapacity < this._capacity * 2) {
5507
- newCapacity = this._capacity * 2;
5615
+ if (newCapacity < this._buffer.length * 2) {
5616
+ newCapacity = this._buffer.length * 2;
5508
5617
  }
5509
- this.setCapacity(newCapacity);
5618
+ let newBuffer = new Uint8Array(newCapacity);
5619
+ if (this.length > 0) {
5620
+ newBuffer.set(this._buffer.subarray(0, 0 + this.length), 0);
5621
+ }
5622
+ this._buffer = newBuffer;
5510
5623
  }
5511
5624
  }
5512
5625
  readAll() {
@@ -6167,6 +6280,7 @@
6167
6280
  return anyMeta;
6168
6281
  }
6169
6282
  handleStaffMeta() {
6283
+ var _a, _b;
6170
6284
  let syData = this._syData.toLowerCase();
6171
6285
  switch (syData) {
6172
6286
  case 'capo':
@@ -6210,7 +6324,7 @@
6210
6324
  this.error('tuning', AlphaTexSymbols.Tuning, true);
6211
6325
  break;
6212
6326
  }
6213
- if (strings !== this._currentStaff.tuning.length && this._currentStaff.chords.size > 0) {
6327
+ if (strings !== this._currentStaff.tuning.length && ((_b = (_a = this._currentStaff.chords) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0) > 0) {
6214
6328
  this.errorMessage('Tuning must be defined before any chord');
6215
6329
  }
6216
6330
  return true;
@@ -6761,23 +6875,25 @@
6761
6875
  beat.addWhammyBarPoint(new BendPoint(offset, value));
6762
6876
  this._sy = this.newSy();
6763
6877
  }
6764
- while (beat.whammyBarPoints.length > 60) {
6765
- beat.removeWhammyBarPoint(beat.whammyBarPoints.length - 1);
6766
- }
6767
- // set positions
6768
- if (!exact) {
6769
- let count = beat.whammyBarPoints.length;
6770
- let step = (60 / count) | 0;
6771
- let i = 0;
6772
- while (i < count) {
6773
- beat.whammyBarPoints[i].offset = Math.min(60, i * step);
6774
- i++;
6878
+ if (beat.whammyBarPoints != null) {
6879
+ while (beat.whammyBarPoints.length > 60) {
6880
+ beat.removeWhammyBarPoint(beat.whammyBarPoints.length - 1);
6881
+ }
6882
+ // set positions
6883
+ if (!exact) {
6884
+ let count = beat.whammyBarPoints.length;
6885
+ let step = (60 / count) | 0;
6886
+ let i = 0;
6887
+ while (i < count) {
6888
+ beat.whammyBarPoints[i].offset = Math.min(60, i * step);
6889
+ i++;
6890
+ }
6891
+ }
6892
+ else {
6893
+ beat.whammyBarPoints.sort((a, b) => {
6894
+ return a.offset - b.offset;
6895
+ });
6775
6896
  }
6776
- }
6777
- else {
6778
- beat.whammyBarPoints.sort((a, b) => {
6779
- return a.offset - b.offset;
6780
- });
6781
6897
  }
6782
6898
  this._allowNegatives = false;
6783
6899
  if (this._sy !== AlphaTexSymbols.RParensis) {
@@ -6791,7 +6907,7 @@
6791
6907
  this._sy = this.newSy();
6792
6908
  let chordName = this._syData;
6793
6909
  let chordId = this.getChordId(this._currentStaff, chordName);
6794
- if (!this._currentStaff.chords.has(chordId)) {
6910
+ if (!this._currentStaff.hasChord(chordId)) {
6795
6911
  let chord = new Chord();
6796
6912
  chord.showDiagram = false;
6797
6913
  chord.name = chordName;
@@ -7034,22 +7150,25 @@
7034
7150
  note.addBendPoint(new BendPoint(offset, value));
7035
7151
  this._sy = this.newSy();
7036
7152
  }
7037
- while (note.bendPoints.length > 60) {
7038
- note.bendPoints.splice(note.bendPoints.length - 1, 1);
7039
- }
7040
- // set positions
7041
- if (exact) {
7042
- note.bendPoints.sort((a, b) => {
7043
- return a.offset - b.offset;
7044
- });
7045
- }
7046
- else {
7047
- let count = note.bendPoints.length;
7048
- let step = (60 / (count - 1)) | 0;
7049
- let i = 0;
7050
- while (i < count) {
7051
- note.bendPoints[i].offset = Math.min(60, i * step);
7052
- i++;
7153
+ const points = note.bendPoints;
7154
+ if (points != null) {
7155
+ while (points.length > 60) {
7156
+ points.splice(points.length - 1, 1);
7157
+ }
7158
+ // set positions
7159
+ if (exact) {
7160
+ points.sort((a, b) => {
7161
+ return a.offset - b.offset;
7162
+ });
7163
+ }
7164
+ else {
7165
+ let count = points.length;
7166
+ let step = (60 / (count - 1)) | 0;
7167
+ let i = 0;
7168
+ while (i < count) {
7169
+ points[i].offset = Math.min(60, i * step);
7170
+ i++;
7171
+ }
7053
7172
  }
7054
7173
  }
7055
7174
  if (this._sy !== AlphaTexSymbols.RParensis) {
@@ -8785,6 +8904,7 @@
8785
8904
  /**
8786
8905
  * Represents a fermata.
8787
8906
  * @json
8907
+ * @json_strict
8788
8908
  */
8789
8909
  class Fermata {
8790
8910
  constructor() {
@@ -12346,7 +12466,8 @@
12346
12466
  super(exports.AlphaTabErrorType.Format, 'Unexpected end of data within reader');
12347
12467
  Object.setPrototypeOf(this, EndOfReaderError.prototype);
12348
12468
  }
12349
- }
12469
+ }
12470
+
12350
12471
  /**
12351
12472
  * This utility public class allows bitwise reading of a stream
12352
12473
  */
@@ -13428,7 +13549,7 @@
13428
13549
  }
13429
13550
  else if (element.getAttribute('type') === 'stop' && this._tieStarts.length > 0 && !note.isTieDestination) {
13430
13551
  note.isTieDestination = true;
13431
- note.tieOriginNoteId = this._tieStarts[0].id;
13552
+ note.tieOrigin = this._tieStarts[0];
13432
13553
  this._tieStarts.splice(0, 1);
13433
13554
  this._tieStartIds.delete(note.id);
13434
13555
  }
@@ -13471,8 +13592,8 @@
13471
13592
  if (this._slurStarts.has(slurNumber)) {
13472
13593
  note.isSlurDestination = true;
13473
13594
  let slurStart = this._slurStarts.get(slurNumber);
13474
- slurStart.slurDestinationNoteId = note.id;
13475
- note.slurOriginNoteId = note.id;
13595
+ slurStart.slurDestination = note;
13596
+ note.slurOrigin = note;
13476
13597
  }
13477
13598
  break;
13478
13599
  }
@@ -17252,6 +17373,7 @@
17252
17373
  set masterVolume(value) {
17253
17374
  value = Math.max(value, SynthConstants.MinVolume);
17254
17375
  this._synthesizer.masterVolume = value;
17376
+ this.onAudioSettingsUpdate();
17255
17377
  }
17256
17378
  get metronomeVolume() {
17257
17379
  return this._metronomeVolume;
@@ -17260,6 +17382,7 @@
17260
17382
  value = Math.max(value, SynthConstants.MinVolume);
17261
17383
  this._metronomeVolume = value;
17262
17384
  this._synthesizer.metronomeVolume = value;
17385
+ this.onAudioSettingsUpdate();
17263
17386
  }
17264
17387
  get countInVolume() {
17265
17388
  return this._countInVolume;
@@ -17281,7 +17404,7 @@
17281
17404
  value = SynthHelper.clamp(value, SynthConstants.MinPlaybackSpeed, SynthConstants.MaxPlaybackSpeed);
17282
17405
  let oldSpeed = this._sequencer.playbackSpeed;
17283
17406
  this._sequencer.playbackSpeed = value;
17284
- this.updateTimePosition(this._timePosition * (oldSpeed / value), true);
17407
+ this.timePosition = this.timePosition * (oldSpeed / value);
17285
17408
  }
17286
17409
  get tickPosition() {
17287
17410
  return this._tickPosition;
@@ -17433,16 +17556,25 @@
17433
17556
  }
17434
17557
  setChannelMute(channel, mute) {
17435
17558
  this._synthesizer.channelSetMute(channel, mute);
17559
+ this.onAudioSettingsUpdate();
17436
17560
  }
17437
17561
  resetChannelStates() {
17438
17562
  this._synthesizer.resetChannelStates();
17439
17563
  }
17440
17564
  setChannelSolo(channel, solo) {
17441
17565
  this._synthesizer.channelSetSolo(channel, solo);
17566
+ this.onAudioSettingsUpdate();
17442
17567
  }
17443
17568
  setChannelVolume(channel, volume) {
17444
17569
  volume = Math.max(volume, SynthConstants.MinVolume);
17445
17570
  this._synthesizer.channelSetMixVolume(channel, volume);
17571
+ this.onAudioSettingsUpdate();
17572
+ }
17573
+ onAudioSettingsUpdate() {
17574
+ // seeking to the currently known position, will ensure we
17575
+ // clear all audio buffers and re-generate the audio
17576
+ // which was not actually played yet.
17577
+ this.timePosition = this.timePosition;
17446
17578
  }
17447
17579
  onSamplesPlayed(sampleCount) {
17448
17580
  let playedMillis = (sampleCount / this._synthesizer.outSampleRate) * 1000;
@@ -17817,8 +17949,7 @@
17817
17949
  }
17818
17950
  else if (parts.length >= 1) {
17819
17951
  this.size = parts[0];
17820
- if (this._currentToken &&
17821
- this._currentToken.text.indexOf('/') === 0) {
17952
+ if (this._currentToken && this._currentToken.text.indexOf('/') === 0) {
17822
17953
  // size / line-height (with spaces befor and after slash)
17823
17954
  if (this._currentToken.text === '/') {
17824
17955
  this.nextToken();
@@ -18484,20 +18615,20 @@
18484
18615
  }
18485
18616
  const o = new Map();
18486
18617
  /*@target web*/
18487
- o.set("scriptFile", obj.scriptFile);
18618
+ o.set("scriptfile", obj.scriptFile);
18488
18619
  /*@target web*/
18489
- o.set("fontDirectory", obj.fontDirectory);
18620
+ o.set("fontdirectory", obj.fontDirectory);
18490
18621
  /*@target web*/
18491
18622
  o.set("file", obj.file);
18492
18623
  /*@target web*/
18493
18624
  o.set("tex", obj.tex);
18494
18625
  /*@target web*/
18495
18626
  o.set("tracks", obj.tracks);
18496
- o.set("enableLazyLoading", obj.enableLazyLoading);
18627
+ o.set("enablelazyloading", obj.enableLazyLoading);
18497
18628
  o.set("engine", obj.engine);
18498
- o.set("logLevel", obj.logLevel);
18499
- o.set("useWorkers", obj.useWorkers);
18500
- o.set("includeNoteBounds", obj.includeNoteBounds);
18629
+ o.set("loglevel", obj.logLevel);
18630
+ o.set("useworkers", obj.useWorkers);
18631
+ o.set("includenotebounds", obj.includeNoteBounds);
18501
18632
  return o;
18502
18633
  }
18503
18634
  static setProperty(obj, property, v) {
@@ -18554,23 +18685,23 @@
18554
18685
  return null;
18555
18686
  }
18556
18687
  const o = new Map();
18557
- o.set("copyrightFont", Font.toJson(obj.copyrightFont));
18558
- o.set("titleFont", Font.toJson(obj.titleFont));
18559
- o.set("subTitleFont", Font.toJson(obj.subTitleFont));
18560
- o.set("wordsFont", Font.toJson(obj.wordsFont));
18561
- o.set("effectFont", Font.toJson(obj.effectFont));
18562
- o.set("fretboardNumberFont", Font.toJson(obj.fretboardNumberFont));
18563
- o.set("tablatureFont", Font.toJson(obj.tablatureFont));
18564
- o.set("graceFont", Font.toJson(obj.graceFont));
18565
- o.set("staffLineColor", Color.toJson(obj.staffLineColor));
18566
- o.set("barSeparatorColor", Color.toJson(obj.barSeparatorColor));
18567
- o.set("barNumberFont", Font.toJson(obj.barNumberFont));
18568
- o.set("barNumberColor", Color.toJson(obj.barNumberColor));
18569
- o.set("fingeringFont", Font.toJson(obj.fingeringFont));
18570
- o.set("markerFont", Font.toJson(obj.markerFont));
18571
- o.set("mainGlyphColor", Color.toJson(obj.mainGlyphColor));
18572
- o.set("secondaryGlyphColor", Color.toJson(obj.secondaryGlyphColor));
18573
- o.set("scoreInfoColor", Color.toJson(obj.scoreInfoColor));
18688
+ o.set("copyrightfont", Font.toJson(obj.copyrightFont));
18689
+ o.set("titlefont", Font.toJson(obj.titleFont));
18690
+ o.set("subtitlefont", Font.toJson(obj.subTitleFont));
18691
+ o.set("wordsfont", Font.toJson(obj.wordsFont));
18692
+ o.set("effectfont", Font.toJson(obj.effectFont));
18693
+ o.set("fretboardnumberfont", Font.toJson(obj.fretboardNumberFont));
18694
+ o.set("tablaturefont", Font.toJson(obj.tablatureFont));
18695
+ o.set("gracefont", Font.toJson(obj.graceFont));
18696
+ o.set("stafflinecolor", Color.toJson(obj.staffLineColor));
18697
+ o.set("barseparatorcolor", Color.toJson(obj.barSeparatorColor));
18698
+ o.set("barnumberfont", Font.toJson(obj.barNumberFont));
18699
+ o.set("barnumbercolor", Color.toJson(obj.barNumberColor));
18700
+ o.set("fingeringfont", Font.toJson(obj.fingeringFont));
18701
+ o.set("markerfont", Font.toJson(obj.markerFont));
18702
+ o.set("mainglyphcolor", Color.toJson(obj.mainGlyphColor));
18703
+ o.set("secondaryglyphcolor", Color.toJson(obj.secondaryGlyphColor));
18704
+ o.set("scoreinfocolor", Color.toJson(obj.scoreInfoColor));
18574
18705
  return o;
18575
18706
  }
18576
18707
  static setProperty(obj, property, v) {
@@ -18644,13 +18775,13 @@
18644
18775
  }
18645
18776
  const o = new Map();
18646
18777
  o.set("scale", obj.scale);
18647
- o.set("stretchForce", obj.stretchForce);
18648
- o.set("layoutMode", obj.layoutMode);
18649
- o.set("staveProfile", obj.staveProfile);
18650
- o.set("barsPerRow", obj.barsPerRow);
18651
- o.set("startBar", obj.startBar);
18652
- o.set("barCount", obj.barCount);
18653
- o.set("barCountPerPartial", obj.barCountPerPartial);
18778
+ o.set("stretchforce", obj.stretchForce);
18779
+ o.set("layoutmode", obj.layoutMode);
18780
+ o.set("staveprofile", obj.staveProfile);
18781
+ o.set("barsperrow", obj.barsPerRow);
18782
+ o.set("startbar", obj.startBar);
18783
+ o.set("barcount", obj.barCount);
18784
+ o.set("barcountperpartial", obj.barCountPerPartial);
18654
18785
  o.set("resources", RenderingResourcesSerializer.toJson(obj.resources));
18655
18786
  o.set("padding", obj.padding);
18656
18787
  return o;
@@ -18714,8 +18845,8 @@
18714
18845
  return null;
18715
18846
  }
18716
18847
  const o = new Map();
18717
- o.set("notationMode", obj.notationMode);
18718
- o.set("fingeringMode", obj.fingeringMode);
18848
+ o.set("notationmode", obj.notationMode);
18849
+ o.set("fingeringmode", obj.fingeringMode);
18719
18850
  {
18720
18851
  const m = new Map();
18721
18852
  o.set("elements", m);
@@ -18723,14 +18854,14 @@
18723
18854
  m.set(k.toString(), v);
18724
18855
  }
18725
18856
  }
18726
- o.set("rhythmMode", obj.rhythmMode);
18727
- o.set("rhythmHeight", obj.rhythmHeight);
18728
- o.set("transpositionPitches", obj.transpositionPitches);
18729
- o.set("displayTranspositionPitches", obj.displayTranspositionPitches);
18730
- o.set("smallGraceTabNotes", obj.smallGraceTabNotes);
18731
- o.set("extendBendArrowsOnTiedNotes", obj.extendBendArrowsOnTiedNotes);
18732
- o.set("extendLineEffectsToBeatEnd", obj.extendLineEffectsToBeatEnd);
18733
- o.set("slurHeight", obj.slurHeight);
18857
+ o.set("rhythmmode", obj.rhythmMode);
18858
+ o.set("rhythmheight", obj.rhythmHeight);
18859
+ o.set("transpositionpitches", obj.transpositionPitches);
18860
+ o.set("displaytranspositionpitches", obj.displayTranspositionPitches);
18861
+ o.set("smallgracetabnotes", obj.smallGraceTabNotes);
18862
+ o.set("extendbendarrowsontiednotes", obj.extendBendArrowsOnTiedNotes);
18863
+ o.set("extendlineeffectstobeatend", obj.extendLineEffectsToBeatEnd);
18864
+ o.set("slurheight", obj.slurHeight);
18734
18865
  return o;
18735
18866
  }
18736
18867
  static setProperty(obj, property, v) {
@@ -18789,8 +18920,8 @@
18789
18920
  }
18790
18921
  const o = new Map();
18791
18922
  o.set("encoding", obj.encoding);
18792
- o.set("mergePartGroupsInMusicXml", obj.mergePartGroupsInMusicXml);
18793
- o.set("beatTextAsLyrics", obj.beatTextAsLyrics);
18923
+ o.set("mergepartgroupsinmusicxml", obj.mergePartGroupsInMusicXml);
18924
+ o.set("beattextaslyrics", obj.beatTextAsLyrics);
18794
18925
  return o;
18795
18926
  }
18796
18927
  static setProperty(obj, property, v) {
@@ -18821,14 +18952,14 @@
18821
18952
  return null;
18822
18953
  }
18823
18954
  const o = new Map();
18824
- o.set("noteWideLength", obj.noteWideLength);
18825
- o.set("noteWideAmplitude", obj.noteWideAmplitude);
18826
- o.set("noteSlightLength", obj.noteSlightLength);
18827
- o.set("noteSlightAmplitude", obj.noteSlightAmplitude);
18828
- o.set("beatWideLength", obj.beatWideLength);
18829
- o.set("beatWideAmplitude", obj.beatWideAmplitude);
18830
- o.set("beatSlightLength", obj.beatSlightLength);
18831
- o.set("beatSlightAmplitude", obj.beatSlightAmplitude);
18955
+ o.set("notewidelength", obj.noteWideLength);
18956
+ o.set("notewideamplitude", obj.noteWideAmplitude);
18957
+ o.set("noteslightlength", obj.noteSlightLength);
18958
+ o.set("noteslightamplitude", obj.noteSlightAmplitude);
18959
+ o.set("beatwidelength", obj.beatWideLength);
18960
+ o.set("beatwideamplitude", obj.beatWideAmplitude);
18961
+ o.set("beatslightlength", obj.beatSlightLength);
18962
+ o.set("beatslightamplitude", obj.beatSlightAmplitude);
18832
18963
  return o;
18833
18964
  }
18834
18965
  static setProperty(obj, property, v) {
@@ -18874,9 +19005,9 @@
18874
19005
  return null;
18875
19006
  }
18876
19007
  const o = new Map();
18877
- o.set("simpleSlidePitchOffset", obj.simpleSlidePitchOffset);
18878
- o.set("simpleSlideDurationRatio", obj.simpleSlideDurationRatio);
18879
- o.set("shiftSlideDurationRatio", obj.shiftSlideDurationRatio);
19008
+ o.set("simpleslidepitchoffset", obj.simpleSlidePitchOffset);
19009
+ o.set("simpleslidedurationratio", obj.simpleSlideDurationRatio);
19010
+ o.set("shiftslidedurationratio", obj.shiftSlideDurationRatio);
18880
19011
  return o;
18881
19012
  }
18882
19013
  static setProperty(obj, property, v) {
@@ -18907,24 +19038,24 @@
18907
19038
  return null;
18908
19039
  }
18909
19040
  const o = new Map();
18910
- o.set("soundFont", obj.soundFont);
18911
- o.set("scrollElement", obj.scrollElement);
18912
- o.set("enablePlayer", obj.enablePlayer);
18913
- o.set("enableCursor", obj.enableCursor);
18914
- o.set("enableAnimatedBeatCursor", obj.enableAnimatedBeatCursor);
18915
- o.set("enableElementHighlighting", obj.enableElementHighlighting);
18916
- o.set("enableUserInteraction", obj.enableUserInteraction);
18917
- o.set("scrollOffsetX", obj.scrollOffsetX);
18918
- o.set("scrollOffsetY", obj.scrollOffsetY);
18919
- o.set("scrollMode", obj.scrollMode);
18920
- o.set("scrollSpeed", obj.scrollSpeed);
19041
+ o.set("soundfont", obj.soundFont);
19042
+ o.set("scrollelement", obj.scrollElement);
19043
+ o.set("enableplayer", obj.enablePlayer);
19044
+ o.set("enablecursor", obj.enableCursor);
19045
+ o.set("enableanimatedbeatcursor", obj.enableAnimatedBeatCursor);
19046
+ o.set("enableelementhighlighting", obj.enableElementHighlighting);
19047
+ o.set("enableuserinteraction", obj.enableUserInteraction);
19048
+ o.set("scrolloffsetx", obj.scrollOffsetX);
19049
+ o.set("scrolloffsety", obj.scrollOffsetY);
19050
+ o.set("scrollmode", obj.scrollMode);
19051
+ o.set("scrollspeed", obj.scrollSpeed);
18921
19052
  /*@target web*/
18922
- o.set("nativeBrowserSmoothScroll", obj.nativeBrowserSmoothScroll);
18923
- o.set("songBookBendDuration", obj.songBookBendDuration);
18924
- o.set("songBookDipDuration", obj.songBookDipDuration);
19053
+ o.set("nativebrowsersmoothscroll", obj.nativeBrowserSmoothScroll);
19054
+ o.set("songbookbendduration", obj.songBookBendDuration);
19055
+ o.set("songbookdipduration", obj.songBookDipDuration);
18925
19056
  o.set("vibrato", VibratoPlaybackSettingsSerializer.toJson(obj.vibrato));
18926
19057
  o.set("slide", SlidePlaybackSettingsSerializer.toJson(obj.slide));
18927
- o.set("playTripletFeel", obj.playTripletFeel);
19058
+ o.set("playtripletfeel", obj.playTripletFeel);
18928
19059
  return o;
18929
19060
  }
18930
19061
  static setProperty(obj, property, v) {
@@ -19186,7 +19317,7 @@
19186
19317
  if (!m) {
19187
19318
  return;
19188
19319
  }
19189
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19320
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19190
19321
  }
19191
19322
  static toJson(obj) {
19192
19323
  if (!obj) {
@@ -19215,17 +19346,17 @@
19215
19346
  if (!m) {
19216
19347
  return;
19217
19348
  }
19218
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19349
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19219
19350
  }
19220
19351
  static toJson(obj) {
19221
19352
  if (!obj) {
19222
19353
  return null;
19223
19354
  }
19224
19355
  const o = new Map();
19225
- o.set("isLinear", obj.isLinear);
19356
+ o.set("islinear", obj.isLinear);
19226
19357
  o.set("type", obj.type);
19227
19358
  o.set("value", obj.value);
19228
- o.set("ratioPosition", obj.ratioPosition);
19359
+ o.set("ratioposition", obj.ratioPosition);
19229
19360
  o.set("text", obj.text);
19230
19361
  return o;
19231
19362
  }
@@ -19256,7 +19387,7 @@
19256
19387
  if (!m) {
19257
19388
  return;
19258
19389
  }
19259
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19390
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19260
19391
  }
19261
19392
  static toJson(obj) {
19262
19393
  if (!obj) {
@@ -19285,26 +19416,26 @@
19285
19416
  if (!m) {
19286
19417
  return;
19287
19418
  }
19288
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19419
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19289
19420
  }
19290
19421
  static toJson(obj) {
19291
19422
  if (!obj) {
19292
19423
  return null;
19293
19424
  }
19294
19425
  const o = new Map();
19295
- o.set("alternateEndings", obj.alternateEndings);
19296
- o.set("keySignature", obj.keySignature);
19297
- o.set("keySignatureType", obj.keySignatureType);
19298
- o.set("isDoubleBar", obj.isDoubleBar);
19299
- o.set("isRepeatStart", obj.isRepeatStart);
19300
- o.set("repeatCount", obj.repeatCount);
19301
- o.set("timeSignatureNumerator", obj.timeSignatureNumerator);
19302
- o.set("timeSignatureDenominator", obj.timeSignatureDenominator);
19303
- o.set("timeSignatureCommon", obj.timeSignatureCommon);
19304
- o.set("tripletFeel", obj.tripletFeel);
19426
+ o.set("alternateendings", obj.alternateEndings);
19427
+ o.set("keysignature", obj.keySignature);
19428
+ o.set("keysignaturetype", obj.keySignatureType);
19429
+ o.set("isdoublebar", obj.isDoubleBar);
19430
+ o.set("isrepeatstart", obj.isRepeatStart);
19431
+ o.set("repeatcount", obj.repeatCount);
19432
+ o.set("timesignaturenumerator", obj.timeSignatureNumerator);
19433
+ o.set("timesignaturedenominator", obj.timeSignatureDenominator);
19434
+ o.set("timesignaturecommon", obj.timeSignatureCommon);
19435
+ o.set("tripletfeel", obj.tripletFeel);
19305
19436
  o.set("section", SectionSerializer.toJson(obj.section));
19306
- o.set("tempoAutomation", AutomationSerializer.toJson(obj.tempoAutomation));
19307
- {
19437
+ o.set("tempoautomation", AutomationSerializer.toJson(obj.tempoAutomation));
19438
+ if (obj.fermata !== null) {
19308
19439
  const m = new Map();
19309
19440
  o.set("fermata", m);
19310
19441
  for (const [k, v] of obj.fermata) {
@@ -19312,7 +19443,7 @@
19312
19443
  }
19313
19444
  }
19314
19445
  o.set("start", obj.start);
19315
- o.set("isAnacrusis", obj.isAnacrusis);
19446
+ o.set("isanacrusis", obj.isAnacrusis);
19316
19447
  return o;
19317
19448
  }
19318
19449
  static setProperty(obj, property, v) {
@@ -19352,7 +19483,7 @@
19352
19483
  JsonHelper.forEach(v, (v, k) => {
19353
19484
  const i = new Fermata();
19354
19485
  FermataSerializer.fromJson(i, v);
19355
- obj.fermata.set(parseInt(k), i);
19486
+ obj.addFermata(parseInt(k), i);
19356
19487
  });
19357
19488
  return true;
19358
19489
  case "start":
@@ -19391,7 +19522,7 @@
19391
19522
  if (!m) {
19392
19523
  return;
19393
19524
  }
19394
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19525
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19395
19526
  }
19396
19527
  static toJson(obj) {
19397
19528
  if (!obj) {
@@ -19420,53 +19551,51 @@
19420
19551
  if (!m) {
19421
19552
  return;
19422
19553
  }
19423
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19554
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19424
19555
  }
19425
19556
  static toJson(obj) {
19557
+ var _a;
19426
19558
  if (!obj) {
19427
19559
  return null;
19428
19560
  }
19429
19561
  const o = new Map();
19430
19562
  o.set("id", obj.id);
19431
19563
  o.set("accentuated", obj.accentuated);
19432
- o.set("bendType", obj.bendType);
19433
- o.set("bendStyle", obj.bendStyle);
19434
- o.set("isContinuedBend", obj.isContinuedBend);
19435
- o.set("bendPoints", obj.bendPoints.map(i => BendPointSerializer.toJson(i)));
19564
+ o.set("bendtype", obj.bendType);
19565
+ o.set("bendstyle", obj.bendStyle);
19566
+ o.set("iscontinuedbend", obj.isContinuedBend);
19567
+ if (obj.bendPoints !== null) {
19568
+ o.set("bendpoints", (_a = obj.bendPoints) === null || _a === void 0 ? void 0 : _a.map(i => BendPointSerializer.toJson(i)));
19569
+ }
19436
19570
  o.set("fret", obj.fret);
19437
19571
  o.set("string", obj.string);
19438
19572
  o.set("octave", obj.octave);
19439
19573
  o.set("tone", obj.tone);
19440
- o.set("percussionArticulation", obj.percussionArticulation);
19441
- o.set("isVisible", obj.isVisible);
19442
- o.set("isLeftHandTapped", obj.isLeftHandTapped);
19443
- o.set("isHammerPullOrigin", obj.isHammerPullOrigin);
19444
- o.set("hammerPullOriginNoteId", obj.hammerPullOriginNoteId);
19445
- o.set("hammerPullDestinationNoteId", obj.hammerPullDestinationNoteId);
19446
- o.set("isSlurDestination", obj.isSlurDestination);
19447
- o.set("slurOriginNoteId", obj.slurOriginNoteId);
19448
- o.set("slurDestinationNoteId", obj.slurDestinationNoteId);
19449
- o.set("harmonicType", obj.harmonicType);
19450
- o.set("harmonicValue", obj.harmonicValue);
19451
- o.set("isGhost", obj.isGhost);
19452
- o.set("isLetRing", obj.isLetRing);
19453
- o.set("isPalmMute", obj.isPalmMute);
19454
- o.set("isDead", obj.isDead);
19455
- o.set("isStaccato", obj.isStaccato);
19456
- o.set("slideInType", obj.slideInType);
19457
- o.set("slideOutType", obj.slideOutType);
19574
+ o.set("percussionarticulation", obj.percussionArticulation);
19575
+ o.set("isvisible", obj.isVisible);
19576
+ o.set("islefthandtapped", obj.isLeftHandTapped);
19577
+ o.set("ishammerpullorigin", obj.isHammerPullOrigin);
19578
+ o.set("isslurdestination", obj.isSlurDestination);
19579
+ o.set("harmonictype", obj.harmonicType);
19580
+ o.set("harmonicvalue", obj.harmonicValue);
19581
+ o.set("isghost", obj.isGhost);
19582
+ o.set("isletring", obj.isLetRing);
19583
+ o.set("ispalmmute", obj.isPalmMute);
19584
+ o.set("isdead", obj.isDead);
19585
+ o.set("isstaccato", obj.isStaccato);
19586
+ o.set("slideintype", obj.slideInType);
19587
+ o.set("slideouttype", obj.slideOutType);
19458
19588
  o.set("vibrato", obj.vibrato);
19459
- o.set("tieOriginNoteId", obj.tieOriginNoteId);
19460
- o.set("tieDestinationNoteId", obj.tieDestinationNoteId);
19461
- o.set("isTieDestination", obj.isTieDestination);
19462
- o.set("leftHandFinger", obj.leftHandFinger);
19463
- o.set("rightHandFinger", obj.rightHandFinger);
19464
- o.set("isFingering", obj.isFingering);
19465
- o.set("trillValue", obj.trillValue);
19466
- o.set("trillSpeed", obj.trillSpeed);
19467
- o.set("durationPercent", obj.durationPercent);
19468
- o.set("accidentalMode", obj.accidentalMode);
19589
+ o.set("istiedestination", obj.isTieDestination);
19590
+ o.set("lefthandfinger", obj.leftHandFinger);
19591
+ o.set("righthandfinger", obj.rightHandFinger);
19592
+ o.set("isfingering", obj.isFingering);
19593
+ o.set("trillvalue", obj.trillValue);
19594
+ o.set("trillspeed", obj.trillSpeed);
19595
+ o.set("durationpercent", obj.durationPercent);
19596
+ o.set("accidentalmode", obj.accidentalMode);
19469
19597
  o.set("dynamics", obj.dynamics);
19598
+ obj.toJson(o);
19470
19599
  return o;
19471
19600
  }
19472
19601
  static setProperty(obj, property, v) {
@@ -19487,11 +19616,13 @@
19487
19616
  obj.isContinuedBend = v;
19488
19617
  return true;
19489
19618
  case "bendpoints":
19490
- obj.bendPoints = [];
19491
- for (const o of v) {
19492
- const i = new BendPoint();
19493
- BendPointSerializer.fromJson(i, o);
19494
- obj.addBendPoint(i);
19619
+ if (v) {
19620
+ obj.bendPoints = [];
19621
+ for (const o of v) {
19622
+ const i = new BendPoint();
19623
+ BendPointSerializer.fromJson(i, o);
19624
+ obj.addBendPoint(i);
19625
+ }
19495
19626
  }
19496
19627
  return true;
19497
19628
  case "fret":
@@ -19518,21 +19649,9 @@
19518
19649
  case "ishammerpullorigin":
19519
19650
  obj.isHammerPullOrigin = v;
19520
19651
  return true;
19521
- case "hammerpulloriginnoteid":
19522
- obj.hammerPullOriginNoteId = v;
19523
- return true;
19524
- case "hammerpulldestinationnoteid":
19525
- obj.hammerPullDestinationNoteId = v;
19526
- return true;
19527
19652
  case "isslurdestination":
19528
19653
  obj.isSlurDestination = v;
19529
19654
  return true;
19530
- case "sluroriginnoteid":
19531
- obj.slurOriginNoteId = v;
19532
- return true;
19533
- case "slurdestinationnoteid":
19534
- obj.slurDestinationNoteId = v;
19535
- return true;
19536
19655
  case "harmonictype":
19537
19656
  obj.harmonicType = JsonHelper.parseEnum(v, HarmonicType);
19538
19657
  return true;
@@ -19563,12 +19682,6 @@
19563
19682
  case "vibrato":
19564
19683
  obj.vibrato = JsonHelper.parseEnum(v, VibratoType);
19565
19684
  return true;
19566
- case "tieoriginnoteid":
19567
- obj.tieOriginNoteId = v;
19568
- return true;
19569
- case "tiedestinationnoteid":
19570
- obj.tieDestinationNoteId = v;
19571
- return true;
19572
19685
  case "istiedestination":
19573
19686
  obj.isTieDestination = v;
19574
19687
  return true;
@@ -19597,7 +19710,7 @@
19597
19710
  obj.dynamics = JsonHelper.parseEnum(v, DynamicValue);
19598
19711
  return true;
19599
19712
  }
19600
- return false;
19713
+ return obj.setProperty(property, v);
19601
19714
  }
19602
19715
  }
19603
19716
 
@@ -19606,50 +19719,53 @@
19606
19719
  if (!m) {
19607
19720
  return;
19608
19721
  }
19609
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19722
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19610
19723
  }
19611
19724
  static toJson(obj) {
19725
+ var _a;
19612
19726
  if (!obj) {
19613
19727
  return null;
19614
19728
  }
19615
19729
  const o = new Map();
19616
19730
  o.set("id", obj.id);
19617
19731
  o.set("notes", obj.notes.map(i => NoteSerializer.toJson(i)));
19618
- o.set("isEmpty", obj.isEmpty);
19619
- o.set("whammyStyle", obj.whammyStyle);
19732
+ o.set("isempty", obj.isEmpty);
19733
+ o.set("whammystyle", obj.whammyStyle);
19620
19734
  o.set("ottava", obj.ottava);
19621
- o.set("isLegatoOrigin", obj.isLegatoOrigin);
19735
+ o.set("islegatoorigin", obj.isLegatoOrigin);
19622
19736
  o.set("duration", obj.duration);
19623
19737
  o.set("automations", obj.automations.map(i => AutomationSerializer.toJson(i)));
19624
19738
  o.set("dots", obj.dots);
19625
- o.set("fadeIn", obj.fadeIn);
19739
+ o.set("fadein", obj.fadeIn);
19626
19740
  o.set("lyrics", obj.lyrics);
19627
- o.set("hasRasgueado", obj.hasRasgueado);
19741
+ o.set("hasrasgueado", obj.hasRasgueado);
19628
19742
  o.set("pop", obj.pop);
19629
19743
  o.set("slap", obj.slap);
19630
19744
  o.set("tap", obj.tap);
19631
19745
  o.set("text", obj.text);
19632
- o.set("brushType", obj.brushType);
19633
- o.set("brushDuration", obj.brushDuration);
19634
- o.set("tupletDenominator", obj.tupletDenominator);
19635
- o.set("tupletNumerator", obj.tupletNumerator);
19636
- o.set("isContinuedWhammy", obj.isContinuedWhammy);
19637
- o.set("whammyBarType", obj.whammyBarType);
19638
- o.set("whammyBarPoints", obj.whammyBarPoints.map(i => BendPointSerializer.toJson(i)));
19746
+ o.set("brushtype", obj.brushType);
19747
+ o.set("brushduration", obj.brushDuration);
19748
+ o.set("tupletdenominator", obj.tupletDenominator);
19749
+ o.set("tupletnumerator", obj.tupletNumerator);
19750
+ o.set("iscontinuedwhammy", obj.isContinuedWhammy);
19751
+ o.set("whammybartype", obj.whammyBarType);
19752
+ if (obj.whammyBarPoints !== null) {
19753
+ o.set("whammybarpoints", (_a = obj.whammyBarPoints) === null || _a === void 0 ? void 0 : _a.map(i => BendPointSerializer.toJson(i)));
19754
+ }
19639
19755
  o.set("vibrato", obj.vibrato);
19640
- o.set("chordId", obj.chordId);
19641
- o.set("graceType", obj.graceType);
19642
- o.set("pickStroke", obj.pickStroke);
19643
- o.set("tremoloSpeed", obj.tremoloSpeed);
19756
+ o.set("chordid", obj.chordId);
19757
+ o.set("gracetype", obj.graceType);
19758
+ o.set("pickstroke", obj.pickStroke);
19759
+ o.set("tremolospeed", obj.tremoloSpeed);
19644
19760
  o.set("crescendo", obj.crescendo);
19645
- o.set("displayStart", obj.displayStart);
19646
- o.set("playbackStart", obj.playbackStart);
19647
- o.set("displayDuration", obj.displayDuration);
19648
- o.set("playbackDuration", obj.playbackDuration);
19761
+ o.set("displaystart", obj.displayStart);
19762
+ o.set("playbackstart", obj.playbackStart);
19763
+ o.set("displayduration", obj.displayDuration);
19764
+ o.set("playbackduration", obj.playbackDuration);
19649
19765
  o.set("dynamics", obj.dynamics);
19650
- o.set("invertBeamDirection", obj.invertBeamDirection);
19651
- o.set("preferredBeamDirection", obj.preferredBeamDirection);
19652
- o.set("beamingMode", obj.beamingMode);
19766
+ o.set("invertbeamdirection", obj.invertBeamDirection);
19767
+ o.set("preferredbeamdirection", obj.preferredBeamDirection);
19768
+ o.set("beamingmode", obj.beamingMode);
19653
19769
  return o;
19654
19770
  }
19655
19771
  static setProperty(obj, property, v) {
@@ -19731,11 +19847,13 @@
19731
19847
  obj.whammyBarType = JsonHelper.parseEnum(v, WhammyType);
19732
19848
  return true;
19733
19849
  case "whammybarpoints":
19734
- obj.whammyBarPoints = [];
19735
- for (const o of v) {
19736
- const i = new BendPoint();
19737
- BendPointSerializer.fromJson(i, o);
19738
- obj.addWhammyBarPoint(i);
19850
+ if (v) {
19851
+ obj.whammyBarPoints = [];
19852
+ for (const o of v) {
19853
+ const i = new BendPoint();
19854
+ BendPointSerializer.fromJson(i, o);
19855
+ obj.addWhammyBarPoint(i);
19856
+ }
19739
19857
  }
19740
19858
  return true;
19741
19859
  case "vibrato":
@@ -19790,7 +19908,7 @@
19790
19908
  if (!m) {
19791
19909
  return;
19792
19910
  }
19793
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19911
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19794
19912
  }
19795
19913
  static toJson(obj) {
19796
19914
  if (!obj) {
@@ -19799,7 +19917,7 @@
19799
19917
  const o = new Map();
19800
19918
  o.set("id", obj.id);
19801
19919
  o.set("beats", obj.beats.map(i => BeatSerializer.toJson(i)));
19802
- o.set("isEmpty", obj.isEmpty);
19920
+ o.set("isempty", obj.isEmpty);
19803
19921
  return o;
19804
19922
  }
19805
19923
  static setProperty(obj, property, v) {
@@ -19828,7 +19946,7 @@
19828
19946
  if (!m) {
19829
19947
  return;
19830
19948
  }
19831
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19949
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19832
19950
  }
19833
19951
  static toJson(obj) {
19834
19952
  if (!obj) {
@@ -19837,9 +19955,9 @@
19837
19955
  const o = new Map();
19838
19956
  o.set("id", obj.id);
19839
19957
  o.set("clef", obj.clef);
19840
- o.set("clefOttava", obj.clefOttava);
19958
+ o.set("clefottava", obj.clefOttava);
19841
19959
  o.set("voices", obj.voices.map(i => VoiceSerializer.toJson(i)));
19842
- o.set("simileMark", obj.simileMark);
19960
+ o.set("similemark", obj.simileMark);
19843
19961
  return o;
19844
19962
  }
19845
19963
  static setProperty(obj, property, v) {
@@ -19874,7 +19992,7 @@
19874
19992
  if (!m) {
19875
19993
  return;
19876
19994
  }
19877
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
19995
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19878
19996
  }
19879
19997
  static toJson(obj) {
19880
19998
  if (!obj) {
@@ -19882,12 +20000,12 @@
19882
20000
  }
19883
20001
  const o = new Map();
19884
20002
  o.set("name", obj.name);
19885
- o.set("firstFret", obj.firstFret);
20003
+ o.set("firstfret", obj.firstFret);
19886
20004
  o.set("strings", obj.strings);
19887
- o.set("barreFrets", obj.barreFrets);
19888
- o.set("showName", obj.showName);
19889
- o.set("showDiagram", obj.showDiagram);
19890
- o.set("showFingering", obj.showFingering);
20005
+ o.set("barrefrets", obj.barreFrets);
20006
+ o.set("showname", obj.showName);
20007
+ o.set("showdiagram", obj.showDiagram);
20008
+ o.set("showfingering", obj.showFingering);
19891
20009
  return o;
19892
20010
  }
19893
20011
  static setProperty(obj, property, v) {
@@ -19923,14 +20041,14 @@
19923
20041
  if (!m) {
19924
20042
  return;
19925
20043
  }
19926
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
20044
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19927
20045
  }
19928
20046
  static toJson(obj) {
19929
20047
  if (!obj) {
19930
20048
  return null;
19931
20049
  }
19932
20050
  const o = new Map();
19933
- o.set("isStandard", obj.isStandard);
20051
+ o.set("isstandard", obj.isStandard);
19934
20052
  o.set("name", obj.name);
19935
20053
  o.set("tunings", obj.tunings);
19936
20054
  return o;
@@ -19956,7 +20074,7 @@
19956
20074
  if (!m) {
19957
20075
  return;
19958
20076
  }
19959
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
20077
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
19960
20078
  }
19961
20079
  static toJson(obj) {
19962
20080
  if (!obj) {
@@ -19964,7 +20082,7 @@
19964
20082
  }
19965
20083
  const o = new Map();
19966
20084
  o.set("bars", obj.bars.map(i => BarSerializer.toJson(i)));
19967
- {
20085
+ if (obj.chords !== null) {
19968
20086
  const m = new Map();
19969
20087
  o.set("chords", m);
19970
20088
  for (const [k, v] of obj.chords) {
@@ -19972,13 +20090,13 @@
19972
20090
  }
19973
20091
  }
19974
20092
  o.set("capo", obj.capo);
19975
- o.set("transpositionPitch", obj.transpositionPitch);
19976
- o.set("displayTranspositionPitch", obj.displayTranspositionPitch);
19977
- o.set("stringTuning", TuningSerializer.toJson(obj.stringTuning));
19978
- o.set("showTablature", obj.showTablature);
19979
- o.set("showStandardNotation", obj.showStandardNotation);
19980
- o.set("isPercussion", obj.isPercussion);
19981
- o.set("standardNotationLineCount", obj.standardNotationLineCount);
20093
+ o.set("transpositionpitch", obj.transpositionPitch);
20094
+ o.set("displaytranspositionpitch", obj.displayTranspositionPitch);
20095
+ o.set("stringtuning", TuningSerializer.toJson(obj.stringTuning));
20096
+ o.set("showtablature", obj.showTablature);
20097
+ o.set("showstandardnotation", obj.showStandardNotation);
20098
+ o.set("ispercussion", obj.isPercussion);
20099
+ o.set("standardnotationlinecount", obj.standardNotationLineCount);
19982
20100
  return o;
19983
20101
  }
19984
20102
  static setProperty(obj, property, v) {
@@ -20034,7 +20152,7 @@
20034
20152
  if (!m) {
20035
20153
  return;
20036
20154
  }
20037
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
20155
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
20038
20156
  }
20039
20157
  static toJson(obj) {
20040
20158
  if (!obj) {
@@ -20045,10 +20163,10 @@
20045
20163
  o.set("balance", obj.balance);
20046
20164
  o.set("port", obj.port);
20047
20165
  o.set("program", obj.program);
20048
- o.set("primaryChannel", obj.primaryChannel);
20049
- o.set("secondaryChannel", obj.secondaryChannel);
20050
- o.set("isMute", obj.isMute);
20051
- o.set("isSolo", obj.isSolo);
20166
+ o.set("primarychannel", obj.primaryChannel);
20167
+ o.set("secondarychannel", obj.secondaryChannel);
20168
+ o.set("ismute", obj.isMute);
20169
+ o.set("issolo", obj.isSolo);
20052
20170
  return o;
20053
20171
  }
20054
20172
  static setProperty(obj, property, v) {
@@ -20087,21 +20205,21 @@
20087
20205
  if (!m) {
20088
20206
  return;
20089
20207
  }
20090
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
20208
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
20091
20209
  }
20092
20210
  static toJson(obj) {
20093
20211
  if (!obj) {
20094
20212
  return null;
20095
20213
  }
20096
20214
  const o = new Map();
20097
- o.set("elementType", obj.elementType);
20098
- o.set("staffLine", obj.staffLine);
20099
- o.set("noteHeadDefault", obj.noteHeadDefault);
20100
- o.set("noteHeadHalf", obj.noteHeadHalf);
20101
- o.set("noteHeadWhole", obj.noteHeadWhole);
20102
- o.set("techniqueSymbol", obj.techniqueSymbol);
20103
- o.set("techniqueSymbolPlacement", obj.techniqueSymbolPlacement);
20104
- o.set("outputMidiNumber", obj.outputMidiNumber);
20215
+ o.set("elementtype", obj.elementType);
20216
+ o.set("staffline", obj.staffLine);
20217
+ o.set("noteheaddefault", obj.noteHeadDefault);
20218
+ o.set("noteheadhalf", obj.noteHeadHalf);
20219
+ o.set("noteheadwhole", obj.noteHeadWhole);
20220
+ o.set("techniquesymbol", obj.techniqueSymbol);
20221
+ o.set("techniquesymbolplacement", obj.techniqueSymbolPlacement);
20222
+ o.set("outputmidinumber", obj.outputMidiNumber);
20105
20223
  return o;
20106
20224
  }
20107
20225
  static setProperty(obj, property, v) {
@@ -20140,7 +20258,7 @@
20140
20258
  if (!m) {
20141
20259
  return;
20142
20260
  }
20143
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
20261
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
20144
20262
  }
20145
20263
  static toJson(obj) {
20146
20264
  if (!obj) {
@@ -20148,11 +20266,11 @@
20148
20266
  }
20149
20267
  const o = new Map();
20150
20268
  o.set("staves", obj.staves.map(i => StaffSerializer.toJson(i)));
20151
- o.set("playbackInfo", PlaybackInformationSerializer.toJson(obj.playbackInfo));
20269
+ o.set("playbackinfo", PlaybackInformationSerializer.toJson(obj.playbackInfo));
20152
20270
  o.set("color", Color.toJson(obj.color));
20153
20271
  o.set("name", obj.name);
20154
- o.set("shortName", obj.shortName);
20155
- o.set("percussionArticulations", obj.percussionArticulations.map(i => InstrumentArticulationSerializer.toJson(i)));
20272
+ o.set("shortname", obj.shortName);
20273
+ o.set("percussionarticulations", obj.percussionArticulations.map(i => InstrumentArticulationSerializer.toJson(i)));
20156
20274
  return o;
20157
20275
  }
20158
20276
  static setProperty(obj, property, v) {
@@ -20196,14 +20314,14 @@
20196
20314
  if (!m) {
20197
20315
  return;
20198
20316
  }
20199
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
20317
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
20200
20318
  }
20201
20319
  static toJson(obj) {
20202
20320
  if (!obj) {
20203
20321
  return null;
20204
20322
  }
20205
20323
  const o = new Map();
20206
- o.set("hideDynamics", obj.hideDynamics);
20324
+ o.set("hidedynamics", obj.hideDynamics);
20207
20325
  return o;
20208
20326
  }
20209
20327
  static setProperty(obj, property, v) {
@@ -20221,7 +20339,7 @@
20221
20339
  if (!m) {
20222
20340
  return;
20223
20341
  }
20224
- JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k.toLowerCase(), v));
20342
+ JsonHelper.forEach(m, (v, k) => this.setProperty(obj, k, v));
20225
20343
  }
20226
20344
  static toJson(obj) {
20227
20345
  if (!obj) {
@@ -20234,13 +20352,13 @@
20234
20352
  o.set("instructions", obj.instructions);
20235
20353
  o.set("music", obj.music);
20236
20354
  o.set("notices", obj.notices);
20237
- o.set("subTitle", obj.subTitle);
20355
+ o.set("subtitle", obj.subTitle);
20238
20356
  o.set("title", obj.title);
20239
20357
  o.set("words", obj.words);
20240
20358
  o.set("tab", obj.tab);
20241
20359
  o.set("tempo", obj.tempo);
20242
- o.set("tempoLabel", obj.tempoLabel);
20243
- o.set("masterBars", obj.masterBars.map(i => MasterBarSerializer.toJson(i)));
20360
+ o.set("tempolabel", obj.tempoLabel);
20361
+ o.set("masterbars", obj.masterBars.map(i => MasterBarSerializer.toJson(i)));
20244
20362
  o.set("tracks", obj.tracks.map(i => TrackSerializer.toJson(i)));
20245
20363
  o.set("stylesheet", RenderStylesheetSerializer.toJson(obj.stylesheet));
20246
20364
  return o;
@@ -20851,6 +20969,18 @@
20851
20969
  */
20852
20970
  class RenderFinishedEventArgs {
20853
20971
  constructor() {
20972
+ /**
20973
+ * Gets or sets the unique id of this event args.
20974
+ */
20975
+ this.id = ModelUtils.newGuid();
20976
+ /**
20977
+ * Gets or sets the x position of the current rendering result.
20978
+ */
20979
+ this.x = 0;
20980
+ /**
20981
+ * Gets or sets the y position of the current rendering result.
20982
+ */
20983
+ this.y = 0;
20854
20984
  /**
20855
20985
  * Gets or sets the width of the current rendering result.
20856
20986
  */
@@ -21389,6 +21519,7 @@
21389
21519
  this.preRender = new EventEmitterOfT();
21390
21520
  this.renderFinished = new EventEmitterOfT();
21391
21521
  this.partialRenderFinished = new EventEmitterOfT();
21522
+ this.partialLayoutFinished = new EventEmitterOfT();
21392
21523
  this.postRenderFinished = new EventEmitter();
21393
21524
  this.error = new EventEmitterOfT();
21394
21525
  this.settings = settings;
@@ -21421,20 +21552,22 @@
21421
21552
  renderScore(score, trackIndexes) {
21422
21553
  try {
21423
21554
  this.score = score;
21424
- let tracks;
21425
- if (!trackIndexes) {
21426
- tracks = score.tracks.slice(0);
21427
- }
21428
- else {
21429
- tracks = [];
21430
- for (let track of trackIndexes) {
21431
- if (track >= 0 && track < score.tracks.length) {
21432
- tracks.push(score.tracks[track]);
21555
+ let tracks = null;
21556
+ if (score != null && trackIndexes != null) {
21557
+ if (!trackIndexes) {
21558
+ tracks = score.tracks.slice(0);
21559
+ }
21560
+ else {
21561
+ tracks = [];
21562
+ for (let track of trackIndexes) {
21563
+ if (track >= 0 && track < score.tracks.length) {
21564
+ tracks.push(score.tracks[track]);
21565
+ }
21433
21566
  }
21434
21567
  }
21435
- }
21436
- if (tracks.length === 0 && score.tracks.length > 0) {
21437
- tracks.push(score.tracks[0]);
21568
+ if (tracks.length === 0 && score.tracks.length > 0) {
21569
+ tracks.push(score.tracks[0]);
21570
+ }
21438
21571
  }
21439
21572
  this.tracks = tracks;
21440
21573
  this.render();
@@ -21460,27 +21593,49 @@
21460
21593
  updateSettings(settings) {
21461
21594
  this.settings = settings;
21462
21595
  }
21596
+ renderResult(resultId) {
21597
+ try {
21598
+ const layout = this.layout;
21599
+ if (layout) {
21600
+ Logger.debug('Rendering', 'Request render of lazy partial ' + resultId);
21601
+ layout.renderLazyPartial(resultId);
21602
+ }
21603
+ else {
21604
+ Logger.warning('Rendering', 'Request render of lazy partial ' + resultId + ' ignored, no layout exists');
21605
+ }
21606
+ }
21607
+ catch (e) {
21608
+ this.error.trigger(e);
21609
+ }
21610
+ }
21463
21611
  render() {
21464
21612
  if (this.width === 0) {
21465
21613
  Logger.warning('Rendering', 'AlphaTab skipped rendering because of width=0 (element invisible)', null);
21466
21614
  return;
21467
21615
  }
21468
21616
  this.boundsLookup = new BoundsLookup();
21469
- if (!this.tracks || this.tracks.length === 0) {
21470
- return;
21471
- }
21472
21617
  this.recreateCanvas();
21473
21618
  this.canvas.lineWidth = this.settings.display.scale;
21474
21619
  this.canvas.settings = this.settings;
21475
- Logger.debug('Rendering', 'Rendering ' + this.tracks.length + ' tracks');
21476
- for (let i = 0; i < this.tracks.length; i++) {
21477
- let track = this.tracks[i];
21478
- Logger.debug('Rendering', 'Track ' + i + ': ' + track.name);
21620
+ if (!this.tracks || this.tracks.length === 0 || !this.score) {
21621
+ Logger.debug('Rendering', 'Clearing rendered tracks because no score or tracks are set');
21622
+ this.preRender.trigger(false);
21623
+ this._renderedTracks = null;
21624
+ this.onRenderFinished();
21625
+ this.postRenderFinished.trigger();
21626
+ Logger.debug('Rendering', 'Clearing finished');
21627
+ }
21628
+ else {
21629
+ Logger.debug('Rendering', 'Rendering ' + this.tracks.length + ' tracks');
21630
+ for (let i = 0; i < this.tracks.length; i++) {
21631
+ let track = this.tracks[i];
21632
+ Logger.debug('Rendering', 'Track ' + i + ': ' + track.name);
21633
+ }
21634
+ this.preRender.trigger(false);
21635
+ this.recreateLayout();
21636
+ this.layoutAndRender();
21637
+ Logger.debug('Rendering', 'Rendering finished');
21479
21638
  }
21480
- this.preRender.trigger(false);
21481
- this.recreateLayout();
21482
- this.layoutAndRender();
21483
- Logger.debug('Rendering', 'Rendering finished');
21484
21639
  }
21485
21640
  resizeRender() {
21486
21641
  if (this.recreateLayout() || this.recreateCanvas() || this._renderedTracks !== this.tracks || !this.tracks) {
@@ -21493,7 +21648,6 @@
21493
21648
  this.preRender.trigger(true);
21494
21649
  this.canvas.settings = this.settings;
21495
21650
  this.layout.resize();
21496
- this.layout.renderAnnotation();
21497
21651
  this.onRenderFinished();
21498
21652
  this.postRenderFinished.trigger();
21499
21653
  }
@@ -21505,7 +21659,6 @@
21505
21659
  layoutAndRender() {
21506
21660
  Logger.debug('Rendering', 'Rendering at scale ' + this.settings.display.scale + ' with layout ' + this.layout.name, null);
21507
21661
  this.layout.layoutAndRender();
21508
- this.layout.renderAnnotation();
21509
21662
  this._renderedTracks = this.tracks;
21510
21663
  this.onRenderFinished();
21511
21664
  this.postRenderFinished.trigger();
@@ -21544,6 +21697,12 @@
21544
21697
  result: result
21545
21698
  });
21546
21699
  });
21700
+ this._renderer.partialLayoutFinished.on(result => {
21701
+ this._main.postMessage({
21702
+ cmd: 'alphaTab.partialLayoutFinished',
21703
+ result: result
21704
+ });
21705
+ });
21547
21706
  this._renderer.renderFinished.on(result => {
21548
21707
  this._main.postMessage({
21549
21708
  cmd: 'alphaTab.renderFinished',
@@ -21571,12 +21730,15 @@
21571
21730
  case 'alphaTab.resizeRender':
21572
21731
  this._renderer.resizeRender();
21573
21732
  break;
21733
+ case 'alphaTab.renderResult':
21734
+ this._renderer.renderResult(data.resultId);
21735
+ break;
21574
21736
  case 'alphaTab.setWidth':
21575
21737
  this._renderer.width = data.width;
21576
21738
  break;
21577
21739
  case 'alphaTab.renderScore':
21578
21740
  this.updateFontSizes(data.fontSizes);
21579
- let score = JsonConverter.jsObjectToScore(data.score, this._renderer.settings);
21741
+ let score = data.score == null ? null : JsonConverter.jsObjectToScore(data.score, this._renderer.settings);
21580
21742
  this.renderMultiple(score, data.trackIndexes);
21581
21743
  break;
21582
21744
  case 'alphaTab.updateSettings':
@@ -23940,7 +24102,8 @@
23940
24102
  this.renderer.preRender.on(_ => {
23941
24103
  this._startTime = Date.now();
23942
24104
  });
23943
- this.renderer.partialRenderFinished.on(this.appendRenderResult.bind(this));
24105
+ this.renderer.partialLayoutFinished.on(this.appendRenderResult.bind(this));
24106
+ this.renderer.partialRenderFinished.on(this.updateRenderResult.bind(this));
23944
24107
  this.renderer.renderFinished.on(r => {
23945
24108
  this.appendRenderResult(r);
23946
24109
  this.appendRenderResult(null); // marks last element
@@ -24102,8 +24265,11 @@
24102
24265
  this._cursorWrapper.height = result.totalHeight;
24103
24266
  }
24104
24267
  }
24105
- if (!result || result.renderResult) {
24106
- this.uiFacade.beginAppendRenderResults(result);
24268
+ this.uiFacade.beginAppendRenderResults(result);
24269
+ }
24270
+ updateRenderResult(result) {
24271
+ if (result && result.renderResult) {
24272
+ this.uiFacade.beginUpdateRenderResults(result);
24107
24273
  }
24108
24274
  }
24109
24275
  /**
@@ -25959,6 +26125,7 @@
25959
26125
  this.boundsLookup = null;
25960
26126
  this.preRender = new EventEmitterOfT();
25961
26127
  this.partialRenderFinished = new EventEmitterOfT();
26128
+ this.partialLayoutFinished = new EventEmitterOfT();
25962
26129
  this.renderFinished = new EventEmitterOfT();
25963
26130
  this.postRenderFinished = new EventEmitter();
25964
26131
  this.error = new EventEmitterOfT();
@@ -26011,6 +26178,12 @@
26011
26178
  cmd: 'alphaTab.resizeRender'
26012
26179
  });
26013
26180
  }
26181
+ renderResult(resultId) {
26182
+ this._worker.postMessage({
26183
+ cmd: 'alphaTab.renderResult',
26184
+ resultId: resultId
26185
+ });
26186
+ }
26014
26187
  get width() {
26015
26188
  return this._width;
26016
26189
  }
@@ -26031,6 +26204,9 @@
26031
26204
  case 'alphaTab.partialRenderFinished':
26032
26205
  this.partialRenderFinished.trigger(data.result);
26033
26206
  break;
26207
+ case 'alphaTab.partialLayoutFinished':
26208
+ this.partialLayoutFinished.trigger(data.result);
26209
+ break;
26034
26210
  case 'alphaTab.renderFinished':
26035
26211
  this.renderFinished.trigger(data.result);
26036
26212
  break;
@@ -26044,7 +26220,7 @@
26044
26220
  }
26045
26221
  }
26046
26222
  renderScore(score, trackIndexes) {
26047
- let jsObject = JsonConverter.scoreToJsObject(score);
26223
+ let jsObject = score == null ? null : JsonConverter.scoreToJsObject(score);
26048
26224
  this._worker.postMessage({
26049
26225
  cmd: 'alphaTab.renderScore',
26050
26226
  score: jsObject,
@@ -26244,6 +26420,16 @@
26244
26420
  }
26245
26421
  }
26246
26422
 
26423
+ /**
26424
+ * @target web
26425
+ */
26426
+ var ResultState;
26427
+ (function (ResultState) {
26428
+ ResultState[ResultState["LayoutDone"] = 0] = "LayoutDone";
26429
+ ResultState[ResultState["RenderRequested"] = 1] = "RenderRequested";
26430
+ ResultState[ResultState["RenderDone"] = 2] = "RenderDone";
26431
+ ResultState[ResultState["Detached"] = 3] = "Detached";
26432
+ })(ResultState || (ResultState = {}));
26247
26433
  /**
26248
26434
  * @target web
26249
26435
  */
@@ -26255,12 +26441,12 @@
26255
26441
  this._totalResultCount = 0;
26256
26442
  this._initialTrackIndexes = null;
26257
26443
  this._barToElementLookup = new Map();
26444
+ this._resultIdToElementLookup = new Map();
26258
26445
  this.rootContainerBecameVisible = new EventEmitter();
26259
26446
  this.canRenderChanged = new EventEmitter();
26260
26447
  this._highlightedElements = [];
26261
26448
  this._scrollContainer = null;
26262
- if (Environment.webPlatform !== WebPlatform.Browser &&
26263
- Environment.webPlatform !== WebPlatform.BrowserModule) {
26449
+ if (Environment.webPlatform !== WebPlatform.Browser && Environment.webPlatform !== WebPlatform.BrowserModule) {
26264
26450
  throw new AlphaTabError(exports.AlphaTabErrorType.General, 'Usage of AlphaTabApi is only possible in browser environments. For usage in node use the Low Level APIs');
26265
26451
  }
26266
26452
  rootElement.classList.add('alphaTab');
@@ -26303,15 +26489,34 @@
26303
26489
  }
26304
26490
  onElementVisibilityChanged(entries) {
26305
26491
  for (const e of entries) {
26306
- if (e.isIntersecting) {
26307
- const htmlElement = e.target;
26308
- if (htmlElement === this.rootContainer.element) {
26492
+ const htmlElement = e.target;
26493
+ if (htmlElement === this.rootContainer.element) {
26494
+ if (e.isIntersecting) {
26309
26495
  this.rootContainerBecameVisible.trigger();
26310
26496
  this._intersectionObserver.unobserve(this.rootContainer.element);
26311
26497
  }
26312
- else if ('svg' in htmlElement.dataset) {
26313
- this.replacePlaceholder(htmlElement, htmlElement.dataset['svg']);
26314
- this._intersectionObserver.unobserve(htmlElement);
26498
+ }
26499
+ else if ('layoutResultId' in htmlElement && this._api.settings.core.enableLazyLoading) {
26500
+ const placeholder = htmlElement;
26501
+ if (e.isIntersecting) {
26502
+ // missing result or result not matching layout -> request render
26503
+ if (placeholder.renderedResultId !== placeholder.layoutResultId) {
26504
+ if (this._resultIdToElementLookup.has(placeholder.layoutResultId)) {
26505
+ this._api.renderer.renderResult(placeholder.layoutResultId);
26506
+ }
26507
+ else {
26508
+ htmlElement.replaceChildren();
26509
+ }
26510
+ }
26511
+ // detached and became visible
26512
+ else if (placeholder.resultState === ResultState.Detached) {
26513
+ htmlElement.replaceChildren(...placeholder.renderedResult);
26514
+ placeholder.resultState = ResultState.RenderDone;
26515
+ }
26516
+ }
26517
+ else if (placeholder.resultState === ResultState.RenderDone) {
26518
+ placeholder.resultState = ResultState.Detached;
26519
+ placeholder.replaceChildren();
26315
26520
  }
26316
26521
  }
26317
26522
  }
@@ -26440,6 +26645,7 @@
26440
26645
  initialRender() {
26441
26646
  this._api.renderer.preRender.on((_) => {
26442
26647
  this._totalResultCount = 0;
26648
+ this._resultIdToElementLookup.clear();
26443
26649
  this._barToElementLookup.clear();
26444
26650
  });
26445
26651
  const initialRender = () => {
@@ -26562,57 +26768,68 @@
26562
26768
  }
26563
26769
  return dataAttributes;
26564
26770
  }
26771
+ beginUpdateRenderResults(renderResult) {
26772
+ if (!this._resultIdToElementLookup.has(renderResult.id)) {
26773
+ return;
26774
+ }
26775
+ const placeholder = this._resultIdToElementLookup.get(renderResult.id);
26776
+ const body = renderResult.renderResult;
26777
+ if (typeof body === 'string') {
26778
+ placeholder.innerHTML = body;
26779
+ }
26780
+ else if ('nodeType' in body) {
26781
+ placeholder.replaceChildren(body);
26782
+ }
26783
+ placeholder.resultState = ResultState.RenderDone;
26784
+ placeholder.renderedResultId = renderResult.id;
26785
+ placeholder.renderedResult = Array.from(placeholder.children);
26786
+ }
26565
26787
  beginAppendRenderResults(renderResult) {
26566
- let canvasElement = this._api.canvasElement.element;
26788
+ const canvasElement = this._api.canvasElement.element;
26567
26789
  // null result indicates that the rendering finished
26568
26790
  if (!renderResult) {
26569
26791
  // so we remove elements that might be from a previous render session
26570
26792
  while (canvasElement.childElementCount > this._totalResultCount) {
26793
+ if (this._api.settings.core.enableLazyLoading) {
26794
+ this._intersectionObserver.unobserve(canvasElement.lastChild);
26795
+ }
26571
26796
  canvasElement.removeChild(canvasElement.lastChild);
26572
26797
  }
26573
26798
  }
26574
26799
  else {
26575
- let body = renderResult.renderResult;
26576
- if (typeof body === 'string') {
26577
- let placeholder;
26578
- if (this._totalResultCount < canvasElement.childElementCount) {
26579
- placeholder = canvasElement.childNodes.item(this._totalResultCount);
26580
- }
26581
- else {
26582
- placeholder = document.createElement('div');
26583
- canvasElement.appendChild(placeholder);
26584
- }
26585
- placeholder.style.width = renderResult.width + 'px';
26586
- placeholder.style.height = renderResult.height + 'px';
26587
- placeholder.style.display = 'inline-block';
26588
- if (!this._api.settings.core.enableLazyLoading) {
26589
- this.replacePlaceholder(placeholder, body);
26590
- }
26591
- else {
26592
- placeholder.dataset['svg'] = body;
26593
- this._intersectionObserver.observe(placeholder);
26594
- }
26595
- // remember which bar is contained in which node for faster lookup
26596
- // on highlight/unhighlight
26597
- for (let i = renderResult.firstMasterBarIndex; i <= renderResult.lastMasterBarIndex; i++) {
26598
- this._barToElementLookup.set(i, placeholder);
26599
- }
26800
+ let placeholder;
26801
+ if (this._totalResultCount < canvasElement.childElementCount) {
26802
+ placeholder = canvasElement.childNodes.item(this._totalResultCount);
26600
26803
  }
26601
26804
  else {
26602
- if (this._totalResultCount < canvasElement.childElementCount) {
26603
- canvasElement.replaceChild(renderResult.renderResult, canvasElement.childNodes.item(this._totalResultCount));
26604
- }
26605
- else {
26606
- canvasElement.appendChild(renderResult.renderResult);
26607
- }
26805
+ placeholder = document.createElement('div');
26806
+ canvasElement.appendChild(placeholder);
26807
+ }
26808
+ placeholder.style.zIndex = '1';
26809
+ placeholder.style.position = 'absolute';
26810
+ placeholder.style.left = renderResult.x + 'px';
26811
+ placeholder.style.top = renderResult.y + 'px';
26812
+ placeholder.style.width = renderResult.width + 'px';
26813
+ placeholder.style.height = renderResult.height + 'px';
26814
+ placeholder.style.display = 'inline-block';
26815
+ placeholder.layoutResultId = renderResult.id;
26816
+ placeholder.resultState = ResultState.LayoutDone;
26817
+ delete placeholder.renderedResultId;
26818
+ delete placeholder.renderedResult;
26819
+ this._resultIdToElementLookup.set(renderResult.id, placeholder);
26820
+ // remember which bar is contained in which node for faster lookup
26821
+ // on highlight/unhighlight
26822
+ for (let i = renderResult.firstMasterBarIndex; i <= renderResult.lastMasterBarIndex; i++) {
26823
+ this._barToElementLookup.set(i, placeholder);
26824
+ }
26825
+ if (this._api.settings.core.enableLazyLoading) {
26826
+ // re-observe to fire event
26827
+ this._intersectionObserver.unobserve(placeholder);
26828
+ this._intersectionObserver.observe(placeholder);
26608
26829
  }
26609
26830
  this._totalResultCount++;
26610
26831
  }
26611
26832
  }
26612
- replacePlaceholder(placeholder, body) {
26613
- placeholder.innerHTML = body;
26614
- delete placeholder.dataset['svg'];
26615
- }
26616
26833
  /**
26617
26834
  * This method creates the player. It detects browser compatibility and
26618
26835
  * initializes a alphaSynth version for the client.
@@ -28840,7 +29057,7 @@
28840
29057
  this.getVoiceContainer(g.beat.voice).addGlyph(g);
28841
29058
  }
28842
29059
  getVoiceContainer(voice) {
28843
- return this._voiceContainers.get(voice.index);
29060
+ return this._voiceContainers.has(voice.index) ? this._voiceContainers.get(voice.index) : undefined;
28844
29061
  }
28845
29062
  getBeatContainer(beat) {
28846
29063
  var _a, _b;
@@ -32076,6 +32293,12 @@
32076
32293
  }
32077
32294
  }
32078
32295
 
32296
+ class LazyPartial {
32297
+ constructor(args, renderCallback) {
32298
+ this.args = args;
32299
+ this.renderCallback = renderCallback;
32300
+ }
32301
+ }
32079
32302
  /**
32080
32303
  * This is the base public class for creating new layouting engines for the score renderer.
32081
32304
  */
@@ -32087,11 +32310,17 @@
32087
32310
  this.scoreInfoGlyphs = new Map();
32088
32311
  this.chordDiagrams = null;
32089
32312
  this.tuningGlyph = null;
32313
+ this._lazyPartials = new Map();
32090
32314
  this.firstBarIndex = 0;
32091
32315
  this.lastBarIndex = 0;
32092
32316
  this.renderer = renderer;
32093
32317
  }
32318
+ resize() {
32319
+ this._lazyPartials.clear();
32320
+ this.doResize();
32321
+ }
32094
32322
  layoutAndRender() {
32323
+ this._lazyPartials.clear();
32095
32324
  let score = this.renderer.score;
32096
32325
  let startIndex = this.renderer.settings.display.startBar;
32097
32326
  startIndex--; // map to array index
@@ -32107,6 +32336,28 @@
32107
32336
  this.createScoreInfoGlyphs();
32108
32337
  this.doLayoutAndRender();
32109
32338
  }
32339
+ registerPartial(args, callback) {
32340
+ this.renderer.partialLayoutFinished.trigger(args);
32341
+ if (!this.renderer.settings.core.enableLazyLoading) {
32342
+ this.internalRenderLazyPartial(args, callback);
32343
+ }
32344
+ else {
32345
+ this._lazyPartials.set(args.id, new LazyPartial(args, callback));
32346
+ }
32347
+ }
32348
+ internalRenderLazyPartial(args, callback) {
32349
+ const canvas = this.renderer.canvas;
32350
+ canvas.beginRender(args.width, args.height);
32351
+ callback(canvas);
32352
+ args.renderResult = canvas.endRender();
32353
+ this.renderer.partialRenderFinished.trigger(args);
32354
+ }
32355
+ renderLazyPartial(resultId) {
32356
+ if (this._lazyPartials.has(resultId)) {
32357
+ const lazyPartial = this._lazyPartials.get(resultId);
32358
+ this.internalRenderLazyPartial(lazyPartial.args, lazyPartial.renderCallback);
32359
+ }
32360
+ }
32110
32361
  createScoreInfoGlyphs() {
32111
32362
  Logger.debug('ScoreLayout', 'Creating score info glyphs');
32112
32363
  let notation = this.renderer.settings.notation;
@@ -32165,11 +32416,14 @@
32165
32416
  let chords = new Map();
32166
32417
  for (let track of this.renderer.tracks) {
32167
32418
  for (let staff of track.staves) {
32168
- for (const [chordId, chord] of staff.chords) {
32169
- if (!chords.has(chordId)) {
32170
- if (chord.showDiagram) {
32171
- chords.set(chordId, chord);
32172
- this.chordDiagrams.addChord(chord);
32419
+ const sc = staff.chords;
32420
+ if (sc) {
32421
+ for (const [chordId, chord] of sc) {
32422
+ if (!chords.has(chordId)) {
32423
+ if (chord.showDiagram) {
32424
+ chords.set(chordId, chord);
32425
+ this.chordDiagrams.addChord(chord);
32426
+ }
32173
32427
  }
32174
32428
  }
32175
32429
  }
@@ -32243,30 +32497,33 @@
32243
32497
  }
32244
32498
  return null;
32245
32499
  }
32246
- renderAnnotation() {
32500
+ layoutAndRenderAnnotation(y) {
32247
32501
  // attention, you are not allowed to remove change this notice within any version of this library without permission!
32248
32502
  let msg = 'rendered by alphaTab';
32249
- let canvas = this.renderer.canvas;
32250
32503
  let resources = this.renderer.settings.display.resources;
32251
32504
  let size = 12 * this.renderer.settings.display.scale;
32252
- let height = size * 2;
32253
- this.height += height;
32254
- let x = this.width / 2;
32255
- canvas.beginRender(this.width, height);
32256
- canvas.color = resources.mainGlyphColor;
32257
- canvas.font = new Font(resources.copyrightFont.family, size, FontStyle.Plain, FontWeight.Bold);
32258
- canvas.textAlign = TextAlign.Center;
32259
- canvas.fillText(msg, x, size);
32260
- let result = canvas.endRender();
32261
- let e = new RenderFinishedEventArgs();
32262
- e.width = this.width;
32505
+ let height = Math.floor(size * 2);
32506
+ const e = new RenderFinishedEventArgs();
32507
+ const font = new Font(resources.copyrightFont.family, size, FontStyle.Plain, FontWeight.Bold);
32508
+ this.renderer.canvas.font = font;
32509
+ const centered = Environment.getLayoutEngineFactory(this.renderer.settings.display.layoutMode).vertical;
32510
+ e.width = this.renderer.canvas.measureText(msg);
32263
32511
  e.height = height;
32264
- e.renderResult = result;
32512
+ e.x = centered
32513
+ ? (this.width - e.width) / 2
32514
+ : this.firstBarX;
32515
+ e.y = y;
32265
32516
  e.totalWidth = this.width;
32266
32517
  e.totalHeight = this.height;
32267
32518
  e.firstMasterBarIndex = -1;
32268
32519
  e.lastMasterBarIndex = -1;
32269
- this.renderer.partialRenderFinished.trigger(e);
32520
+ this.registerPartial(e, canvas => {
32521
+ canvas.color = resources.mainGlyphColor;
32522
+ canvas.font = font;
32523
+ canvas.textAlign = TextAlign.Left;
32524
+ canvas.fillText(msg, 0, size);
32525
+ });
32526
+ return y + height;
32270
32527
  }
32271
32528
  }
32272
32529
 
@@ -32291,7 +32548,16 @@
32291
32548
  get supportsResize() {
32292
32549
  return false;
32293
32550
  }
32294
- resize() { }
32551
+ get firstBarX() {
32552
+ let x = this._pagePadding[0];
32553
+ if (this._group) {
32554
+ x += this._group.accoladeSpacing;
32555
+ }
32556
+ return x;
32557
+ }
32558
+ doResize() {
32559
+ // not supported
32560
+ }
32295
32561
  doLayoutAndRender() {
32296
32562
  this._pagePadding = this.renderer.settings.display.padding;
32297
32563
  if (!this._pagePadding) {
@@ -32314,7 +32580,6 @@
32314
32580
  ];
32315
32581
  }
32316
32582
  let score = this.renderer.score;
32317
- let canvas = this.renderer.canvas;
32318
32583
  let startIndex = this.renderer.settings.display.startBar;
32319
32584
  startIndex--; // map to array index
32320
32585
  startIndex = Math.min(score.masterBars.length - 1, Math.max(0, startIndex));
@@ -32373,35 +32638,39 @@
32373
32638
  currentPartial.masterBars[currentPartial.masterBars.length - 1].index, null);
32374
32639
  }
32375
32640
  this._group.finalizeGroup();
32376
- this.height = this._group.y + this._group.height + this._pagePadding[3];
32641
+ this.height = Math.floor(this._group.y + this._group.height);
32377
32642
  this.width = this._group.x + this._group.width + this._pagePadding[2];
32378
32643
  currentBarIndex = 0;
32644
+ let x = 0;
32379
32645
  for (let i = 0; i < partials.length; i++) {
32380
32646
  let partial = partials[i];
32381
- canvas.beginRender(partial.width, this.height);
32382
- canvas.color = this.renderer.settings.display.resources.mainGlyphColor;
32383
- canvas.textAlign = TextAlign.Left;
32384
- let renderX = this._group.getBarX(partial.masterBars[0].index) + this._group.accoladeSpacing;
32385
- if (i === 0) {
32386
- renderX -= this._group.x + this._group.accoladeSpacing;
32387
- }
32388
- Logger.debug(this.name, 'Rendering partial from bar ' +
32389
- partial.masterBars[0].index +
32390
- ' to ' +
32391
- partial.masterBars[partial.masterBars.length - 1].index, null);
32392
- this._group.paintPartial(-renderX, this._group.y, this.renderer.canvas, currentBarIndex, partial.masterBars.length);
32393
- let result = canvas.endRender();
32394
- let e = new RenderFinishedEventArgs();
32647
+ const e = new RenderFinishedEventArgs();
32648
+ e.x = x;
32649
+ e.y = 0;
32395
32650
  e.totalWidth = this.width;
32396
32651
  e.totalHeight = this.height;
32397
32652
  e.width = partial.width;
32398
32653
  e.height = this.height;
32399
- e.renderResult = result;
32400
32654
  e.firstMasterBarIndex = partial.masterBars[0].index;
32401
32655
  e.lastMasterBarIndex = partial.masterBars[partial.masterBars.length - 1].index;
32402
- this.renderer.partialRenderFinished.trigger(e);
32656
+ x += partial.width;
32657
+ const partialBarIndex = currentBarIndex;
32658
+ this.registerPartial(e, canvas => {
32659
+ canvas.color = this.renderer.settings.display.resources.mainGlyphColor;
32660
+ canvas.textAlign = TextAlign.Left;
32661
+ let renderX = this._group.getBarX(partial.masterBars[0].index) + this._group.accoladeSpacing;
32662
+ if (i === 0) {
32663
+ renderX -= this._group.x + this._group.accoladeSpacing;
32664
+ }
32665
+ Logger.debug(this.name, 'Rendering partial from bar ' +
32666
+ partial.masterBars[0].index +
32667
+ ' to ' +
32668
+ partial.masterBars[partial.masterBars.length - 1].index, null);
32669
+ this._group.paintPartial(-renderX, this._group.y, canvas, partialBarIndex, partial.masterBars.length);
32670
+ });
32403
32671
  currentBarIndex += partial.masterBars.length;
32404
32672
  }
32673
+ this.height = this.layoutAndRenderAnnotation(this.height) + this._pagePadding[3];
32405
32674
  }
32406
32675
  }
32407
32676
  HorizontalScreenLayout.PagePadding = [20, 20, 20, 20];
@@ -32442,13 +32711,12 @@
32442
32711
  this._pagePadding[1]
32443
32712
  ];
32444
32713
  }
32445
- let x = this._pagePadding[0];
32446
- let y = this._pagePadding[1];
32714
+ let y = 0;
32447
32715
  this.width = this.renderer.width;
32448
32716
  this._allMasterBarRenderers = [];
32449
32717
  //
32450
32718
  // 1. Score Info
32451
- y = this.layoutAndRenderScoreInfo(x, y, -1);
32719
+ y = this.layoutAndRenderScoreInfo(y, -1);
32452
32720
  //
32453
32721
  // 2. Tunings
32454
32722
  y = this.layoutAndRenderTunings(y, -1);
@@ -32457,20 +32725,27 @@
32457
32725
  y = this.layoutAndRenderChordDiagrams(y, -1);
32458
32726
  //
32459
32727
  // 4. One result per StaveGroup
32460
- y = this.layoutAndRenderScore(x, y);
32728
+ y = this.layoutAndRenderScore(y);
32729
+ y = this.layoutAndRenderAnnotation(y);
32461
32730
  this.height = y + this._pagePadding[3];
32462
32731
  }
32463
32732
  get supportsResize() {
32464
32733
  return true;
32465
32734
  }
32466
- resize() {
32735
+ get firstBarX() {
32467
32736
  let x = this._pagePadding[0];
32468
- let y = this._pagePadding[1];
32737
+ if (this._groups.length > 0) {
32738
+ x += this._groups[0].accoladeSpacing;
32739
+ }
32740
+ return x;
32741
+ }
32742
+ doResize() {
32743
+ let y = 0;
32469
32744
  this.width = this.renderer.width;
32470
32745
  let oldHeight = this.height;
32471
32746
  //
32472
32747
  // 1. Score Info
32473
- y = this.layoutAndRenderScoreInfo(x, y, oldHeight);
32748
+ y = this.layoutAndRenderScoreInfo(y, oldHeight);
32474
32749
  //
32475
32750
  // 2. Tunings
32476
32751
  y = this.layoutAndRenderTunings(y, oldHeight);
@@ -32479,7 +32754,8 @@
32479
32754
  y = this.layoutAndRenderChordDiagrams(y, oldHeight);
32480
32755
  //
32481
32756
  // 4. One result per StaveGroup
32482
- y = this.resizeAndRenderScore(x, y, oldHeight);
32757
+ y = this.resizeAndRenderScore(y, oldHeight);
32758
+ y = this.layoutAndRenderAnnotation(y);
32483
32759
  this.height = y + this._pagePadding[3];
32484
32760
  }
32485
32761
  layoutAndRenderTunings(y, totalHeight = -1) {
@@ -32487,54 +32763,56 @@
32487
32763
  return y;
32488
32764
  }
32489
32765
  let res = this.renderer.settings.display.resources;
32766
+ this.tuningGlyph.x = this._pagePadding[0];
32490
32767
  this.tuningGlyph.width = this.width;
32491
32768
  this.tuningGlyph.doLayout();
32492
32769
  let tuningHeight = this.tuningGlyph.height + 11 * this.scale;
32493
- y += tuningHeight;
32494
- let canvas = this.renderer.canvas;
32495
- canvas.beginRender(this.width, tuningHeight);
32496
- canvas.color = res.scoreInfoColor;
32497
- canvas.textAlign = TextAlign.Center;
32498
- this.tuningGlyph.paint(this._pagePadding[0], 0, canvas);
32499
- let result = canvas.endRender();
32500
- let e = new RenderFinishedEventArgs();
32770
+ const e = new RenderFinishedEventArgs();
32771
+ e.x = 0;
32772
+ e.y = y;
32501
32773
  e.width = this.width;
32502
32774
  e.height = tuningHeight;
32503
- e.renderResult = result;
32504
32775
  e.totalWidth = this.width;
32505
- e.totalHeight = totalHeight < 0 ? y : totalHeight;
32776
+ e.totalHeight = totalHeight < 0 ? y + e.height : totalHeight;
32506
32777
  e.firstMasterBarIndex = -1;
32507
32778
  e.lastMasterBarIndex = -1;
32508
- this.renderer.partialRenderFinished.trigger(e);
32509
- return y;
32779
+ this.registerPartial(e, (canvas) => {
32780
+ canvas.color = res.scoreInfoColor;
32781
+ canvas.textAlign = TextAlign.Center;
32782
+ this.tuningGlyph.paint(0, 0, canvas);
32783
+ });
32784
+ return y + tuningHeight;
32510
32785
  }
32511
32786
  layoutAndRenderChordDiagrams(y, totalHeight = -1) {
32512
32787
  if (!this.chordDiagrams) {
32513
32788
  return y;
32514
32789
  }
32515
- let res = this.renderer.settings.display.resources;
32790
+ const res = this.renderer.settings.display.resources;
32516
32791
  this.chordDiagrams.width = this.width;
32517
32792
  this.chordDiagrams.doLayout();
32518
- let canvas = this.renderer.canvas;
32519
- canvas.beginRender(this.width, this.chordDiagrams.height);
32520
- canvas.color = res.scoreInfoColor;
32521
- canvas.textAlign = TextAlign.Center;
32522
- this.chordDiagrams.paint(0, 0, canvas);
32523
- let result = canvas.endRender();
32524
- y += this.chordDiagrams.height;
32525
- let e = new RenderFinishedEventArgs();
32793
+ const diagramHeight = Math.floor(this.chordDiagrams.height);
32794
+ const e = new RenderFinishedEventArgs();
32795
+ e.x = 0;
32796
+ e.y = y;
32526
32797
  e.width = this.width;
32527
- e.height = this.chordDiagrams.height;
32528
- e.renderResult = result;
32798
+ e.height = diagramHeight;
32529
32799
  e.totalWidth = this.width;
32530
- e.totalHeight = totalHeight < 0 ? y : totalHeight;
32800
+ e.totalHeight = totalHeight < 0 ? y + diagramHeight : totalHeight;
32531
32801
  e.firstMasterBarIndex = -1;
32532
32802
  e.lastMasterBarIndex = -1;
32533
- this.renderer.partialRenderFinished.trigger(e);
32534
- return y;
32803
+ this.registerPartial(e, (canvas) => {
32804
+ canvas.color = res.scoreInfoColor;
32805
+ canvas.textAlign = TextAlign.Center;
32806
+ this.chordDiagrams.paint(0, 0, canvas);
32807
+ });
32808
+ return y + diagramHeight;
32535
32809
  }
32536
- layoutAndRenderScoreInfo(x, y, totalHeight = -1) {
32810
+ layoutAndRenderScoreInfo(y, totalHeight = -1) {
32537
32811
  Logger.debug(this.name, 'Layouting score info');
32812
+ const e = new RenderFinishedEventArgs();
32813
+ e.x = 0;
32814
+ e.y = y;
32815
+ let infoHeight = this._pagePadding[1];
32538
32816
  let scale = this.scale;
32539
32817
  let res = this.renderer.settings.display.resources;
32540
32818
  let centeredGlyphs = [
@@ -32548,9 +32826,9 @@
32548
32826
  if (this.scoreInfoGlyphs.has(centeredGlyphs[i])) {
32549
32827
  let glyph = this.scoreInfoGlyphs.get(centeredGlyphs[i]);
32550
32828
  glyph.x = this.width / 2;
32551
- glyph.y = y;
32829
+ glyph.y = infoHeight;
32552
32830
  glyph.textAlign = TextAlign.Center;
32553
- y += glyph.font.size * scale;
32831
+ infoHeight += glyph.font.size * scale;
32554
32832
  }
32555
32833
  }
32556
32834
  let musicOrWords = false;
@@ -32558,51 +32836,46 @@
32558
32836
  if (this.scoreInfoGlyphs.has(NotationElement.ScoreMusic)) {
32559
32837
  let glyph = this.scoreInfoGlyphs.get(NotationElement.ScoreMusic);
32560
32838
  glyph.x = this.width - this._pagePadding[2];
32561
- glyph.y = y;
32839
+ glyph.y = infoHeight;
32562
32840
  glyph.textAlign = TextAlign.Right;
32563
32841
  musicOrWords = true;
32564
32842
  musicOrWordsHeight = glyph.font.size * scale;
32565
32843
  }
32566
32844
  if (this.scoreInfoGlyphs.has(NotationElement.ScoreWords)) {
32567
32845
  let glyph = this.scoreInfoGlyphs.get(NotationElement.ScoreWords);
32568
- glyph.x = x;
32569
- glyph.y = y;
32846
+ glyph.x = this._pagePadding[0];
32847
+ glyph.y = infoHeight;
32570
32848
  glyph.textAlign = TextAlign.Left;
32571
32849
  musicOrWords = true;
32572
32850
  musicOrWordsHeight = glyph.font.size * scale;
32573
32851
  }
32574
32852
  if (musicOrWords) {
32575
- y += musicOrWordsHeight;
32576
- }
32577
- y += 17 * this.scale;
32578
- let canvas = this.renderer.canvas;
32579
- canvas.beginRender(this.width, y);
32580
- canvas.color = res.scoreInfoColor;
32581
- canvas.textAlign = TextAlign.Center;
32582
- for (const g of this.scoreInfoGlyphs.values()) {
32583
- g.paint(0, 0, canvas);
32853
+ infoHeight += musicOrWordsHeight;
32584
32854
  }
32585
- let result = canvas.endRender();
32586
- let e = new RenderFinishedEventArgs();
32855
+ infoHeight = Math.floor(infoHeight + 17 * this.scale);
32587
32856
  e.width = this.width;
32588
- e.height = y;
32589
- e.renderResult = result;
32857
+ e.height = infoHeight;
32590
32858
  e.totalWidth = this.width;
32591
- e.totalHeight = totalHeight < 0 ? y : totalHeight;
32859
+ e.totalHeight = totalHeight < 0 ? y + e.height : totalHeight;
32592
32860
  e.firstMasterBarIndex = -1;
32593
32861
  e.lastMasterBarIndex = -1;
32594
- this.renderer.partialRenderFinished.trigger(e);
32595
- return y;
32862
+ this.registerPartial(e, (canvas) => {
32863
+ canvas.color = res.scoreInfoColor;
32864
+ canvas.textAlign = TextAlign.Center;
32865
+ for (const g of this.scoreInfoGlyphs.values()) {
32866
+ g.paint(0, 0, canvas);
32867
+ }
32868
+ });
32869
+ return y + infoHeight;
32596
32870
  }
32597
- resizeAndRenderScore(x, y, oldHeight) {
32598
- let canvas = this.renderer.canvas;
32871
+ resizeAndRenderScore(y, oldHeight) {
32599
32872
  // if we have a fixed number of bars per row, we only need to refit them.
32600
32873
  if (this.renderer.settings.display.barsPerRow !== -1) {
32601
32874
  for (let i = 0; i < this._groups.length; i++) {
32602
32875
  let group = this._groups[i];
32603
32876
  this.fitGroup(group);
32604
32877
  group.finalizeGroup();
32605
- y += this.paintGroup(group, oldHeight, canvas);
32878
+ y += this.paintGroup(group, oldHeight);
32606
32879
  }
32607
32880
  }
32608
32881
  else {
@@ -32611,7 +32884,7 @@
32611
32884
  let maxWidth = this.maxWidth;
32612
32885
  let group = this.createEmptyStaveGroup();
32613
32886
  group.index = this._groups.length;
32614
- group.x = x;
32887
+ group.x = this._pagePadding[0];
32615
32888
  group.y = y;
32616
32889
  while (currentIndex < this._allMasterBarRenderers.length) {
32617
32890
  // if the current renderer still has space in the current group add it
@@ -32635,11 +32908,11 @@
32635
32908
  this._groups.push(group);
32636
32909
  this.fitGroup(group);
32637
32910
  group.finalizeGroup();
32638
- y += this.paintGroup(group, oldHeight, canvas);
32911
+ y += this.paintGroup(group, oldHeight);
32639
32912
  // note: we do not increase currentIndex here to have it added to the next group
32640
32913
  group = this.createEmptyStaveGroup();
32641
32914
  group.index = this._groups.length;
32642
- group.x = x;
32915
+ group.x = this._pagePadding[0];
32643
32916
  group.y = y;
32644
32917
  }
32645
32918
  }
@@ -32647,12 +32920,11 @@
32647
32920
  // don't forget to finish the last group
32648
32921
  this.fitGroup(group);
32649
32922
  group.finalizeGroup();
32650
- y += this.paintGroup(group, oldHeight, canvas);
32923
+ y += this.paintGroup(group, oldHeight);
32651
32924
  }
32652
32925
  return y;
32653
32926
  }
32654
- layoutAndRenderScore(x, y) {
32655
- let canvas = this.renderer.canvas;
32927
+ layoutAndRenderScore(y) {
32656
32928
  let startIndex = this.firstBarIndex;
32657
32929
  let currentBarIndex = startIndex;
32658
32930
  let endBarIndex = this.lastBarIndex;
@@ -32661,38 +32933,38 @@
32661
32933
  // create group and align set proper coordinates
32662
32934
  let group = this.createStaveGroup(currentBarIndex, endBarIndex);
32663
32935
  this._groups.push(group);
32664
- group.x = x;
32936
+ group.x = this._pagePadding[0];
32665
32937
  group.y = y;
32666
32938
  currentBarIndex = group.lastBarIndex + 1;
32667
32939
  // finalize group (sizing etc).
32668
32940
  this.fitGroup(group);
32669
32941
  group.finalizeGroup();
32670
32942
  Logger.debug(this.name, 'Rendering partial from bar ' + group.firstBarIndex + ' to ' + group.lastBarIndex, null);
32671
- y += this.paintGroup(group, y, canvas);
32943
+ y += this.paintGroup(group, y);
32672
32944
  }
32673
32945
  return y;
32674
32946
  }
32675
- paintGroup(group, totalHeight, canvas) {
32947
+ paintGroup(group, totalHeight) {
32676
32948
  // paint into canvas
32677
- let height = group.height + 20 * this.scale;
32678
- canvas.beginRender(this.width, height);
32679
- this.renderer.canvas.color = this.renderer.settings.display.resources.mainGlyphColor;
32680
- this.renderer.canvas.textAlign = TextAlign.Left;
32681
- // NOTE: we use this negation trick to make the group paint itself to 0/0 coordinates
32682
- // since we use partial drawing
32683
- group.paint(0, -group.y, canvas);
32684
- // calculate coordinates for next group
32685
- totalHeight += height;
32686
- let result = canvas.endRender();
32687
- let args = new RenderFinishedEventArgs();
32949
+ let height = Math.floor(group.height + 20 * this.scale);
32950
+ const args = new RenderFinishedEventArgs();
32951
+ args.x = 0;
32952
+ args.y = group.y;
32688
32953
  args.totalWidth = this.width;
32689
32954
  args.totalHeight = totalHeight;
32690
32955
  args.width = this.width;
32691
32956
  args.height = height;
32692
- args.renderResult = result;
32693
32957
  args.firstMasterBarIndex = group.firstBarIndex;
32694
32958
  args.lastMasterBarIndex = group.lastBarIndex;
32695
- this.renderer.partialRenderFinished.trigger(args);
32959
+ this.registerPartial(args, canvas => {
32960
+ this.renderer.canvas.color = this.renderer.settings.display.resources.mainGlyphColor;
32961
+ this.renderer.canvas.textAlign = TextAlign.Left;
32962
+ // NOTE: we use this negation trick to make the group paint itself to 0/0 coordinates
32963
+ // since we use partial drawing
32964
+ group.paint(0, -args.y, canvas);
32965
+ });
32966
+ // calculate coordinates for next group
32967
+ totalHeight += height;
32696
32968
  return height;
32697
32969
  }
32698
32970
  /**
@@ -32702,7 +32974,6 @@
32702
32974
  if (group.isFull || group.width > this.maxWidth) {
32703
32975
  group.scaleToWidth(this.maxWidth);
32704
32976
  }
32705
- this.width = Math.max(this.width, group.width);
32706
32977
  }
32707
32978
  createStaveGroup(currentBarIndex, endIndex) {
32708
32979
  let group = this.createEmptyStaveGroup();
@@ -39135,7 +39406,7 @@
39135
39406
  }
39136
39407
  else if (c.attributes.has('end') && this._tieStarts.length > 0 && !note.isTieDestination) {
39137
39408
  note.isTieDestination = true;
39138
- note.tieOriginNoteId = this._tieStarts[0].id;
39409
+ note.tieOrigin = this._tieStarts[0];
39139
39410
  this._tieStarts.splice(0, 1);
39140
39411
  this._tieStartIds.delete(note.id);
39141
39412
  }
@@ -40281,8 +40552,8 @@
40281
40552
  // </auto-generated>
40282
40553
  class VersionInfo {
40283
40554
  }
40284
- VersionInfo.version = '1.3.0-alpha.136';
40285
- VersionInfo.date = '2021-11-28T16:51:01.877Z';
40555
+ VersionInfo.version = '1.3.0-alpha.140';
40556
+ VersionInfo.date = '2021-12-29T23:06:43.677Z';
40286
40557
 
40287
40558
  var index$5 = /*#__PURE__*/Object.freeze({
40288
40559
  __proto__: null,
@@ -41174,95 +41445,98 @@
41174
41445
  const diagramCollectionProperty = properties.addElement('Property');
41175
41446
  diagramCollectionProperty.attributes.set('name', name);
41176
41447
  const diagramCollectionItems = diagramCollectionProperty.addElement('Items');
41177
- for (const [id, chord] of staff.chords) {
41178
- const diagramCollectionItem = diagramCollectionItems.addElement('Item');
41179
- diagramCollectionItem.attributes.set('id', id);
41180
- diagramCollectionItem.attributes.set('name', chord.name);
41181
- const diagram = diagramCollectionItem.addElement('Diagram');
41182
- diagram.attributes.set('stringCount', chord.strings.length.toString());
41183
- diagram.attributes.set('fretCount', '5');
41184
- diagram.attributes.set('baseFret', (chord.firstFret - 1).toString());
41185
- diagram.attributes.set('barStates', chord.strings.map(_ => '1').join(' '));
41186
- const frets = [];
41187
- const fretToStrings = new Map();
41188
- for (let i = 0; i < chord.strings.length; i++) {
41189
- let chordFret = chord.strings[i];
41190
- if (chordFret !== -1) {
41191
- const fretNode = diagram.addElement('Fret');
41192
- const chordString = (chord.strings.length - 1 - i);
41193
- fretNode.attributes.set('string', chordString.toString());
41194
- fretNode.attributes.set('fret', (chordFret - chord.firstFret + 1).toString());
41195
- if (!fretToStrings.has(chordFret)) {
41196
- fretToStrings.set(chordFret, []);
41197
- frets.push(chordFret);
41198
- }
41199
- fretToStrings.get(chordFret).push(chordString);
41200
- }
41201
- }
41202
- frets.sort();
41203
- // try to rebuild the barre frets
41204
- const fingering = diagram.addElement('Fingering');
41205
- if (chord.barreFrets.length > 0) {
41206
- const fingers = [
41207
- Fingers.LittleFinger,
41208
- Fingers.AnnularFinger,
41209
- Fingers.MiddleFinger,
41210
- Fingers.IndexFinger,
41211
- ];
41212
- for (const fret of frets) {
41213
- const fretStrings = fretToStrings.get(fret);
41214
- if (fretStrings.length > 1 && chord.barreFrets.indexOf(fret) >= 0) {
41215
- const finger = fingers.length > 0 ? fingers.pop() : Fingers.IndexFinger;
41216
- for (const fretString of fretStrings) {
41217
- const position = fingering.addElement('Position');
41218
- switch (finger) {
41219
- case Fingers.LittleFinger:
41220
- position.attributes.set('finger', 'Pinky');
41221
- break;
41222
- case Fingers.AnnularFinger:
41223
- position.attributes.set('finger', 'Ring');
41224
- break;
41225
- case Fingers.MiddleFinger:
41226
- position.attributes.set('finger', 'Middle');
41227
- break;
41228
- case Fingers.IndexFinger:
41229
- position.attributes.set('finger', 'Index');
41230
- break;
41448
+ const sc = staff.chords;
41449
+ if (sc) {
41450
+ for (const [id, chord] of sc) {
41451
+ const diagramCollectionItem = diagramCollectionItems.addElement('Item');
41452
+ diagramCollectionItem.attributes.set('id', id);
41453
+ diagramCollectionItem.attributes.set('name', chord.name);
41454
+ const diagram = diagramCollectionItem.addElement('Diagram');
41455
+ diagram.attributes.set('stringCount', chord.strings.length.toString());
41456
+ diagram.attributes.set('fretCount', '5');
41457
+ diagram.attributes.set('baseFret', (chord.firstFret - 1).toString());
41458
+ diagram.attributes.set('barStates', chord.strings.map(_ => '1').join(' '));
41459
+ const frets = [];
41460
+ const fretToStrings = new Map();
41461
+ for (let i = 0; i < chord.strings.length; i++) {
41462
+ let chordFret = chord.strings[i];
41463
+ if (chordFret !== -1) {
41464
+ const fretNode = diagram.addElement('Fret');
41465
+ const chordString = (chord.strings.length - 1 - i);
41466
+ fretNode.attributes.set('string', chordString.toString());
41467
+ fretNode.attributes.set('fret', (chordFret - chord.firstFret + 1).toString());
41468
+ if (!fretToStrings.has(chordFret)) {
41469
+ fretToStrings.set(chordFret, []);
41470
+ frets.push(chordFret);
41471
+ }
41472
+ fretToStrings.get(chordFret).push(chordString);
41473
+ }
41474
+ }
41475
+ frets.sort();
41476
+ // try to rebuild the barre frets
41477
+ const fingering = diagram.addElement('Fingering');
41478
+ if (chord.barreFrets.length > 0) {
41479
+ const fingers = [
41480
+ Fingers.LittleFinger,
41481
+ Fingers.AnnularFinger,
41482
+ Fingers.MiddleFinger,
41483
+ Fingers.IndexFinger,
41484
+ ];
41485
+ for (const fret of frets) {
41486
+ const fretStrings = fretToStrings.get(fret);
41487
+ if (fretStrings.length > 1 && chord.barreFrets.indexOf(fret) >= 0) {
41488
+ const finger = fingers.length > 0 ? fingers.pop() : Fingers.IndexFinger;
41489
+ for (const fretString of fretStrings) {
41490
+ const position = fingering.addElement('Position');
41491
+ switch (finger) {
41492
+ case Fingers.LittleFinger:
41493
+ position.attributes.set('finger', 'Pinky');
41494
+ break;
41495
+ case Fingers.AnnularFinger:
41496
+ position.attributes.set('finger', 'Ring');
41497
+ break;
41498
+ case Fingers.MiddleFinger:
41499
+ position.attributes.set('finger', 'Middle');
41500
+ break;
41501
+ case Fingers.IndexFinger:
41502
+ position.attributes.set('finger', 'Index');
41503
+ break;
41504
+ }
41505
+ position.attributes.set('fret', (fret - chord.firstFret + 1).toString());
41506
+ position.attributes.set('string', fretString.toString());
41231
41507
  }
41232
- position.attributes.set('fret', (fret - chord.firstFret + 1).toString());
41233
- position.attributes.set('string', fretString.toString());
41234
41508
  }
41235
41509
  }
41236
41510
  }
41511
+ const showName = diagram.addElement('Property');
41512
+ showName.attributes.set('name', 'ShowName');
41513
+ showName.attributes.set('type', 'bool');
41514
+ showName.attributes.set('value', chord.showName ? "true" : "false");
41515
+ const showDiagram = diagram.addElement('Property');
41516
+ showDiagram.attributes.set('name', 'ShowDiagram');
41517
+ showDiagram.attributes.set('type', 'bool');
41518
+ showDiagram.attributes.set('value', chord.showDiagram ? "true" : "false");
41519
+ const showFingering = diagram.addElement('Property');
41520
+ showFingering.attributes.set('name', 'ShowFingering');
41521
+ showFingering.attributes.set('type', 'bool');
41522
+ showFingering.attributes.set('value', chord.showFingering ? "true" : "false");
41523
+ // TODO Chord details
41524
+ const chordNode = diagram.addElement('Chord');
41525
+ const keyNoteNode = chordNode.addElement('KeyNote');
41526
+ keyNoteNode.attributes.set('step', 'C');
41527
+ keyNoteNode.attributes.set('accidental', 'Natural');
41528
+ const bassNoteNode = chordNode.addElement('BassNote');
41529
+ bassNoteNode.attributes.set('step', 'C');
41530
+ bassNoteNode.attributes.set('accidental', 'Natural');
41531
+ const degree1Node = chordNode.addElement('Degree');
41532
+ degree1Node.attributes.set('interval', 'Third');
41533
+ degree1Node.attributes.set('alteration', 'Major');
41534
+ degree1Node.attributes.set('omitted', 'false');
41535
+ const degree2Node = chordNode.addElement('Degree');
41536
+ degree2Node.attributes.set('interval', 'Fifth');
41537
+ degree2Node.attributes.set('alteration', 'Perfect');
41538
+ degree2Node.attributes.set('omitted', 'false');
41237
41539
  }
41238
- const showName = diagram.addElement('Property');
41239
- showName.attributes.set('name', 'ShowName');
41240
- showName.attributes.set('type', 'bool');
41241
- showName.attributes.set('value', chord.showName ? "true" : "false");
41242
- const showDiagram = diagram.addElement('Property');
41243
- showDiagram.attributes.set('name', 'ShowDiagram');
41244
- showDiagram.attributes.set('type', 'bool');
41245
- showDiagram.attributes.set('value', chord.showDiagram ? "true" : "false");
41246
- const showFingering = diagram.addElement('Property');
41247
- showFingering.attributes.set('name', 'ShowFingering');
41248
- showFingering.attributes.set('type', 'bool');
41249
- showFingering.attributes.set('value', chord.showFingering ? "true" : "false");
41250
- // TODO Chord details
41251
- const chordNode = diagram.addElement('Chord');
41252
- const keyNoteNode = chordNode.addElement('KeyNote');
41253
- keyNoteNode.attributes.set('step', 'C');
41254
- keyNoteNode.attributes.set('accidental', 'Natural');
41255
- const bassNoteNode = chordNode.addElement('BassNote');
41256
- bassNoteNode.attributes.set('step', 'C');
41257
- bassNoteNode.attributes.set('accidental', 'Natural');
41258
- const degree1Node = chordNode.addElement('Degree');
41259
- degree1Node.attributes.set('interval', 'Third');
41260
- degree1Node.attributes.set('alteration', 'Major');
41261
- degree1Node.attributes.set('omitted', 'false');
41262
- const degree2Node = chordNode.addElement('Degree');
41263
- degree2Node.attributes.set('interval', 'Fifth');
41264
- degree2Node.attributes.set('alteration', 'Perfect');
41265
- degree2Node.attributes.set('omitted', 'false');
41266
41540
  }
41267
41541
  }
41268
41542
  writeSimplePropertyNode(parent, propertyName, propertyValueTagName, propertyValue) {
@@ -41465,10 +41739,12 @@
41465
41739
  this.writeFermatas(masterBarNode, masterBar);
41466
41740
  }
41467
41741
  writeFermatas(parent, masterBar) {
41468
- if (masterBar.fermata.size === 0) {
41742
+ var _a, _b;
41743
+ const fermataCount = ((_b = (_a = masterBar.fermata) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0);
41744
+ if (fermataCount === 0) {
41469
41745
  return;
41470
41746
  }
41471
- if (masterBar.fermata.size > 0) {
41747
+ if (fermataCount > 0) {
41472
41748
  const fermatas = parent.addElement('Fermatas');
41473
41749
  for (const [offset, fermata] of masterBar.fermata) {
41474
41750
  this.writeFermata(fermatas, offset, fermata);