xstate 5.0.0-beta.40 → 5.0.0-beta.42
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/actions/dist/xstate-actions.cjs.js +3 -3
- package/actions/dist/xstate-actions.development.cjs.js +3 -3
- package/actions/dist/xstate-actions.development.esm.js +3 -3
- package/actions/dist/xstate-actions.esm.js +3 -3
- package/actions/dist/xstate-actions.umd.min.js +1 -1
- package/actions/dist/xstate-actions.umd.min.js.map +1 -1
- package/actors/dist/xstate-actors.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.esm.js +1 -1
- package/actors/dist/xstate-actors.esm.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/declarations/src/State.d.ts +36 -43
- package/dist/declarations/src/StateMachine.d.ts +13 -30
- package/dist/declarations/src/StateNode.d.ts +2 -2
- package/dist/declarations/src/index.d.ts +4 -5
- package/dist/declarations/src/interpreter.d.ts +14 -10
- package/dist/declarations/src/stateUtils.d.ts +7 -8
- package/dist/declarations/src/types.d.ts +114 -22
- package/dist/{interpreter-bae5c279.development.cjs.js → interpreter-23e4041c.development.cjs.js} +49 -42
- package/dist/{interpreter-ed0fac7e.esm.js → interpreter-3d0c0ff2.esm.js} +49 -40
- package/dist/{interpreter-586abde4.cjs.js → interpreter-b6bdd134.cjs.js} +49 -42
- package/dist/{interpreter-410d7ca9.development.esm.js → interpreter-f2620ea7.development.esm.js} +49 -40
- package/dist/{raise-37f9f3b8.development.esm.js → raise-51ae36e5.development.esm.js} +84 -183
- package/dist/{raise-27909189.cjs.js → raise-6b64c553.cjs.js} +81 -181
- package/dist/{raise-8325e2df.development.cjs.js → raise-8f482ce9.development.cjs.js} +85 -185
- package/dist/{raise-2b2fdec3.esm.js → raise-d2084327.esm.js} +80 -179
- package/dist/{send-59f66c58.esm.js → send-4e732fa5.esm.js} +7 -6
- package/dist/{send-f6b49072.development.esm.js → send-7a350091.development.esm.js} +7 -6
- package/dist/{send-4fdf275e.cjs.js → send-85b562d8.cjs.js} +7 -6
- package/dist/{send-c45d0d2c.development.cjs.js → send-cc8f864e.development.cjs.js} +7 -6
- package/dist/xstate.cjs.js +27 -56
- package/dist/xstate.cjs.mjs +0 -4
- package/dist/xstate.development.cjs.js +27 -56
- package/dist/xstate.development.cjs.mjs +0 -4
- package/dist/xstate.development.esm.js +31 -56
- package/dist/xstate.esm.js +31 -56
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.esm.js +2 -2
- package/guards/dist/xstate-guards.esm.js +2 -2
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/declarations/src/mapState.d.ts +0 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var interpreter = require('./interpreter-
|
|
3
|
+
var interpreter = require('./interpreter-23e4041c.development.cjs.js');
|
|
4
4
|
|
|
5
5
|
const cache = new WeakMap();
|
|
6
6
|
function memo(object, key, fn) {
|
|
@@ -63,7 +63,7 @@ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
|
|
|
63
63
|
const configuredInput = input || referenced.input;
|
|
64
64
|
actorRef = interpreter.createActor(referenced.src, {
|
|
65
65
|
id: resolvedId,
|
|
66
|
-
src
|
|
66
|
+
src,
|
|
67
67
|
parent: actorScope?.self,
|
|
68
68
|
systemId,
|
|
69
69
|
input: typeof configuredInput === 'function' ? configuredInput({
|
|
@@ -89,7 +89,7 @@ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
|
|
|
89
89
|
if (!actorRef) {
|
|
90
90
|
console.warn(`Actor type '${src}' not found in machine '${actorScope.id}'.`);
|
|
91
91
|
}
|
|
92
|
-
return [
|
|
92
|
+
return [cloneMachineSnapshot(state, {
|
|
93
93
|
children: {
|
|
94
94
|
...state.children,
|
|
95
95
|
[resolvedId]: actorRef
|
|
@@ -107,7 +107,7 @@ function executeSpawn(actorScope, {
|
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
109
|
actorScope.defer(() => {
|
|
110
|
-
if (actorRef.
|
|
110
|
+
if (actorRef._processingStatus === interpreter.ProcessingStatus.Stopped) {
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
113
|
try {
|
|
@@ -152,7 +152,7 @@ function resolveStop(_, state, args, actionParams, {
|
|
|
152
152
|
};
|
|
153
153
|
delete children[resolvedActorRef.id];
|
|
154
154
|
}
|
|
155
|
-
return [
|
|
155
|
+
return [cloneMachineSnapshot(state, {
|
|
156
156
|
children
|
|
157
157
|
}), resolvedActorRef];
|
|
158
158
|
}
|
|
@@ -168,7 +168,7 @@ function executeStop(actorScope, actorRef) {
|
|
|
168
168
|
|
|
169
169
|
// this allows us to prevent an actor from being started if it gets stopped within the same macrostep
|
|
170
170
|
// this can happen, for example, when the invoking state is being exited immediately by an always transition
|
|
171
|
-
if (actorRef.
|
|
171
|
+
if (actorRef._processingStatus !== interpreter.ProcessingStatus.Running) {
|
|
172
172
|
actorScope.stopChild(actorRef);
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
@@ -685,10 +685,9 @@ function getStateNodeByPath(stateNode, statePath) {
|
|
|
685
685
|
/**
|
|
686
686
|
* Returns the state nodes represented by the current state value.
|
|
687
687
|
*
|
|
688
|
-
* @param
|
|
688
|
+
* @param stateValue The state value or State instance
|
|
689
689
|
*/
|
|
690
|
-
function getStateNodes(stateNode,
|
|
691
|
-
const stateValue = state instanceof State ? state.value : interpreter.toStateValue(state);
|
|
690
|
+
function getStateNodes(stateNode, stateValue) {
|
|
692
691
|
if (typeof stateValue === 'string') {
|
|
693
692
|
return [stateNode, stateNode.states[stateValue]];
|
|
694
693
|
}
|
|
@@ -909,7 +908,7 @@ function microstep(transitions, currentState, actorScope, event, isInitial, inte
|
|
|
909
908
|
if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
|
|
910
909
|
return nextState;
|
|
911
910
|
}
|
|
912
|
-
return
|
|
911
|
+
return cloneMachineSnapshot(nextState, {
|
|
913
912
|
configuration: nextConfiguration,
|
|
914
913
|
historyValue
|
|
915
914
|
});
|
|
@@ -973,9 +972,9 @@ function enterStates(currentState, event, actorScope, filteredTransitions, mutCo
|
|
|
973
972
|
if (ancestorMarker) {
|
|
974
973
|
continue;
|
|
975
974
|
}
|
|
976
|
-
nextState =
|
|
975
|
+
nextState = cloneMachineSnapshot(nextState, {
|
|
977
976
|
status: 'done',
|
|
978
|
-
output: getMachineOutput(nextState, event, actorScope,
|
|
977
|
+
output: getMachineOutput(nextState, event, actorScope, nextState.machine.root, rootCompletionNode)
|
|
979
978
|
});
|
|
980
979
|
}
|
|
981
980
|
}
|
|
@@ -1129,7 +1128,7 @@ function resolveActionsAndContextWorker(currentState, event, actorScope, actions
|
|
|
1129
1128
|
event
|
|
1130
1129
|
}) : action.params : undefined;
|
|
1131
1130
|
if (!('resolve' in resolvedAction)) {
|
|
1132
|
-
if (actorScope?.self.
|
|
1131
|
+
if (actorScope?.self._processingStatus === interpreter.ProcessingStatus.Running) {
|
|
1133
1132
|
resolvedAction(actionArgs, actionParams);
|
|
1134
1133
|
} else {
|
|
1135
1134
|
actorScope?.defer(() => {
|
|
@@ -1147,7 +1146,7 @@ function resolveActionsAndContextWorker(currentState, event, actorScope, actions
|
|
|
1147
1146
|
retries?.push([builtinAction, params]);
|
|
1148
1147
|
}
|
|
1149
1148
|
if ('execute' in builtinAction) {
|
|
1150
|
-
if (actorScope?.self.
|
|
1149
|
+
if (actorScope?.self._processingStatus === interpreter.ProcessingStatus.Running) {
|
|
1151
1150
|
builtinAction.execute(actorScope, params);
|
|
1152
1151
|
} else {
|
|
1153
1152
|
actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
|
|
@@ -1179,7 +1178,7 @@ function macrostep(state, event, actorScope, internalQueue = []) {
|
|
|
1179
1178
|
|
|
1180
1179
|
// Handle stop event
|
|
1181
1180
|
if (event.type === interpreter.XSTATE_STOP) {
|
|
1182
|
-
nextState =
|
|
1181
|
+
nextState = cloneMachineSnapshot(stopChildren(nextState, event, actorScope), {
|
|
1183
1182
|
status: 'stopped'
|
|
1184
1183
|
});
|
|
1185
1184
|
states.push(nextState);
|
|
@@ -1257,194 +1256,96 @@ function resolveStateValue(rootNode, stateValue) {
|
|
|
1257
1256
|
const configuration = getConfiguration(getStateNodes(rootNode, stateValue));
|
|
1258
1257
|
return getStateValue(rootNode, [...configuration]);
|
|
1259
1258
|
}
|
|
1260
|
-
function getInitialConfiguration(rootNode) {
|
|
1261
|
-
const configuration = [];
|
|
1262
|
-
const initialTransition = rootNode.initial;
|
|
1263
|
-
const statesToEnter = new Set();
|
|
1264
|
-
const statesForDefaultEntry = new Set([rootNode]);
|
|
1265
|
-
computeEntrySet([initialTransition], {}, statesForDefaultEntry, statesToEnter);
|
|
1266
|
-
for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
|
|
1267
|
-
configuration.push(stateNodeToEnter);
|
|
1268
|
-
}
|
|
1269
|
-
return configuration;
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
class State {
|
|
1273
|
-
/**
|
|
1274
|
-
* Indicates whether the state is a final state.
|
|
1275
|
-
*/
|
|
1276
|
-
|
|
1277
|
-
/**
|
|
1278
|
-
* The output data of the top-level finite state.
|
|
1279
|
-
*/
|
|
1280
|
-
|
|
1281
|
-
/**
|
|
1282
|
-
* The enabled state nodes representative of the state value.
|
|
1283
|
-
*/
|
|
1284
|
-
|
|
1285
|
-
/**
|
|
1286
|
-
* An object mapping actor names to spawned/invoked actors.
|
|
1287
|
-
*/
|
|
1288
|
-
|
|
1289
|
-
/**
|
|
1290
|
-
* Creates a new State instance for the given `stateValue` and `context`.
|
|
1291
|
-
* @param stateValue
|
|
1292
|
-
* @param context
|
|
1293
|
-
*/
|
|
1294
|
-
static from(stateValue, context = {}, machine) {
|
|
1295
|
-
if (stateValue instanceof State) {
|
|
1296
|
-
if (stateValue.context !== context) {
|
|
1297
|
-
return new State({
|
|
1298
|
-
value: stateValue.value,
|
|
1299
|
-
context,
|
|
1300
|
-
meta: {},
|
|
1301
|
-
configuration: [],
|
|
1302
|
-
// TODO: fix,
|
|
1303
|
-
children: {},
|
|
1304
|
-
status: 'active'
|
|
1305
|
-
}, machine);
|
|
1306
|
-
}
|
|
1307
|
-
return stateValue;
|
|
1308
|
-
}
|
|
1309
|
-
const configuration = getConfiguration(getStateNodes(machine.root, stateValue));
|
|
1310
|
-
return new State({
|
|
1311
|
-
value: stateValue,
|
|
1312
|
-
context,
|
|
1313
|
-
meta: undefined,
|
|
1314
|
-
configuration: Array.from(configuration),
|
|
1315
|
-
children: {},
|
|
1316
|
-
status: 'active'
|
|
1317
|
-
}, machine);
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
/**
|
|
1321
|
-
* Creates a new `State` instance that represents the current state of a running machine.
|
|
1322
|
-
*
|
|
1323
|
-
* @param config
|
|
1324
|
-
*/
|
|
1325
|
-
constructor(config, machine) {
|
|
1326
|
-
this.machine = machine;
|
|
1327
|
-
this.tags = void 0;
|
|
1328
|
-
this.value = void 0;
|
|
1329
|
-
this.status = void 0;
|
|
1330
|
-
this.error = void 0;
|
|
1331
|
-
this.context = void 0;
|
|
1332
|
-
this.historyValue = {};
|
|
1333
|
-
this.configuration = void 0;
|
|
1334
|
-
this.children = void 0;
|
|
1335
|
-
this.context = config.context;
|
|
1336
|
-
this.historyValue = config.historyValue || {};
|
|
1337
|
-
this.matches = this.matches.bind(this);
|
|
1338
|
-
this.toStrings = this.toStrings.bind(this);
|
|
1339
|
-
this.configuration = config.configuration ?? Array.from(getConfiguration(getStateNodes(machine.root, config.value)));
|
|
1340
|
-
this.children = config.children;
|
|
1341
|
-
this.value = getStateValue(machine.root, this.configuration);
|
|
1342
|
-
this.tags = new Set(interpreter.flatten(this.configuration.map(sn => sn.tags)));
|
|
1343
|
-
this.status = config.status;
|
|
1344
|
-
this.output = config.output;
|
|
1345
|
-
this.error = config.error;
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
/**
|
|
1349
|
-
* Returns an array of all the string leaf state node paths.
|
|
1350
|
-
* @param stateValue
|
|
1351
|
-
* @param delimiter The character(s) that separate each subpath in the string state node path.
|
|
1352
|
-
*/
|
|
1353
|
-
toStrings(stateValue = this.value) {
|
|
1354
|
-
if (typeof stateValue === 'string') {
|
|
1355
|
-
return [stateValue];
|
|
1356
|
-
}
|
|
1357
|
-
const valueKeys = Object.keys(stateValue);
|
|
1358
|
-
return valueKeys.concat(...valueKeys.map(key => this.toStrings(stateValue[key]).map(s => key + interpreter.STATE_DELIMITER + s)));
|
|
1359
|
-
}
|
|
1360
|
-
toJSON() {
|
|
1361
|
-
const {
|
|
1362
|
-
configuration,
|
|
1363
|
-
tags,
|
|
1364
|
-
machine,
|
|
1365
|
-
...jsonValues
|
|
1366
|
-
} = this;
|
|
1367
|
-
return {
|
|
1368
|
-
...jsonValues,
|
|
1369
|
-
tags: Array.from(tags),
|
|
1370
|
-
meta: this.meta
|
|
1371
|
-
};
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
/**
|
|
1375
|
-
* Whether the current state value is a subset of the given parent state value.
|
|
1376
|
-
* @param parentStateValue
|
|
1377
|
-
*/
|
|
1378
|
-
matches(parentStateValue) {
|
|
1379
|
-
return interpreter.matchesState(parentStateValue, this.value);
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
/**
|
|
1383
|
-
* Whether the current state configuration has a state node with the specified `tag`.
|
|
1384
|
-
* @param tag
|
|
1385
|
-
*/
|
|
1386
|
-
hasTag(tag) {
|
|
1387
|
-
return this.tags.has(tag);
|
|
1388
|
-
}
|
|
1389
1259
|
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
get nextEvents() {
|
|
1412
|
-
return memo(this, 'nextEvents', () => {
|
|
1413
|
-
return [...new Set(interpreter.flatten([...this.configuration.map(sn => sn.ownEvents)]))];
|
|
1414
|
-
});
|
|
1415
|
-
}
|
|
1416
|
-
get meta() {
|
|
1417
|
-
return this.configuration.reduce((acc, stateNode) => {
|
|
1418
|
-
if (stateNode.meta !== undefined) {
|
|
1419
|
-
acc[stateNode.id] = stateNode.meta;
|
|
1260
|
+
function createMachineSnapshot(config, machine) {
|
|
1261
|
+
return {
|
|
1262
|
+
status: config.status,
|
|
1263
|
+
output: config.output,
|
|
1264
|
+
error: config.error,
|
|
1265
|
+
machine,
|
|
1266
|
+
context: config.context,
|
|
1267
|
+
configuration: config.configuration,
|
|
1268
|
+
value: getStateValue(machine.root, config.configuration),
|
|
1269
|
+
tags: new Set(interpreter.flatten(config.configuration.map(sn => sn.tags))),
|
|
1270
|
+
children: config.children,
|
|
1271
|
+
historyValue: config.historyValue || {},
|
|
1272
|
+
matches(parentStateValue) {
|
|
1273
|
+
return interpreter.matchesState(parentStateValue, this.value);
|
|
1274
|
+
},
|
|
1275
|
+
hasTag(tag) {
|
|
1276
|
+
return this.tags.has(tag);
|
|
1277
|
+
},
|
|
1278
|
+
can(event) {
|
|
1279
|
+
if (!this.machine) {
|
|
1280
|
+
console.warn(`state.can(...) used outside of a machine-created State object; this will always return false.`);
|
|
1420
1281
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1282
|
+
const transitionData = this.machine.getTransitionData(this, event);
|
|
1283
|
+
return !!transitionData?.length &&
|
|
1284
|
+
// Check that at least one transition is not forbidden
|
|
1285
|
+
transitionData.some(t => t.target !== undefined || t.actions.length);
|
|
1286
|
+
},
|
|
1287
|
+
get nextEvents() {
|
|
1288
|
+
return memo(this, 'nextEvents', () => {
|
|
1289
|
+
return [...new Set(interpreter.flatten([...this.configuration.map(sn => sn.ownEvents)]))];
|
|
1290
|
+
});
|
|
1291
|
+
},
|
|
1292
|
+
get meta() {
|
|
1293
|
+
return this.configuration.reduce((acc, stateNode) => {
|
|
1294
|
+
if (stateNode.meta !== undefined) {
|
|
1295
|
+
acc[stateNode.id] = stateNode.meta;
|
|
1296
|
+
}
|
|
1297
|
+
return acc;
|
|
1298
|
+
}, {});
|
|
1299
|
+
},
|
|
1300
|
+
toJSON() {
|
|
1301
|
+
const {
|
|
1302
|
+
configuration,
|
|
1303
|
+
tags,
|
|
1304
|
+
machine,
|
|
1305
|
+
nextEvents,
|
|
1306
|
+
toJSON,
|
|
1307
|
+
can,
|
|
1308
|
+
hasTag,
|
|
1309
|
+
matches,
|
|
1310
|
+
...jsonValues
|
|
1311
|
+
} = this;
|
|
1312
|
+
return {
|
|
1313
|
+
...jsonValues,
|
|
1314
|
+
tags: Array.from(tags)
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1424
1318
|
}
|
|
1425
|
-
function
|
|
1426
|
-
return
|
|
1319
|
+
function cloneMachineSnapshot(state, config = {}) {
|
|
1320
|
+
return createMachineSnapshot(
|
|
1321
|
+
// TODO: it's wasteful that this spread triggers getters
|
|
1322
|
+
{
|
|
1427
1323
|
...state,
|
|
1428
1324
|
...config
|
|
1429
1325
|
}, state.machine);
|
|
1430
1326
|
}
|
|
1431
|
-
function getPersistedState(state) {
|
|
1327
|
+
function getPersistedState(state, options) {
|
|
1432
1328
|
const {
|
|
1433
1329
|
configuration,
|
|
1434
1330
|
tags,
|
|
1435
1331
|
machine,
|
|
1436
1332
|
children,
|
|
1437
1333
|
context,
|
|
1334
|
+
can,
|
|
1335
|
+
hasTag,
|
|
1336
|
+
matches,
|
|
1337
|
+
toJSON,
|
|
1338
|
+
nextEvents,
|
|
1438
1339
|
...jsonValues
|
|
1439
1340
|
} = state;
|
|
1440
1341
|
const childrenJson = {};
|
|
1441
1342
|
for (const id in children) {
|
|
1442
1343
|
const child = children[id];
|
|
1443
|
-
if (typeof child.src !== 'string') {
|
|
1344
|
+
if (typeof child.src !== 'string' && (!options || !('__unsafeAllowInlineActors' in options))) {
|
|
1444
1345
|
throw new Error('An inline child actor cannot be persisted.');
|
|
1445
1346
|
}
|
|
1446
1347
|
childrenJson[id] = {
|
|
1447
|
-
state: child.getPersistedState(),
|
|
1348
|
+
state: child.getPersistedState(options),
|
|
1448
1349
|
src: child.src,
|
|
1449
1350
|
systemId: child._systemId
|
|
1450
1351
|
};
|
|
@@ -1538,10 +1439,10 @@ function raise(eventOrExpr, options) {
|
|
|
1538
1439
|
return raise;
|
|
1539
1440
|
}
|
|
1540
1441
|
|
|
1541
|
-
exports.State = State;
|
|
1542
1442
|
exports.and = and;
|
|
1543
1443
|
exports.cancel = cancel;
|
|
1544
|
-
exports.
|
|
1444
|
+
exports.cloneMachineSnapshot = cloneMachineSnapshot;
|
|
1445
|
+
exports.createMachineSnapshot = createMachineSnapshot;
|
|
1545
1446
|
exports.evaluateGuard = evaluateGuard;
|
|
1546
1447
|
exports.formatInitialTransition = formatInitialTransition;
|
|
1547
1448
|
exports.formatTransition = formatTransition;
|
|
@@ -1549,7 +1450,6 @@ exports.formatTransitions = formatTransitions;
|
|
|
1549
1450
|
exports.getCandidates = getCandidates;
|
|
1550
1451
|
exports.getConfiguration = getConfiguration;
|
|
1551
1452
|
exports.getDelayedTransitions = getDelayedTransitions;
|
|
1552
|
-
exports.getInitialConfiguration = getInitialConfiguration;
|
|
1553
1453
|
exports.getInitialStateNodes = getInitialStateNodes;
|
|
1554
1454
|
exports.getPersistedState = getPersistedState;
|
|
1555
1455
|
exports.getStateNodeByPath = getStateNodeByPath;
|