@flexiberry/berrycore 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/adapter/cli-adapter.d.ts +37 -0
- package/dist/adapter/cli-adapter.js +119 -0
- package/dist/berry-core.d.ts +108 -0
- package/dist/berry-core.js +258 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +18 -0
- package/dist/interpreter/environment.d.ts +45 -0
- package/dist/interpreter/environment.js +96 -0
- package/dist/interpreter/errors.d.ts +16 -0
- package/dist/interpreter/errors.js +27 -0
- package/dist/interpreter/interpreter.d.ts +111 -0
- package/dist/interpreter/interpreter.js +682 -0
- package/dist/interpreter/interpreter.types.d.ts +182 -0
- package/dist/interpreter/interpreter.types.js +73 -0
- package/dist/parser/ast/ast.engine.d.ts +103 -0
- package/dist/parser/ast/ast.engine.js +526 -0
- package/dist/parser/ast/ast.types.d.ts +242 -0
- package/dist/parser/ast/ast.types.js +37 -0
- package/dist/parser/formatter/formatter.d.ts +44 -0
- package/dist/parser/formatter/formatter.js +214 -0
- package/dist/parser/tokenizer/reader/grammer/api.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/api.grammer.js +102 -0
- package/dist/parser/tokenizer/reader/grammer/capture.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/capture.grammer.js +21 -0
- package/dist/parser/tokenizer/reader/grammer/check.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/check.grammer.js +21 -0
- package/dist/parser/tokenizer/reader/grammer/comment.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/comment.grammer.js +13 -0
- package/dist/parser/tokenizer/reader/grammer/conditions.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/conditions.grammer.js +68 -0
- package/dist/parser/tokenizer/reader/grammer/input.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/input.grammer.js +17 -0
- package/dist/parser/tokenizer/reader/grammer/keyvalue.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/keyvalue.grammer.js +240 -0
- package/dist/parser/tokenizer/reader/grammer/link.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/link.grammer.js +17 -0
- package/dist/parser/tokenizer/reader/grammer/params.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/params.grammer.js +21 -0
- package/dist/parser/tokenizer/reader/grammer/step.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/step.grammer.js +25 -0
- package/dist/parser/tokenizer/reader/grammer/task.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/task.grammer.js +17 -0
- package/dist/parser/tokenizer/reader/grammer/var.grammer.d.ts +2 -0
- package/dist/parser/tokenizer/reader/grammer/var.grammer.js +47 -0
- package/dist/parser/tokenizer/reader/lexer.engine.d.ts +43 -0
- package/dist/parser/tokenizer/reader/lexer.engine.js +178 -0
- package/dist/parser/tokenizer/reader/lexer.types.d.ts +18 -0
- package/dist/parser/tokenizer/reader/lexer.types.js +1 -0
- package/dist/parser/tokenizer/token.d.ts +13 -0
- package/dist/parser/tokenizer/token.js +13 -0
- package/dist/parser/tokenizer/tokenType.d.ts +58 -0
- package/dist/parser/tokenizer/tokenType.js +64 -0
- package/dist/script/format-util.d.ts +33 -0
- package/dist/script/format-util.js +94 -0
- package/dist/script/postman.util.d.ts +88 -0
- package/dist/script/postman.util.js +176 -0
- package/dist/script/swagger.util.d.ts +80 -0
- package/dist/script/swagger.util.js +202 -0
- package/dist/util/store-util.d.ts +5 -0
- package/dist/util/store-util.js +22 -0
- package/package.json +25 -0
- package/readme.md +107 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interpreter Types
|
|
3
|
+
*
|
|
4
|
+
* Runtime value types, execution status, event types,
|
|
5
|
+
* and the IOAdapter interface for CLI/UI input abstraction.
|
|
6
|
+
*/
|
|
7
|
+
/** Any value that can exist at runtime */
|
|
8
|
+
export type RuntimeValue = string | number | boolean | Record<string, unknown> | null;
|
|
9
|
+
export declare enum ExecutionStatus {
|
|
10
|
+
Pending = "PENDING",
|
|
11
|
+
Running = "RUNNING",
|
|
12
|
+
Pass = "PASS",
|
|
13
|
+
Failed = "FAILED",
|
|
14
|
+
Skipped = "SKIPPED",
|
|
15
|
+
Paused = "PAUSED",
|
|
16
|
+
Stopped = "STOPPED",
|
|
17
|
+
Killed = "KILLED"
|
|
18
|
+
}
|
|
19
|
+
export declare enum InterpreterEvent {
|
|
20
|
+
/** Interpreter has started execution */
|
|
21
|
+
Start = "START",
|
|
22
|
+
/** Interpreter has completed all tasks */
|
|
23
|
+
Completed = "COMPLETED",
|
|
24
|
+
/** A task is about to begin */
|
|
25
|
+
TaskBegin = "TASK_BEGIN",
|
|
26
|
+
/** A task has finished */
|
|
27
|
+
TaskDone = "TASK_DONE",
|
|
28
|
+
/** A step is about to begin */
|
|
29
|
+
StepBegin = "STEP_BEGIN",
|
|
30
|
+
/** A step has finished */
|
|
31
|
+
StepDone = "STEP_DONE",
|
|
32
|
+
/** An API call is about to be made */
|
|
33
|
+
ApiCallBegin = "API_CALL_BEGIN",
|
|
34
|
+
/** An API call has completed */
|
|
35
|
+
ApiCallDone = "API_CALL_DONE",
|
|
36
|
+
/** General log message */
|
|
37
|
+
Log = "LOG",
|
|
38
|
+
/** Runtime error occurred */
|
|
39
|
+
Error = "ERROR",
|
|
40
|
+
/** Interpreter requires user input */
|
|
41
|
+
InputRequired = "INPUT_REQUIRED",
|
|
42
|
+
/** Execution state changed (paused, resumed, killed) */
|
|
43
|
+
StateChanged = "STATE_CHANGED",
|
|
44
|
+
/** Data from an Input statement has been loaded */
|
|
45
|
+
DataLoaded = "DATA_LOADED"
|
|
46
|
+
}
|
|
47
|
+
export interface StartPayload {
|
|
48
|
+
readonly totalTasks: number;
|
|
49
|
+
readonly totalApis: number;
|
|
50
|
+
readonly totalVars: number;
|
|
51
|
+
readonly startTime: Date;
|
|
52
|
+
readonly plan: ReadonlyArray<{
|
|
53
|
+
readonly title: string | null;
|
|
54
|
+
readonly steps: ReadonlyArray<{
|
|
55
|
+
readonly targetName: string;
|
|
56
|
+
}>;
|
|
57
|
+
}>;
|
|
58
|
+
}
|
|
59
|
+
export interface CompletedPayload {
|
|
60
|
+
readonly endTime: Date;
|
|
61
|
+
readonly taskResults: readonly TaskResult[];
|
|
62
|
+
}
|
|
63
|
+
export interface TaskResult {
|
|
64
|
+
readonly title: string | null;
|
|
65
|
+
readonly status: ExecutionStatus;
|
|
66
|
+
readonly startTime: Date;
|
|
67
|
+
readonly endTime: Date;
|
|
68
|
+
readonly steps: readonly StepResult[];
|
|
69
|
+
}
|
|
70
|
+
export interface StepResult {
|
|
71
|
+
readonly targetName: string;
|
|
72
|
+
readonly status: ExecutionStatus;
|
|
73
|
+
readonly startTime: Date;
|
|
74
|
+
readonly endTime: Date;
|
|
75
|
+
readonly error: string | null;
|
|
76
|
+
readonly response: ApiResponse | null;
|
|
77
|
+
readonly checksPassed: boolean | null;
|
|
78
|
+
}
|
|
79
|
+
export interface ApiResponse {
|
|
80
|
+
readonly status: number;
|
|
81
|
+
readonly headers: Record<string, string>;
|
|
82
|
+
readonly body: unknown;
|
|
83
|
+
}
|
|
84
|
+
export interface LogPayload {
|
|
85
|
+
readonly level: "info" | "warn" | "debug";
|
|
86
|
+
readonly message: string;
|
|
87
|
+
}
|
|
88
|
+
export interface ErrorPayload {
|
|
89
|
+
readonly message: string;
|
|
90
|
+
readonly line?: number;
|
|
91
|
+
readonly column?: number;
|
|
92
|
+
}
|
|
93
|
+
export type EventPayloadMap = {
|
|
94
|
+
[InterpreterEvent.Start]: StartPayload;
|
|
95
|
+
[InterpreterEvent.Completed]: CompletedPayload;
|
|
96
|
+
[InterpreterEvent.TaskBegin]: {
|
|
97
|
+
readonly title: string | null;
|
|
98
|
+
readonly index: number;
|
|
99
|
+
};
|
|
100
|
+
[InterpreterEvent.TaskDone]: TaskResult;
|
|
101
|
+
[InterpreterEvent.StepBegin]: {
|
|
102
|
+
readonly targetName: string;
|
|
103
|
+
readonly index: number;
|
|
104
|
+
readonly taskIndex: number;
|
|
105
|
+
};
|
|
106
|
+
[InterpreterEvent.StepDone]: StepResult & {
|
|
107
|
+
readonly taskIndex: number;
|
|
108
|
+
readonly index: number;
|
|
109
|
+
};
|
|
110
|
+
[InterpreterEvent.ApiCallBegin]: {
|
|
111
|
+
readonly method: string;
|
|
112
|
+
readonly url: string;
|
|
113
|
+
readonly apiName: string;
|
|
114
|
+
};
|
|
115
|
+
[InterpreterEvent.ApiCallDone]: {
|
|
116
|
+
readonly apiName: string;
|
|
117
|
+
readonly status: number;
|
|
118
|
+
readonly duration: number;
|
|
119
|
+
};
|
|
120
|
+
[InterpreterEvent.Log]: LogPayload;
|
|
121
|
+
[InterpreterEvent.Error]: ErrorPayload;
|
|
122
|
+
[InterpreterEvent.InputRequired]: {
|
|
123
|
+
readonly prompt: string;
|
|
124
|
+
};
|
|
125
|
+
[InterpreterEvent.StateChanged]: {
|
|
126
|
+
readonly state: ExecutionState;
|
|
127
|
+
readonly reason: string;
|
|
128
|
+
};
|
|
129
|
+
[InterpreterEvent.DataLoaded]: {
|
|
130
|
+
readonly rows: Record<string, string>[];
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
export type EventListener<E extends InterpreterEvent> = (payload: EventPayloadMap[E]) => void | Promise<void>;
|
|
134
|
+
export type LogLevel = "info" | "warn" | "error" | "debug" | "step" | "task" | "api";
|
|
135
|
+
/** Commands that can be sent to the interpreter at any time */
|
|
136
|
+
export declare enum ExecutionCommand {
|
|
137
|
+
/** Continue to the next step (default behavior) */
|
|
138
|
+
Continue = "CONTINUE",
|
|
139
|
+
/** Skip the current/next step and move on */
|
|
140
|
+
Skip = "SKIP",
|
|
141
|
+
/** Stop the current task (skip remaining steps) and move to next task */
|
|
142
|
+
Stop = "STOP",
|
|
143
|
+
/** Pause execution — wait for Continue or Kill */
|
|
144
|
+
Pause = "PAUSE",
|
|
145
|
+
/** Kill execution — clean up all resources and abort immediately */
|
|
146
|
+
Kill = "KILL"
|
|
147
|
+
}
|
|
148
|
+
/** The current execution state of the interpreter */
|
|
149
|
+
export declare enum ExecutionState {
|
|
150
|
+
Idle = "IDLE",
|
|
151
|
+
Running = "RUNNING",
|
|
152
|
+
Paused = "PAUSED",
|
|
153
|
+
Stopped = "STOPPED",
|
|
154
|
+
Killed = "KILLED",
|
|
155
|
+
Completed = "COMPLETED"
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Abstraction for user input, output, AND execution control.
|
|
159
|
+
* Implement this for CLI (readline/stdout) or UI (callback/websocket).
|
|
160
|
+
*/
|
|
161
|
+
export interface IOAdapter {
|
|
162
|
+
/** Prompt the user for input and return the response */
|
|
163
|
+
prompt(message: string): Promise<string>;
|
|
164
|
+
/** Optional: confirm yes/no from user */
|
|
165
|
+
confirm?(message: string): Promise<boolean>;
|
|
166
|
+
/**
|
|
167
|
+
* Push a log line to the output.
|
|
168
|
+
* Called by the interpreter for real-time status updates.
|
|
169
|
+
*/
|
|
170
|
+
log?(level: LogLevel, message: string): void;
|
|
171
|
+
/**
|
|
172
|
+
* Register a callback that the adapter calls when the user issues a command.
|
|
173
|
+
* The interpreter calls this once at startup to give the adapter
|
|
174
|
+
* a way to send commands back.
|
|
175
|
+
*/
|
|
176
|
+
onCommand?(handler: (command: ExecutionCommand) => void): void;
|
|
177
|
+
/**
|
|
178
|
+
* Called when the interpreter is being killed.
|
|
179
|
+
* Adapter should clean up its resources (close readline, sockets, etc.).
|
|
180
|
+
*/
|
|
181
|
+
dispose?(): void;
|
|
182
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interpreter Types
|
|
3
|
+
*
|
|
4
|
+
* Runtime value types, execution status, event types,
|
|
5
|
+
* and the IOAdapter interface for CLI/UI input abstraction.
|
|
6
|
+
*/
|
|
7
|
+
// ─── Execution Status ───────────────────────────────────────────────────────
|
|
8
|
+
export var ExecutionStatus;
|
|
9
|
+
(function (ExecutionStatus) {
|
|
10
|
+
ExecutionStatus["Pending"] = "PENDING";
|
|
11
|
+
ExecutionStatus["Running"] = "RUNNING";
|
|
12
|
+
ExecutionStatus["Pass"] = "PASS";
|
|
13
|
+
ExecutionStatus["Failed"] = "FAILED";
|
|
14
|
+
ExecutionStatus["Skipped"] = "SKIPPED";
|
|
15
|
+
ExecutionStatus["Paused"] = "PAUSED";
|
|
16
|
+
ExecutionStatus["Stopped"] = "STOPPED";
|
|
17
|
+
ExecutionStatus["Killed"] = "KILLED";
|
|
18
|
+
})(ExecutionStatus || (ExecutionStatus = {}));
|
|
19
|
+
// ─── Interpreter Events ─────────────────────────────────────────────────────
|
|
20
|
+
export var InterpreterEvent;
|
|
21
|
+
(function (InterpreterEvent) {
|
|
22
|
+
/** Interpreter has started execution */
|
|
23
|
+
InterpreterEvent["Start"] = "START";
|
|
24
|
+
/** Interpreter has completed all tasks */
|
|
25
|
+
InterpreterEvent["Completed"] = "COMPLETED";
|
|
26
|
+
/** A task is about to begin */
|
|
27
|
+
InterpreterEvent["TaskBegin"] = "TASK_BEGIN";
|
|
28
|
+
/** A task has finished */
|
|
29
|
+
InterpreterEvent["TaskDone"] = "TASK_DONE";
|
|
30
|
+
/** A step is about to begin */
|
|
31
|
+
InterpreterEvent["StepBegin"] = "STEP_BEGIN";
|
|
32
|
+
/** A step has finished */
|
|
33
|
+
InterpreterEvent["StepDone"] = "STEP_DONE";
|
|
34
|
+
/** An API call is about to be made */
|
|
35
|
+
InterpreterEvent["ApiCallBegin"] = "API_CALL_BEGIN";
|
|
36
|
+
/** An API call has completed */
|
|
37
|
+
InterpreterEvent["ApiCallDone"] = "API_CALL_DONE";
|
|
38
|
+
/** General log message */
|
|
39
|
+
InterpreterEvent["Log"] = "LOG";
|
|
40
|
+
/** Runtime error occurred */
|
|
41
|
+
InterpreterEvent["Error"] = "ERROR";
|
|
42
|
+
/** Interpreter requires user input */
|
|
43
|
+
InterpreterEvent["InputRequired"] = "INPUT_REQUIRED";
|
|
44
|
+
/** Execution state changed (paused, resumed, killed) */
|
|
45
|
+
InterpreterEvent["StateChanged"] = "STATE_CHANGED";
|
|
46
|
+
/** Data from an Input statement has been loaded */
|
|
47
|
+
InterpreterEvent["DataLoaded"] = "DATA_LOADED";
|
|
48
|
+
})(InterpreterEvent || (InterpreterEvent = {}));
|
|
49
|
+
// ─── Execution Commands ─────────────────────────────────────────────────────
|
|
50
|
+
/** Commands that can be sent to the interpreter at any time */
|
|
51
|
+
export var ExecutionCommand;
|
|
52
|
+
(function (ExecutionCommand) {
|
|
53
|
+
/** Continue to the next step (default behavior) */
|
|
54
|
+
ExecutionCommand["Continue"] = "CONTINUE";
|
|
55
|
+
/** Skip the current/next step and move on */
|
|
56
|
+
ExecutionCommand["Skip"] = "SKIP";
|
|
57
|
+
/** Stop the current task (skip remaining steps) and move to next task */
|
|
58
|
+
ExecutionCommand["Stop"] = "STOP";
|
|
59
|
+
/** Pause execution — wait for Continue or Kill */
|
|
60
|
+
ExecutionCommand["Pause"] = "PAUSE";
|
|
61
|
+
/** Kill execution — clean up all resources and abort immediately */
|
|
62
|
+
ExecutionCommand["Kill"] = "KILL";
|
|
63
|
+
})(ExecutionCommand || (ExecutionCommand = {}));
|
|
64
|
+
/** The current execution state of the interpreter */
|
|
65
|
+
export var ExecutionState;
|
|
66
|
+
(function (ExecutionState) {
|
|
67
|
+
ExecutionState["Idle"] = "IDLE";
|
|
68
|
+
ExecutionState["Running"] = "RUNNING";
|
|
69
|
+
ExecutionState["Paused"] = "PAUSED";
|
|
70
|
+
ExecutionState["Stopped"] = "STOPPED";
|
|
71
|
+
ExecutionState["Killed"] = "KILLED";
|
|
72
|
+
ExecutionState["Completed"] = "COMPLETED";
|
|
73
|
+
})(ExecutionState || (ExecutionState = {}));
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST Engine — Recursive Descent Parser
|
|
3
|
+
*
|
|
4
|
+
* Consumes Token[] from the LexerEngine and produces a ProgramNode AST.
|
|
5
|
+
* Each parse* method corresponds to one grammar rule from reader_v2.
|
|
6
|
+
*
|
|
7
|
+
* Architecture rules enforced:
|
|
8
|
+
* - Parser ONLY produces AST — no runtime execution
|
|
9
|
+
* - Deterministic recursive descent
|
|
10
|
+
* - Throws syntax errors with line/column info
|
|
11
|
+
*/
|
|
12
|
+
import { Token } from "../tokenizer/token.js";
|
|
13
|
+
import { ProgramNode } from "./ast.types.js";
|
|
14
|
+
export declare class ParserError extends Error {
|
|
15
|
+
readonly line: number;
|
|
16
|
+
readonly column: number;
|
|
17
|
+
constructor(message: string, line: number, column: number);
|
|
18
|
+
}
|
|
19
|
+
export declare class Ast {
|
|
20
|
+
static parse(code: string): ProgramNode;
|
|
21
|
+
}
|
|
22
|
+
export declare class AstEngine {
|
|
23
|
+
private readonly tokens;
|
|
24
|
+
private cursor;
|
|
25
|
+
constructor(tokens: Token[]);
|
|
26
|
+
/** Entry point: parse entire token stream into ProgramNode */
|
|
27
|
+
build(): ProgramNode;
|
|
28
|
+
private parseStatement;
|
|
29
|
+
/**
|
|
30
|
+
* Grammar: Var ((@)(pointed) (title))? keyValueLoop
|
|
31
|
+
* Tokens: Var, optional Pointer+Pointed+Title, then key-value pairs
|
|
32
|
+
*/
|
|
33
|
+
private parseVarDeclaration;
|
|
34
|
+
private parsePointerReference;
|
|
35
|
+
/**
|
|
36
|
+
* Grammar: Link <path>
|
|
37
|
+
* Tokens: Link, LinkPath
|
|
38
|
+
*/
|
|
39
|
+
private parseLinkStatement;
|
|
40
|
+
/**
|
|
41
|
+
* Grammar: Input <path>
|
|
42
|
+
* Tokens: Input, InputPath
|
|
43
|
+
*/
|
|
44
|
+
private parseInputStatement;
|
|
45
|
+
/**
|
|
46
|
+
* Grammar: Api (GET|POST|..)? #identifier title?
|
|
47
|
+
* Url value
|
|
48
|
+
* Header keyValueLoop
|
|
49
|
+
* Body type `content`
|
|
50
|
+
*/
|
|
51
|
+
private parseApiBlock;
|
|
52
|
+
private parseUrlStatement;
|
|
53
|
+
private parseHeaderBlock;
|
|
54
|
+
private parseBodyBlock;
|
|
55
|
+
/**
|
|
56
|
+
* Grammar: Task title?
|
|
57
|
+
* Tokens: Task, Title
|
|
58
|
+
*/
|
|
59
|
+
private parseTaskBlock;
|
|
60
|
+
/**
|
|
61
|
+
* Grammar: Step Call Api identifier
|
|
62
|
+
* Tokens: Step, Call, Api, Identifier
|
|
63
|
+
*/
|
|
64
|
+
private parseStepBlock;
|
|
65
|
+
/**
|
|
66
|
+
* Grammar: Params keyValueLoop
|
|
67
|
+
* Tokens: Params, then key-value pairs
|
|
68
|
+
*/
|
|
69
|
+
private parseParamsBlock;
|
|
70
|
+
/**
|
|
71
|
+
* Grammar: Capture keyValueLoop
|
|
72
|
+
* Tokens: Capture, then key-value pairs
|
|
73
|
+
*/
|
|
74
|
+
private parseCaptureBlock;
|
|
75
|
+
/**
|
|
76
|
+
* Grammar: Check conditionLoop
|
|
77
|
+
* Tokens: Check, then condition list
|
|
78
|
+
*/
|
|
79
|
+
private parseCheckBlock;
|
|
80
|
+
/**
|
|
81
|
+
* Grammar: (- key: value)*
|
|
82
|
+
* Loops while Hyphen tokens appear
|
|
83
|
+
*/
|
|
84
|
+
private parseKeyValuePairs;
|
|
85
|
+
/**
|
|
86
|
+
* Grammar: (- lhs operator rhs (OR lhs operator rhs)*)*
|
|
87
|
+
* Loops while Hyphen tokens appear
|
|
88
|
+
*/
|
|
89
|
+
private parseConditions;
|
|
90
|
+
private parseComment;
|
|
91
|
+
/** Check if we've reached EOF */
|
|
92
|
+
private isEof;
|
|
93
|
+
/** Peek at current token without consuming */
|
|
94
|
+
private peek;
|
|
95
|
+
/** Check if current token matches expected type */
|
|
96
|
+
private check;
|
|
97
|
+
/** Consume current token and return it */
|
|
98
|
+
private advance;
|
|
99
|
+
/** Expect a specific token type or throw a ParserError */
|
|
100
|
+
private expect;
|
|
101
|
+
/** Extract NodePosition from a Token */
|
|
102
|
+
private positionOf;
|
|
103
|
+
}
|