@coderline/alphatab 1.3.0-alpha.518 → 1.3.0-alpha.520

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.518 (develop, build 518)
2
+ * alphaTab v1.3.0-alpha.520 (develop, build 520)
3
3
  *
4
4
  * Copyright © 2023, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -3887,11 +3887,11 @@
3887
3887
  points.splice(1, 1);
3888
3888
  }
3889
3889
  else {
3890
- Logger.warning('Model', 'Unsupported whammy type detected, fallback to custom', null);
3890
+ Logger.warning('Model', 'Unsupported whammy type detected, fallback to custom');
3891
3891
  }
3892
3892
  }
3893
3893
  else {
3894
- Logger.warning('Model', 'Unsupported whammy type detected, fallback to custom', null);
3894
+ Logger.warning('Model', 'Unsupported whammy type detected, fallback to custom');
3895
3895
  }
3896
3896
  }
3897
3897
  }
@@ -5686,39 +5686,35 @@
5686
5686
  AlphaTexSymbols[AlphaTexSymbols["MetaCommand"] = 12] = "MetaCommand";
5687
5687
  AlphaTexSymbols[AlphaTexSymbols["Multiply"] = 13] = "Multiply";
5688
5688
  AlphaTexSymbols[AlphaTexSymbols["LowerThan"] = 14] = "LowerThan";
5689
- AlphaTexSymbols[AlphaTexSymbols["Property"] = 15] = "Property";
5690
5689
  })(AlphaTexSymbols || (AlphaTexSymbols = {}));
5691
5690
  class AlphaTexError extends AlphaTabError {
5692
- constructor(message) {
5691
+ constructor(message, position, line, col, nonTerm, expected, symbol, symbolData = null) {
5693
5692
  super(exports.AlphaTabErrorType.AlphaTex, message);
5694
- this.position = 0;
5695
- this.nonTerm = '';
5696
- this.expected = AlphaTexSymbols.No;
5697
- this.symbol = AlphaTexSymbols.No;
5698
- this.symbolData = null;
5693
+ this.position = position;
5694
+ this.line = line;
5695
+ this.col = col;
5696
+ this.nonTerm = nonTerm !== null && nonTerm !== void 0 ? nonTerm : '';
5697
+ this.expected = expected !== null && expected !== void 0 ? expected : AlphaTexSymbols.No;
5698
+ this.symbol = symbol !== null && symbol !== void 0 ? symbol : AlphaTexSymbols.No;
5699
+ this.symbolData = symbolData;
5699
5700
  Object.setPrototypeOf(this, AlphaTexError.prototype);
5700
5701
  }
5701
- static symbolError(position, nonTerm, expected, symbol, symbolData = null) {
5702
- let message;
5702
+ static symbolError(position, line, col, nonTerm, expected, symbol, symbolData = null) {
5703
+ let message = `MalFormed AlphaTex: @${position} (line ${line}, col ${col}): Error on block ${nonTerm}`;
5703
5704
  if (expected !== symbol) {
5704
- message = `MalFormed AlphaTex: @${position}: Error on block ${nonTerm}, expected a ${AlphaTexSymbols[expected]} found a ${AlphaTexSymbols[symbol]}: '${symbolData}'`;
5705
+ message += `, expected a ${AlphaTexSymbols[expected]} found a ${AlphaTexSymbols[symbol]}`;
5706
+ if (symbolData !== null) {
5707
+ message += `: '${symbolData}'`;
5708
+ }
5705
5709
  }
5706
5710
  else {
5707
- message = `MalFormed AlphaTex: @${position}: Error on block ${nonTerm}, invalid value: '${symbolData}'`;
5708
- }
5709
- let exception = new AlphaTexError(message);
5710
- exception.position = position;
5711
- exception.nonTerm = nonTerm;
5712
- exception.expected = expected;
5713
- exception.symbol = symbol;
5714
- exception.symbolData = symbolData;
5715
- return exception;
5716
- }
5717
- static errorMessage(position, message) {
5718
- message = `MalFormed AlphaTex: @${position}: ${message}`;
5719
- let exception = new AlphaTexError(message);
5720
- exception.position = position;
5721
- return exception;
5711
+ message += `, invalid value: '${symbolData}'`;
5712
+ }
5713
+ return new AlphaTexError(message, position, line, col, nonTerm, expected, symbol, symbolData);
5714
+ }
5715
+ static errorMessage(message, position, line, col) {
5716
+ message = `MalFormed AlphaTex: @${position} (line ${line}, col ${col}): ${message}`;
5717
+ return new AlphaTexError(message, position, line, col, null, null, null, null);
5722
5718
  }
5723
5719
  }
5724
5720
  /**
@@ -5729,8 +5725,13 @@
5729
5725
  super();
5730
5726
  this._trackChannel = 0;
5731
5727
  this._input = "";
5732
- this._ch = 0;
5728
+ this._ch = AlphaTexImporter.Eof;
5729
+ // Keeps track of where in input string we are
5733
5730
  this._curChPos = 0;
5731
+ this._line = 1;
5732
+ this._col = 0;
5733
+ // Last known position that had valid syntax/symbols
5734
+ this._lastValidSpot = [0, 1, 0];
5734
5735
  this._sy = AlphaTexSymbols.No;
5735
5736
  this._syData = "";
5736
5737
  this._allowNegatives = false;
@@ -5759,6 +5760,9 @@
5759
5760
  this._lyrics = new Map();
5760
5761
  this.createDefaultScore();
5761
5762
  this._curChPos = 0;
5763
+ this._line = 1;
5764
+ this._col = 0;
5765
+ this.saveValidSpot();
5762
5766
  this._currentDuration = Duration.Quarter;
5763
5767
  this._currentDynamics = DynamicValue.F;
5764
5768
  this._currentTuplet = 1;
@@ -5766,9 +5770,16 @@
5766
5770
  this._sy = this.newSy();
5767
5771
  if (this._sy === AlphaTexSymbols.LowerThan) {
5768
5772
  // potential XML, stop parsing (alphaTex never starts with <)
5769
- throw new UnsupportedFormatError('Unknown start sign <');
5773
+ throw new UnsupportedFormatError("Unknown start sign '<' (meant to import as XML?)");
5774
+ }
5775
+ else if (this._sy === AlphaTexSymbols.Eof) {
5776
+ throw new UnsupportedFormatError('Unexpected end of file');
5777
+ }
5778
+ const anyMetaRead = this.metaData();
5779
+ const anyBarsRead = this.bars();
5780
+ if (!anyMetaRead && !anyBarsRead) {
5781
+ throw new UnsupportedFormatError('No alphaTex data found');
5770
5782
  }
5771
- this.score();
5772
5783
  this.consolidate();
5773
5784
  this._score.finish(this.settings);
5774
5785
  this._score.rebuildRepeatGroups();
@@ -5779,16 +5790,18 @@
5779
5790
  }
5780
5791
  catch (e) {
5781
5792
  if (e instanceof AlphaTexError) {
5782
- throw new UnsupportedFormatError(e.message);
5793
+ throw new UnsupportedFormatError(e.message, e);
5783
5794
  }
5784
5795
  else {
5785
5796
  throw e;
5786
5797
  }
5787
5798
  }
5788
5799
  }
5800
+ /**
5801
+ * Ensures all staffs of all tracks have the correct number of bars
5802
+ * (the number of bars per staff and track could be inconsistent)
5803
+ */
5789
5804
  consolidate() {
5790
- // the number of bars per staff and track could be inconsistent,
5791
- // we need to ensure all staffs of all tracks have the correct number of bars
5792
5805
  for (let track of this._score.tracks) {
5793
5806
  for (let staff of track.staves) {
5794
5807
  while (staff.bars.length < this._score.masterBars.length) {
@@ -5800,21 +5813,33 @@
5800
5813
  }
5801
5814
  }
5802
5815
  }
5803
- error(nonterm, expected, symbolError = true) {
5804
- let e;
5805
- if (symbolError) {
5806
- e = AlphaTexError.symbolError(this._curChPos, nonterm, expected, this._sy, this._syData);
5816
+ error(nonterm, expected, wrongSymbol = true) {
5817
+ let receivedSymbol;
5818
+ let showSyData = false;
5819
+ if (wrongSymbol) {
5820
+ receivedSymbol = this._sy;
5821
+ if (
5822
+ // These are the only symbols that can have associated _syData set
5823
+ receivedSymbol === AlphaTexSymbols.String ||
5824
+ receivedSymbol === AlphaTexSymbols.Number ||
5825
+ receivedSymbol === AlphaTexSymbols.MetaCommand // ||
5826
+ // Tuning does not have a toString() yet, therefore excluded.
5827
+ // receivedSymbol === AlphaTexSymbols.Tuning
5828
+ ) {
5829
+ showSyData = true;
5830
+ }
5807
5831
  }
5808
5832
  else {
5809
- e = AlphaTexError.symbolError(this._curChPos, nonterm, expected, expected, this._syData);
5833
+ receivedSymbol = expected;
5810
5834
  }
5835
+ let e = AlphaTexError.symbolError(this._lastValidSpot[0], this._lastValidSpot[1], this._lastValidSpot[2], nonterm, expected, receivedSymbol, showSyData ? this._syData : null);
5811
5836
  if (this.logErrors) {
5812
5837
  Logger.error(this.name, e.message);
5813
5838
  }
5814
5839
  throw e;
5815
5840
  }
5816
5841
  errorMessage(message) {
5817
- let e = AlphaTexError.errorMessage(this._curChPos, message);
5842
+ let e = AlphaTexError.errorMessage(message, this._lastValidSpot[0], this._lastValidSpot[1], this._lastValidSpot[2]);
5818
5843
  if (this.logErrors) {
5819
5844
  Logger.error(this.name, e.message);
5820
5845
  }
@@ -6007,29 +6032,48 @@
6007
6032
  }
6008
6033
  }
6009
6034
  /**
6010
- * Reads the next character of the source stream.
6035
+ * Reads, saves, and returns the next character of the source stream.
6011
6036
  */
6012
6037
  nextChar() {
6013
6038
  if (this._curChPos < this._input.length) {
6014
6039
  this._ch = this._input.charCodeAt(this._curChPos++);
6040
+ // line/col counting
6041
+ if (this._ch === 0x0a /* \n */) {
6042
+ this._line++;
6043
+ this._col = 0;
6044
+ }
6045
+ else {
6046
+ this._col++;
6047
+ }
6015
6048
  }
6016
6049
  else {
6017
- this._ch = 0;
6050
+ this._ch = AlphaTexImporter.Eof;
6018
6051
  }
6019
6052
  return this._ch;
6020
6053
  }
6021
6054
  /**
6022
- * Reads the next terminal symbol.
6055
+ * Saves the current position, line, and column.
6056
+ * All parsed data until this point is assumed to be valid.
6057
+ */
6058
+ saveValidSpot() {
6059
+ this._lastValidSpot = [this._curChPos, this._line, this._col];
6060
+ }
6061
+ /**
6062
+ * Reads, saves, and returns the next terminal symbol.
6023
6063
  */
6024
6064
  newSy() {
6065
+ // When a new symbol is read, the previous one is assumed to be valid.
6066
+ // The valid spot is also moved forward when reading past whitespace or comments.
6067
+ this.saveValidSpot();
6025
6068
  this._sy = AlphaTexSymbols.No;
6026
- do {
6069
+ while (this._sy === AlphaTexSymbols.No) {
6027
6070
  if (this._ch === AlphaTexImporter.Eof) {
6028
6071
  this._sy = AlphaTexSymbols.Eof;
6029
6072
  }
6030
- else if (this._ch === 0x20 || this._ch === 0x0b || this._ch === 0x0d || this._ch === 0x0a || this._ch === 0x09) {
6073
+ else if (AlphaTexImporter.isWhiteSpace(this._ch)) {
6031
6074
  // skip whitespaces
6032
6075
  this._ch = this.nextChar();
6076
+ this.saveValidSpot();
6033
6077
  }
6034
6078
  else if (this._ch === 0x2f /* / */) {
6035
6079
  this._ch = this.nextChar();
@@ -6057,8 +6101,9 @@
6057
6101
  }
6058
6102
  }
6059
6103
  else {
6060
- this.error('symbol', AlphaTexSymbols.String, false);
6104
+ this.error('comment', AlphaTexSymbols.String, false);
6061
6105
  }
6106
+ this.saveValidSpot();
6062
6107
  }
6063
6108
  else if (this._ch === 0x22 /* " */ || this._ch === 0x27 /* ' */) {
6064
6109
  let startChar = this._ch;
@@ -6069,6 +6114,9 @@
6069
6114
  s += String.fromCharCode(this._ch);
6070
6115
  this._ch = this.nextChar();
6071
6116
  }
6117
+ if (this._ch === AlphaTexImporter.Eof) {
6118
+ this.errorMessage('String opened but never closed');
6119
+ }
6072
6120
  this._syData = s;
6073
6121
  this._ch = this.nextChar();
6074
6122
  }
@@ -6129,7 +6177,7 @@
6129
6177
  this._sy = AlphaTexSymbols.Number;
6130
6178
  this._syData = this.readNumber();
6131
6179
  }
6132
- else if (AlphaTexImporter.isLetter(this._ch)) {
6180
+ else if (AlphaTexImporter.isNameLetter(this._ch)) {
6133
6181
  let name = this.readName();
6134
6182
  let tuning = this._allowTuning ? ModelUtils.parseTuning(name) : null;
6135
6183
  if (tuning) {
@@ -6144,25 +6192,20 @@
6144
6192
  else {
6145
6193
  this.error('symbol', AlphaTexSymbols.String, false);
6146
6194
  }
6147
- } while (this._sy === AlphaTexSymbols.No);
6195
+ }
6148
6196
  return this._sy;
6149
6197
  }
6150
6198
  /**
6151
- * Checks if the given character is a letter.
6199
+ * Checks if the given character is a valid letter for a name.
6152
6200
  * (no control characters, whitespaces, numbers or dots)
6153
- * @param code the character
6154
- * @returns true if the given character is a letter, otherwise false.
6155
6201
  */
6156
- static isLetter(code) {
6157
- // no control characters, whitespaces, numbers or dots
6158
- return (!AlphaTexImporter.isTerminal(code) &&
6159
- ((code >= 0x21 && code <= 0x2f) || (code >= 0x3a && code <= 0x7e) || code > 0x80)); /* Unicode Symbols */
6202
+ static isNameLetter(ch) {
6203
+ return (!AlphaTexImporter.isTerminal(ch) && ( // no control characters, whitespaces, numbers or dots
6204
+ (0x21 <= ch && ch <= 0x2f) ||
6205
+ (0x3a <= ch && ch <= 0x7e) ||
6206
+ 0x80 <= ch // Unicode Symbols
6207
+ ));
6160
6208
  }
6161
- /**
6162
- * Checks if the given charater is a non terminal.
6163
- * @param ch the character
6164
- * @returns true if the given character is a terminal, otherwise false.
6165
- */
6166
6209
  static isTerminal(ch) {
6167
6210
  return (ch === 0x2e /* . */ ||
6168
6211
  ch === 0x7b /* { */ ||
@@ -6176,13 +6219,17 @@
6176
6219
  ch === 0x22 /* " */ ||
6177
6220
  ch === 0x5c /* \ */);
6178
6221
  }
6179
- /**
6180
- * Checks if the given character is a digit.
6181
- * @param code the character
6182
- * @returns true if the given character is a digit, otherwise false.
6183
- */
6184
- isDigit(code) {
6185
- return (code >= 0x30 && code <= 0x39) /* 0-9 */ || (code === 0x2d /* - */ && this._allowNegatives); // allow - if negatives
6222
+ static isWhiteSpace(ch) {
6223
+ return (ch === 0x09 /* \t */ ||
6224
+ ch === 0x0a /* \n */ ||
6225
+ ch === 0x0b /* \v */ ||
6226
+ ch === 0x0d /* \r */ ||
6227
+ ch === 0x20 /* space */);
6228
+ }
6229
+ isDigit(ch) {
6230
+ return ((ch >= 0x30 && ch <= 0x39) /* 0-9 */ ||
6231
+ (this._allowNegatives && ch === 0x2d /* - */) // allow minus sign if negatives
6232
+ );
6186
6233
  }
6187
6234
  /**
6188
6235
  * Reads a string from the stream.
@@ -6193,7 +6240,7 @@
6193
6240
  do {
6194
6241
  str += String.fromCharCode(this._ch);
6195
6242
  this._ch = this.nextChar();
6196
- } while (AlphaTexImporter.isLetter(this._ch) || this.isDigit(this._ch) || this._ch === 0x23 /* # */);
6243
+ } while (AlphaTexImporter.isNameLetter(this._ch) || this.isDigit(this._ch));
6197
6244
  return str;
6198
6245
  }
6199
6246
  /**
@@ -6208,16 +6255,6 @@
6208
6255
  } while (this.isDigit(this._ch));
6209
6256
  return parseInt(str);
6210
6257
  }
6211
- score() {
6212
- if (this._sy === AlphaTexSymbols.Eof) {
6213
- throw new UnsupportedFormatError('Unexpected end of file');
6214
- }
6215
- const anyMetaRead = this.metaData();
6216
- const anyBarsRead = this.bars();
6217
- if (!anyMetaRead && !anyBarsRead) {
6218
- throw new UnsupportedFormatError('No alphaTex data found');
6219
- }
6220
- }
6221
6258
  metaData() {
6222
6259
  let anyMeta = false;
6223
6260
  let continueReading = true;
@@ -6513,45 +6550,40 @@
6513
6550
  return anyData;
6514
6551
  }
6515
6552
  trackStaffMeta() {
6516
- let anyMeta = false;
6517
- if (this._sy === AlphaTexSymbols.MetaCommand) {
6518
- anyMeta = true;
6519
- let syData = this._syData.toLowerCase();
6520
- if (syData === 'track') {
6521
- this._staffHasExplicitTuning = false;
6522
- this._staffTuningApplied = false;
6553
+ if (this._sy !== AlphaTexSymbols.MetaCommand) {
6554
+ return false;
6555
+ }
6556
+ if (this._syData.toLowerCase() === 'track') {
6557
+ this._staffHasExplicitTuning = false;
6558
+ this._staffTuningApplied = false;
6559
+ this._sy = this.newSy();
6560
+ // new track starting? - if no masterbars it's the \track of the initial track.
6561
+ if (this._score.masterBars.length > 0) {
6562
+ this.newTrack();
6563
+ }
6564
+ // name
6565
+ if (this._sy === AlphaTexSymbols.String) {
6566
+ this._currentTrack.name = this._syData;
6523
6567
  this._sy = this.newSy();
6524
- // new track starting? - if no masterbars it's the \track of the initial track.
6525
- if (this._score.masterBars.length > 0) {
6526
- this.newTrack();
6527
- }
6528
- // name
6529
- if (this._sy === AlphaTexSymbols.String) {
6530
- this._currentTrack.name = this._syData;
6531
- this._sy = this.newSy();
6532
- }
6533
- // short name
6534
- if (this._sy === AlphaTexSymbols.String) {
6535
- this._currentTrack.shortName = this._syData;
6536
- this._sy = this.newSy();
6537
- }
6538
6568
  }
6539
- if (this._sy === AlphaTexSymbols.MetaCommand) {
6540
- syData = this._syData.toLowerCase();
6541
- if (syData === 'staff') {
6542
- this._staffHasExplicitTuning = false;
6543
- this._staffTuningApplied = false;
6544
- this._sy = this.newSy();
6545
- if (this._currentTrack.staves[0].bars.length > 0) {
6546
- this._currentTrack.ensureStaveCount(this._currentTrack.staves.length + 1);
6547
- this._currentStaff = this._currentTrack.staves[this._currentTrack.staves.length - 1];
6548
- this._currentDynamics = DynamicValue.F;
6549
- }
6550
- this.staffProperties();
6551
- }
6569
+ // short name
6570
+ if (this._sy === AlphaTexSymbols.String) {
6571
+ this._currentTrack.shortName = this._syData;
6572
+ this._sy = this.newSy();
6552
6573
  }
6553
6574
  }
6554
- return anyMeta;
6575
+ if (this._sy === AlphaTexSymbols.MetaCommand && this._syData.toLowerCase() === 'staff') {
6576
+ this._staffHasExplicitTuning = false;
6577
+ this._staffTuningApplied = false;
6578
+ this._sy = this.newSy();
6579
+ if (this._currentTrack.staves[0].bars.length > 0) {
6580
+ this._currentTrack.ensureStaveCount(this._currentTrack.staves.length + 1);
6581
+ this._currentStaff = this._currentTrack.staves[this._currentTrack.staves.length - 1];
6582
+ this._currentDynamics = DynamicValue.F;
6583
+ }
6584
+ this.staffProperties();
6585
+ }
6586
+ return true;
6555
6587
  }
6556
6588
  staffProperties() {
6557
6589
  if (this._sy !== AlphaTexSymbols.LBrace) {
@@ -6605,7 +6637,7 @@
6605
6637
  // reset to defaults
6606
6638
  this._currentStaff.displayTranspositionPitch = 0;
6607
6639
  this._currentStaff.stringTuning.tunings = [];
6608
- if (program == 15 || program >= 24 && program <= 31) {
6640
+ if (program == 15 || (program >= 24 && program <= 31)) {
6609
6641
  // dulcimer+guitar E4 B3 G3 D3 A2 E2
6610
6642
  this._currentStaff.displayTranspositionPitch = -12;
6611
6643
  this._currentStaff.stringTuning.tunings = Tuning.getDefaultTuningFor(6).tunings;
@@ -6723,7 +6755,7 @@
6723
6755
  beat.duration = this._currentDuration;
6724
6756
  beat.dynamics = this._currentDynamics;
6725
6757
  if (this._currentTuplet !== 1 && !beat.hasTuplet) {
6726
- this.applyTuplet(beat, this._currentTuplet);
6758
+ AlphaTexImporter.applyTuplet(beat, this._currentTuplet);
6727
6759
  }
6728
6760
  // beat multiplier (repeat beat n times)
6729
6761
  let beatRepeat = 1;
@@ -6788,7 +6820,6 @@
6788
6820
  }
6789
6821
  this._sy = this.newSy();
6790
6822
  while (this._sy === AlphaTexSymbols.String) {
6791
- this._syData = this._syData.toLowerCase();
6792
6823
  if (!this.applyBeatEffect(beat)) {
6793
6824
  this.error('beat-effects', AlphaTexSymbols.String, false);
6794
6825
  }
@@ -6837,7 +6868,7 @@
6837
6868
  this.error('tuplet', AlphaTexSymbols.Number, true);
6838
6869
  return false;
6839
6870
  }
6840
- this.applyTuplet(beat, this._syData);
6871
+ AlphaTexImporter.applyTuplet(beat, this._syData);
6841
6872
  }
6842
6873
  else if (syData === 'tb' || syData === 'tbe') {
6843
6874
  let exact = syData === 'tbe';
@@ -7024,7 +7055,7 @@
7024
7055
  getChordId(currentStaff, chordName) {
7025
7056
  return chordName.toLowerCase() + currentStaff.index + currentStaff.track.index;
7026
7057
  }
7027
- applyTuplet(beat, tuplet) {
7058
+ static applyTuplet(beat, tuplet) {
7028
7059
  switch (tuplet) {
7029
7060
  case 3:
7030
7061
  beat.tupletNumerator = 3;
@@ -7140,9 +7171,8 @@
7140
7171
  this._sy = this.newSy();
7141
7172
  while (this._sy === AlphaTexSymbols.String) {
7142
7173
  let syData = this._syData.toLowerCase();
7143
- this._syData = syData;
7144
7174
  if (syData === 'b' || syData === 'be') {
7145
- let exact = this._syData === 'be';
7175
+ let exact = syData === 'be';
7146
7176
  // read points
7147
7177
  this._sy = this.newSy();
7148
7178
  if (this._sy !== AlphaTexSymbols.LParensis) {
@@ -25632,7 +25662,7 @@
25632
25662
  settings = new Settings();
25633
25663
  }
25634
25664
  let importers = Environment.buildImporters();
25635
- Logger.debug('ScoreLoader', 'Loading score from ' + data.length + ' bytes using ' + importers.length + ' importers', null);
25665
+ Logger.debug('ScoreLoader', `Loading score from ${data.length} bytes using ${importers.length} importers`);
25636
25666
  let score = null;
25637
25667
  let bb = ByteBuffer.fromBuffer(data);
25638
25668
  for (let importer of importers) {
@@ -28306,7 +28336,8 @@
28306
28336
  let currentBeatGlyph = beatGlyphs[i];
28307
28337
  switch (currentBeatGlyph.beat.graceType) {
28308
28338
  case GraceType.None:
28309
- currentBeatGlyph.x = positions.get(currentBeatGlyph.beat.absoluteDisplayStart) * scale - currentBeatGlyph.onTimeX;
28339
+ currentBeatGlyph.x =
28340
+ positions.get(currentBeatGlyph.beat.absoluteDisplayStart) * scale - currentBeatGlyph.onTimeX;
28310
28341
  break;
28311
28342
  default:
28312
28343
  const graceDisplayStart = currentBeatGlyph.beat.graceGroup.beats[0].absoluteDisplayStart;
@@ -28315,14 +28346,21 @@
28315
28346
  if (currentBeatGlyph.beat.graceGroup.isComplete && positions.has(graceDisplayStart)) {
28316
28347
  currentBeatGlyph.x = positions.get(graceDisplayStart) * scale - currentBeatGlyph.onTimeX;
28317
28348
  let graceSprings = this.renderer.layoutingInfo.allGraceRods.get(graceGroupId);
28318
- let graceTargetPreBeat = this.renderer.layoutingInfo.springs.get(graceDisplayStart).preBeatWidth;
28349
+ // get the pre beat stretch of this voice/staff, not the
28350
+ // shared space. This way we use the potentially empty space (see discussions/1092).
28351
+ const afterGraceBeat = currentBeatGlyph.beat.graceGroup.beats[currentBeatGlyph.beat.graceGroup.beats.length - 1]
28352
+ .nextBeat;
28353
+ const preBeatStretch = afterGraceBeat
28354
+ ? this.renderer.layoutingInfo.getPreBeatSize(afterGraceBeat) +
28355
+ BeatContainerGlyph.GraceBeatPadding * this.renderer.scale
28356
+ : 0;
28319
28357
  // move right in front to the note
28320
- currentBeatGlyph.x -= graceTargetPreBeat;
28358
+ currentBeatGlyph.x -= preBeatStretch;
28321
28359
  // respect the post beat width of the grace note
28322
28360
  currentBeatGlyph.x -= graceSprings[currentBeatGlyph.beat.graceIndex].postSpringWidth;
28323
28361
  // shift to right position of the particular grace note
28324
28362
  currentBeatGlyph.x += graceSprings[currentBeatGlyph.beat.graceIndex].graceBeatWidth;
28325
- // move the whole group again forward for cases where another track has e.g. 3 beats and here we have only 2.
28363
+ // move the whole group again forward for cases where another track has e.g. 3 beats and here we have only 2.
28326
28364
  // so we shift the whole group of this voice to stick to the end of the group.
28327
28365
  const lastGraceSpring = graceSprings[currentBeatGlyph.beat.graceGroup.beats.length - 1];
28328
28366
  currentBeatGlyph.x -= lastGraceSpring.graceBeatWidth;
@@ -28330,21 +28368,22 @@
28330
28368
  else {
28331
28369
  // placement for improper grace beats where no beat in the same bar follows
28332
28370
  let graceSpring = this.renderer.layoutingInfo.incompleteGraceRods.get(graceGroupId);
28333
- const relativeOffset = graceSpring[currentBeatGlyph.beat.graceIndex].postSpringWidth
28334
- - graceSpring[currentBeatGlyph.beat.graceIndex].preSpringWidth;
28371
+ const relativeOffset = graceSpring[currentBeatGlyph.beat.graceIndex].postSpringWidth -
28372
+ graceSpring[currentBeatGlyph.beat.graceIndex].preSpringWidth;
28335
28373
  if (i > 0) {
28336
28374
  if (currentBeatGlyph.beat.graceIndex === 0) {
28337
28375
  // we place the grace beat directly after the previous one
28338
- // otherwise this causes flickers on resizing
28376
+ // otherwise this causes flickers on resizing
28339
28377
  currentBeatGlyph.x = beatGlyphs[i - 1].x + beatGlyphs[i - 1].width;
28340
28378
  }
28341
28379
  else {
28342
28380
  // for the multiple grace glyphs we take the width of the grace rod
28343
28381
  // this width setting is aligned with the positioning logic below
28344
- currentBeatGlyph.x = beatGlyphs[i - 1].x
28345
- + graceSpring[currentBeatGlyph.beat.graceIndex - 1].postSpringWidth
28346
- - graceSpring[currentBeatGlyph.beat.graceIndex - 1].preSpringWidth
28347
- - relativeOffset;
28382
+ currentBeatGlyph.x =
28383
+ beatGlyphs[i - 1].x +
28384
+ graceSpring[currentBeatGlyph.beat.graceIndex - 1].postSpringWidth -
28385
+ graceSpring[currentBeatGlyph.beat.graceIndex - 1].preSpringWidth -
28386
+ relativeOffset;
28348
28387
  }
28349
28388
  }
28350
28389
  else {
@@ -28394,8 +28433,7 @@
28394
28433
  this.tupletGroups.push(bg.beat.tupletGroup);
28395
28434
  }
28396
28435
  }
28397
- doLayout() {
28398
- }
28436
+ doLayout() { }
28399
28437
  paint(cx, cy, canvas) {
28400
28438
  // canvas.color = Color.random();
28401
28439
  // canvas.strokeRect(cx + this.x, cy + this.y, this.width, this.renderer.height);
@@ -32197,38 +32235,38 @@
32197
32235
  }
32198
32236
  }
32199
32237
  setPreBeatSize(beat, size) {
32200
- if (!this.preBeatSizes.has(beat.index) || this.preBeatSizes.get(beat.index) < size) {
32201
- this.preBeatSizes.set(beat.index, size);
32238
+ if (!this.preBeatSizes.has(beat.id) || this.preBeatSizes.get(beat.id) < size) {
32239
+ this.preBeatSizes.set(beat.id, size);
32202
32240
  this.version++;
32203
32241
  }
32204
32242
  }
32205
32243
  getPreBeatSize(beat) {
32206
- if (this.preBeatSizes.has(beat.index)) {
32207
- return this.preBeatSizes.get(beat.index);
32244
+ if (this.preBeatSizes.has(beat.id)) {
32245
+ return this.preBeatSizes.get(beat.id);
32208
32246
  }
32209
32247
  return 0;
32210
32248
  }
32211
32249
  setOnBeatSize(beat, size) {
32212
- if (!this.onBeatSizes.has(beat.index) || this.onBeatSizes.get(beat.index) < size) {
32213
- this.onBeatSizes.set(beat.index, size);
32250
+ if (!this.onBeatSizes.has(beat.id) || this.onBeatSizes.get(beat.id) < size) {
32251
+ this.onBeatSizes.set(beat.id, size);
32214
32252
  this.version++;
32215
32253
  }
32216
32254
  }
32217
32255
  getOnBeatSize(beat) {
32218
- if (this.onBeatSizes.has(beat.index)) {
32219
- return this.onBeatSizes.get(beat.index);
32256
+ if (this.onBeatSizes.has(beat.id)) {
32257
+ return this.onBeatSizes.get(beat.id);
32220
32258
  }
32221
32259
  return 0;
32222
32260
  }
32223
32261
  getBeatCenterX(beat) {
32224
- if (this.onBeatCenterX.has(beat.index)) {
32225
- return this.onBeatCenterX.get(beat.index);
32262
+ if (this.onBeatCenterX.has(beat.id)) {
32263
+ return this.onBeatCenterX.get(beat.id);
32226
32264
  }
32227
32265
  return 0;
32228
32266
  }
32229
32267
  setBeatCenterX(beat, x) {
32230
- if (!this.onBeatCenterX.has(beat.index) || this.onBeatCenterX.get(beat.index) < x) {
32231
- this.onBeatCenterX.set(beat.index, x);
32268
+ if (!this.onBeatCenterX.has(beat.id) || this.onBeatCenterX.get(beat.id) < x) {
32269
+ this.onBeatCenterX.set(beat.id, x);
32232
32270
  this.version++;
32233
32271
  }
32234
32272
  }
@@ -36222,16 +36260,19 @@
36222
36260
  this._beat = beat;
36223
36261
  }
36224
36262
  doLayout() {
36225
- this.width = 10 * this.scale;
36263
+ this.width =
36264
+ this._beat.brushType === BrushType.ArpeggioUp || this._beat.brushType === BrushType.ArpeggioDown
36265
+ ? 10 * this.scale
36266
+ : 0;
36226
36267
  }
36227
36268
  paint(cx, cy, canvas) {
36228
- let scoreBarRenderer = this.renderer;
36229
- let lineSize = scoreBarRenderer.lineOffset;
36230
- let startY = cy + this.y + (scoreBarRenderer.getNoteY(this._beat.maxNote, NoteYPosition.Bottom) - lineSize);
36231
- let endY = cy + this.y + scoreBarRenderer.getNoteY(this._beat.minNote, NoteYPosition.Top) + lineSize;
36232
- let arrowX = cx + this.x + this.width / 2;
36233
- let arrowSize = 8 * this.scale;
36234
- if (this._beat.brushType !== BrushType.None) {
36269
+ if (this._beat.brushType === BrushType.ArpeggioUp || this._beat.brushType === BrushType.ArpeggioDown) {
36270
+ let scoreBarRenderer = this.renderer;
36271
+ let lineSize = scoreBarRenderer.lineOffset;
36272
+ let startY = cy + this.y + (scoreBarRenderer.getNoteY(this._beat.maxNote, NoteYPosition.Bottom) - lineSize);
36273
+ let endY = cy + this.y + scoreBarRenderer.getNoteY(this._beat.minNote, NoteYPosition.Top) + lineSize;
36274
+ let arrowX = cx + this.x + this.width / 2;
36275
+ let arrowSize = 8 * this.scale;
36235
36276
  let glyph = new NoteVibratoGlyph(0, 0, VibratoType.Slight, 1.2, true);
36236
36277
  glyph.renderer = this.renderer;
36237
36278
  glyph.doLayout();
@@ -41355,8 +41396,8 @@
41355
41396
  // </auto-generated>
41356
41397
  class VersionInfo {
41357
41398
  }
41358
- VersionInfo.version = '1.3.0-alpha.518';
41359
- VersionInfo.date = '2023-01-14T01:08:10.114Z';
41399
+ VersionInfo.version = '1.3.0-alpha.520';
41400
+ VersionInfo.date = '2023-01-16T01:10:39.941Z';
41360
41401
 
41361
41402
  var index$5 = /*#__PURE__*/Object.freeze({
41362
41403
  __proto__: null,