@depup/vitest 4.1.10-depup.8 → 4.1.11-depup.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.
package/README.md
CHANGED
|
@@ -13,25 +13,26 @@ npm install @depup/vitest
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [vitest](https://www.npmjs.com/package/vitest) @ 4.1.
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [vitest](https://www.npmjs.com/package/vitest) @ 4.1.11 |
|
|
17
|
+
| Processed | 2026-08-23 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
|
-
| Deps updated |
|
|
19
|
+
| Deps updated | 12 |
|
|
20
20
|
|
|
21
21
|
## Dependency Changes
|
|
22
22
|
|
|
23
23
|
| Dependency | From | To |
|
|
24
24
|
|------------|------|-----|
|
|
25
|
-
| es-module-lexer | ^2.0.0 | ^2.3.
|
|
25
|
+
| es-module-lexer | ^2.0.0 | ^2.3.2 |
|
|
26
26
|
| expect-type | ^1.3.0 | ^1.4.0 |
|
|
27
|
-
| magic-string | ^0.30.21 | ^1.
|
|
27
|
+
| magic-string | ^0.30.21 | ^1.2.2 |
|
|
28
28
|
| obug | ^2.1.1 | ^2.1.4 |
|
|
29
29
|
| picomatch | ^4.0.3 | ^4.0.5 |
|
|
30
30
|
| std-env | ^4.0.0-rc.1 | ^4.2.0 |
|
|
31
|
-
| tinybench | ^2.9.0 | ^6.
|
|
32
|
-
| tinyexec | ^1.0.2 | ^1.
|
|
31
|
+
| tinybench | ^2.9.0 | ^6.1.3 |
|
|
32
|
+
| tinyexec | ^1.0.2 | ^1.3.0 |
|
|
33
33
|
| tinyglobby | ^0.2.15 | ^0.2.17 |
|
|
34
|
-
|
|
|
34
|
+
| tinyrainbow | ^3.1.0 | ^3.1.1 |
|
|
35
|
+
| vite | ^6.0.0 || ^7.0.0 || ^8.0.0 | ^8.2.2 |
|
|
35
36
|
| why-is-node-running | ^2.3.0 | ^3.2.2 |
|
|
36
37
|
|
|
37
38
|
---
|
package/changes.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"bumped": {
|
|
3
3
|
"es-module-lexer": {
|
|
4
4
|
"from": "^2.0.0",
|
|
5
|
-
"to": "^2.3.
|
|
5
|
+
"to": "^2.3.2"
|
|
6
6
|
},
|
|
7
7
|
"expect-type": {
|
|
8
8
|
"from": "^1.3.0",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"magic-string": {
|
|
12
12
|
"from": "^0.30.21",
|
|
13
|
-
"to": "^1.
|
|
13
|
+
"to": "^1.2.2"
|
|
14
14
|
},
|
|
15
15
|
"obug": {
|
|
16
16
|
"from": "^2.1.1",
|
|
@@ -26,25 +26,29 @@
|
|
|
26
26
|
},
|
|
27
27
|
"tinybench": {
|
|
28
28
|
"from": "^2.9.0",
|
|
29
|
-
"to": "^6.
|
|
29
|
+
"to": "^6.1.3"
|
|
30
30
|
},
|
|
31
31
|
"tinyexec": {
|
|
32
32
|
"from": "^1.0.2",
|
|
33
|
-
"to": "^1.
|
|
33
|
+
"to": "^1.3.0"
|
|
34
34
|
},
|
|
35
35
|
"tinyglobby": {
|
|
36
36
|
"from": "^0.2.15",
|
|
37
37
|
"to": "^0.2.17"
|
|
38
38
|
},
|
|
39
|
+
"tinyrainbow": {
|
|
40
|
+
"from": "^3.1.0",
|
|
41
|
+
"to": "^3.1.1"
|
|
42
|
+
},
|
|
39
43
|
"vite": {
|
|
40
44
|
"from": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
41
|
-
"to": "^8.
|
|
45
|
+
"to": "^8.2.2"
|
|
42
46
|
},
|
|
43
47
|
"why-is-node-running": {
|
|
44
48
|
"from": "^2.3.0",
|
|
45
49
|
"to": "^3.2.2"
|
|
46
50
|
}
|
|
47
51
|
},
|
|
48
|
-
"timestamp": "2026-
|
|
49
|
-
"totalUpdated":
|
|
52
|
+
"timestamp": "2026-08-23T00:30:02.494Z",
|
|
53
|
+
"totalUpdated": 12
|
|
50
54
|
}
|
|
@@ -621,7 +621,7 @@ class CAC extends EventEmitter {
|
|
|
621
621
|
|
|
622
622
|
const cac = (name = "") => new CAC(name);
|
|
623
623
|
|
|
624
|
-
var version = "4.1.
|
|
624
|
+
var version = "4.1.11";
|
|
625
625
|
|
|
626
626
|
const apiConfig = (port) => ({
|
|
627
627
|
port: {
|
|
@@ -2336,7 +2336,7 @@ function normalizeCliOptions(cliFilters, argv) {
|
|
|
2336
2336
|
}
|
|
2337
2337
|
async function start(mode, cliFilters, options) {
|
|
2338
2338
|
try {
|
|
2339
|
-
const { startVitest } = await import('./cli-api.
|
|
2339
|
+
const { startVitest } = await import('./cli-api.CnMVyzaz.js').then(function (n) { return n.q; });
|
|
2340
2340
|
const ctx = await startVitest(mode, cliFilters.map(normalize), normalizeCliOptions(cliFilters, options));
|
|
2341
2341
|
if (!ctx.shouldKeepServer()) await ctx.exit();
|
|
2342
2342
|
} catch (e) {
|
|
@@ -2358,7 +2358,7 @@ async function init(project) {
|
|
|
2358
2358
|
}
|
|
2359
2359
|
async function collect(mode, cliFilters, options) {
|
|
2360
2360
|
try {
|
|
2361
|
-
const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.
|
|
2361
|
+
const { prepareVitest, processCollected, outputFileList } = await import('./cli-api.CnMVyzaz.js').then(function (n) { return n.q; });
|
|
2362
2362
|
const ctx = await prepareVitest(mode, {
|
|
2363
2363
|
...normalizeCliOptions(cliFilters, options),
|
|
2364
2364
|
watch: false,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import fs, { promises, existsSync, mkdirSync, readFileSync, statSync, readdirSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import fs, { promises, existsSync, mkdirSync, readFileSync, statfsSync, statSync, readdirSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { relative, resolve, dirname, join, extname, normalize, basename, isAbsolute } from 'pathe';
|
|
3
3
|
import { C as CoverageProviderMap } from './coverage.CTzCuANN.js';
|
|
4
4
|
import path, { resolve as resolve$1 } from 'node:path';
|
|
@@ -13,7 +13,7 @@ import nodeos__default, { tmpdir } from 'node:os';
|
|
|
13
13
|
import { generateHash as generateHash$1, createTaskName, validateTags, calculateSuiteHash, hasFailed, generateFileHash, limitConcurrency, createFileTask as createFileTask$1, createTagsFilter, someTasksAreOnly, interpretTaskModes, getTasks, isTestCase } from '@vitest/runner/utils';
|
|
14
14
|
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
15
15
|
import { serializeValue } from '@vitest/utils/serialize';
|
|
16
|
-
import { v as version$1 } from './cac.
|
|
16
|
+
import { v as version$1 } from './cac.uFydS1Z4.js';
|
|
17
17
|
import { rootDir, distDir } from '../path.js';
|
|
18
18
|
import { f as createIndexLocationsMap, g as TraceMap, o as originalPositionFor, h as ancestor, s as stringify, p as parse, i as printError, j as Typechecker, k as generateCodeFrame, l as escapeRegExp, m as createDefinesScript, a as BenchmarkReportsMap, R as ReportersMap, n as groupBy, q as BlobReporter, r as readBlobs, t as convertTasksToEvents, H as HangingProcessReporter, w as wildcardPatternToRegExp, u as stdout } from './index.UpGiHP7g.js';
|
|
19
19
|
import { N as NativeModuleRunner } from './nativeModuleRunner.BIakptoF.js';
|
|
@@ -2622,8 +2622,9 @@ class BrowserPool {
|
|
|
2622
2622
|
providedContext: this._providedContext || "[{}]",
|
|
2623
2623
|
otelCarrier: this._traces.getContextCarrier()
|
|
2624
2624
|
});
|
|
2625
|
-
}).then(() => {
|
|
2625
|
+
}).then(async () => {
|
|
2626
2626
|
debug?.("[%s] test %s finished running", sessionId, file);
|
|
2627
|
+
await maybeCollectChromiumGarbage(this.project, sessionId);
|
|
2627
2628
|
this.runNextTest(method, sessionId);
|
|
2628
2629
|
}).catch((error) => {
|
|
2629
2630
|
// if user cancels the test run manually, ignore the error and exit gracefully
|
|
@@ -2661,6 +2662,72 @@ function shouldIgnoreDebugger(provider, browser) {
|
|
|
2661
2662
|
if (provider === "webdriverio") return browser !== "chrome" && browser !== "edge";
|
|
2662
2663
|
return browser !== "chromium";
|
|
2663
2664
|
}
|
|
2665
|
+
// Best-effort workaround for chromium/playwright bug
|
|
2666
|
+
// https://issues.chromium.org/issues/530892387
|
|
2667
|
+
// Trigger gc on lower disk (default to 4GB)
|
|
2668
|
+
const chromiumGCDiskThreshold = process.env.VITEST_CHROMIUM_GC_DISK_THRESHOLD_GB ? Number(process.env.VITEST_CHROMIUM_GC_DISK_THRESHOLD_GB) * 1024 ** 3 : 4 * 1024 ** 3;
|
|
2669
|
+
const forceChromiumGC = !!process.env.VITEST_CHROMIUM_GC_FORCE;
|
|
2670
|
+
const debugGC = createDebugger("vitest:browser:gc");
|
|
2671
|
+
async function maybeCollectChromiumGarbage(project, sessionId) {
|
|
2672
|
+
// trigger only on linux/chromium/playwright
|
|
2673
|
+
const provider = project.browser.provider;
|
|
2674
|
+
if (!forceChromiumGC && process.platform !== "linux" || provider.name !== "playwright" || project.config.browser.name !== "chromium" || !project.config.browser.isolate || !provider.getCDPSession) return;
|
|
2675
|
+
const start = performance.now();
|
|
2676
|
+
const diagnostics = {
|
|
2677
|
+
statfsBeforeMs: void 0,
|
|
2678
|
+
statfsAfterMs: void 0,
|
|
2679
|
+
cdpSessionMs: void 0,
|
|
2680
|
+
cdpSendMs: void 0,
|
|
2681
|
+
cdpDetachMs: void 0,
|
|
2682
|
+
forced: forceChromiumGC
|
|
2683
|
+
};
|
|
2684
|
+
try {
|
|
2685
|
+
// Playwright enables --disable-dev-shm-usage by default, which makes
|
|
2686
|
+
// Chromium use TMPDIR or /tmp for shared memory files.
|
|
2687
|
+
// https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/chromium/chromiumSwitches.ts
|
|
2688
|
+
// https://source.chromium.org/chromium/chromium/src/+/main:base/files/file_util_posix.cc
|
|
2689
|
+
const tempDirectory = process.env.TMPDIR || "/tmp";
|
|
2690
|
+
let operationStart = performance.now();
|
|
2691
|
+
const fsStats = statfsSync(tempDirectory);
|
|
2692
|
+
diagnostics.statfsBeforeMs = performance.now() - operationStart;
|
|
2693
|
+
const available = fsStats.bavail * fsStats.bsize;
|
|
2694
|
+
diagnostics.availableBytesBefore = available.toString();
|
|
2695
|
+
diagnostics.thresholdBytes = chromiumGCDiskThreshold.toString();
|
|
2696
|
+
diagnostics.tempDirectory = tempDirectory;
|
|
2697
|
+
diagnostics.triggered = available < chromiumGCDiskThreshold;
|
|
2698
|
+
if (available >= chromiumGCDiskThreshold) return;
|
|
2699
|
+
operationStart = performance.now();
|
|
2700
|
+
// `detach` is available only internally and not on CDPSession type
|
|
2701
|
+
const cdp = await provider.getCDPSession(sessionId);
|
|
2702
|
+
diagnostics.cdpSessionMs = performance.now() - operationStart;
|
|
2703
|
+
try {
|
|
2704
|
+
operationStart = performance.now();
|
|
2705
|
+
await cdp.send("HeapProfiler.collectGarbage");
|
|
2706
|
+
diagnostics.cdpSendMs = performance.now() - operationStart;
|
|
2707
|
+
} finally {
|
|
2708
|
+
operationStart = performance.now();
|
|
2709
|
+
await cdp.detach().catch((error) => {
|
|
2710
|
+
debugGC?.("[%s] failed to detach Chromium CDP session: %s", sessionId, error);
|
|
2711
|
+
});
|
|
2712
|
+
diagnostics.cdpDetachMs = performance.now() - operationStart;
|
|
2713
|
+
}
|
|
2714
|
+
if (debugGC?.enabled) {
|
|
2715
|
+
operationStart = performance.now();
|
|
2716
|
+
const fsStatsAfter = statfsSync(tempDirectory);
|
|
2717
|
+
diagnostics.statfsAfterMs = performance.now() - operationStart;
|
|
2718
|
+
diagnostics.availableBytesAfter = (fsStatsAfter.bavail * fsStatsAfter.bsize).toString();
|
|
2719
|
+
}
|
|
2720
|
+
const availableGiB = available / 1024 ** 3;
|
|
2721
|
+
const thresholdGiB = chromiumGCDiskThreshold / 1024 ** 3;
|
|
2722
|
+
debugGC?.("[%s] Low disk space detected in %s (%s GiB available, %s GiB threshold). Vitest triggered Chromium garbage collection to prevent browser crashes.", sessionId, tempDirectory, availableGiB.toFixed(1), thresholdGiB.toFixed(1));
|
|
2723
|
+
} catch (error) {
|
|
2724
|
+
// don't surface if fs or cdp fails
|
|
2725
|
+
debugGC?.("[%s] failed to collect Chromium garbage: %s", sessionId, error);
|
|
2726
|
+
} finally {
|
|
2727
|
+
diagnostics.totalMs = performance.now() - start;
|
|
2728
|
+
debugGC?.("[%s] Chromium garbage collection check: %O", sessionId, diagnostics);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2664
2731
|
|
|
2665
2732
|
function createMethodsRPC(project, methodsOptions = {}) {
|
|
2666
2733
|
const vitest = project.vitest;
|
package/dist/cli.js
CHANGED
package/dist/node.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as vite from 'vite';
|
|
2
2
|
import { resolveConfig as resolveConfig$1, mergeConfig } from 'vite';
|
|
3
3
|
export { esbuildVersion, isCSSRequest, isFileLoadingAllowed, parseAst, parseAstAsync, rollupVersion, version as viteVersion } from 'vite';
|
|
4
|
-
import { V as Vitest, a as VitestPlugin } from './chunks/cli-api.
|
|
5
|
-
export { F as ForksPoolWorker, G as GitNotFoundError, b as TestsNotFoundError, T as ThreadsPoolWorker, c as TypecheckPoolWorker, d as VitestPackageInstaller, e as VmForksPoolWorker, f as VmThreadsPoolWorker, g as createDebugger, h as createMethodsRPC, i as createViteLogger, j as createVitest, k as escapeTestName, l as experimental_getRunnerTask, m as getFilePoolName, n as isFileServingAllowed, o as isValidApiRequest, r as registerConsoleShortcuts, p as resolveFsAllow, s as startVitest } from './chunks/cli-api.
|
|
6
|
-
export { p as parseCLI } from './chunks/cac.
|
|
4
|
+
import { V as Vitest, a as VitestPlugin } from './chunks/cli-api.CnMVyzaz.js';
|
|
5
|
+
export { F as ForksPoolWorker, G as GitNotFoundError, b as TestsNotFoundError, T as ThreadsPoolWorker, c as TypecheckPoolWorker, d as VitestPackageInstaller, e as VmForksPoolWorker, f as VmThreadsPoolWorker, g as createDebugger, h as createMethodsRPC, i as createViteLogger, j as createVitest, k as escapeTestName, l as experimental_getRunnerTask, m as getFilePoolName, n as isFileServingAllowed, o as isValidApiRequest, r as registerConsoleShortcuts, p as resolveFsAllow, s as startVitest } from './chunks/cli-api.CnMVyzaz.js';
|
|
6
|
+
export { p as parseCLI } from './chunks/cac.uFydS1Z4.js';
|
|
7
7
|
import { r as resolveConfig$2 } from './chunks/coverage.DM_a_rWm.js';
|
|
8
8
|
export { B as BaseCoverageProvider, a as BaseSequencer, b as resolveApiServerConfig } from './chunks/coverage.DM_a_rWm.js';
|
|
9
9
|
import { slash, deepClone } from '@vitest/utils/helpers';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/vitest",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.1.
|
|
4
|
+
"version": "4.1.11-depup.0",
|
|
5
5
|
"description": "Next generation testing framework powered by Vite (with updated dependencies)",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -142,12 +142,12 @@
|
|
|
142
142
|
"happy-dom": "*",
|
|
143
143
|
"jsdom": "*",
|
|
144
144
|
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
145
|
-
"@vitest/browser-
|
|
146
|
-
"@vitest/
|
|
147
|
-
"@vitest/browser-
|
|
148
|
-
"@vitest/
|
|
149
|
-
"@vitest/coverage-
|
|
150
|
-
"@vitest/ui": "4.1.
|
|
145
|
+
"@vitest/browser-playwright": "4.1.11",
|
|
146
|
+
"@vitest/browser-preview": "4.1.11",
|
|
147
|
+
"@vitest/browser-webdriverio": "4.1.11",
|
|
148
|
+
"@vitest/coverage-v8": "4.1.11",
|
|
149
|
+
"@vitest/coverage-istanbul": "4.1.11",
|
|
150
|
+
"@vitest/ui": "4.1.11"
|
|
151
151
|
},
|
|
152
152
|
"peerDependenciesMeta": {
|
|
153
153
|
"@edge-runtime/vm": {
|
|
@@ -188,26 +188,26 @@
|
|
|
188
188
|
}
|
|
189
189
|
},
|
|
190
190
|
"dependencies": {
|
|
191
|
-
"es-module-lexer": "^2.3.
|
|
191
|
+
"es-module-lexer": "^2.3.2",
|
|
192
192
|
"expect-type": "^1.4.0",
|
|
193
|
-
"magic-string": "^1.
|
|
193
|
+
"magic-string": "^1.2.2",
|
|
194
194
|
"obug": "^2.1.4",
|
|
195
195
|
"pathe": "^2.0.3",
|
|
196
196
|
"picomatch": "^4.0.5",
|
|
197
197
|
"std-env": "^4.2.0",
|
|
198
|
-
"tinybench": "^6.
|
|
199
|
-
"tinyexec": "^1.
|
|
198
|
+
"tinybench": "^6.1.3",
|
|
199
|
+
"tinyexec": "^1.3.0",
|
|
200
200
|
"tinyglobby": "^0.2.17",
|
|
201
|
-
"tinyrainbow": "^3.1.
|
|
202
|
-
"vite": "^8.
|
|
201
|
+
"tinyrainbow": "^3.1.1",
|
|
202
|
+
"vite": "^8.2.2",
|
|
203
203
|
"why-is-node-running": "^3.2.2",
|
|
204
|
-
"@vitest/expect": "4.1.
|
|
205
|
-
"@vitest/mocker": "4.1.
|
|
206
|
-
"@vitest/pretty-format": "4.1.
|
|
207
|
-
"@vitest/runner": "4.1.
|
|
208
|
-
"@vitest/spy": "4.1.
|
|
209
|
-
"@vitest/
|
|
210
|
-
"@vitest/
|
|
204
|
+
"@vitest/expect": "4.1.11",
|
|
205
|
+
"@vitest/mocker": "4.1.11",
|
|
206
|
+
"@vitest/pretty-format": "4.1.11",
|
|
207
|
+
"@vitest/runner": "4.1.11",
|
|
208
|
+
"@vitest/spy": "4.1.11",
|
|
209
|
+
"@vitest/utils": "4.1.11",
|
|
210
|
+
"@vitest/snapshot": "4.1.11"
|
|
211
211
|
},
|
|
212
212
|
"devDependencies": {
|
|
213
213
|
"@antfu/install-pkg": "^1.1.0",
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
"changes": {
|
|
248
248
|
"es-module-lexer": {
|
|
249
249
|
"from": "^2.0.0",
|
|
250
|
-
"to": "^2.3.
|
|
250
|
+
"to": "^2.3.2"
|
|
251
251
|
},
|
|
252
252
|
"expect-type": {
|
|
253
253
|
"from": "^1.3.0",
|
|
@@ -255,7 +255,7 @@
|
|
|
255
255
|
},
|
|
256
256
|
"magic-string": {
|
|
257
257
|
"from": "^0.30.21",
|
|
258
|
-
"to": "^1.
|
|
258
|
+
"to": "^1.2.2"
|
|
259
259
|
},
|
|
260
260
|
"obug": {
|
|
261
261
|
"from": "^2.1.1",
|
|
@@ -271,29 +271,33 @@
|
|
|
271
271
|
},
|
|
272
272
|
"tinybench": {
|
|
273
273
|
"from": "^2.9.0",
|
|
274
|
-
"to": "^6.
|
|
274
|
+
"to": "^6.1.3"
|
|
275
275
|
},
|
|
276
276
|
"tinyexec": {
|
|
277
277
|
"from": "^1.0.2",
|
|
278
|
-
"to": "^1.
|
|
278
|
+
"to": "^1.3.0"
|
|
279
279
|
},
|
|
280
280
|
"tinyglobby": {
|
|
281
281
|
"from": "^0.2.15",
|
|
282
282
|
"to": "^0.2.17"
|
|
283
283
|
},
|
|
284
|
+
"tinyrainbow": {
|
|
285
|
+
"from": "^3.1.0",
|
|
286
|
+
"to": "^3.1.1"
|
|
287
|
+
},
|
|
284
288
|
"vite": {
|
|
285
289
|
"from": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
286
|
-
"to": "^8.
|
|
290
|
+
"to": "^8.2.2"
|
|
287
291
|
},
|
|
288
292
|
"why-is-node-running": {
|
|
289
293
|
"from": "^2.3.0",
|
|
290
294
|
"to": "^3.2.2"
|
|
291
295
|
}
|
|
292
296
|
},
|
|
293
|
-
"depsUpdated":
|
|
297
|
+
"depsUpdated": 12,
|
|
294
298
|
"originalPackage": "vitest",
|
|
295
|
-
"originalVersion": "4.1.
|
|
296
|
-
"processedAt": "2026-
|
|
299
|
+
"originalVersion": "4.1.11",
|
|
300
|
+
"processedAt": "2026-08-23T00:30:05.726Z",
|
|
297
301
|
"smokeTest": "passed"
|
|
298
302
|
}
|
|
299
303
|
}
|