@xterm/xterm 6.1.0-beta.23 → 6.1.0-beta.230

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +62 -38
  2. package/css/xterm.css +29 -22
  3. package/lib/xterm.js +1 -1
  4. package/lib/xterm.js.map +1 -1
  5. package/lib/xterm.mjs +8 -34
  6. package/lib/xterm.mjs.map +4 -4
  7. package/package.json +25 -22
  8. package/src/browser/AccessibilityManager.ts +11 -6
  9. package/src/browser/Clipboard.ts +6 -3
  10. package/src/browser/CoreBrowserTerminal.ts +147 -318
  11. package/src/browser/Dom.ts +178 -0
  12. package/src/browser/Linkifier.ts +11 -11
  13. package/src/browser/OscLinkProvider.ts +82 -14
  14. package/src/browser/RenderDebouncer.ts +2 -2
  15. package/src/browser/TimeBasedDebouncer.ts +2 -2
  16. package/src/browser/Types.ts +12 -11
  17. package/src/browser/Viewport.ts +55 -20
  18. package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
  19. package/src/browser/decorations/OverviewRulerRenderer.ts +33 -17
  20. package/src/browser/input/CompositionHelper.ts +44 -8
  21. package/src/browser/public/Terminal.ts +25 -28
  22. package/src/browser/renderer/dom/DomRenderer.ts +242 -76
  23. package/src/browser/renderer/dom/DomRendererRowFactory.ts +19 -13
  24. package/src/browser/renderer/dom/WidthCache.ts +54 -52
  25. package/src/browser/renderer/shared/Constants.ts +7 -0
  26. package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
  27. package/src/browser/renderer/shared/Types.ts +8 -2
  28. package/src/browser/scrollable/abstractScrollbar.ts +300 -0
  29. package/src/browser/scrollable/fastDomNode.ts +126 -0
  30. package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
  31. package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
  32. package/src/browser/scrollable/mouseEvent.ts +292 -0
  33. package/src/browser/scrollable/scrollable.ts +486 -0
  34. package/src/browser/scrollable/scrollableElement.ts +581 -0
  35. package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
  36. package/src/browser/scrollable/scrollbarArrow.ts +110 -0
  37. package/src/browser/scrollable/scrollbarState.ts +246 -0
  38. package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
  39. package/src/browser/scrollable/touch.ts +485 -0
  40. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  41. package/src/browser/scrollable/widget.ts +23 -0
  42. package/src/browser/services/CharSizeService.ts +2 -2
  43. package/src/browser/services/CoreBrowserService.ts +7 -5
  44. package/src/browser/services/KeyboardService.ts +67 -0
  45. package/src/browser/services/LinkProviderService.ts +1 -1
  46. package/src/browser/services/MouseCoordsService.ts +47 -0
  47. package/src/browser/services/MouseService.ts +518 -25
  48. package/src/browser/services/RenderService.ts +28 -16
  49. package/src/browser/services/SelectionService.ts +42 -35
  50. package/src/browser/services/Services.ts +40 -17
  51. package/src/browser/services/ThemeService.ts +2 -2
  52. package/src/common/Async.ts +141 -0
  53. package/src/common/CircularList.ts +2 -2
  54. package/src/common/Color.ts +8 -0
  55. package/src/common/CoreTerminal.ts +31 -21
  56. package/src/common/Event.ts +118 -0
  57. package/src/common/InputHandler.ts +283 -81
  58. package/src/common/Lifecycle.ts +113 -0
  59. package/src/common/Platform.ts +13 -3
  60. package/src/common/SortedList.ts +7 -3
  61. package/src/common/TaskQueue.ts +14 -5
  62. package/src/common/Types.ts +51 -31
  63. package/src/common/Version.ts +9 -0
  64. package/src/common/buffer/Buffer.ts +34 -19
  65. package/src/common/buffer/BufferLine.ts +133 -65
  66. package/src/common/buffer/BufferLineStringCache.ts +69 -0
  67. package/src/common/buffer/BufferSet.ts +11 -6
  68. package/src/common/buffer/CellData.ts +57 -0
  69. package/src/common/buffer/Marker.ts +2 -2
  70. package/src/common/buffer/Types.ts +6 -2
  71. package/src/common/data/EscapeSequences.ts +71 -70
  72. package/src/common/input/Keyboard.ts +14 -7
  73. package/src/common/input/KittyKeyboard.ts +526 -0
  74. package/src/common/input/Win32InputMode.ts +297 -0
  75. package/src/common/input/WriteBuffer.ts +69 -32
  76. package/src/common/input/XParseColor.ts +2 -2
  77. package/src/common/parser/ApcParser.ts +197 -0
  78. package/src/common/parser/Constants.ts +14 -4
  79. package/src/common/parser/DcsParser.ts +5 -5
  80. package/src/common/parser/EscapeSequenceParser.ts +205 -63
  81. package/src/common/parser/OscParser.ts +5 -5
  82. package/src/common/parser/Params.ts +27 -8
  83. package/src/common/parser/Types.ts +36 -2
  84. package/src/common/public/BufferLineApiView.ts +2 -2
  85. package/src/common/public/BufferNamespaceApi.ts +3 -3
  86. package/src/common/public/ParserApi.ts +3 -0
  87. package/src/common/services/BufferService.ts +14 -9
  88. package/src/common/services/CharsetService.ts +4 -0
  89. package/src/common/services/CoreService.ts +18 -4
  90. package/src/common/services/DecorationService.ts +258 -8
  91. package/src/common/services/LogService.ts +1 -31
  92. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
  93. package/src/common/services/OptionsService.ts +13 -4
  94. package/src/common/services/ServiceRegistry.ts +9 -7
  95. package/src/common/services/Services.ts +49 -40
  96. package/src/common/services/UnicodeService.ts +1 -1
  97. package/typings/xterm.d.ts +318 -34
  98. package/src/common/TypedArrayUtils.ts +0 -17
  99. package/src/vs/base/browser/browser.ts +0 -141
  100. package/src/vs/base/browser/canIUse.ts +0 -49
  101. package/src/vs/base/browser/dom.ts +0 -2369
  102. package/src/vs/base/browser/fastDomNode.ts +0 -316
  103. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  104. package/src/vs/base/browser/iframe.ts +0 -135
  105. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  106. package/src/vs/base/browser/mouseEvent.ts +0 -229
  107. package/src/vs/base/browser/touch.ts +0 -372
  108. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  109. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  110. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  111. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  112. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  113. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  114. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  115. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  116. package/src/vs/base/browser/ui/widget.ts +0 -57
  117. package/src/vs/base/browser/window.ts +0 -14
  118. package/src/vs/base/common/arrays.ts +0 -887
  119. package/src/vs/base/common/arraysFind.ts +0 -202
  120. package/src/vs/base/common/assert.ts +0 -71
  121. package/src/vs/base/common/async.ts +0 -1992
  122. package/src/vs/base/common/cancellation.ts +0 -148
  123. package/src/vs/base/common/charCode.ts +0 -450
  124. package/src/vs/base/common/collections.ts +0 -140
  125. package/src/vs/base/common/decorators.ts +0 -130
  126. package/src/vs/base/common/equals.ts +0 -146
  127. package/src/vs/base/common/errors.ts +0 -303
  128. package/src/vs/base/common/event.ts +0 -1778
  129. package/src/vs/base/common/functional.ts +0 -32
  130. package/src/vs/base/common/hash.ts +0 -316
  131. package/src/vs/base/common/iterator.ts +0 -159
  132. package/src/vs/base/common/keyCodes.ts +0 -526
  133. package/src/vs/base/common/keybindings.ts +0 -284
  134. package/src/vs/base/common/lazy.ts +0 -47
  135. package/src/vs/base/common/lifecycle.ts +0 -801
  136. package/src/vs/base/common/linkedList.ts +0 -142
  137. package/src/vs/base/common/map.ts +0 -202
  138. package/src/vs/base/common/numbers.ts +0 -98
  139. package/src/vs/base/common/observable.ts +0 -76
  140. package/src/vs/base/common/observableInternal/api.ts +0 -31
  141. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  142. package/src/vs/base/common/observableInternal/base.ts +0 -489
  143. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  144. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  145. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  146. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  147. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  148. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  149. package/src/vs/base/common/platform.ts +0 -281
  150. package/src/vs/base/common/scrollable.ts +0 -522
  151. package/src/vs/base/common/sequence.ts +0 -34
  152. package/src/vs/base/common/stopwatch.ts +0 -43
  153. package/src/vs/base/common/strings.ts +0 -557
  154. package/src/vs/base/common/symbols.ts +0 -9
  155. package/src/vs/base/common/uint.ts +0 -59
  156. package/src/vs/patches/nls.ts +0 -90
  157. package/src/vs/typings/base-common.d.ts +0 -20
  158. package/src/vs/typings/require.d.ts +0 -42
  159. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  160. package/src/vs/typings/vscode-globals-product.d.ts +0 -33
@@ -14,13 +14,18 @@ export const enum ParserState {
14
14
  CSI_PARAM = 4,
15
15
  CSI_INTERMEDIATE = 5,
16
16
  CSI_IGNORE = 6,
17
- SOS_PM_APC_STRING = 7,
17
+ SOS_PM_STRING = 7,
18
18
  OSC_STRING = 8,
19
19
  DCS_ENTRY = 9,
20
20
  DCS_PARAM = 10,
21
21
  DCS_IGNORE = 11,
22
22
  DCS_INTERMEDIATE = 12,
23
- DCS_PASSTHROUGH = 13
23
+ DCS_PASSTHROUGH = 13,
24
+ APC_ENTRY = 14,
25
+ APC_INTERMEDIATE = 15,
26
+ APC_PASSTHROUGH = 16,
27
+ // Number of states, meaning LAST_STATE + 1.
28
+ STATE_LENGTH = 17
24
29
  }
25
30
 
26
31
  /**
@@ -41,7 +46,10 @@ export const enum ParserAction {
41
46
  CLEAR = 11,
42
47
  DCS_HOOK = 12,
43
48
  DCS_PUT = 13,
44
- DCS_UNHOOK = 14
49
+ DCS_UNHOOK = 14,
50
+ APC_START = 15,
51
+ APC_PUT = 16,
52
+ APC_END = 17
45
53
  }
46
54
 
47
55
  /**
@@ -55,4 +63,6 @@ export const enum OscState {
55
63
  }
56
64
 
57
65
  // payload limit for OSC and DCS
58
- export const PAYLOAD_LIMIT = 10000000;
66
+ export const enum ParserConstants {
67
+ PAYLOAD_LIMIT = 10000000
68
+ }
@@ -7,7 +7,7 @@ import { IDisposable } from 'common/Types';
7
7
  import { IDcsHandler, IParams, IHandlerCollection, IDcsParser, DcsFallbackHandlerType, ISubParserStackState } from 'common/parser/Types';
8
8
  import { utf32ToString } from 'common/input/TextDecoder';
9
9
  import { Params } from 'common/parser/Params';
10
- import { PAYLOAD_LIMIT } from 'common/parser/Constants';
10
+ import { ParserConstants } from 'common/parser/Constants';
11
11
 
12
12
  const EMPTY_HANDLERS: IDcsHandler[] = [];
13
13
 
@@ -29,9 +29,7 @@ export class DcsParser implements IDcsParser {
29
29
  }
30
30
 
31
31
  public registerHandler(ident: number, handler: IDcsHandler): IDisposable {
32
- if (this._handlers[ident] === undefined) {
33
- this._handlers[ident] = [];
34
- }
32
+ this._handlers[ident] ??= [];
35
33
  const handlerList = this._handlers[ident];
36
34
  handlerList.push(handler);
37
35
  return {
@@ -140,6 +138,8 @@ EMPTY_PARAMS.addParam(0);
140
138
  * Note: The payload is currently limited to 50 MB (hardcoded).
141
139
  */
142
140
  export class DcsHandler implements IDcsHandler {
141
+ private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
142
+
143
143
  private _data = '';
144
144
  private _params: IParams = EMPTY_PARAMS;
145
145
  private _hitLimit: boolean = false;
@@ -161,7 +161,7 @@ export class DcsHandler implements IDcsHandler {
161
161
  return;
162
162
  }
163
163
  this._data += utf32ToString(data, start, end);
164
- if (this._data.length > PAYLOAD_LIMIT) {
164
+ if (this._data.length > DcsHandler._payloadLimit) {
165
165
  this._data = '';
166
166
  this._hitLimit = true;
167
167
  }
@@ -3,13 +3,32 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType } from 'common/parser/Types';
6
+ import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from 'common/parser/Types';
7
7
  import { ParserState, ParserAction } from 'common/parser/Constants';
8
- import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
8
+ import { Disposable, toDisposable } from 'common/Lifecycle';
9
9
  import { IDisposable } from 'common/Types';
10
10
  import { Params } from 'common/parser/Params';
11
11
  import { OscParser } from 'common/parser/OscParser';
12
12
  import { DcsParser } from 'common/parser/DcsParser';
13
+ import { ApcParser } from 'common/parser/ApcParser';
14
+
15
+ /**
16
+ * VT commands done by the parser
17
+ */
18
+ // @vt: #Y ESC CSI "Control Sequence Introducer" "ESC [" "Start of a CSI sequence."
19
+ // @vt: #Y ESC OSC "Operating System Command" "ESC ]" "Start of an OSC sequence."
20
+ // @vt: #Y ESC DCS "Device Control String" "ESC P" "Start of a DCS sequence."
21
+ // @vt: #Y ESC ST "String Terminator" "ESC \" "Terminator used for string type sequences."
22
+ // @vt: #Y ESC PM "Privacy Message" "ESC ^" "Start of a privacy message."
23
+ // @vt: #Y ESC APC "Application Program Command" "ESC _" "Start of an APC sequence."
24
+ // @vt: #Y C1 CSI "Control Sequence Introducer" "\x9B" "Start of a CSI sequence."
25
+ // @vt: #Y C1 OSC "Operating System Command" "\x9D" "Start of an OSC sequence."
26
+ // @vt: #Y C1 DCS "Device Control String" "\x90" "Start of a DCS sequence."
27
+ // @vt: #Y C1 ST "String Terminator" "\x9C" "Terminator used for string type sequences."
28
+ // @vt: #Y C1 PM "Privacy Message" "\x9E" "Start of a privacy message."
29
+ // @vt: #Y C1 APC "Application Program Command" "\x9F" "Start of an APC sequence."
30
+ // @vt: #Y C0 NUL "Null" "\0, \x00" "NUL is ignored."
31
+ // @vt: #Y C0 ESC "Escape" "\e, \x1B" "Start of a sequence. Cancels any other sequence."
13
32
 
14
33
  /**
15
34
  * Table values are generated like this:
@@ -17,8 +36,8 @@ import { DcsParser } from 'common/parser/DcsParser';
17
36
  * value: action << TableValue.TRANSITION_ACTION_SHIFT | nextState
18
37
  */
19
38
  const enum TableAccess {
20
- TRANSITION_ACTION_SHIFT = 4,
21
- TRANSITION_STATE_MASK = 15,
39
+ TRANSITION_ACTION_SHIFT = 8,
40
+ TRANSITION_STATE_MASK = 255,
22
41
  INDEX_STATE_SHIFT = 8
23
42
  }
24
43
 
@@ -26,10 +45,10 @@ const enum TableAccess {
26
45
  * Transition table for EscapeSequenceParser.
27
46
  */
28
47
  export class TransitionTable {
29
- public table: Uint8Array;
48
+ public table: Uint16Array;
30
49
 
31
50
  constructor(length: number) {
32
- this.table = new Uint8Array(length);
51
+ this.table = new Uint16Array(length);
33
52
  }
34
53
 
35
54
  /**
@@ -76,7 +95,9 @@ const NON_ASCII_PRINTABLE = 0xA0;
76
95
  * Taken from https://vt100.net/emu/dec_ansi_parser.
77
96
  */
78
97
  export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
79
- const table: TransitionTable = new TransitionTable(4095);
98
+ // table size:
99
+ // (ParserState.STATE_LENGTH - 1) << TableAccess.INDEX_STATE_SHIFT | NON_ASCII_PRINTABLE + 1
100
+ const table: TransitionTable = new TransitionTable(4257);
80
101
 
81
102
  // range macro for byte
82
103
  const BYTE_VALUES = 256;
@@ -89,22 +110,22 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
89
110
  EXECUTABLES.push(0x19);
90
111
  EXECUTABLES.push.apply(EXECUTABLES, r(0x1c, 0x20));
91
112
 
92
- const states: number[] = r(ParserState.GROUND, ParserState.DCS_PASSTHROUGH + 1);
93
- let state: any;
113
+ const states: number[] = r(ParserState.GROUND, ParserState.STATE_LENGTH);
94
114
 
95
115
  // set default transition
96
116
  table.setDefault(ParserAction.ERROR, ParserState.GROUND);
97
117
  // printables
98
118
  table.addMany(PRINTABLES, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
99
119
  // global anywhere rules
100
- for (state in states) {
120
+ for (const state of states) {
101
121
  table.addMany([0x18, 0x1a, 0x99, 0x9a], state, ParserAction.EXECUTE, ParserState.GROUND);
102
122
  table.addMany(r(0x80, 0x90), state, ParserAction.EXECUTE, ParserState.GROUND);
103
123
  table.addMany(r(0x90, 0x98), state, ParserAction.EXECUTE, ParserState.GROUND);
104
124
  table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator
105
125
  table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC
106
126
  table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC
107
- table.addMany([0x98, 0x9e, 0x9f], state, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
127
+ table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_STRING); // SOS, PM
128
+ table.add(0x9f, state, ParserAction.CLEAR, ParserState.APC_ENTRY); // APC
108
129
  table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI
109
130
  table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS
110
131
  }
@@ -128,12 +149,27 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
128
149
  table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
129
150
  table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);
130
151
  table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);
131
- // sos/pm/apc does nothing
132
- table.addMany([0x58, 0x5e, 0x5f], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
133
- table.addMany(PRINTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
134
- table.addMany(EXECUTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
135
- table.add(0x9c, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.GROUND);
136
- table.add(0x7f, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
152
+ // sos/pm
153
+ table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
154
+ table.addMany(PRINTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
155
+ table.addMany(EXECUTABLES, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
156
+ table.add(0x9c, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.GROUND);
157
+ table.add(0x7f, ParserState.SOS_PM_STRING, ParserAction.IGNORE, ParserState.SOS_PM_STRING);
158
+ // apc
159
+ table.add(0x5f, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.APC_ENTRY);
160
+ table.addMany(EXECUTABLES, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);
161
+ table.add(0x7f, ParserState.APC_ENTRY, ParserAction.IGNORE, ParserState.APC_ENTRY);
162
+ table.addMany(r(0x20, 0x30), ParserState.APC_ENTRY, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);
163
+ table.addMany(r(0x30, 0x7f), ParserState.APC_ENTRY, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);
164
+ table.addMany(r(0x30, 0x7f), ParserState.APC_INTERMEDIATE, ParserAction.APC_START, ParserState.APC_PASSTHROUGH);
165
+ table.addMany(EXECUTABLES, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);
166
+ table.addMany(r(0x20, 0x30), ParserState.APC_INTERMEDIATE, ParserAction.COLLECT, ParserState.APC_INTERMEDIATE);
167
+ table.add(0x7f, ParserState.APC_INTERMEDIATE, ParserAction.IGNORE, ParserState.APC_INTERMEDIATE);
168
+ table.addMany(PRINTABLES, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
169
+ table.addMany(EXECUTABLES, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);
170
+ table.addMany(r(0x08, 0x0e), ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
171
+ table.add(0x7f, ParserState.APC_PASSTHROUGH, ParserAction.IGNORE, ParserState.APC_PASSTHROUGH);
172
+ table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_PASSTHROUGH, ParserAction.APC_END, ParserState.GROUND);
137
173
  // csi entries
138
174
  table.add(0x5b, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.CSI_ENTRY);
139
175
  table.addMany(r(0x40, 0x7f), ParserState.CSI_ENTRY, ParserAction.CSI_DISPATCH, ParserState.GROUND);
@@ -162,22 +198,18 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
162
198
  table.add(0x50, ParserState.ESCAPE, ParserAction.CLEAR, ParserState.DCS_ENTRY);
163
199
  table.addMany(EXECUTABLES, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
164
200
  table.add(0x7f, ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
165
- table.addMany(r(0x1c, 0x20), ParserState.DCS_ENTRY, ParserAction.IGNORE, ParserState.DCS_ENTRY);
166
201
  table.addMany(r(0x20, 0x30), ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
167
202
  table.addMany(r(0x30, 0x3c), ParserState.DCS_ENTRY, ParserAction.PARAM, ParserState.DCS_PARAM);
168
203
  table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_ENTRY, ParserAction.COLLECT, ParserState.DCS_PARAM);
169
204
  table.addMany(EXECUTABLES, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
170
205
  table.addMany(r(0x20, 0x80), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
171
- table.addMany(r(0x1c, 0x20), ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
172
206
  table.addMany(EXECUTABLES, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
173
207
  table.add(0x7f, ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
174
- table.addMany(r(0x1c, 0x20), ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_PARAM);
175
208
  table.addMany(r(0x30, 0x3c), ParserState.DCS_PARAM, ParserAction.PARAM, ParserState.DCS_PARAM);
176
209
  table.addMany([0x3c, 0x3d, 0x3e, 0x3f], ParserState.DCS_PARAM, ParserAction.IGNORE, ParserState.DCS_IGNORE);
177
210
  table.addMany(r(0x20, 0x30), ParserState.DCS_PARAM, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
178
211
  table.addMany(EXECUTABLES, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
179
212
  table.add(0x7f, ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
180
- table.addMany(r(0x1c, 0x20), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_INTERMEDIATE);
181
213
  table.addMany(r(0x20, 0x30), ParserState.DCS_INTERMEDIATE, ParserAction.COLLECT, ParserState.DCS_INTERMEDIATE);
182
214
  table.addMany(r(0x30, 0x40), ParserState.DCS_INTERMEDIATE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
183
215
  table.addMany(r(0x40, 0x7f), ParserState.DCS_INTERMEDIATE, ParserAction.DCS_HOOK, ParserState.DCS_PASSTHROUGH);
@@ -193,6 +225,7 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
193
225
  table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
194
226
  table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
195
227
  table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
228
+ table.add(NON_ASCII_PRINTABLE, ParserState.APC_PASSTHROUGH, ParserAction.APC_PUT, ParserState.APC_PASSTHROUGH);
196
229
  return table;
197
230
  })();
198
231
 
@@ -239,10 +272,13 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
239
272
  // handler lookup containers
240
273
  protected _printHandler: PrintHandlerType;
241
274
  protected _executeHandlers: { [flag: number]: ExecuteHandlerType };
275
+ // fast path for EXE bytes < 0x18
276
+ protected _executeHandlersArr: (ExecuteHandlerType | undefined)[];
242
277
  protected _csiHandlers: IHandlerCollection<CsiHandlerType>;
243
278
  protected _escHandlers: IHandlerCollection<EscHandlerType>;
244
279
  protected readonly _oscParser: IOscParser;
245
280
  protected readonly _dcsParser: IDcsParser;
281
+ protected readonly _apcParser: IApcParser;
246
282
  protected _errorHandler: (state: IParsingState) => IParsingState;
247
283
 
248
284
  // fallback handlers
@@ -281,15 +317,18 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
281
317
  this._errorHandlerFb = (state: IParsingState): IParsingState => state;
282
318
  this._printHandler = this._printHandlerFb;
283
319
  this._executeHandlers = Object.create(null);
320
+ this._executeHandlersArr = new Array(0x18).fill(undefined);
284
321
  this._csiHandlers = Object.create(null);
285
322
  this._escHandlers = Object.create(null);
286
323
  this._register(toDisposable(() => {
287
324
  this._csiHandlers = Object.create(null);
288
325
  this._executeHandlers = Object.create(null);
326
+ this._executeHandlersArr = new Array(0x18).fill(undefined);
289
327
  this._escHandlers = Object.create(null);
290
328
  }));
291
329
  this._oscParser = this._register(new OscParser());
292
330
  this._dcsParser = this._register(new DcsParser());
331
+ this._apcParser = this._register(new ApcParser());
293
332
  this._errorHandler = this._errorHandlerFb;
294
333
 
295
334
  // swallow 7bit ST (ESC+\)
@@ -351,9 +390,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
351
390
 
352
391
  public registerEscHandler(id: IFunctionIdentifier, handler: EscHandlerType): IDisposable {
353
392
  const ident = this._identifier(id, [0x30, 0x7e]);
354
- if (this._escHandlers[ident] === undefined) {
355
- this._escHandlers[ident] = [];
356
- }
393
+ this._escHandlers[ident] ??= [];
357
394
  const handlerList = this._escHandlers[ident];
358
395
  handlerList.push(handler);
359
396
  return {
@@ -373,10 +410,14 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
373
410
  }
374
411
 
375
412
  public setExecuteHandler(flag: string, handler: ExecuteHandlerType): void {
376
- this._executeHandlers[flag.charCodeAt(0)] = handler;
413
+ const code = flag.charCodeAt(0);
414
+ this._executeHandlers[code] = handler;
415
+ if (code < 0x18) this._executeHandlersArr[code] = handler;
377
416
  }
378
417
  public clearExecuteHandler(flag: string): void {
379
- if (this._executeHandlers[flag.charCodeAt(0)]) delete this._executeHandlers[flag.charCodeAt(0)];
418
+ const code = flag.charCodeAt(0);
419
+ if (this._executeHandlers[code]) delete this._executeHandlers[code];
420
+ if (code < 0x18) this._executeHandlersArr[code] = undefined;
380
421
  }
381
422
  public setExecuteHandlerFallback(handler: ExecuteFallbackHandlerType): void {
382
423
  this._executeHandlerFb = handler;
@@ -384,9 +425,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
384
425
 
385
426
  public registerCsiHandler(id: IFunctionIdentifier, handler: CsiHandlerType): IDisposable {
386
427
  const ident = this._identifier(id);
387
- if (this._csiHandlers[ident] === undefined) {
388
- this._csiHandlers[ident] = [];
389
- }
428
+ this._csiHandlers[ident] ??= [];
390
429
  const handlerList = this._csiHandlers[ident];
391
430
  handlerList.push(handler);
392
431
  return {
@@ -425,6 +464,18 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
425
464
  this._oscParser.setHandlerFallback(handler);
426
465
  }
427
466
 
467
+ public registerApcHandler(id: IFunctionIdentifier, handler: IApcHandler): IDisposable {
468
+ id.prefix = undefined; // APC does not support prefix byte
469
+ return this._apcParser.registerHandler(this._identifier(id, [0x30, 0x7e]), handler);
470
+ }
471
+ public clearApcHandler(id: IFunctionIdentifier): void {
472
+ id.prefix = undefined; // APC does not support prefix byte
473
+ this._apcParser.clearHandler(this._identifier(id, [0x30, 0x7e]));
474
+ }
475
+ public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {
476
+ this._apcParser.setHandlerFallback(handler);
477
+ }
478
+
428
479
  public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {
429
480
  this._errorHandler = callback;
430
481
  }
@@ -445,8 +496,8 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
445
496
  this.currentState = this.initialState;
446
497
  this._oscParser.reset();
447
498
  this._dcsParser.reset();
448
- this._params.reset();
449
- this._params.addParam(0); // ZDM
499
+ this._apcParser.reset();
500
+ this._params.resetZdm();
450
501
  this._collect = 0;
451
502
  this.precedingJoinState = 0;
452
503
  // abort pending continuation from async handler
@@ -489,6 +540,10 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
489
540
  * - OSC_STRING:OSC_PUT
490
541
  * - DCS_PASSTHROUGH:DCS_PUT
491
542
  *
543
+ * Additionally the following fast paths exist before the table lookup:
544
+ * - EXE bytes < 0x18 in non-payload states (avoids table lookup entirely)
545
+ * - 7-bit CSI sequences without intermediates (ESC [ params final)
546
+ *
492
547
  * Note on asynchronous handler support:
493
548
  * Any handler returning a promise will be treated as asynchronous.
494
549
  * To keep the in-band blocking working for async handlers, `parse` pauses execution,
@@ -591,8 +646,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
591
646
  return handlerResult;
592
647
  }
593
648
  if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
594
- this._params.reset();
595
- this._params.addParam(0); // ZDM
649
+ this._params.resetZdm();
596
650
  this._collect = 0;
597
651
  break;
598
652
  case ParserStackType.OSC:
@@ -602,8 +656,17 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
602
656
  return handlerResult;
603
657
  }
604
658
  if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
605
- this._params.reset();
606
- this._params.addParam(0); // ZDM
659
+ this._params.resetZdm();
660
+ this._collect = 0;
661
+ break;
662
+ case ParserStackType.APC:
663
+ code = data[this._parseStack.chunkPos];
664
+ handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);
665
+ if (handlerResult) {
666
+ return handlerResult;
667
+ }
668
+ if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
669
+ this._params.resetZdm();
607
670
  this._collect = 0;
608
671
  break;
609
672
  }
@@ -621,34 +684,90 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
621
684
  for (let i = start; i < length; ++i) {
622
685
  code = data[i];
623
686
 
687
+ // EXE fast-path: common control bytes (0x00-0x17) in non-payload states
688
+ if (code < 0x18 && this.currentState <= ParserState.CSI_IGNORE) {
689
+ (this._executeHandlersArr[code] ?? this._executeHandlerFb)(code);
690
+ this.precedingJoinState = 0;
691
+ continue;
692
+ }
693
+
694
+ // CSI fast-path: collapse ESC [ into a single entry, parse params+final in a tight loop
695
+ if (code === 0x1b
696
+ && this.currentState < ParserState.OSC_STRING
697
+ && i + 2 < length && data[i + 1] === 0x5b
698
+ ) {
699
+ this._params.resetZdm();
700
+ this._collect = 0;
701
+ let k = i + 2;
702
+ let ch = data[k];
703
+ if (ch >= 0x3c && ch <= 0x3f) {
704
+ this._collect = ch;
705
+ k++;
706
+ }
707
+ let csiDone = false;
708
+ for (; k < length; k++) {
709
+ ch = data[k];
710
+ if (ch >= 0x30 && ch <= 0x39) {
711
+ this._params.addDigit(ch - 48);
712
+ } else if (ch === 0x3b) {
713
+ this._params.addParam(0);
714
+ } else if (ch === 0x3a) {
715
+ this._params.addSubParam(-1);
716
+ } else if (ch >= 0x40 && ch <= 0x7e) {
717
+ const handlers = this._csiHandlers[this._collect << 8 | ch];
718
+ let j = handlers ? handlers.length - 1 : -1;
719
+ for (; j >= 0; j--) {
720
+ handlerResult = handlers[j](this._params);
721
+ if (handlerResult === true) {
722
+ break;
723
+ } else if (handlerResult instanceof Promise) {
724
+ transition = ParserAction.CSI_DISPATCH << TableAccess.TRANSITION_ACTION_SHIFT | ParserState.GROUND;
725
+ this._preserveStack(ParserStackType.CSI, handlers, j, transition, k);
726
+ return handlerResult;
727
+ }
728
+ }
729
+ if (j < 0) {
730
+ this._csiHandlerFb(this._collect << 8 | ch, this._params);
731
+ }
732
+ this.precedingJoinState = 0;
733
+ i = k;
734
+ this.currentState = ParserState.GROUND;
735
+ csiDone = true;
736
+ break;
737
+ } else {
738
+ break;
739
+ }
740
+ }
741
+ if (!csiDone) {
742
+ i = k - 1;
743
+ this.currentState = ParserState.CSI_PARAM;
744
+ }
745
+ continue;
746
+ }
747
+
624
748
  // normal transition & action lookup
625
- transition = this._transitions.table[this.currentState << TableAccess.INDEX_STATE_SHIFT | (code < 0xa0 ? code : NON_ASCII_PRINTABLE)];
749
+ transition = this._transitions.table[
750
+ this.currentState << TableAccess.INDEX_STATE_SHIFT |
751
+ (code < NON_ASCII_PRINTABLE ? code : NON_ASCII_PRINTABLE)
752
+ ];
626
753
  switch (transition >> TableAccess.TRANSITION_ACTION_SHIFT) {
627
754
  case ParserAction.PRINT:
628
- // read ahead with loop unrolling
629
755
  // Note: 0x20 (SP) is included, 0x7F (DEL) is excluded
630
- for (let j = i + 1; ; ++j) {
631
- if (j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
632
- this._printHandler(data, i, j);
633
- i = j - 1;
634
- break;
635
- }
636
- if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
637
- this._printHandler(data, i, j);
638
- i = j - 1;
639
- break;
640
- }
641
- if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
642
- this._printHandler(data, i, j);
643
- i = j - 1;
644
- break;
645
- }
646
- if (++j >= length || (code = data[j]) < 0x20 || (code > 0x7e && code < NON_ASCII_PRINTABLE)) {
647
- this._printHandler(data, i, j);
648
- i = j - 1;
649
- break;
756
+ let c = i;
757
+ const l4 = length - 4;
758
+ while (c < l4
759
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
760
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
761
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
762
+ && data[++c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)
763
+ ) {}
764
+ if (c >= l4) {
765
+ while (c < length && data[c] >= 0x20 && (data[c] <= 0x7e || data[c] >= NON_ASCII_PRINTABLE)) {
766
+ c++;
650
767
  }
651
768
  }
769
+ this._printHandler(data, i, c);
770
+ i = c - 1;
652
771
  break;
653
772
  case ParserAction.EXECUTE:
654
773
  if (this._executeHandlers[code]) this._executeHandlers[code]();
@@ -730,8 +849,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
730
849
  this.precedingJoinState = 0;
731
850
  break;
732
851
  case ParserAction.CLEAR:
733
- this._params.reset();
734
- this._params.addParam(0); // ZDM
852
+ this._params.resetZdm();
735
853
  this._collect = 0;
736
854
  break;
737
855
  case ParserAction.DCS_HOOK:
@@ -755,8 +873,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
755
873
  return handlerResult;
756
874
  }
757
875
  if (code === 0x1b) transition |= ParserState.ESCAPE;
758
- this._params.reset();
759
- this._params.addParam(0); // ZDM
876
+ this._params.resetZdm();
760
877
  this._collect = 0;
761
878
  this.precedingJoinState = 0;
762
879
  break;
@@ -780,8 +897,33 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
780
897
  return handlerResult;
781
898
  }
782
899
  if (code === 0x1b) transition |= ParserState.ESCAPE;
783
- this._params.reset();
784
- this._params.addParam(0); // ZDM
900
+ this._params.resetZdm();
901
+ this._collect = 0;
902
+ this.precedingJoinState = 0;
903
+ break;
904
+ case ParserAction.APC_START:
905
+ this._apcParser.start(this._collect << 8 | code);
906
+ break;
907
+ case ParserAction.APC_PUT:
908
+ // inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c
909
+ // allowed: 00/08 .. 00/13, 02/00 .. 07/14 + NON_ASCII_PRINTABLE
910
+ for (let j = i + 1; ; ++j) {
911
+ if (j < length && (
912
+ (data[j] >= 0x20 && data[j] < 0x7f) || (data[j] >= 0x08 && data[j] < 0x0e) || data[j] >= NON_ASCII_PRINTABLE
913
+ )) continue;
914
+ this._apcParser.put(data, i, j);
915
+ i = j - 1;
916
+ break;
917
+ }
918
+ break;
919
+ case ParserAction.APC_END:
920
+ handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);
921
+ if (handlerResult) {
922
+ this._preserveStack(ParserStackType.APC, [], 0, transition, i);
923
+ return handlerResult;
924
+ }
925
+ if (code === 0x1b) transition |= ParserState.ESCAPE;
926
+ this._params.resetZdm();
785
927
  this._collect = 0;
786
928
  this.precedingJoinState = 0;
787
929
  break;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { IOscHandler, IHandlerCollection, OscFallbackHandlerType, IOscParser, ISubParserStackState } from 'common/parser/Types';
7
- import { OscState, PAYLOAD_LIMIT } from 'common/parser/Constants';
7
+ import { OscState, ParserConstants } from 'common/parser/Constants';
8
8
  import { utf32ToString } from 'common/input/TextDecoder';
9
9
  import { IDisposable } from 'common/Types';
10
10
 
@@ -23,9 +23,7 @@ export class OscParser implements IOscParser {
23
23
  };
24
24
 
25
25
  public registerHandler(ident: number, handler: IOscHandler): IDisposable {
26
- if (this._handlers[ident] === undefined) {
27
- this._handlers[ident] = [];
28
- }
26
+ this._handlers[ident] ??= [];
29
27
  const handlerList = this._handlers[ident];
30
28
  handlerList.push(handler);
31
29
  return {
@@ -194,6 +192,8 @@ export class OscParser implements IOscParser {
194
192
  * as OSC handlers.
195
193
  */
196
194
  export class OscHandler implements IOscHandler {
195
+ private static _payloadLimit = ParserConstants.PAYLOAD_LIMIT;
196
+
197
197
  private _data = '';
198
198
  private _hitLimit: boolean = false;
199
199
 
@@ -209,7 +209,7 @@ export class OscHandler implements IOscHandler {
209
209
  return;
210
210
  }
211
211
  this._data += utf32ToString(data, start, end);
212
- if (this._data.length > PAYLOAD_LIMIT) {
212
+ if (this._data.length > OscHandler._payloadLimit) {
213
213
  this._data = '';
214
214
  this._hitLimit = true;
215
215
  }
@@ -4,10 +4,16 @@
4
4
  */
5
5
  import { IParams, ParamsArray } from 'common/parser/Types';
6
6
 
7
- // max value supported for a single param/subparam (clamped to positive int32 range)
8
- const MAX_VALUE = 0x7FFFFFFF;
9
- // max allowed subparams for a single sequence (hardcoded limitation)
10
- const MAX_SUBPARAMS = 256;
7
+ const enum Constants {
8
+ /**
9
+ * Max value supported for a single param/subparam (clamped to positive int32 range)
10
+ */
11
+ MAX_VALUE = 0x7FFFFFFF,
12
+ /**
13
+ * Max allowed subparams for a single sequence (hardcoded limitation)
14
+ */
15
+ MAX_SUBPARAMS = 256
16
+ }
11
17
 
12
18
  /**
13
19
  * Params storage class.
@@ -70,7 +76,7 @@ export class Params implements IParams {
70
76
  * @param maxSubParamsLength max length of storable sub parameters
71
77
  */
72
78
  constructor(public maxLength: number = 32, public maxSubParamsLength: number = 32) {
73
- if (maxSubParamsLength > MAX_SUBPARAMS) {
79
+ if (maxSubParamsLength > Constants.MAX_SUBPARAMS) {
74
80
  throw new Error('maxSubParamsLength must not be greater than 256');
75
81
  }
76
82
  this.params = new Int32Array(maxLength);
@@ -129,6 +135,19 @@ export class Params implements IParams {
129
135
  this._digitIsSub = false;
130
136
  }
131
137
 
138
+ /**
139
+ * Reset and add 0 as first param (ZDM).
140
+ */
141
+ public resetZdm(): void {
142
+ this.length = 1;
143
+ this._subParamsLength = 0;
144
+ this._rejectDigits = false;
145
+ this._rejectSubDigits = false;
146
+ this._digitIsSub = false;
147
+ this._subParamsIdx[0] = 0;
148
+ this.params[0] = 0;
149
+ }
150
+
132
151
  /**
133
152
  * Add a parameter value.
134
153
  * `Params` only stores up to `maxLength` parameters, any later
@@ -146,7 +165,7 @@ export class Params implements IParams {
146
165
  throw new Error('values lesser than -1 are not allowed');
147
166
  }
148
167
  this._subParamsIdx[this.length] = this._subParamsLength << 8 | this._subParamsLength;
149
- this.params[this.length++] = value > MAX_VALUE ? MAX_VALUE : value;
168
+ this.params[this.length++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;
150
169
  }
151
170
 
152
171
  /**
@@ -168,7 +187,7 @@ export class Params implements IParams {
168
187
  if (value < -1) {
169
188
  throw new Error('values lesser than -1 are not allowed');
170
189
  }
171
- this._subParams[this._subParamsLength++] = value > MAX_VALUE ? MAX_VALUE : value;
190
+ this._subParams[this._subParamsLength++] = value > Constants.MAX_VALUE ? Constants.MAX_VALUE : value;
172
191
  this._subParamsIdx[this.length - 1]++;
173
192
  }
174
193
 
@@ -224,6 +243,6 @@ export class Params implements IParams {
224
243
 
225
244
  const store = this._digitIsSub ? this._subParams : this.params;
226
245
  const cur = store[length - 1];
227
- store[length - 1] = ~cur ? Math.min(cur * 10 + value, MAX_VALUE) : value;
246
+ store[length - 1] = ~cur ? Math.min(cur * 10 + value, Constants.MAX_VALUE) : value;
228
247
  }
229
248
  }