typia 3.5.0-dev.20230126 → 3.5.0-dev.20230212
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/README.md +70 -70
- package/lib/factories/MetadataCollection.d.ts +9 -1
- package/lib/factories/MetadataCollection.js +75 -2
- package/lib/factories/MetadataCollection.js.map +1 -1
- package/lib/factories/internal/metadata/iterate_metadata_native.js +0 -3
- package/lib/factories/internal/metadata/iterate_metadata_native.js.map +1 -1
- package/lib/functional/$is_between.d.ts +1 -0
- package/lib/functional/$is_between.js +8 -0
- package/lib/functional/$is_between.js.map +1 -0
- package/lib/metadata/IMetadataTag.d.ts +3 -7
- package/lib/metadata/Metadata.js +2 -2
- package/lib/metadata/Metadata.js.map +1 -1
- package/lib/module.d.ts +210 -6
- package/lib/module.js +88 -9
- package/lib/module.js.map +1 -1
- package/lib/programmers/AssertProgrammer.js +3 -2
- package/lib/programmers/AssertProgrammer.js.map +1 -1
- package/lib/programmers/AssertPruneProgrammer.d.ts +5 -0
- package/lib/programmers/AssertPruneProgrammer.js +37 -0
- package/lib/programmers/AssertPruneProgrammer.js.map +1 -0
- package/lib/programmers/CheckerProgrammer.d.ts +2 -2
- package/lib/programmers/CheckerProgrammer.js +21 -16
- package/lib/programmers/CheckerProgrammer.js.map +1 -1
- package/lib/programmers/FeatureProgrammer.d.ts +114 -18
- package/lib/programmers/FeatureProgrammer.js +4 -4
- package/lib/programmers/FeatureProgrammer.js.map +1 -1
- package/lib/programmers/IsProgrammer.d.ts +4 -3
- package/lib/programmers/IsProgrammer.js +72 -61
- package/lib/programmers/IsProgrammer.js.map +1 -1
- package/lib/programmers/IsPruneProgrammer.d.ts +5 -0
- package/lib/programmers/IsPruneProgrammer.js +37 -0
- package/lib/programmers/IsPruneProgrammer.js.map +1 -0
- package/lib/programmers/PruneProgrammer.d.ts +5 -0
- package/lib/programmers/PruneProgrammer.js +279 -0
- package/lib/programmers/PruneProgrammer.js.map +1 -0
- package/lib/programmers/StringifyProgrammer.js +26 -21
- package/lib/programmers/StringifyProgrammer.js.map +1 -1
- package/lib/programmers/ValidateProgrammer.js +3 -2
- package/lib/programmers/ValidateProgrammer.js.map +1 -1
- package/lib/programmers/ValidatePruneProgrammer.d.ts +5 -0
- package/lib/programmers/ValidatePruneProgrammer.js +37 -0
- package/lib/programmers/ValidatePruneProgrammer.js.map +1 -0
- package/lib/programmers/helpers/AtomicPredicator.d.ts +2 -0
- package/lib/programmers/helpers/AtomicPredicator.js +9 -1
- package/lib/programmers/helpers/AtomicPredicator.js.map +1 -1
- package/lib/programmers/helpers/IExpressionEntry.d.ts +2 -2
- package/lib/programmers/helpers/OptionPredicator.d.ts +1 -0
- package/lib/programmers/helpers/OptionPredicator.js +4 -0
- package/lib/programmers/helpers/OptionPredicator.js.map +1 -1
- package/lib/programmers/helpers/PruneJoiner.d.ts +8 -0
- package/lib/programmers/helpers/PruneJoiner.js +60 -0
- package/lib/programmers/helpers/PruneJoiner.js.map +1 -0
- package/lib/programmers/helpers/StringifyJoinder.d.ts +1 -1
- package/lib/programmers/helpers/StringifyJoinder.js +2 -4
- package/lib/programmers/helpers/StringifyJoinder.js.map +1 -1
- package/lib/programmers/internal/application_object.js +11 -11
- package/lib/programmers/internal/application_object.js.map +1 -1
- package/lib/programmers/internal/application_schema.js +21 -12
- package/lib/programmers/internal/application_schema.js.map +1 -1
- package/lib/programmers/internal/check_dynamic_properties.js +34 -11
- package/lib/programmers/internal/check_dynamic_properties.js.map +1 -1
- package/lib/programmers/internal/check_native.js +9 -1
- package/lib/programmers/internal/check_native.js.map +1 -1
- package/lib/programmers/internal/check_object.d.ts +1 -0
- package/lib/programmers/internal/check_object.js +13 -9
- package/lib/programmers/internal/check_object.js.map +1 -1
- package/lib/programmers/internal/check_union_array_like.d.ts +1 -1
- package/lib/programmers/internal/check_union_array_like.js +3 -1
- package/lib/programmers/internal/check_union_array_like.js.map +1 -1
- package/lib/programmers/internal/feature_object_entries.d.ts +2 -2
- package/lib/programmers/internal/feature_object_entries.js.map +1 -1
- package/lib/programmers/internal/prune_object_properties.d.ts +1 -0
- package/lib/programmers/internal/prune_object_properties.js +28 -0
- package/lib/programmers/internal/prune_object_properties.js.map +1 -0
- package/lib/programmers/internal/stringify_dynamic_properties.js.map +1 -1
- package/lib/programmers/internal/stringify_regular_properties.js.map +1 -1
- package/lib/transformers/CallExpressionTransformer.js +17 -3
- package/lib/transformers/CallExpressionTransformer.js.map +1 -1
- package/lib/transformers/ITransformOptions.d.ts +14 -0
- package/lib/transformers/features/miscellaneous/ApplicationTransformer.js +3 -1
- package/lib/transformers/features/miscellaneous/ApplicationTransformer.js.map +1 -1
- package/lib/transformers/features/miscellaneous/AssertPruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/AssertPruneTransformer.js +23 -0
- package/lib/transformers/features/miscellaneous/AssertPruneTransformer.js.map +1 -0
- package/lib/transformers/features/miscellaneous/CreateAssertPruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/CreateAssertPruneTransformer.js +17 -0
- package/lib/transformers/features/miscellaneous/CreateAssertPruneTransformer.js.map +1 -0
- package/lib/transformers/features/miscellaneous/CreateIsPruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/CreateIsPruneTransformer.js +17 -0
- package/lib/transformers/features/miscellaneous/CreateIsPruneTransformer.js.map +1 -0
- package/lib/transformers/features/miscellaneous/CreatePruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/CreatePruneTransformer.js +17 -0
- package/lib/transformers/features/miscellaneous/CreatePruneTransformer.js.map +1 -0
- package/lib/transformers/features/miscellaneous/CreateValidatePruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/CreateValidatePruneTransformer.js +17 -0
- package/lib/transformers/features/miscellaneous/CreateValidatePruneTransformer.js.map +1 -0
- package/lib/transformers/features/miscellaneous/IsPruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/IsPruneTransformer.js +23 -0
- package/lib/transformers/features/miscellaneous/IsPruneTransformer.js.map +1 -0
- package/lib/transformers/features/miscellaneous/PruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/PruneTransformer.js +34 -0
- package/lib/transformers/features/miscellaneous/PruneTransformer.js.map +1 -0
- package/lib/transformers/features/miscellaneous/ValidatePruneTransformer.d.ts +5 -0
- package/lib/transformers/features/miscellaneous/ValidatePruneTransformer.js +23 -0
- package/lib/transformers/features/miscellaneous/ValidatePruneTransformer.js.map +1 -0
- package/package.json +5 -4
- package/src/factories/MetadataCollection.ts +41 -2
- package/src/factories/internal/metadata/iterate_metadata_native.ts +0 -5
- package/src/functional/$is_between.ts +7 -0
- package/src/metadata/IMetadataTag.ts +4 -19
- package/src/metadata/Metadata.ts +3 -6
- package/src/module.ts +366 -19
- package/src/programmers/AssertProgrammer.ts +3 -2
- package/src/programmers/AssertPruneProgrammer.ts +59 -0
- package/src/programmers/CheckerProgrammer.ts +21 -13
- package/src/programmers/FeatureProgrammer.ts +146 -21
- package/src/programmers/IsProgrammer.ts +107 -87
- package/src/programmers/IsPruneProgrammer.ts +63 -0
- package/src/programmers/PruneProgrammer.ts +323 -0
- package/src/programmers/StringifyProgrammer.ts +51 -34
- package/src/programmers/ValidateProgrammer.ts +3 -2
- package/src/programmers/ValidatePruneProgrammer.ts +73 -0
- package/src/programmers/helpers/AtomicPredicator.ts +17 -1
- package/src/programmers/helpers/IExpressionEntry.ts +4 -2
- package/src/programmers/helpers/OptionPredicator.ts +4 -0
- package/src/programmers/helpers/PruneJoiner.ts +52 -0
- package/src/programmers/helpers/StringifyJoinder.ts +7 -4
- package/src/programmers/internal/application_object.ts +5 -5
- package/src/programmers/internal/application_schema.ts +33 -27
- package/src/programmers/internal/check_dynamic_properties.ts +67 -16
- package/src/programmers/internal/check_native.ts +14 -2
- package/src/programmers/internal/check_object.ts +8 -2
- package/src/programmers/internal/check_union_array_like.ts +4 -2
- package/src/programmers/internal/feature_object_entries.ts +6 -1
- package/src/programmers/internal/prune_object_properties.ts +60 -0
- package/src/programmers/internal/stringify_dynamic_properties.ts +2 -2
- package/src/programmers/internal/stringify_regular_properties.ts +2 -2
- package/src/transformers/CallExpressionTransformer.ts +27 -16
- package/src/transformers/ITransformOptions.ts +15 -0
- package/src/transformers/features/miscellaneous/ApplicationTransformer.ts +3 -1
- package/src/transformers/features/miscellaneous/AssertPruneTransformer.ts +38 -0
- package/src/transformers/features/miscellaneous/CreateAssertPruneTransformer.ts +32 -0
- package/src/transformers/features/{protocols/MessageTransformer.ts → miscellaneous/CreateIsPruneTransformer.ts} +6 -6
- package/src/transformers/features/miscellaneous/CreatePruneTransformer.ts +31 -0
- package/src/transformers/features/miscellaneous/CreateValidatePruneTransformer.ts +32 -0
- package/src/transformers/features/miscellaneous/IsPruneTransformer.ts +38 -0
- package/src/transformers/features/miscellaneous/PruneTransformer.ts +46 -0
- package/src/transformers/features/miscellaneous/ValidatePruneTransformer.ts +38 -0
- package/lib/factories/ProtocolFactory.d.ts +0 -8
- package/lib/factories/ProtocolFactory.js +0 -112
- package/lib/factories/ProtocolFactory.js.map +0 -1
- package/lib/factories/internal/protocols/ProtocolMetadataUtil.d.ts +0 -16
- package/lib/factories/internal/protocols/ProtocolMetadataUtil.js +0 -156
- package/lib/factories/internal/protocols/ProtocolMetadataUtil.js.map +0 -1
- package/lib/factories/internal/protocols/emplace_protocol_object.d.ts +0 -3
- package/lib/factories/internal/protocols/emplace_protocol_object.js +0 -47
- package/lib/factories/internal/protocols/emplace_protocol_object.js.map +0 -1
- package/lib/factories/internal/protocols/emplace_protocol_property.d.ts +0 -4
- package/lib/factories/internal/protocols/emplace_protocol_property.js +0 -20
- package/lib/factories/internal/protocols/emplace_protocol_property.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_atomic.d.ts +0 -3
- package/lib/factories/internal/protocols/iterate_protocol_atomic.js +0 -69
- package/lib/factories/internal/protocols/iterate_protocol_atomic.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_constant.d.ts +0 -2
- package/lib/factories/internal/protocols/iterate_protocol_constant.js +0 -30
- package/lib/factories/internal/protocols/iterate_protocol_constant.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_main.d.ts +0 -3
- package/lib/factories/internal/protocols/iterate_protocol_main.js +0 -17
- package/lib/factories/internal/protocols/iterate_protocol_main.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_map.d.ts +0 -4
- package/lib/factories/internal/protocols/iterate_protocol_map.js +0 -75
- package/lib/factories/internal/protocols/iterate_protocol_map.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_metadata.d.ts +0 -5
- package/lib/factories/internal/protocols/iterate_protocol_metadata.js +0 -190
- package/lib/factories/internal/protocols/iterate_protocol_metadata.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_native.d.ts +0 -2
- package/lib/factories/internal/protocols/iterate_protocol_native.js +0 -33
- package/lib/factories/internal/protocols/iterate_protocol_native.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_never.d.ts +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_never.js +0 -6
- package/lib/factories/internal/protocols/iterate_protocol_never.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_object.d.ts +0 -4
- package/lib/factories/internal/protocols/iterate_protocol_object.js +0 -157
- package/lib/factories/internal/protocols/iterate_protocol_object.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_repeated.d.ts +0 -5
- package/lib/factories/internal/protocols/iterate_protocol_repeated.js +0 -25
- package/lib/factories/internal/protocols/iterate_protocol_repeated.js.map +0 -1
- package/lib/factories/internal/protocols/iterate_protocol_tuple.d.ts +0 -3
- package/lib/factories/internal/protocols/iterate_protocol_tuple.js +0 -46
- package/lib/factories/internal/protocols/iterate_protocol_tuple.js.map +0 -1
- package/lib/functional/$proto_bytes.d.ts +0 -2
- package/lib/functional/$proto_bytes.js +0 -37
- package/lib/functional/$proto_bytes.js.map +0 -1
- package/lib/functional/$proto_field.d.ts +0 -10
- package/lib/functional/$proto_field.js +0 -42
- package/lib/functional/$proto_field.js.map +0 -1
- package/lib/functional/$proto_float.d.ts +0 -4
- package/lib/functional/$proto_float.js +0 -28
- package/lib/functional/$proto_float.js.map +0 -1
- package/lib/functional/$proto_i32.d.ts +0 -2
- package/lib/functional/$proto_i32.js +0 -23
- package/lib/functional/$proto_i32.js.map +0 -1
- package/lib/functional/$proto_i64.d.ts +0 -2
- package/lib/functional/$proto_i64.js +0 -31
- package/lib/functional/$proto_i64.js.map +0 -1
- package/lib/functional/$proto_size.d.ts +0 -6
- package/lib/functional/$proto_size.js +0 -76
- package/lib/functional/$proto_size.js.map +0 -1
- package/lib/functional/$proto_string.d.ts +0 -2
- package/lib/functional/$proto_string.js +0 -34
- package/lib/functional/$proto_string.js.map +0 -1
- package/lib/functional/$varint.d.ts +0 -6
- package/lib/functional/$varint.js +0 -99
- package/lib/functional/$varint.js.map +0 -1
- package/lib/functional/$zigzag.d.ts +0 -4
- package/lib/functional/$zigzag.js +0 -34
- package/lib/functional/$zigzag.js.map +0 -1
- package/lib/messages/IProtocolMap.d.ts +0 -5
- package/lib/messages/IProtocolMap.js +0 -3
- package/lib/messages/IProtocolMap.js.map +0 -1
- package/lib/messages/IProtocolMessage.d.ts +0 -5
- package/lib/messages/IProtocolMessage.js +0 -3
- package/lib/messages/IProtocolMessage.js.map +0 -1
- package/lib/messages/IProtocolProperty.d.ts +0 -12
- package/lib/messages/IProtocolProperty.js +0 -3
- package/lib/messages/IProtocolProperty.js.map +0 -1
- package/lib/programmers/MessageProgrammer.d.ts +0 -5
- package/lib/programmers/MessageProgrammer.js +0 -141
- package/lib/programmers/MessageProgrammer.js.map +0 -1
- package/lib/transformers/features/protocols/MessageTransformer.d.ts +0 -5
- package/lib/transformers/features/protocols/MessageTransformer.js +0 -17
- package/lib/transformers/features/protocols/MessageTransformer.js.map +0 -1
- package/lib/utils/NameEncoder.d.ts +0 -4
- package/lib/utils/NameEncoder.js +0 -89
- package/lib/utils/NameEncoder.js.map +0 -1
- package/src/factories/ProtocolFactory.ts +0 -79
- package/src/factories/internal/protocols/ProtocolMetadataUtil.ts +0 -163
- package/src/factories/internal/protocols/emplace_protocol_object.ts +0 -25
- package/src/factories/internal/protocols/emplace_protocol_property.ts +0 -12
- package/src/factories/internal/protocols/iterate_protocol_atomic.ts +0 -34
- package/src/factories/internal/protocols/iterate_protocol_constant.ts +0 -27
- package/src/factories/internal/protocols/iterate_protocol_main.ts +0 -19
- package/src/factories/internal/protocols/iterate_protocol_map.ts +0 -58
- package/src/factories/internal/protocols/iterate_protocol_metadata.ts +0 -96
- package/src/factories/internal/protocols/iterate_protocol_native.ts +0 -34
- package/src/factories/internal/protocols/iterate_protocol_never.ts +0 -1
- package/src/factories/internal/protocols/iterate_protocol_object.ts +0 -110
- package/src/factories/internal/protocols/iterate_protocol_repeated.ts +0 -34
- package/src/factories/internal/protocols/iterate_protocol_tuple.ts +0 -29
- package/src/functional/$proto_bytes.ts +0 -25
- package/src/functional/$proto_field.ts +0 -30
- package/src/functional/$proto_float.ts +0 -37
- package/src/functional/$proto_i32.ts +0 -29
- package/src/functional/$proto_i64.ts +0 -37
- package/src/functional/$proto_size.ts +0 -82
- package/src/functional/$proto_string.ts +0 -24
- package/src/functional/$varint.ts +0 -130
- package/src/functional/$zigzag.ts +0 -39
- package/src/messages/IProtocolMap.ts +0 -5
- package/src/messages/IProtocolMessage.ts +0 -6
- package/src/messages/IProtocolProperty.ts +0 -13
- package/src/programmers/MessageProgrammer.ts +0 -126
- package/src/utils/NameEncoder.ts +0 -32
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
import { IdentifierFactory } from "../factories/IdentifierFactory";
|
|
4
|
+
import { StatementFactory } from "../factories/StatementFactory";
|
|
5
|
+
|
|
6
|
+
import { IProject } from "../transformers/IProject";
|
|
7
|
+
|
|
8
|
+
import { AssertProgrammer } from "./AssertProgrammer";
|
|
9
|
+
import { PruneProgrammer } from "./PruneProgrammer";
|
|
10
|
+
|
|
11
|
+
export namespace AssertPruneProgrammer {
|
|
12
|
+
export const generate =
|
|
13
|
+
(project: IProject, modulo: ts.LeftHandSideExpression) =>
|
|
14
|
+
(type: ts.Type) =>
|
|
15
|
+
ts.factory.createArrowFunction(
|
|
16
|
+
undefined,
|
|
17
|
+
undefined,
|
|
18
|
+
[IdentifierFactory.parameter("input")],
|
|
19
|
+
undefined,
|
|
20
|
+
undefined,
|
|
21
|
+
ts.factory.createBlock([
|
|
22
|
+
StatementFactory.constant(
|
|
23
|
+
"assert",
|
|
24
|
+
AssertProgrammer.generate(project, modulo)(type),
|
|
25
|
+
),
|
|
26
|
+
StatementFactory.constant(
|
|
27
|
+
"prune",
|
|
28
|
+
PruneProgrammer.generate(
|
|
29
|
+
{
|
|
30
|
+
...project,
|
|
31
|
+
options: {
|
|
32
|
+
...project.options,
|
|
33
|
+
functional: false,
|
|
34
|
+
numeric: false,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
modulo,
|
|
38
|
+
)(type),
|
|
39
|
+
),
|
|
40
|
+
ts.factory.createExpressionStatement(
|
|
41
|
+
ts.factory.createCallExpression(
|
|
42
|
+
ts.factory.createIdentifier("assert"),
|
|
43
|
+
undefined,
|
|
44
|
+
[ts.factory.createIdentifier("input")],
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
ts.factory.createExpressionStatement(
|
|
48
|
+
ts.factory.createCallExpression(
|
|
49
|
+
ts.factory.createIdentifier("prune"),
|
|
50
|
+
undefined,
|
|
51
|
+
[ts.factory.createIdentifier("input")],
|
|
52
|
+
),
|
|
53
|
+
),
|
|
54
|
+
ts.factory.createReturnStatement(
|
|
55
|
+
ts.factory.createIdentifier("input"),
|
|
56
|
+
),
|
|
57
|
+
]),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -13,6 +13,7 @@ import { MetadataObject } from "../metadata/MetadataObject";
|
|
|
13
13
|
import { IProject } from "../transformers/IProject";
|
|
14
14
|
|
|
15
15
|
import { FeatureProgrammer } from "./FeatureProgrammer";
|
|
16
|
+
import { AtomicPredicator } from "./helpers/AtomicPredicator";
|
|
16
17
|
import { FunctionImporter } from "./helpers/FunctionImporeter";
|
|
17
18
|
import { IExpressionEntry } from "./helpers/IExpressionEntry";
|
|
18
19
|
import { OptionPredicator } from "./helpers/OptionPredicator";
|
|
@@ -36,7 +37,7 @@ export namespace CheckerProgrammer {
|
|
|
36
37
|
equals: boolean;
|
|
37
38
|
numeric: boolean;
|
|
38
39
|
combiner: IConfig.Combiner;
|
|
39
|
-
decoder?: FeatureProgrammer.Decoder<Metadata>;
|
|
40
|
+
decoder?: FeatureProgrammer.Decoder<Metadata, ts.Expression>;
|
|
40
41
|
joiner: IConfig.IJoiner;
|
|
41
42
|
success: ts.Expression;
|
|
42
43
|
}
|
|
@@ -53,7 +54,10 @@ export namespace CheckerProgrammer {
|
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
56
|
export interface IJoiner {
|
|
56
|
-
object(
|
|
57
|
+
object(
|
|
58
|
+
input: ts.Expression,
|
|
59
|
+
entries: IExpressionEntry[],
|
|
60
|
+
): ts.Expression;
|
|
57
61
|
array(input: ts.Expression, arrow: ts.ArrowFunction): ts.Expression;
|
|
58
62
|
tuple?(exprs: ts.Expression[]): ts.Expression;
|
|
59
63
|
|
|
@@ -246,6 +250,7 @@ export namespace CheckerProgrammer {
|
|
|
246
250
|
//----
|
|
247
251
|
// CHECK OPTIONAL
|
|
248
252
|
//----
|
|
253
|
+
// @todo -> should be elaborated
|
|
249
254
|
const checkOptional: boolean = meta.empty() || meta.isUnionBucket();
|
|
250
255
|
|
|
251
256
|
// NULLABLE
|
|
@@ -288,12 +293,14 @@ export namespace CheckerProgrammer {
|
|
|
288
293
|
//----
|
|
289
294
|
// CONSTANT VALUES
|
|
290
295
|
for (const constant of meta.constants)
|
|
291
|
-
|
|
292
|
-
|
|
296
|
+
if (AtomicPredicator.constant(meta)(constant.type))
|
|
297
|
+
for (const val of constant.values)
|
|
298
|
+
add(true, getConstantValue(val));
|
|
293
299
|
|
|
294
300
|
// ATOMIC VALUES
|
|
295
301
|
for (const type of meta.atomics)
|
|
296
|
-
if (type ===
|
|
302
|
+
if (AtomicPredicator.atomic(meta)(type) === false) continue;
|
|
303
|
+
else if (type === "number")
|
|
297
304
|
binaries.push({
|
|
298
305
|
expression: check_number(project, config.numeric)(
|
|
299
306
|
input,
|
|
@@ -320,14 +327,15 @@ export namespace CheckerProgrammer {
|
|
|
320
327
|
|
|
321
328
|
// TEMPLATE LITERAL VALUES
|
|
322
329
|
if (meta.templates.length)
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
330
|
+
if (AtomicPredicator.template(meta))
|
|
331
|
+
binaries.push({
|
|
332
|
+
expression: check_template(importer)(
|
|
333
|
+
input,
|
|
334
|
+
meta.templates,
|
|
335
|
+
tags,
|
|
336
|
+
),
|
|
337
|
+
combined: false,
|
|
338
|
+
});
|
|
331
339
|
|
|
332
340
|
// NATIVE CLASSES
|
|
333
341
|
for (const native of meta.natives)
|
|
@@ -21,29 +21,135 @@ export namespace FeatureProgrammer {
|
|
|
21
21
|
/* -----------------------------------------------------------
|
|
22
22
|
PARAMETERS
|
|
23
23
|
----------------------------------------------------------- */
|
|
24
|
-
export interface IConfig {
|
|
24
|
+
export interface IConfig<Output extends ts.ConciseBody = ts.ConciseBody> {
|
|
25
|
+
/**
|
|
26
|
+
* Prefix name of functions for specific object types.
|
|
27
|
+
*/
|
|
25
28
|
functors: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Prefix name of functions for union object types.
|
|
32
|
+
*/
|
|
26
33
|
unioners: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether to archive access path or not.
|
|
37
|
+
*/
|
|
27
38
|
path: boolean;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Whether to trace exception or not.
|
|
42
|
+
*/
|
|
28
43
|
trace: boolean;
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Initializer of metadata.
|
|
47
|
+
*/
|
|
48
|
+
initializer(
|
|
49
|
+
project: IProject,
|
|
50
|
+
type: ts.Type,
|
|
51
|
+
): [MetadataCollection, Metadata];
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Decoder, station of every types.
|
|
55
|
+
*/
|
|
56
|
+
decoder: Decoder<Metadata, Output>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Object configurator.
|
|
60
|
+
*/
|
|
31
61
|
objector: IConfig.IObjector;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Generator of functions for object types.
|
|
65
|
+
*/
|
|
32
66
|
generator?: Partial<IConfig.IGenerator>;
|
|
33
67
|
}
|
|
34
68
|
export namespace IConfig {
|
|
35
69
|
export interface IObjector {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Type checker when union object type comes.
|
|
72
|
+
*/
|
|
73
|
+
checker: Decoder<Metadata, ts.Expression>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Decoder, function call expression generator of specific typed objects.
|
|
77
|
+
*/
|
|
78
|
+
decoder: Decoder<MetadataObject, ts.Expression>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Joiner of expressions from properties.
|
|
82
|
+
*/
|
|
83
|
+
joiner(
|
|
84
|
+
input: ts.Expression,
|
|
85
|
+
entries: IExpressionEntry[],
|
|
86
|
+
parent: MetadataObject,
|
|
87
|
+
): ts.ConciseBody;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Union type specificator.
|
|
91
|
+
*
|
|
92
|
+
* Expression of an algorithm specifying object type and calling
|
|
93
|
+
* the `decoder` function of the specified object type.
|
|
94
|
+
*/
|
|
95
|
+
unionizer: Decoder<MetadataObject[], ts.Expression>;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Handler of union type specification failure.
|
|
99
|
+
*
|
|
100
|
+
* @param value Expression of input parameter
|
|
101
|
+
* @param expected Expected type name
|
|
102
|
+
* @param explore Exploration info
|
|
103
|
+
* @returns Statement of failure
|
|
104
|
+
*/
|
|
105
|
+
failure(
|
|
41
106
|
value: ts.Expression,
|
|
42
107
|
expected: string,
|
|
43
108
|
explore?: IExplore,
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
|
|
109
|
+
): ts.Statement;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Transformer of type checking expression by discrimination.
|
|
113
|
+
*
|
|
114
|
+
* When an object type has been specified by a discrimination without full
|
|
115
|
+
* iteration, the `unionizer` will decode the object instance after
|
|
116
|
+
* the last type checking.
|
|
117
|
+
*
|
|
118
|
+
* In such circumtance, you can transform the last type checking function.
|
|
119
|
+
*
|
|
120
|
+
* @param exp Current expression about type checking
|
|
121
|
+
* @returns Transformed expression
|
|
122
|
+
* @deprecated
|
|
123
|
+
*/
|
|
124
|
+
is?(exp: ts.Expression): ts.Expression;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Transformer of non-undefined type checking by discrimination.
|
|
128
|
+
*
|
|
129
|
+
* When specifying an union type of objects, `typia` tries to find
|
|
130
|
+
* descrimination way just by checking only one property type.
|
|
131
|
+
* If succeeded to find the discrimination way, `typia` will check the target
|
|
132
|
+
* property type and in the checking, non-undefined type checking would be
|
|
133
|
+
* done.
|
|
134
|
+
*
|
|
135
|
+
* In such process, you can transform the non-undefined type checking.
|
|
136
|
+
*
|
|
137
|
+
* @param exp
|
|
138
|
+
* @returns Transformed expression
|
|
139
|
+
* @deprecated
|
|
140
|
+
*/
|
|
141
|
+
required?(exp: ts.Expression): ts.Expression;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Conditon wrapper when unable to specify any object type.
|
|
145
|
+
*
|
|
146
|
+
* When failed to specify an object type through discrimination, full
|
|
147
|
+
* iteration type checking would be happend. In such circumstance, you
|
|
148
|
+
* can wrap the condition with additional function.
|
|
149
|
+
*
|
|
150
|
+
* @param condition Current condition
|
|
151
|
+
* @returns A function wrapped current condition
|
|
152
|
+
*/
|
|
47
153
|
full?: (
|
|
48
154
|
condition: ts.Expression,
|
|
49
155
|
) => (
|
|
@@ -53,10 +159,20 @@ export namespace FeatureProgrammer {
|
|
|
53
159
|
) => ts.Expression;
|
|
54
160
|
}
|
|
55
161
|
export interface IGenerator {
|
|
162
|
+
/**
|
|
163
|
+
*
|
|
164
|
+
* @param col
|
|
165
|
+
*/
|
|
56
166
|
functors(col: MetadataCollection): ts.VariableStatement[];
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
*
|
|
170
|
+
* @param col
|
|
171
|
+
*/
|
|
57
172
|
unioners(col: MetadataCollection): ts.VariableStatement[];
|
|
58
173
|
}
|
|
59
174
|
}
|
|
175
|
+
|
|
60
176
|
export interface IExplore {
|
|
61
177
|
tracable: boolean;
|
|
62
178
|
source: "top" | "object";
|
|
@@ -65,24 +181,30 @@ export namespace FeatureProgrammer {
|
|
|
65
181
|
start?: number;
|
|
66
182
|
}
|
|
67
183
|
|
|
68
|
-
export interface
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
184
|
+
export interface Decoder<
|
|
185
|
+
T,
|
|
186
|
+
Output extends ts.ConciseBody = ts.ConciseBody,
|
|
187
|
+
> {
|
|
72
188
|
(
|
|
73
189
|
input: ts.Expression,
|
|
74
190
|
target: T,
|
|
75
191
|
explore: IExplore,
|
|
76
192
|
tags: IMetadataTag[],
|
|
77
|
-
):
|
|
78
|
-
}
|
|
79
|
-
export interface ObjectJoiner {
|
|
80
|
-
(entries: IExpressionEntry[], parent: MetadataObject): ts.ConciseBody;
|
|
193
|
+
): Output;
|
|
81
194
|
}
|
|
82
195
|
|
|
83
196
|
/* -----------------------------------------------------------
|
|
84
197
|
GENERATORS
|
|
85
198
|
----------------------------------------------------------- */
|
|
199
|
+
/**
|
|
200
|
+
* Generates a decoder function for a specific type.
|
|
201
|
+
*
|
|
202
|
+
* @param project Project configuration
|
|
203
|
+
* @param config Detailed configuration for programming
|
|
204
|
+
* @param importer Function importer
|
|
205
|
+
* @param addition Generator of additinal statements in the top of function
|
|
206
|
+
* @returns Currying function generating type decoder function
|
|
207
|
+
*/
|
|
86
208
|
export const generate =
|
|
87
209
|
(
|
|
88
210
|
project: IProject,
|
|
@@ -96,7 +218,7 @@ export namespace FeatureProgrammer {
|
|
|
96
218
|
const [collection, meta] = config.initializer(project, type);
|
|
97
219
|
|
|
98
220
|
// ITERATE OVER ALL METADATA
|
|
99
|
-
const output: ts.
|
|
221
|
+
const output: ts.ConciseBody = config.decoder(
|
|
100
222
|
ValueFactory.INPUT(),
|
|
101
223
|
meta,
|
|
102
224
|
{
|
|
@@ -130,7 +252,9 @@ export namespace FeatureProgrammer {
|
|
|
130
252
|
...(added || []),
|
|
131
253
|
...functors,
|
|
132
254
|
...unioners,
|
|
133
|
-
ts.
|
|
255
|
+
...(ts.isBlock(output)
|
|
256
|
+
? output.statements
|
|
257
|
+
: [ts.factory.createReturnStatement(output)]),
|
|
134
258
|
],
|
|
135
259
|
true,
|
|
136
260
|
),
|
|
@@ -170,6 +294,7 @@ export namespace FeatureProgrammer {
|
|
|
170
294
|
undefined,
|
|
171
295
|
undefined,
|
|
172
296
|
config.objector.joiner(
|
|
297
|
+
ts.factory.createIdentifier("input"),
|
|
173
298
|
feature_object_entries(config)(obj)(
|
|
174
299
|
ts.factory.createIdentifier("input"),
|
|
175
300
|
),
|
|
@@ -16,61 +16,68 @@ import { check_object } from "./internal/check_object";
|
|
|
16
16
|
import { feature_object_entries } from "./internal/feature_object_entries";
|
|
17
17
|
|
|
18
18
|
export namespace IsProgrammer {
|
|
19
|
-
export const CONFIG =
|
|
20
|
-
options?: Partial<CONFIG.IOptions
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
19
|
+
export const CONFIG =
|
|
20
|
+
(options?: Partial<CONFIG.IOptions>) =>
|
|
21
|
+
(importer: FunctionImporter): CheckerProgrammer.IConfig => ({
|
|
22
|
+
functors: "$io",
|
|
23
|
+
unioners: "$iu",
|
|
24
|
+
trace: false,
|
|
25
|
+
path: false,
|
|
26
|
+
equals: !!options?.object,
|
|
27
|
+
numeric: OptionPredicator.numeric({
|
|
28
|
+
numeric: options?.numeric,
|
|
29
|
+
}),
|
|
30
|
+
combiner: () => (type: "and" | "or") => {
|
|
31
|
+
const initial: ts.TrueLiteral | ts.FalseLiteral =
|
|
32
|
+
type === "and"
|
|
33
|
+
? ts.factory.createTrue()
|
|
34
|
+
: ts.factory.createFalse();
|
|
35
|
+
const binder =
|
|
36
|
+
type === "and"
|
|
37
|
+
? ts.factory.createLogicalAnd
|
|
38
|
+
: ts.factory.createLogicalOr;
|
|
39
|
+
return (
|
|
40
|
+
_input: ts.Expression,
|
|
41
|
+
binaries: CheckerProgrammer.IBinary[],
|
|
42
|
+
) =>
|
|
43
|
+
binaries.length
|
|
44
|
+
? binaries
|
|
45
|
+
.map((binary) => binary.expression)
|
|
46
|
+
.reduce((x, y) => binder(x, y))
|
|
47
|
+
: initial;
|
|
48
|
+
},
|
|
49
|
+
joiner: {
|
|
50
|
+
object:
|
|
51
|
+
options?.object ||
|
|
52
|
+
check_object({
|
|
53
|
+
equals: !!options?.object,
|
|
54
|
+
undefined: OptionPredicator.undefined({
|
|
55
|
+
undefined: options?.undefined,
|
|
56
|
+
}),
|
|
57
|
+
assert: true,
|
|
58
|
+
reduce: ts.factory.createLogicalAnd,
|
|
59
|
+
positive: ts.factory.createTrue(),
|
|
60
|
+
superfluous: () => ts.factory.createFalse(),
|
|
61
|
+
})(importer),
|
|
62
|
+
array: (input, arrow) =>
|
|
63
|
+
ts.factory.createCallExpression(
|
|
64
|
+
IdentifierFactory.join(input, "every"),
|
|
65
|
+
undefined,
|
|
66
|
+
[arrow],
|
|
67
|
+
),
|
|
68
|
+
failure: () => ts.factory.createFalse(),
|
|
69
|
+
},
|
|
70
|
+
success: ts.factory.createTrue(),
|
|
71
|
+
});
|
|
69
72
|
|
|
70
73
|
export namespace CONFIG {
|
|
71
74
|
export interface IOptions {
|
|
72
75
|
numeric: boolean;
|
|
73
|
-
|
|
76
|
+
undefined: boolean;
|
|
77
|
+
object: (
|
|
78
|
+
input: ts.Expression,
|
|
79
|
+
entries: IExpressionEntry<ts.Expression>[],
|
|
80
|
+
) => ts.Expression;
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
|
|
@@ -88,45 +95,48 @@ export namespace IsProgrammer {
|
|
|
88
95
|
const config = CONFIG({
|
|
89
96
|
object: check_object({
|
|
90
97
|
equals,
|
|
98
|
+
undefined: OptionPredicator.undefined(project.options),
|
|
91
99
|
assert: true,
|
|
92
100
|
reduce: ts.factory.createLogicalAnd,
|
|
93
101
|
positive: ts.factory.createTrue(),
|
|
94
102
|
superfluous: () => ts.factory.createFalse(),
|
|
95
|
-
}),
|
|
103
|
+
})(importer),
|
|
96
104
|
numeric: OptionPredicator.numeric(project.options),
|
|
97
|
-
});
|
|
105
|
+
})(importer);
|
|
98
106
|
config.trace = equals;
|
|
99
107
|
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
config.decoder = (input, target, explore, tags) => {
|
|
109
|
+
if (
|
|
110
|
+
target.size() === 1 &&
|
|
111
|
+
target.objects.length === 1 &&
|
|
112
|
+
target.required === true &&
|
|
113
|
+
target.nullable === false
|
|
114
|
+
) {
|
|
115
|
+
// ONLY WHEN OBJECT WITH SOME ATOMIC PROPERTIES
|
|
116
|
+
const obj: MetadataObject = target.objects[0]!;
|
|
102
117
|
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
target,
|
|
126
|
-
explore,
|
|
127
|
-
tags,
|
|
128
|
-
);
|
|
129
|
-
};
|
|
118
|
+
obj._Is_simple() &&
|
|
119
|
+
(equals === false ||
|
|
120
|
+
OptionPredicator.undefined(project.options) === false)
|
|
121
|
+
)
|
|
122
|
+
return ts.factory.createLogicalAnd(
|
|
123
|
+
ExpressionFactory.isObject(input, {
|
|
124
|
+
checkNull: true,
|
|
125
|
+
checkArray: false,
|
|
126
|
+
}),
|
|
127
|
+
config.joiner.object(
|
|
128
|
+
input,
|
|
129
|
+
feature_object_entries(config as any)(obj)(input),
|
|
130
|
+
),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
return CheckerProgrammer.decode(project, config, importer)(
|
|
134
|
+
input,
|
|
135
|
+
target,
|
|
136
|
+
explore,
|
|
137
|
+
tags,
|
|
138
|
+
);
|
|
139
|
+
};
|
|
130
140
|
|
|
131
141
|
// GENERATE CHECKER
|
|
132
142
|
return CheckerProgrammer.generate(project, config, importer, () =>
|
|
@@ -137,21 +147,31 @@ export namespace IsProgrammer {
|
|
|
137
147
|
export const generate_functors = (
|
|
138
148
|
project: IProject,
|
|
139
149
|
importer: FunctionImporter,
|
|
140
|
-
) =>
|
|
150
|
+
) =>
|
|
151
|
+
CheckerProgrammer.generate_functors(
|
|
152
|
+
project,
|
|
153
|
+
CONFIG()(importer),
|
|
154
|
+
importer,
|
|
155
|
+
);
|
|
141
156
|
|
|
142
157
|
export const generate_unioners = (
|
|
143
158
|
project: IProject,
|
|
144
159
|
importer: FunctionImporter,
|
|
145
|
-
) =>
|
|
160
|
+
) =>
|
|
161
|
+
CheckerProgrammer.generate_unioners(
|
|
162
|
+
project,
|
|
163
|
+
CONFIG()(importer),
|
|
164
|
+
importer,
|
|
165
|
+
);
|
|
146
166
|
|
|
147
167
|
/* -----------------------------------------------------------
|
|
148
168
|
DECODERS
|
|
149
169
|
----------------------------------------------------------- */
|
|
150
170
|
export const decode = (project: IProject, importer: FunctionImporter) =>
|
|
151
|
-
CheckerProgrammer.decode(project, CONFIG(), importer);
|
|
171
|
+
CheckerProgrammer.decode(project, CONFIG()(importer), importer);
|
|
152
172
|
|
|
153
|
-
export const decode_object = () =>
|
|
154
|
-
CheckerProgrammer.decode_object(CONFIG());
|
|
173
|
+
export const decode_object = (importer: FunctionImporter) =>
|
|
174
|
+
CheckerProgrammer.decode_object(CONFIG()(importer));
|
|
155
175
|
|
|
156
176
|
export function decode_to_json(input: ts.Expression): ts.Expression {
|
|
157
177
|
return ts.factory.createLogicalAnd(
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
import { IdentifierFactory } from "../factories/IdentifierFactory";
|
|
4
|
+
import { StatementFactory } from "../factories/StatementFactory";
|
|
5
|
+
|
|
6
|
+
import { IProject } from "../transformers/IProject";
|
|
7
|
+
|
|
8
|
+
import { IsProgrammer } from "./IsProgrammer";
|
|
9
|
+
import { PruneProgrammer } from "./PruneProgrammer";
|
|
10
|
+
|
|
11
|
+
export namespace IsPruneProgrammer {
|
|
12
|
+
export const generate =
|
|
13
|
+
(project: IProject, modulo: ts.LeftHandSideExpression) =>
|
|
14
|
+
(type: ts.Type) =>
|
|
15
|
+
ts.factory.createArrowFunction(
|
|
16
|
+
undefined,
|
|
17
|
+
undefined,
|
|
18
|
+
[IdentifierFactory.parameter("input")],
|
|
19
|
+
undefined,
|
|
20
|
+
undefined,
|
|
21
|
+
ts.factory.createBlock([
|
|
22
|
+
StatementFactory.constant(
|
|
23
|
+
"is",
|
|
24
|
+
IsProgrammer.generate(project, modulo)(type),
|
|
25
|
+
),
|
|
26
|
+
StatementFactory.constant(
|
|
27
|
+
"prune",
|
|
28
|
+
PruneProgrammer.generate(
|
|
29
|
+
{
|
|
30
|
+
...project,
|
|
31
|
+
options: {
|
|
32
|
+
...project.options,
|
|
33
|
+
functional: false,
|
|
34
|
+
numeric: false,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
modulo,
|
|
38
|
+
)(type),
|
|
39
|
+
),
|
|
40
|
+
ts.factory.createIfStatement(
|
|
41
|
+
ts.factory.createPrefixUnaryExpression(
|
|
42
|
+
ts.SyntaxKind.ExclamationToken,
|
|
43
|
+
ts.factory.createCallExpression(
|
|
44
|
+
ts.factory.createIdentifier("is"),
|
|
45
|
+
undefined,
|
|
46
|
+
[ts.factory.createIdentifier("input")],
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
ts.factory.createReturnStatement(
|
|
50
|
+
ts.factory.createFalse(),
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
ts.factory.createExpressionStatement(
|
|
54
|
+
ts.factory.createCallExpression(
|
|
55
|
+
ts.factory.createIdentifier("prune"),
|
|
56
|
+
undefined,
|
|
57
|
+
[ts.factory.createIdentifier("input")],
|
|
58
|
+
),
|
|
59
|
+
),
|
|
60
|
+
ts.factory.createReturnStatement(ts.factory.createTrue()),
|
|
61
|
+
]),
|
|
62
|
+
);
|
|
63
|
+
}
|