webpack 5.76.3 → 5.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (68) hide show
  1. package/bin/webpack.js +0 -0
  2. package/lib/APIPlugin.js +25 -18
  3. package/lib/CompatibilityPlugin.js +53 -52
  4. package/lib/ConstPlugin.js +22 -15
  5. package/lib/ContextModule.js +3 -2
  6. package/lib/DefinePlugin.js +44 -36
  7. package/lib/DelegatedModule.js +2 -1
  8. package/lib/DllModule.js +2 -1
  9. package/lib/ErrorHelpers.js +61 -22
  10. package/lib/ExportsInfoApiPlugin.js +16 -9
  11. package/lib/ExternalModule.js +2 -1
  12. package/lib/FlagAllModulesAsUsedPlugin.js +22 -27
  13. package/lib/FlagDependencyExportsPlugin.js +336 -348
  14. package/lib/FlagDependencyUsagePlugin.js +6 -8
  15. package/lib/FlagEntryExportAsUsedPlugin.js +22 -23
  16. package/lib/HotModuleReplacementPlugin.js +50 -45
  17. package/lib/JavascriptMetaInfoPlugin.js +16 -9
  18. package/lib/ModuleTypeConstants.js +50 -0
  19. package/lib/NodeStuffPlugin.js +35 -31
  20. package/lib/NormalModule.js +2 -1
  21. package/lib/NormalModuleFactory.js +27 -1
  22. package/lib/ProvidePlugin.js +17 -10
  23. package/lib/RawModule.js +2 -1
  24. package/lib/RequireJsStuffPlugin.js +15 -15
  25. package/lib/UseStrictPlugin.js +15 -8
  26. package/lib/WebpackIsIncludedPlugin.js +16 -9
  27. package/lib/WebpackOptionsApply.js +2 -1
  28. package/lib/config/defaults.js +17 -8
  29. package/lib/config/normalization.js +5 -0
  30. package/lib/container/ContainerEntryModule.js +2 -1
  31. package/lib/css/CssParser.js +22 -2
  32. package/lib/debug/ProfilingPlugin.js +20 -12
  33. package/lib/dependencies/AMDPlugin.js +26 -20
  34. package/lib/dependencies/CommonJsImportsParserPlugin.js +5 -4
  35. package/lib/dependencies/CommonJsPlugin.js +29 -25
  36. package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -1
  37. package/lib/dependencies/HarmonyModulesPlugin.js +11 -5
  38. package/lib/dependencies/ImportMetaContextPlugin.js +11 -5
  39. package/lib/dependencies/ImportMetaPlugin.js +26 -20
  40. package/lib/dependencies/ImportPlugin.js +14 -7
  41. package/lib/dependencies/RequireContextPlugin.js +12 -6
  42. package/lib/dependencies/RequireEnsurePlugin.js +13 -7
  43. package/lib/dependencies/RequireIncludePlugin.js +11 -5
  44. package/lib/dependencies/SystemPlugin.js +21 -15
  45. package/lib/dependencies/URLPlugin.js +15 -9
  46. package/lib/dependencies/WorkerDependency.js +37 -2
  47. package/lib/dependencies/WorkerPlugin.js +19 -10
  48. package/lib/javascript/JavascriptModulesPlugin.js +157 -164
  49. package/lib/json/JsonModulesPlugin.js +13 -5
  50. package/lib/library/AmdLibraryPlugin.js +22 -6
  51. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +2 -1
  52. package/lib/node/ReadFileCompileWasmPlugin.js +2 -1
  53. package/lib/optimize/ConcatenatedModule.js +2 -1
  54. package/lib/optimize/InnerGraphPlugin.js +47 -46
  55. package/lib/optimize/SideEffectsFlagPlugin.js +43 -43
  56. package/lib/sharing/ConsumeSharedPlugin.js +4 -0
  57. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +9 -6
  58. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +42 -43
  59. package/lib/web/FetchCompileAsyncWasmPlugin.js +2 -1
  60. package/lib/web/FetchCompileWasmPlugin.js +40 -40
  61. package/package.json +1 -1
  62. package/schemas/WebpackOptions.check.js +1 -1
  63. package/schemas/WebpackOptions.json +28 -0
  64. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  65. package/schemas/plugins/container/ContainerPlugin.json +8 -0
  66. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  67. package/schemas/plugins/container/ModuleFederationPlugin.json +8 -0
  68. package/types.d.ts +20 -0
@@ -10,15 +10,21 @@ const RequireEnsureItemDependency = require("./RequireEnsureItemDependency");
10
10
 
11
11
  const RequireEnsureDependenciesBlockParserPlugin = require("./RequireEnsureDependenciesBlockParserPlugin");
12
12
 
13
+ const {
14
+ JAVASCRIPT_MODULE_TYPE_AUTO,
15
+ JAVASCRIPT_MODULE_TYPE_DYNAMIC
16
+ } = require("../ModuleTypeConstants");
13
17
  const {
14
18
  evaluateToString,
15
19
  toConstantDependency
16
20
  } = require("../javascript/JavascriptParserHelpers");
17
21
 
22
+ const PLUGIN_NAME = "RequireEnsurePlugin";
23
+
18
24
  class RequireEnsurePlugin {
19
25
  apply(compiler) {
20
26
  compiler.hooks.compilation.tap(
21
- "RequireEnsurePlugin",
27
+ PLUGIN_NAME,
22
28
  (compilation, { normalModuleFactory }) => {
23
29
  compilation.dependencyFactories.set(
24
30
  RequireEnsureItemDependency,
@@ -44,21 +50,21 @@ class RequireEnsurePlugin {
44
50
  new RequireEnsureDependenciesBlockParserPlugin().apply(parser);
45
51
  parser.hooks.evaluateTypeof
46
52
  .for("require.ensure")
47
- .tap("RequireEnsurePlugin", evaluateToString("function"));
53
+ .tap(PLUGIN_NAME, evaluateToString("function"));
48
54
  parser.hooks.typeof
49
55
  .for("require.ensure")
50
56
  .tap(
51
- "RequireEnsurePlugin",
57
+ PLUGIN_NAME,
52
58
  toConstantDependency(parser, JSON.stringify("function"))
53
59
  );
54
60
  };
55
61
 
56
62
  normalModuleFactory.hooks.parser
57
- .for("javascript/auto")
58
- .tap("RequireEnsurePlugin", handler);
63
+ .for(JAVASCRIPT_MODULE_TYPE_AUTO)
64
+ .tap(PLUGIN_NAME, handler);
59
65
  normalModuleFactory.hooks.parser
60
- .for("javascript/dynamic")
61
- .tap("RequireEnsurePlugin", handler);
66
+ .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
67
+ .tap(PLUGIN_NAME, handler);
62
68
  }
63
69
  );
64
70
  }
@@ -5,13 +5,19 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const {
9
+ JAVASCRIPT_MODULE_TYPE_AUTO,
10
+ JAVASCRIPT_MODULE_TYPE_DYNAMIC
11
+ } = require("../ModuleTypeConstants");
8
12
  const RequireIncludeDependency = require("./RequireIncludeDependency");
9
13
  const RequireIncludeDependencyParserPlugin = require("./RequireIncludeDependencyParserPlugin");
10
14
 
15
+ const PLUGIN_NAME = "RequireIncludePlugin";
16
+
11
17
  class RequireIncludePlugin {
12
18
  apply(compiler) {
13
19
  compiler.hooks.compilation.tap(
14
- "RequireIncludePlugin",
20
+ PLUGIN_NAME,
15
21
  (compilation, { normalModuleFactory }) => {
16
22
  compilation.dependencyFactories.set(
17
23
  RequireIncludeDependency,
@@ -30,11 +36,11 @@ class RequireIncludePlugin {
30
36
  };
31
37
 
32
38
  normalModuleFactory.hooks.parser
33
- .for("javascript/auto")
34
- .tap("RequireIncludePlugin", handler);
39
+ .for(JAVASCRIPT_MODULE_TYPE_AUTO)
40
+ .tap(PLUGIN_NAME, handler);
35
41
  normalModuleFactory.hooks.parser
36
- .for("javascript/dynamic")
37
- .tap("RequireIncludePlugin", handler);
42
+ .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
43
+ .tap(PLUGIN_NAME, handler);
38
44
  }
39
45
  );
40
46
  }
@@ -5,6 +5,10 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const {
9
+ JAVASCRIPT_MODULE_TYPE_AUTO,
10
+ JAVASCRIPT_MODULE_TYPE_DYNAMIC
11
+ } = require("../ModuleTypeConstants");
8
12
  const RuntimeGlobals = require("../RuntimeGlobals");
9
13
  const WebpackError = require("../WebpackError");
10
14
  const {
@@ -18,6 +22,8 @@ const SystemRuntimeModule = require("./SystemRuntimeModule");
18
22
 
19
23
  /** @typedef {import("../Compiler")} Compiler */
20
24
 
25
+ const PLUGIN_NAME = "SystemPlugin";
26
+
21
27
  class SystemPlugin {
22
28
  /**
23
29
  * Apply the plugin
@@ -26,17 +32,17 @@ class SystemPlugin {
26
32
  */
27
33
  apply(compiler) {
28
34
  compiler.hooks.compilation.tap(
29
- "SystemPlugin",
35
+ PLUGIN_NAME,
30
36
  (compilation, { normalModuleFactory }) => {
31
37
  compilation.hooks.runtimeRequirementInModule
32
38
  .for(RuntimeGlobals.system)
33
- .tap("SystemPlugin", (module, set) => {
39
+ .tap(PLUGIN_NAME, (module, set) => {
34
40
  set.add(RuntimeGlobals.requireScope);
35
41
  });
36
42
 
37
43
  compilation.hooks.runtimeRequirementInTree
38
44
  .for(RuntimeGlobals.system)
39
- .tap("SystemPlugin", (chunk, set) => {
45
+ .tap(PLUGIN_NAME, (chunk, set) => {
40
46
  compilation.addRuntimeModule(chunk, new SystemRuntimeModule());
41
47
  });
42
48
 
@@ -48,11 +54,11 @@ class SystemPlugin {
48
54
  const setNotSupported = name => {
49
55
  parser.hooks.evaluateTypeof
50
56
  .for(name)
51
- .tap("SystemPlugin", evaluateToString("undefined"));
57
+ .tap(PLUGIN_NAME, evaluateToString("undefined"));
52
58
  parser.hooks.expression
53
59
  .for(name)
54
60
  .tap(
55
- "SystemPlugin",
61
+ PLUGIN_NAME,
56
62
  expressionIsUnsupported(
57
63
  parser,
58
64
  name + " is not supported by webpack."
@@ -63,27 +69,27 @@ class SystemPlugin {
63
69
  parser.hooks.typeof
64
70
  .for("System.import")
65
71
  .tap(
66
- "SystemPlugin",
72
+ PLUGIN_NAME,
67
73
  toConstantDependency(parser, JSON.stringify("function"))
68
74
  );
69
75
  parser.hooks.evaluateTypeof
70
76
  .for("System.import")
71
- .tap("SystemPlugin", evaluateToString("function"));
77
+ .tap(PLUGIN_NAME, evaluateToString("function"));
72
78
  parser.hooks.typeof
73
79
  .for("System")
74
80
  .tap(
75
- "SystemPlugin",
81
+ PLUGIN_NAME,
76
82
  toConstantDependency(parser, JSON.stringify("object"))
77
83
  );
78
84
  parser.hooks.evaluateTypeof
79
85
  .for("System")
80
- .tap("SystemPlugin", evaluateToString("object"));
86
+ .tap(PLUGIN_NAME, evaluateToString("object"));
81
87
 
82
88
  setNotSupported("System.set");
83
89
  setNotSupported("System.get");
84
90
  setNotSupported("System.register");
85
91
 
86
- parser.hooks.expression.for("System").tap("SystemPlugin", expr => {
92
+ parser.hooks.expression.for("System").tap(PLUGIN_NAME, expr => {
87
93
  const dep = new ConstDependency(RuntimeGlobals.system, expr.range, [
88
94
  RuntimeGlobals.system
89
95
  ]);
@@ -92,7 +98,7 @@ class SystemPlugin {
92
98
  return true;
93
99
  });
94
100
 
95
- parser.hooks.call.for("System.import").tap("SystemPlugin", expr => {
101
+ parser.hooks.call.for("System.import").tap(PLUGIN_NAME, expr => {
96
102
  parser.state.module.addWarning(
97
103
  new SystemImportDeprecationWarning(expr.loc)
98
104
  );
@@ -107,11 +113,11 @@ class SystemPlugin {
107
113
  };
108
114
 
109
115
  normalModuleFactory.hooks.parser
110
- .for("javascript/auto")
111
- .tap("SystemPlugin", handler);
116
+ .for(JAVASCRIPT_MODULE_TYPE_AUTO)
117
+ .tap(PLUGIN_NAME, handler);
112
118
  normalModuleFactory.hooks.parser
113
- .for("javascript/dynamic")
114
- .tap("SystemPlugin", handler);
119
+ .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
120
+ .tap(PLUGIN_NAME, handler);
115
121
  }
116
122
  );
117
123
  }
@@ -6,6 +6,10 @@
6
6
  "use strict";
7
7
 
8
8
  const { pathToFileURL } = require("url");
9
+ const {
10
+ JAVASCRIPT_MODULE_TYPE_AUTO,
11
+ JAVASCRIPT_MODULE_TYPE_ESM
12
+ } = require("../ModuleTypeConstants");
9
13
  const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
10
14
  const { approve } = require("../javascript/JavascriptParserHelpers");
11
15
  const InnerGraph = require("../optimize/InnerGraph");
@@ -16,13 +20,15 @@ const URLDependency = require("./URLDependency");
16
20
  /** @typedef {import("../NormalModule")} NormalModule */
17
21
  /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
18
22
 
23
+ const PLUGIN_NAME = "URLPlugin";
24
+
19
25
  class URLPlugin {
20
26
  /**
21
27
  * @param {Compiler} compiler compiler
22
28
  */
23
29
  apply(compiler) {
24
30
  compiler.hooks.compilation.tap(
25
- "URLPlugin",
31
+ PLUGIN_NAME,
26
32
  (compilation, { normalModuleFactory }) => {
27
33
  compilation.dependencyFactories.set(URLDependency, normalModuleFactory);
28
34
  compilation.dependencyTemplates.set(
@@ -76,10 +82,10 @@ class URLPlugin {
76
82
  return request;
77
83
  };
78
84
 
79
- parser.hooks.canRename.for("URL").tap("URLPlugin", approve);
85
+ parser.hooks.canRename.for("URL").tap(PLUGIN_NAME, approve);
80
86
  parser.hooks.evaluateNewExpression
81
87
  .for("URL")
82
- .tap("URLPlugin", expr => {
88
+ .tap(PLUGIN_NAME, expr => {
83
89
  const request = getUrlRequest(expr);
84
90
  if (!request) return;
85
91
  const url = new URL(request, getUrl(parser.state.module));
@@ -88,7 +94,7 @@ class URLPlugin {
88
94
  .setString(url.toString())
89
95
  .setRange(expr.range);
90
96
  });
91
- parser.hooks.new.for("URL").tap("URLPlugin", _expr => {
97
+ parser.hooks.new.for("URL").tap(PLUGIN_NAME, _expr => {
92
98
  const expr = /** @type {NewExpressionNode} */ (_expr);
93
99
 
94
100
  const request = getUrlRequest(expr);
@@ -107,7 +113,7 @@ class URLPlugin {
107
113
  InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
108
114
  return true;
109
115
  });
110
- parser.hooks.isPure.for("NewExpression").tap("URLPlugin", _expr => {
116
+ parser.hooks.isPure.for("NewExpression").tap(PLUGIN_NAME, _expr => {
111
117
  const expr = /** @type {NewExpressionNode} */ (_expr);
112
118
  const { callee } = expr;
113
119
  if (callee.type !== "Identifier") return;
@@ -121,12 +127,12 @@ class URLPlugin {
121
127
  };
122
128
 
123
129
  normalModuleFactory.hooks.parser
124
- .for("javascript/auto")
125
- .tap("URLPlugin", parserCallback);
130
+ .for(JAVASCRIPT_MODULE_TYPE_AUTO)
131
+ .tap(PLUGIN_NAME, parserCallback);
126
132
 
127
133
  normalModuleFactory.hooks.parser
128
- .for("javascript/esm")
129
- .tap("URLPlugin", parserCallback);
134
+ .for(JAVASCRIPT_MODULE_TYPE_ESM)
135
+ .tap(PLUGIN_NAME, parserCallback);
130
136
  }
131
137
  );
132
138
  }
@@ -25,10 +25,16 @@ class WorkerDependency extends ModuleDependency {
25
25
  /**
26
26
  * @param {string} request request
27
27
  * @param {[number, number]} range range
28
+ * @param {Object} workerDependencyOptions options
29
+ * @param {string} workerDependencyOptions.publicPath public path for the worker
28
30
  */
29
- constructor(request, range) {
31
+ constructor(request, range, workerDependencyOptions) {
30
32
  super(request);
31
33
  this.range = range;
34
+ // If options are updated, don't forget to update the hash and serialization functions
35
+ this.options = workerDependencyOptions;
36
+ /** Cache the hash */
37
+ this._hashUpdate = undefined;
32
38
  }
33
39
 
34
40
  /**
@@ -48,6 +54,31 @@ class WorkerDependency extends ModuleDependency {
48
54
  get category() {
49
55
  return "worker";
50
56
  }
57
+
58
+ /**
59
+ * Update the hash
60
+ * @param {Hash} hash hash to be updated
61
+ * @param {UpdateHashContext} context context
62
+ * @returns {void}
63
+ */
64
+ updateHash(hash, context) {
65
+ if (this._hashUpdate === undefined) {
66
+ this._hashUpdate = JSON.stringify(this.options);
67
+ }
68
+ hash.update(this._hashUpdate);
69
+ }
70
+
71
+ serialize(context) {
72
+ const { write } = context;
73
+ write(this.options);
74
+ super.serialize(context);
75
+ }
76
+
77
+ deserialize(context) {
78
+ const { read } = context;
79
+ this.options = read();
80
+ super.deserialize(context);
81
+ }
51
82
  }
52
83
 
53
84
  WorkerDependency.Template = class WorkerDependencyTemplate extends (
@@ -69,6 +100,10 @@ WorkerDependency.Template = class WorkerDependencyTemplate extends (
69
100
  chunkGraph.getBlockChunkGroup(block)
70
101
  );
71
102
  const chunk = entrypoint.getEntrypointChunk();
103
+ // We use the workerPublicPath option if provided, else we fallback to the RuntimeGlobal publicPath
104
+ const workerImportBaseUrl = dep.options.publicPath
105
+ ? `"${dep.options.publicPath}"`
106
+ : RuntimeGlobals.publicPath;
72
107
 
73
108
  runtimeRequirements.add(RuntimeGlobals.publicPath);
74
109
  runtimeRequirements.add(RuntimeGlobals.baseURI);
@@ -77,7 +112,7 @@ WorkerDependency.Template = class WorkerDependencyTemplate extends (
77
112
  source.replace(
78
113
  dep.range[0],
79
114
  dep.range[1] - 1,
80
- `/* worker import */ ${RuntimeGlobals.publicPath} + ${
115
+ `/* worker import */ ${workerImportBaseUrl} + ${
81
116
  RuntimeGlobals.getChunkScriptFilename
82
117
  }(${JSON.stringify(chunk.id)}), ${RuntimeGlobals.baseURI}`
83
118
  );
@@ -8,6 +8,10 @@
8
8
  const { pathToFileURL } = require("url");
9
9
  const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
10
10
  const CommentCompilationWarning = require("../CommentCompilationWarning");
11
+ const {
12
+ JAVASCRIPT_MODULE_TYPE_AUTO,
13
+ JAVASCRIPT_MODULE_TYPE_ESM
14
+ } = require("../ModuleTypeConstants");
11
15
  const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
12
16
  const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin");
13
17
  const { equals } = require("../util/ArrayHelpers");
@@ -47,11 +51,14 @@ const DEFAULT_SYNTAX = [
47
51
  /** @type {WeakMap<ParserState, number>} */
48
52
  const workerIndexMap = new WeakMap();
49
53
 
54
+ const PLUGIN_NAME = "WorkerPlugin";
55
+
50
56
  class WorkerPlugin {
51
- constructor(chunkLoading, wasmLoading, module) {
57
+ constructor(chunkLoading, wasmLoading, module, workerPublicPath) {
52
58
  this._chunkLoading = chunkLoading;
53
59
  this._wasmLoading = wasmLoading;
54
60
  this._module = module;
61
+ this._workerPublicPath = workerPublicPath;
55
62
  }
56
63
  /**
57
64
  * Apply the plugin
@@ -70,7 +77,7 @@ class WorkerPlugin {
70
77
  compiler.root
71
78
  );
72
79
  compiler.hooks.thisCompilation.tap(
73
- "WorkerPlugin",
80
+ PLUGIN_NAME,
74
81
  (compilation, { normalModuleFactory }) => {
75
82
  compilation.dependencyFactories.set(
76
83
  WorkerDependency,
@@ -298,7 +305,9 @@ class WorkerPlugin {
298
305
  }
299
306
  });
300
307
  block.loc = expr.loc;
301
- const dep = new WorkerDependency(url.string, range);
308
+ const dep = new WorkerDependency(url.string, range, {
309
+ publicPath: this._workerPublicPath
310
+ });
302
311
  dep.loc = expr.loc;
303
312
  block.addDependency(dep);
304
313
  parser.state.module.addBlock(block);
@@ -372,7 +381,7 @@ class WorkerPlugin {
372
381
  if (item.endsWith("()")) {
373
382
  parser.hooks.call
374
383
  .for(item.slice(0, -2))
375
- .tap("WorkerPlugin", handleNewWorker);
384
+ .tap(PLUGIN_NAME, handleNewWorker);
376
385
  } else {
377
386
  const match = /^(.+?)(\(\))?\s+from\s+(.+)$/.exec(item);
378
387
  if (match) {
@@ -381,7 +390,7 @@ class WorkerPlugin {
381
390
  const source = match[3];
382
391
  (call ? parser.hooks.call : parser.hooks.new)
383
392
  .for(harmonySpecifierTag)
384
- .tap("WorkerPlugin", expr => {
393
+ .tap(PLUGIN_NAME, expr => {
385
394
  const settings = /** @type {HarmonySettings} */ (
386
395
  parser.currentTagData
387
396
  );
@@ -395,7 +404,7 @@ class WorkerPlugin {
395
404
  return handleNewWorker(expr);
396
405
  });
397
406
  } else {
398
- parser.hooks.new.for(item).tap("WorkerPlugin", handleNewWorker);
407
+ parser.hooks.new.for(item).tap(PLUGIN_NAME, handleNewWorker);
399
408
  }
400
409
  }
401
410
  };
@@ -406,11 +415,11 @@ class WorkerPlugin {
406
415
  }
407
416
  };
408
417
  normalModuleFactory.hooks.parser
409
- .for("javascript/auto")
410
- .tap("WorkerPlugin", parserPlugin);
418
+ .for(JAVASCRIPT_MODULE_TYPE_AUTO)
419
+ .tap(PLUGIN_NAME, parserPlugin);
411
420
  normalModuleFactory.hooks.parser
412
- .for("javascript/esm")
413
- .tap("WorkerPlugin", parserPlugin);
421
+ .for(JAVASCRIPT_MODULE_TYPE_ESM)
422
+ .tap(PLUGIN_NAME, parserPlugin);
414
423
  }
415
424
  );
416
425
  }