@modern-js/babel-compiler 2.0.0-beta.3 → 2.0.0-beta.6
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/CHANGELOG.md +61 -0
- package/dist/js/modern/build.js +35 -9
- package/dist/js/modern/buildWatch.js +107 -68
- package/dist/js/modern/compiler.js +48 -26
- package/dist/js/modern/compilerErrorResult.js +12 -11
- package/dist/js/modern/constants.js +9 -6
- package/dist/js/modern/defaults.js +20 -4
- package/dist/js/modern/getFinalOption.js +40 -21
- package/dist/js/modern/index.js +37 -12
- package/dist/js/modern/utils.js +8 -4
- package/dist/js/modern/validate.js +17 -22
- package/dist/js/node/build.js +62 -20
- package/dist/js/node/buildWatch.js +136 -79
- package/dist/js/node/compiler.js +84 -44
- package/dist/js/node/compilerErrorResult.js +32 -15
- package/dist/js/node/constants.js +29 -10
- package/dist/js/node/defaults.js +42 -12
- package/dist/js/node/getFinalOption.js +66 -33
- package/dist/js/node/index.js +61 -42
- package/dist/js/node/type.js +15 -0
- package/dist/js/node/utils.js +35 -10
- package/dist/js/node/validate.js +44 -33
- package/dist/js/treeshaking/build.js +224 -0
- package/dist/js/treeshaking/buildWatch.js +417 -0
- package/dist/js/treeshaking/compiler.js +140 -0
- package/dist/js/treeshaking/compilerErrorResult.js +110 -0
- package/dist/js/treeshaking/constants.js +7 -0
- package/dist/js/treeshaking/defaults.js +44 -0
- package/dist/js/treeshaking/getFinalOption.js +137 -0
- package/dist/js/treeshaking/index.js +166 -0
- package/dist/js/treeshaking/type.js +1 -0
- package/dist/js/treeshaking/utils.js +5 -0
- package/dist/js/treeshaking/validate.js +38 -0
- package/package.json +4 -4
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function _defineProperty(obj, key, value) {
|
|
2
|
+
if (key in obj) {
|
|
3
|
+
Object.defineProperty(obj, key, {
|
|
4
|
+
value: value,
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true
|
|
8
|
+
});
|
|
9
|
+
} else {
|
|
10
|
+
obj[key] = value;
|
|
11
|
+
}
|
|
12
|
+
return obj;
|
|
13
|
+
}
|
|
14
|
+
function _objectSpread(target) {
|
|
15
|
+
for(var i = 1; i < arguments.length; i++){
|
|
16
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
17
|
+
var ownKeys = Object.keys(source);
|
|
18
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
19
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
20
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
ownKeys.forEach(function(key) {
|
|
24
|
+
_defineProperty(target, key, source[key]);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return target;
|
|
28
|
+
}
|
|
29
|
+
import { defaultDistFileExtMap } from "./constants";
|
|
30
|
+
var defaultOptions = {
|
|
31
|
+
enableWatch: false,
|
|
32
|
+
enableVirtualDist: false,
|
|
33
|
+
extensions: [],
|
|
34
|
+
filenames: [],
|
|
35
|
+
distFileExtMap: defaultDistFileExtMap,
|
|
36
|
+
ignore: [],
|
|
37
|
+
quiet: false,
|
|
38
|
+
verbose: false,
|
|
39
|
+
clean: false
|
|
40
|
+
};
|
|
41
|
+
var mergeDefaultOption = function(compilerOptions) {
|
|
42
|
+
return _objectSpread({}, defaultOptions, compilerOptions);
|
|
43
|
+
};
|
|
44
|
+
export { mergeDefaultOption };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
function _arrayLikeToArray(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _arrayWithoutHoles(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
8
|
+
}
|
|
9
|
+
function _defineProperty(obj, key, value) {
|
|
10
|
+
if (key in obj) {
|
|
11
|
+
Object.defineProperty(obj, key, {
|
|
12
|
+
value: value,
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
obj[key] = value;
|
|
19
|
+
}
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
22
|
+
function _iterableToArray(iter) {
|
|
23
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
24
|
+
}
|
|
25
|
+
function _nonIterableSpread() {
|
|
26
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
27
|
+
}
|
|
28
|
+
function _objectSpread(target) {
|
|
29
|
+
for(var i = 1; i < arguments.length; i++){
|
|
30
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
31
|
+
var ownKeys = Object.keys(source);
|
|
32
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
33
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
34
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
ownKeys.forEach(function(key) {
|
|
38
|
+
_defineProperty(target, key, source[key]);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return target;
|
|
42
|
+
}
|
|
43
|
+
function ownKeys(object, enumerableOnly) {
|
|
44
|
+
var keys = Object.keys(object);
|
|
45
|
+
if (Object.getOwnPropertySymbols) {
|
|
46
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
47
|
+
if (enumerableOnly) {
|
|
48
|
+
symbols = symbols.filter(function(sym) {
|
|
49
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
keys.push.apply(keys, symbols);
|
|
53
|
+
}
|
|
54
|
+
return keys;
|
|
55
|
+
}
|
|
56
|
+
function _objectSpreadProps(target, source) {
|
|
57
|
+
source = source != null ? source : {};
|
|
58
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
59
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
60
|
+
} else {
|
|
61
|
+
ownKeys(Object(source)).forEach(function(key) {
|
|
62
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return target;
|
|
66
|
+
}
|
|
67
|
+
function _toConsumableArray(arr) {
|
|
68
|
+
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
69
|
+
}
|
|
70
|
+
function _unsupportedIterableToArray(o, minLen) {
|
|
71
|
+
if (!o) return;
|
|
72
|
+
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
73
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
74
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
75
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
76
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
77
|
+
}
|
|
78
|
+
import { glob } from "@modern-js/utils";
|
|
79
|
+
import { DEFAULT_EXTENSIONS } from "@babel/core";
|
|
80
|
+
import { mergeDefaultOption } from "./defaults";
|
|
81
|
+
var getGlobPattern = function(dir, extensions) {
|
|
82
|
+
if (extensions.length > 1) {
|
|
83
|
+
return "".concat(dir, "/**/*{").concat(extensions.join(","), "}");
|
|
84
|
+
} else if (extensions.length === 1) {
|
|
85
|
+
return "".concat(dir, "/**/*").concat(extensions[0]);
|
|
86
|
+
} else {
|
|
87
|
+
return "".concat(dir, "/**/*");
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var getFinalExtensions = function(extensions) {
|
|
91
|
+
var isExtensions = function(ext) {
|
|
92
|
+
return Array.isArray(ext);
|
|
93
|
+
};
|
|
94
|
+
var isExtensionsFunc = function(ext) {
|
|
95
|
+
return typeof ext === "function";
|
|
96
|
+
};
|
|
97
|
+
if (isExtensions(extensions)) {
|
|
98
|
+
return _toConsumableArray(extensions).concat(_toConsumableArray(DEFAULT_EXTENSIONS));
|
|
99
|
+
} else if (isExtensionsFunc(extensions)) {
|
|
100
|
+
return extensions(DEFAULT_EXTENSIONS);
|
|
101
|
+
} else {
|
|
102
|
+
return DEFAULT_EXTENSIONS;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var getFilesFromDir = function(param) {
|
|
106
|
+
var dir = param.dir, _finalExt = param.finalExt, finalExt = _finalExt === void 0 ? [] : _finalExt, _ignore = param.ignore, ignore = _ignore === void 0 ? [] : _ignore;
|
|
107
|
+
var globFindFilenames = [];
|
|
108
|
+
var globPattern = getGlobPattern(dir, finalExt);
|
|
109
|
+
globFindFilenames = glob.sync(globPattern, {
|
|
110
|
+
ignore: ignore
|
|
111
|
+
});
|
|
112
|
+
return globFindFilenames;
|
|
113
|
+
};
|
|
114
|
+
var getFinalCompilerOption = function(option) {
|
|
115
|
+
var optionWithDefault = mergeDefaultOption(option);
|
|
116
|
+
var sourceDir = option.sourceDir, ignore = option.ignore, _enableWatch = option.enableWatch, enableWatch = _enableWatch === void 0 ? false : _enableWatch, watchDir = option.watchDir, _extensions = option.extensions, extensions = _extensions === void 0 ? DEFAULT_EXTENSIONS : _extensions;
|
|
117
|
+
var globFindFilenames = [];
|
|
118
|
+
var finalExt = getFinalExtensions(extensions);
|
|
119
|
+
if (sourceDir) {
|
|
120
|
+
globFindFilenames = getFilesFromDir({
|
|
121
|
+
dir: sourceDir,
|
|
122
|
+
ignore: ignore,
|
|
123
|
+
finalExt: finalExt
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (enableWatch) {
|
|
127
|
+
globFindFilenames = getFilesFromDir({
|
|
128
|
+
dir: watchDir,
|
|
129
|
+
ignore: ignore,
|
|
130
|
+
finalExt: finalExt
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return _objectSpreadProps(_objectSpread({}, optionWithDefault), {
|
|
134
|
+
filenames: _toConsumableArray(optionWithDefault.filenames).concat(_toConsumableArray(globFindFilenames))
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
export { getFilesFromDir, getFinalCompilerOption, getFinalExtensions, getGlobPattern };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
+
try {
|
|
3
|
+
var info = gen[key](arg);
|
|
4
|
+
var value = info.value;
|
|
5
|
+
} catch (error) {
|
|
6
|
+
reject(error);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (info.done) {
|
|
10
|
+
resolve(value);
|
|
11
|
+
} else {
|
|
12
|
+
Promise.resolve(value).then(_next, _throw);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _asyncToGenerator(fn) {
|
|
16
|
+
return function() {
|
|
17
|
+
var self = this, args = arguments;
|
|
18
|
+
return new Promise(function(resolve, reject) {
|
|
19
|
+
var gen = fn.apply(self, args);
|
|
20
|
+
function _next(value) {
|
|
21
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
+
}
|
|
23
|
+
function _throw(err) {
|
|
24
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
+
}
|
|
26
|
+
_next(undefined);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
var __generator = this && this.__generator || function(thisArg, body) {
|
|
31
|
+
var f, y, t, g, _ = {
|
|
32
|
+
label: 0,
|
|
33
|
+
sent: function() {
|
|
34
|
+
if (t[0] & 1) throw t[1];
|
|
35
|
+
return t[1];
|
|
36
|
+
},
|
|
37
|
+
trys: [],
|
|
38
|
+
ops: []
|
|
39
|
+
};
|
|
40
|
+
return g = {
|
|
41
|
+
next: verb(0),
|
|
42
|
+
"throw": verb(1),
|
|
43
|
+
"return": verb(2)
|
|
44
|
+
}, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
45
|
+
return this;
|
|
46
|
+
}), g;
|
|
47
|
+
function verb(n) {
|
|
48
|
+
return function(v) {
|
|
49
|
+
return step([
|
|
50
|
+
n,
|
|
51
|
+
v
|
|
52
|
+
]);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function step(op) {
|
|
56
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
57
|
+
while(_)try {
|
|
58
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
59
|
+
if (y = 0, t) op = [
|
|
60
|
+
op[0] & 2,
|
|
61
|
+
t.value
|
|
62
|
+
];
|
|
63
|
+
switch(op[0]){
|
|
64
|
+
case 0:
|
|
65
|
+
case 1:
|
|
66
|
+
t = op;
|
|
67
|
+
break;
|
|
68
|
+
case 4:
|
|
69
|
+
_.label++;
|
|
70
|
+
return {
|
|
71
|
+
value: op[1],
|
|
72
|
+
done: false
|
|
73
|
+
};
|
|
74
|
+
case 5:
|
|
75
|
+
_.label++;
|
|
76
|
+
y = op[1];
|
|
77
|
+
op = [
|
|
78
|
+
0
|
|
79
|
+
];
|
|
80
|
+
continue;
|
|
81
|
+
case 7:
|
|
82
|
+
op = _.ops.pop();
|
|
83
|
+
_.trys.pop();
|
|
84
|
+
continue;
|
|
85
|
+
default:
|
|
86
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
87
|
+
_ = 0;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
91
|
+
_.label = op[1];
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
95
|
+
_.label = t[1];
|
|
96
|
+
t = op;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
if (t && _.label < t[2]) {
|
|
100
|
+
_.label = t[2];
|
|
101
|
+
_.ops.push(op);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
if (t[2]) _.ops.pop();
|
|
105
|
+
_.trys.pop();
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
op = body.call(thisArg, _);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
op = [
|
|
111
|
+
6,
|
|
112
|
+
e
|
|
113
|
+
];
|
|
114
|
+
y = 0;
|
|
115
|
+
} finally{
|
|
116
|
+
f = t = 0;
|
|
117
|
+
}
|
|
118
|
+
if (op[0] & 5) throw op[1];
|
|
119
|
+
return {
|
|
120
|
+
value: op[0] ? op[1] : void 0,
|
|
121
|
+
done: true
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
import { getFinalCompilerOption } from "./getFinalOption";
|
|
126
|
+
import { build } from "./build";
|
|
127
|
+
import { buildWatch } from "./buildWatch";
|
|
128
|
+
import { validate } from "./validate";
|
|
129
|
+
function compiler(compilerOptions) {
|
|
130
|
+
return _compiler.apply(this, arguments);
|
|
131
|
+
}
|
|
132
|
+
function _compiler() {
|
|
133
|
+
_compiler = _asyncToGenerator(function(compilerOptions) {
|
|
134
|
+
var babelOptions, validRet, finalCompilerOption;
|
|
135
|
+
var _arguments = arguments;
|
|
136
|
+
return __generator(this, function(_state) {
|
|
137
|
+
babelOptions = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
|
|
138
|
+
validRet = validate(compilerOptions);
|
|
139
|
+
if (validRet) {
|
|
140
|
+
return [
|
|
141
|
+
2,
|
|
142
|
+
validRet
|
|
143
|
+
];
|
|
144
|
+
}
|
|
145
|
+
finalCompilerOption = getFinalCompilerOption(compilerOptions);
|
|
146
|
+
if (compilerOptions.enableWatch) {
|
|
147
|
+
return [
|
|
148
|
+
2,
|
|
149
|
+
buildWatch(finalCompilerOption, babelOptions)
|
|
150
|
+
];
|
|
151
|
+
} else {
|
|
152
|
+
return [
|
|
153
|
+
2,
|
|
154
|
+
build(finalCompilerOption, babelOptions)
|
|
155
|
+
];
|
|
156
|
+
}
|
|
157
|
+
return [
|
|
158
|
+
2
|
|
159
|
+
];
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
return _compiler.apply(this, arguments);
|
|
163
|
+
}
|
|
164
|
+
export * from "./buildWatch";
|
|
165
|
+
export * from "./type";
|
|
166
|
+
export { compiler };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { logger } from "@modern-js/utils";
|
|
2
|
+
var sourceDirAndFileNamesValidMessage = "At least one of the sourceDir and filenames configurations must be configured";
|
|
3
|
+
var watchDirValidMessage = "should set watchDir when enableWatch is true";
|
|
4
|
+
var validateSourceDirAndFileNames = function(compilerOptions) {
|
|
5
|
+
var sourceDir = compilerOptions.sourceDir, filenames = compilerOptions.filenames, quiet = compilerOptions.quiet;
|
|
6
|
+
if (!sourceDir && !filenames) {
|
|
7
|
+
if (!quiet) {
|
|
8
|
+
logger.error(sourceDirAndFileNamesValidMessage);
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
code: 1,
|
|
12
|
+
message: sourceDirAndFileNamesValidMessage,
|
|
13
|
+
virtualDists: []
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
};
|
|
18
|
+
var validateWatchDir = function(compilerOptions) {
|
|
19
|
+
var watchDir = compilerOptions.watchDir, enableWatch = compilerOptions.enableWatch, quiet = compilerOptions.quiet;
|
|
20
|
+
if (enableWatch && !watchDir) {
|
|
21
|
+
if (!quiet) {
|
|
22
|
+
logger.error(watchDirValidMessage);
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
code: 1,
|
|
26
|
+
message: watchDirValidMessage,
|
|
27
|
+
virtualDists: []
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
var validate = function(compilerOptions) {
|
|
33
|
+
if (compilerOptions.enableWatch) {
|
|
34
|
+
return validateWatchDir(compilerOptions);
|
|
35
|
+
}
|
|
36
|
+
return validateSourceDirAndFileNames(compilerOptions);
|
|
37
|
+
};
|
|
38
|
+
export { sourceDirAndFileNamesValidMessage, validate, validateSourceDirAndFileNames, validateWatchDir, watchDirValidMessage };
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "2.0.0-beta.
|
|
14
|
+
"version": "2.0.0-beta.6",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"main": "./dist/js/node/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@babel/core": "^7.18.0",
|
|
32
32
|
"@babel/runtime": "^7.18.0",
|
|
33
|
-
"@modern-js/utils": "2.0.0-beta.
|
|
33
|
+
"@modern-js/utils": "2.0.0-beta.6"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@babel/plugin-transform-classes": "^7.18.0",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"@types/node": "^14",
|
|
42
42
|
"typescript": "^4",
|
|
43
43
|
"jest": "^27",
|
|
44
|
-
"@scripts/build": "2.0.0-beta.
|
|
45
|
-
"@scripts/jest-config": "2.0.0-beta.
|
|
44
|
+
"@scripts/build": "2.0.0-beta.6",
|
|
45
|
+
"@scripts/jest-config": "2.0.0-beta.6"
|
|
46
46
|
},
|
|
47
47
|
"sideEffects": false,
|
|
48
48
|
"modernConfig": {
|