@scriptc/compiler 0.0.21 → 0.0.23
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/ambient/scriptc-node-fallback.d.ts +117 -37
- package/dist/backend/cc-cache.test.d.ts +1 -0
- package/dist/backend/cc-cache.test.js +2507 -0
- package/dist/backend/cc-cache.test.js.map +1 -0
- package/dist/backend/cc.d.ts +69 -11
- package/dist/backend/cc.js +1937 -222
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-async.js +3 -1
- package/dist/backend/emission/emit-async.js.map +1 -1
- package/dist/backend/emission/emit-exprs.d.ts +10 -0
- package/dist/backend/emission/emit-exprs.js +482 -18
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-stmts.js +13 -5
- package/dist/backend/emission/emit-stmts.js.map +1 -1
- package/dist/backend/emission/emit-types.js +4 -1
- package/dist/backend/emission/emit-types.js.map +1 -1
- package/dist/backend/emission/emit-walkers.js +108 -7
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +27 -1
- package/dist/backend/emission/emitter.js +84 -3
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +1 -0
- package/dist/backend/llvm/dyn.js +305 -8
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +831 -23
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +3 -2
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/compat/fetch-profile.d.ts +118 -0
- package/dist/compat/fetch-profile.js +531 -0
- package/dist/compat/fetch-profile.js.map +1 -0
- package/dist/coverage/surface-manifest.js +69 -0
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -0
- package/dist/diagnostics/diagnostic.js +27 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +24 -15
- package/dist/frontend/lowering/lower-builtins.js +217 -69
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +41 -0
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +32 -11
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +3 -3
- package/dist/frontend/lowering/lower-exprs.js +87 -15
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +7 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +123 -7
- package/dist/frontend/lowering/lower-island.js +1976 -26
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +17 -1
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +33 -9
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +40 -0
- package/dist/frontend/lowering/lowerer.js +290 -18
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.js +55 -12
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/program.d.ts +20 -4
- package/dist/frontend/program.js +391 -49
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.d.ts +10 -0
- package/dist/frontend/resolve.js +37 -0
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/ts7/enums.d.ts +9 -0
- package/dist/frontend/ts7/enums.js +8 -6
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/program.js +4 -1
- package/dist/frontend/ts7/program.js.map +1 -1
- package/dist/frontend/types.d.ts +16 -9
- package/dist/frontend/types.js +119 -38
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +70 -14
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +55 -26
- package/dist/ir/nodes.js +42 -29
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +106 -9
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/int-infer.js +7 -1
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +80 -0
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/sidecar-validate.js +5 -0
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +3 -0
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +1097 -130
package/dist/ir/validate.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, islandPromisePayloadTag, isJsonSafeType, isRefCounted, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./nodes.js";
|
|
1
|
+
import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DATE_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, islandPromisePayloadTag, isJsonSafeType, isRefCounted, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./nodes.js";
|
|
2
2
|
/** Per-method signature for strIntrinsic: `argTypes` lists every argument
|
|
3
3
|
* position (optional ones included); `minArgs` is how many may be omitted
|
|
4
4
|
* from the end (backends fill the documented defaults). Exported for the
|
|
@@ -54,6 +54,22 @@ export const REGEX_INTRINSIC_SIGS = {
|
|
|
54
54
|
* the libCall case checks it specially, like process.envGet's result.
|
|
55
55
|
* Exported for the frontend's lib-boundary pass (lib-boundary.ts). */
|
|
56
56
|
export const LIB_FN_SIGS = {
|
|
57
|
+
"fetch.start": { argTypes: [STRING, DYN], result: { kind: "promise", inner: DYN } },
|
|
58
|
+
"fetch.responseNew": { argTypes: [DYN, DYN], result: DYN },
|
|
59
|
+
"fetch.responseJson": { argTypes: [DYN], result: { kind: "promise", inner: DYN } },
|
|
60
|
+
"fetch.responseText": { argTypes: [DYN], result: { kind: "promise", inner: STRING } },
|
|
61
|
+
"fetch.responseBytes": { argTypes: [DYN], result: { kind: "promise", inner: BYTES_U8 } },
|
|
62
|
+
"fetch.abortControllerNew": { argTypes: [], result: DYN },
|
|
63
|
+
"fetch.abortTimeout": { argTypes: [DYN], result: DYN },
|
|
64
|
+
"fetch.abortNow": { argTypes: [DYN], result: DYN },
|
|
65
|
+
"fetch.abortAny": { argTypes: [DYN], result: DYN },
|
|
66
|
+
"fetch.streamNew": { argTypes: [DYN], result: DYN },
|
|
67
|
+
// Program-dependent iterable: typed arrays/bytes/string stay intact so
|
|
68
|
+
// the native stream can pull lazily; checked-dynamic values are the
|
|
69
|
+
// fallback. The libCall validator below checks the closed set.
|
|
70
|
+
"fetch.streamFrom": { argTypes: [null], result: DYN },
|
|
71
|
+
// The chunk/result record depends on ReadableStream<T>; validated below.
|
|
72
|
+
"fetch.readerRead": { argTypes: [DYN], result: VOID },
|
|
57
73
|
"island.eval": { argTypes: [STRING], result: STRING },
|
|
58
74
|
"island.import": { argTypes: [STRING, STRING, STRING], result: JSVAL },
|
|
59
75
|
"island.importDyn": { argTypes: [STRING], result: JSVAL },
|
|
@@ -242,7 +258,7 @@ export const LIB_FN_SIGS = {
|
|
|
242
258
|
"fs.statSync": { argTypes: [STRING], result: STATS_T },
|
|
243
259
|
"fs.lstatSync": { argTypes: [STRING], result: STATS_T },
|
|
244
260
|
"fs.openSync": { argTypes: [STRING, STRING], result: F64 },
|
|
245
|
-
"fs.readSync": { argTypes: [F64, BYTES_U8, F64, F64], result: F64 },
|
|
261
|
+
"fs.readSync": { argTypes: [F64, BYTES_U8, F64, F64, F64], result: F64 },
|
|
246
262
|
// fs.watch's callback func type is program-dependent (zero params, or
|
|
247
263
|
// the eventType string) — the slot pins arity and the path/receiver.
|
|
248
264
|
"fs.watch": { argTypes: [STRING], result: FSWATCHER_T },
|
|
@@ -1007,7 +1023,30 @@ export const LIB_FN_SIGS = {
|
|
|
1007
1023
|
"number.isInteger": { argTypes: [F64], result: BOOL },
|
|
1008
1024
|
"number.isSafeInteger": { argTypes: [F64], result: BOOL },
|
|
1009
1025
|
"date.now": { argTypes: [], result: F64 },
|
|
1026
|
+
"date.newNow": { argTypes: [], result: DATE_T },
|
|
1027
|
+
"date.newMs": { argTypes: [F64], result: DATE_T },
|
|
1028
|
+
"date.newString": { argTypes: [STRING], result: DATE_T },
|
|
1029
|
+
"date.getTime": { argTypes: [DATE_T], result: F64 },
|
|
1030
|
+
"date.valueOf": { argTypes: [DATE_T], result: F64 },
|
|
1010
1031
|
"date.toISOString": { argTypes: [F64], result: STRING },
|
|
1032
|
+
"date.toISOStringValue": { argTypes: [DATE_T], result: STRING },
|
|
1033
|
+
"date.getFullYear": { argTypes: [DATE_T], result: F64 },
|
|
1034
|
+
"date.getUTCFullYear": { argTypes: [DATE_T], result: F64 },
|
|
1035
|
+
"date.getMonth": { argTypes: [DATE_T], result: F64 },
|
|
1036
|
+
"date.getUTCMonth": { argTypes: [DATE_T], result: F64 },
|
|
1037
|
+
"date.getDate": { argTypes: [DATE_T], result: F64 },
|
|
1038
|
+
"date.getUTCDate": { argTypes: [DATE_T], result: F64 },
|
|
1039
|
+
"date.getDay": { argTypes: [DATE_T], result: F64 },
|
|
1040
|
+
"date.getUTCDay": { argTypes: [DATE_T], result: F64 },
|
|
1041
|
+
"date.getHours": { argTypes: [DATE_T], result: F64 },
|
|
1042
|
+
"date.getUTCHours": { argTypes: [DATE_T], result: F64 },
|
|
1043
|
+
"date.getMinutes": { argTypes: [DATE_T], result: F64 },
|
|
1044
|
+
"date.getUTCMinutes": { argTypes: [DATE_T], result: F64 },
|
|
1045
|
+
"date.getSeconds": { argTypes: [DATE_T], result: F64 },
|
|
1046
|
+
"date.getUTCSeconds": { argTypes: [DATE_T], result: F64 },
|
|
1047
|
+
"date.getMilliseconds": { argTypes: [DATE_T], result: F64 },
|
|
1048
|
+
"date.getUTCMilliseconds": { argTypes: [DATE_T], result: F64 },
|
|
1049
|
+
"date.getTimezoneOffset": { argTypes: [DATE_T], result: F64 },
|
|
1011
1050
|
"date.parseGetTime": { argTypes: [STRING], result: F64 },
|
|
1012
1051
|
"date.utc": { argTypes: [F64, F64, F64, F64, F64, F64, F64], result: F64 },
|
|
1013
1052
|
"text.decode": { argTypes: [BYTES_U8], result: STRING },
|
|
@@ -1292,15 +1331,22 @@ export function validateModule(mod) {
|
|
|
1292
1331
|
}
|
|
1293
1332
|
u.arms.forEach((arm, i) => {
|
|
1294
1333
|
// The unit kinds (undefinedT/nullT) are valid arms — union membership
|
|
1295
|
-
// is the ONLY place they may appear; void/union/map/dyn/jsval
|
|
1296
|
-
// stay out (maps
|
|
1334
|
+
// is the ONLY place they may appear; void/union/map/dyn/jsval/date
|
|
1335
|
+
// stay out (maps and scalar Date values have no supported union
|
|
1336
|
+
// representation/discriminant to narrow on). Func/set arm
|
|
1297
1337
|
// sibling rules live in unionFuncSetArmsOk (shared with the frontend's
|
|
1298
1338
|
// union builders): a func arm allows unit and FUNC siblings (the
|
|
1299
1339
|
// nullable-callback shape, and the primitive-constructor tables where
|
|
1300
1340
|
// closure pointer identity per tag is the narrowing); a set arm is
|
|
1301
1341
|
// valid exactly when every other arm is a unit (the defaulted-Set-
|
|
1302
1342
|
// param ABI); func/set-beside-data stays out.
|
|
1303
|
-
if (arm.kind === "void" ||
|
|
1343
|
+
if (arm.kind === "void" ||
|
|
1344
|
+
arm.kind === "union" ||
|
|
1345
|
+
arm.kind === "map" ||
|
|
1346
|
+
arm.kind === "dyn" ||
|
|
1347
|
+
arm.kind === "jsval" ||
|
|
1348
|
+
arm.kind === "date" ||
|
|
1349
|
+
arm.kind === "generator") {
|
|
1304
1350
|
errors.push({ message: `union ${u.id}: arm ${i} is ${arm.kind}`, loc: noLoc });
|
|
1305
1351
|
}
|
|
1306
1352
|
if ((arm.kind === "func" || arm.kind === "set") &&
|
|
@@ -1550,6 +1596,17 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
1550
1596
|
// Optional chains open a binding scope: chainRecv is valid only inside
|
|
1551
1597
|
// the body of the optChain whose id it names.
|
|
1552
1598
|
const activeChains = new Map();
|
|
1599
|
+
const liveDynRefEligible = (type, seen = new Set()) => {
|
|
1600
|
+
if (type.kind === "record" ||
|
|
1601
|
+
type.kind === "array" ||
|
|
1602
|
+
type.kind === "bytes") {
|
|
1603
|
+
return true;
|
|
1604
|
+
}
|
|
1605
|
+
if (type.kind !== "union" || seen.has(type.unionId))
|
|
1606
|
+
return false;
|
|
1607
|
+
seen.add(type.unionId);
|
|
1608
|
+
return unions.get(type.unionId)?.arms.some((arm) => liveDynRefEligible(arm, seen)) ?? false;
|
|
1609
|
+
};
|
|
1553
1610
|
function checkExpr(e) {
|
|
1554
1611
|
switch (e.kind) {
|
|
1555
1612
|
case "numLit":
|
|
@@ -2974,6 +3031,9 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
2974
3031
|
if (!canConvertToDyn(vt, (id) => records.get(id), (id) => unions.get(id))) {
|
|
2975
3032
|
err(`dynFrom of non-dyn-convertible type ${vt.kind}`, e.loc);
|
|
2976
3033
|
}
|
|
3034
|
+
if (e.liveRef && !liveDynRefEligible(vt)) {
|
|
3035
|
+
err(`live dynFrom of unsupported type ${vt.kind}`, e.loc);
|
|
3036
|
+
}
|
|
2977
3037
|
break;
|
|
2978
3038
|
}
|
|
2979
3039
|
case "dynFromJsval": {
|
|
@@ -3449,6 +3509,35 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
3449
3509
|
if (want)
|
|
3450
3510
|
expectType(a, want, `libCall ${e.fn} arg ${i}`);
|
|
3451
3511
|
});
|
|
3512
|
+
if (e.fn === "fetch.streamFrom") {
|
|
3513
|
+
const t = e.args[0]?.type;
|
|
3514
|
+
const ok = t?.kind === "string" ||
|
|
3515
|
+
(t?.kind === "bytes" && t.elem === "u8") ||
|
|
3516
|
+
(t?.kind === "array" &&
|
|
3517
|
+
canConvertToDyn(t.elem, (id) => records.get(id), (id) => unions.get(id))) ||
|
|
3518
|
+
t?.kind === "dyn";
|
|
3519
|
+
if (!ok) {
|
|
3520
|
+
err(`libCall fetch.streamFrom arg 0: expected a supported iterable, got ${t?.kind}`, e.loc);
|
|
3521
|
+
}
|
|
3522
|
+
break;
|
|
3523
|
+
}
|
|
3524
|
+
if (e.fn === "fetch.readerRead") {
|
|
3525
|
+
if (e.type.kind !== "promise" || e.type.inner.kind !== "record") {
|
|
3526
|
+
err(`libCall fetch.readerRead must return a promise of a read-result record`, e.loc);
|
|
3527
|
+
}
|
|
3528
|
+
break;
|
|
3529
|
+
}
|
|
3530
|
+
if (e.fn === "fetch.responseText" || e.fn === "fetch.responseBytes") {
|
|
3531
|
+
const valueType = e.fn === "fetch.responseText" ? STRING : BYTES_U8;
|
|
3532
|
+
const inner = e.type.kind === "promise" ? e.type.inner : null;
|
|
3533
|
+
const union = inner?.kind === "union" ? unions.get(inner.unionId) : undefined;
|
|
3534
|
+
if (inner === null ||
|
|
3535
|
+
(!typeEquals(inner, valueType) &&
|
|
3536
|
+
!union?.arms.some((arm) => typeEquals(arm, valueType)))) {
|
|
3537
|
+
err(`libCall ${e.fn} must return a promise whose value includes ${valueType.kind}`, e.loc);
|
|
3538
|
+
}
|
|
3539
|
+
break;
|
|
3540
|
+
}
|
|
3452
3541
|
if (e.fn === "string.fromCharCode") {
|
|
3453
3542
|
// One packed f64[] or one bytes value (the spread form).
|
|
3454
3543
|
const t = e.args[0]?.type;
|
|
@@ -4523,11 +4612,16 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4523
4612
|
}
|
|
4524
4613
|
}
|
|
4525
4614
|
else {
|
|
4526
|
-
// throw: any
|
|
4615
|
+
// throw: any exception-representable payload (the throw
|
|
4616
|
+
// statement's rule). Date cannot retain its object kind in the
|
|
4617
|
+
// untyped exception cell.
|
|
4527
4618
|
if (e.arg === null) {
|
|
4528
4619
|
err("genResume throw with no payload", e.loc);
|
|
4529
4620
|
}
|
|
4530
|
-
else if (e.arg.type.kind === "void" ||
|
|
4621
|
+
else if (e.arg.type.kind === "void" ||
|
|
4622
|
+
e.arg.type.kind === "dyn" ||
|
|
4623
|
+
e.arg.type.kind === "caught" ||
|
|
4624
|
+
e.arg.type.kind === "date") {
|
|
4531
4625
|
err(`genResume throw of a ${e.arg.type.kind} value`, e.loc);
|
|
4532
4626
|
}
|
|
4533
4627
|
}
|
|
@@ -4706,7 +4800,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4706
4800
|
getProp: 1, setProp: 2, getIdx: 2, setIdx: 3, globalGet: 0,
|
|
4707
4801
|
undefLit: 0, nullLit: 0, iterNew: 1, defineGetter: 3, objSpread: 2,
|
|
4708
4802
|
callSpread: 3, // callee + pre array + spread source
|
|
4709
|
-
callMethod: null, optCallMethod: null, callFn: null, construct: null, // receiver/callee + any number of args
|
|
4803
|
+
callMethod: null, optCallMethod: null, callFn: null, callFnThis: null, construct: null, // receiver/callee + any number of args
|
|
4710
4804
|
objLit: null, arrLit: null, tplStrings: null, // variable length (objLit: key/value pairs; tplStrings: n cooked + n raw)
|
|
4711
4805
|
};
|
|
4712
4806
|
const want = arity[e.op];
|
|
@@ -4716,6 +4810,9 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4716
4810
|
if (want === null && e.op !== "objLit" && e.op !== "arrLit" && e.op !== "tplStrings" && e.args.length < 1) {
|
|
4717
4811
|
err(`jsOp ${e.op} needs a receiver/callee arg`, e.loc);
|
|
4718
4812
|
}
|
|
4813
|
+
if (e.op === "callFnThis" && e.args.length < 2) {
|
|
4814
|
+
err("jsOp callFnThis needs a callee and receiver", e.loc);
|
|
4815
|
+
}
|
|
4719
4816
|
if (e.op === "objLit" && e.args.length % 2 !== 0) {
|
|
4720
4817
|
err("jsOp objLit takes key/value pairs", e.loc);
|
|
4721
4818
|
}
|
|
@@ -5038,7 +5135,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
5038
5135
|
checkExpr(s.value);
|
|
5039
5136
|
// dyn throws are allowed: the dyn node rides the REF cell arm by
|
|
5040
5137
|
// reference (the JS-lane `throw err` of a dyn argument).
|
|
5041
|
-
if (s.value.type.kind === "void" || s.value.type.kind === "caught") {
|
|
5138
|
+
if (s.value.type.kind === "void" || s.value.type.kind === "caught" || s.value.type.kind === "date") {
|
|
5042
5139
|
err(`throw of a ${s.value.type.kind} value`, s.loc);
|
|
5043
5140
|
}
|
|
5044
5141
|
break;
|