@csszyx/unplugin 0.11.6 → 0.11.7
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/dist/css-mangler.cjs +41 -41
- package/dist/css-mangler.mjs +41 -41
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/next-prebuild.cjs +3 -3
- package/dist/next-prebuild.mjs +3 -3
- package/dist/next-turbo-loader.cjs +9 -3
- package/dist/next-turbo-loader.mjs +9 -3
- package/dist/next-watcher.cjs +1 -1
- package/dist/next-watcher.mjs +1 -1
- package/dist/shared/{unplugin.CP2cz9bA.cjs → unplugin.ByAzFdqO.cjs} +246 -211
- package/dist/shared/{unplugin.CBKZoxQ1.cjs → unplugin.CZKUWN1J.cjs} +1 -1
- package/dist/shared/{unplugin.BS60onPk.mjs → unplugin.CtHwCYxE.mjs} +244 -209
- package/dist/shared/{unplugin.ByzV6iZE.mjs → unplugin.CwcOd1q3.mjs} +7 -6
- package/dist/shared/{unplugin.BFN_Ueyx.cjs → unplugin.D6hes1O8.cjs} +2 -2
- package/dist/shared/{unplugin.D0N9bprz.cjs → unplugin.D8vSG36M.cjs} +6 -5
- package/dist/shared/{unplugin.ChwZMl_w.mjs → unplugin.Dqt1aLCX.mjs} +3 -3
- package/dist/shared/{unplugin.B3cvNxnk.mjs → unplugin.VSslRpfN.mjs} +1 -1
- package/dist/vite.cjs +2 -2
- package/dist/vite.mjs +2 -2
- package/dist/webpack.cjs +2 -2
- package/dist/webpack.mjs +2 -2
- package/package.json +7 -7
package/dist/css-mangler.cjs
CHANGED
|
@@ -12,61 +12,61 @@ function unescapeTailwindClass(escapedName) {
|
|
|
12
12
|
let result = "";
|
|
13
13
|
let i = 0;
|
|
14
14
|
while (i < escapedName.length) {
|
|
15
|
-
if (escapedName[i]
|
|
16
|
-
i++;
|
|
17
|
-
if (i >= escapedName.length) {
|
|
18
|
-
break;
|
|
19
|
-
}
|
|
20
|
-
const char = escapedName[i];
|
|
21
|
-
if (/[0-9a-f]/i.test(char)) {
|
|
22
|
-
let hexStr = "";
|
|
23
|
-
while (i < escapedName.length && /[0-9a-f]/i.test(escapedName[i]) && hexStr.length < 6) {
|
|
24
|
-
hexStr += escapedName[i];
|
|
25
|
-
i++;
|
|
26
|
-
}
|
|
27
|
-
if (i < escapedName.length && escapedName[i] === " ") {
|
|
28
|
-
i++;
|
|
29
|
-
}
|
|
30
|
-
const codePoint = parseInt(hexStr, 16);
|
|
31
|
-
if (codePoint > 0) {
|
|
32
|
-
result += String.fromCodePoint(codePoint);
|
|
33
|
-
}
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
result += char;
|
|
37
|
-
i++;
|
|
38
|
-
} else {
|
|
15
|
+
if (escapedName[i] !== "\\") {
|
|
39
16
|
result += escapedName[i];
|
|
40
17
|
i++;
|
|
18
|
+
continue;
|
|
41
19
|
}
|
|
20
|
+
const decoded = readCssEscape(escapedName, i + 1);
|
|
21
|
+
if (!decoded) break;
|
|
22
|
+
result += decoded.value;
|
|
23
|
+
i = decoded.next;
|
|
42
24
|
}
|
|
43
25
|
return result;
|
|
44
26
|
}
|
|
27
|
+
function readCssEscape(source, start) {
|
|
28
|
+
if (start >= source.length) return null;
|
|
29
|
+
if (!/[0-9a-f]/i.test(source[start])) return { value: source[start], next: start + 1 };
|
|
30
|
+
let next = start;
|
|
31
|
+
let hex = "";
|
|
32
|
+
while (next < source.length && /[0-9a-f]/i.test(source[next]) && hex.length < 6) {
|
|
33
|
+
hex += source[next];
|
|
34
|
+
next++;
|
|
35
|
+
}
|
|
36
|
+
if (source[next] === " ") next++;
|
|
37
|
+
const codePoint = parseInt(hex, 16);
|
|
38
|
+
return { value: codePoint > 0 ? String.fromCodePoint(codePoint) : "", next };
|
|
39
|
+
}
|
|
40
|
+
function escapeLeadingClassCharacter(className, char) {
|
|
41
|
+
if (/\d/.test(char)) {
|
|
42
|
+
return `\\3${char} `;
|
|
43
|
+
}
|
|
44
|
+
if (char === "-" && className.length > 1) {
|
|
45
|
+
const next = className[1];
|
|
46
|
+
if (/\d/.test(next) || next === "-") {
|
|
47
|
+
return "\\-";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
function escapeClassCharacter(char) {
|
|
53
|
+
if (/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/.test(char)) {
|
|
54
|
+
return `\\${char}`;
|
|
55
|
+
}
|
|
56
|
+
return char;
|
|
57
|
+
}
|
|
45
58
|
function escapeCSSClassName(className) {
|
|
46
59
|
let result = "";
|
|
47
60
|
for (let i = 0; i < className.length; i++) {
|
|
48
61
|
const char = className[i];
|
|
49
|
-
const code = char.charCodeAt(0);
|
|
50
62
|
if (i === 0) {
|
|
51
|
-
|
|
52
|
-
|
|
63
|
+
const escapedLeading = escapeLeadingClassCharacter(className, char);
|
|
64
|
+
if (escapedLeading !== null) {
|
|
65
|
+
result += escapedLeading;
|
|
53
66
|
continue;
|
|
54
67
|
}
|
|
55
|
-
if (char === "-" && i + 1 < className.length) {
|
|
56
|
-
const next = className[i + 1];
|
|
57
|
-
if (/\d/.test(next) || next === "-") {
|
|
58
|
-
result += "\\-";
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/.test(char)) {
|
|
64
|
-
result += `\\${char}`;
|
|
65
|
-
} else if (code >= 128) {
|
|
66
|
-
result += char;
|
|
67
|
-
} else {
|
|
68
|
-
result += char;
|
|
69
68
|
}
|
|
69
|
+
result += escapeClassCharacter(char);
|
|
70
70
|
}
|
|
71
71
|
return result;
|
|
72
72
|
}
|
package/dist/css-mangler.mjs
CHANGED
|
@@ -5,61 +5,61 @@ function unescapeTailwindClass(escapedName) {
|
|
|
5
5
|
let result = "";
|
|
6
6
|
let i = 0;
|
|
7
7
|
while (i < escapedName.length) {
|
|
8
|
-
if (escapedName[i]
|
|
9
|
-
i++;
|
|
10
|
-
if (i >= escapedName.length) {
|
|
11
|
-
break;
|
|
12
|
-
}
|
|
13
|
-
const char = escapedName[i];
|
|
14
|
-
if (/[0-9a-f]/i.test(char)) {
|
|
15
|
-
let hexStr = "";
|
|
16
|
-
while (i < escapedName.length && /[0-9a-f]/i.test(escapedName[i]) && hexStr.length < 6) {
|
|
17
|
-
hexStr += escapedName[i];
|
|
18
|
-
i++;
|
|
19
|
-
}
|
|
20
|
-
if (i < escapedName.length && escapedName[i] === " ") {
|
|
21
|
-
i++;
|
|
22
|
-
}
|
|
23
|
-
const codePoint = parseInt(hexStr, 16);
|
|
24
|
-
if (codePoint > 0) {
|
|
25
|
-
result += String.fromCodePoint(codePoint);
|
|
26
|
-
}
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
result += char;
|
|
30
|
-
i++;
|
|
31
|
-
} else {
|
|
8
|
+
if (escapedName[i] !== "\\") {
|
|
32
9
|
result += escapedName[i];
|
|
33
10
|
i++;
|
|
11
|
+
continue;
|
|
34
12
|
}
|
|
13
|
+
const decoded = readCssEscape(escapedName, i + 1);
|
|
14
|
+
if (!decoded) break;
|
|
15
|
+
result += decoded.value;
|
|
16
|
+
i = decoded.next;
|
|
35
17
|
}
|
|
36
18
|
return result;
|
|
37
19
|
}
|
|
20
|
+
function readCssEscape(source, start) {
|
|
21
|
+
if (start >= source.length) return null;
|
|
22
|
+
if (!/[0-9a-f]/i.test(source[start])) return { value: source[start], next: start + 1 };
|
|
23
|
+
let next = start;
|
|
24
|
+
let hex = "";
|
|
25
|
+
while (next < source.length && /[0-9a-f]/i.test(source[next]) && hex.length < 6) {
|
|
26
|
+
hex += source[next];
|
|
27
|
+
next++;
|
|
28
|
+
}
|
|
29
|
+
if (source[next] === " ") next++;
|
|
30
|
+
const codePoint = parseInt(hex, 16);
|
|
31
|
+
return { value: codePoint > 0 ? String.fromCodePoint(codePoint) : "", next };
|
|
32
|
+
}
|
|
33
|
+
function escapeLeadingClassCharacter(className, char) {
|
|
34
|
+
if (/\d/.test(char)) {
|
|
35
|
+
return `\\3${char} `;
|
|
36
|
+
}
|
|
37
|
+
if (char === "-" && className.length > 1) {
|
|
38
|
+
const next = className[1];
|
|
39
|
+
if (/\d/.test(next) || next === "-") {
|
|
40
|
+
return "\\-";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
function escapeClassCharacter(char) {
|
|
46
|
+
if (/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/.test(char)) {
|
|
47
|
+
return `\\${char}`;
|
|
48
|
+
}
|
|
49
|
+
return char;
|
|
50
|
+
}
|
|
38
51
|
function escapeCSSClassName(className) {
|
|
39
52
|
let result = "";
|
|
40
53
|
for (let i = 0; i < className.length; i++) {
|
|
41
54
|
const char = className[i];
|
|
42
|
-
const code = char.charCodeAt(0);
|
|
43
55
|
if (i === 0) {
|
|
44
|
-
|
|
45
|
-
|
|
56
|
+
const escapedLeading = escapeLeadingClassCharacter(className, char);
|
|
57
|
+
if (escapedLeading !== null) {
|
|
58
|
+
result += escapedLeading;
|
|
46
59
|
continue;
|
|
47
60
|
}
|
|
48
|
-
if (char === "-" && i + 1 < className.length) {
|
|
49
|
-
const next = className[i + 1];
|
|
50
|
-
if (/\d/.test(next) || next === "-") {
|
|
51
|
-
result += "\\-";
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/.test(char)) {
|
|
57
|
-
result += `\\${char}`;
|
|
58
|
-
} else if (code >= 128) {
|
|
59
|
-
result += char;
|
|
60
|
-
} else {
|
|
61
|
-
result += char;
|
|
62
61
|
}
|
|
62
|
+
result += escapeClassCharacter(char);
|
|
63
63
|
}
|
|
64
64
|
return result;
|
|
65
65
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
const cssMangler = require('./css-mangler.cjs');
|
|
6
|
-
const unplugin = require('./shared/unplugin.
|
|
6
|
+
const unplugin = require('./shared/unplugin.ByAzFdqO.cjs');
|
|
7
7
|
const types = require('@csszyx/types');
|
|
8
8
|
require('postcss');
|
|
9
9
|
require('postcss-selector-parser');
|
|
@@ -21,7 +21,7 @@ require('@csszyx/vue-adapter');
|
|
|
21
21
|
require('unplugin');
|
|
22
22
|
require('./shared/unplugin.BCwRIUs_.cjs');
|
|
23
23
|
require('./shared/unplugin.Rov-j_Wm.cjs');
|
|
24
|
-
require('./shared/unplugin.
|
|
24
|
+
require('./shared/unplugin.D8vSG36M.cjs');
|
|
25
25
|
require('postcss-value-parser');
|
|
26
26
|
|
|
27
27
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createPostCSSPlugin, escapeCSSClassName, mangleCSS, mangleCSSSync, unescapeTailwindClass } from './css-mangler.mjs';
|
|
2
|
-
export { a as appendTailwindSourceDirective, b as assertNoRSCBoundaryViolation, c as assertNoRSCGraphViolation, d as collectMangleHybridHazards, e as computeSafelistRelPath, f as createGlobalVarAliasValidationOptions, g as createGlobalVarMapAssetSource, h as createGlobalVarScanCacheKey, i as createRSCModuleRecord, j as cssHasContentScope, k as cssImportsTailwind, u as default, l as deleteRSCModuleRecord, m as esbuildPlugin, n as extractGlobalVarAliasesForManifest, o as fileMayContainSafelistableSz, p as findLocalImportSources, q as findRSCBoundaryViolation, r as findRSCGraphViolation, s as hasInjectableTailwindCandidate, t as hasTokens, v as hasUseClientDirective, w as hasUseServerDirective, x as isCompileSourceOptedIn, y as isHardIgnoredPath, z as isMonorepoPackage, A as isPackagesSkippedSource, B as isRSCServerModule, C as isTailwindReservedGlobalVar, D as mangleCodeClassesSync, E as mangleHybridHazardMessage, F as mergeThemes, G as missingTailwindEntryMessage, H as normalizeGlobalVarAliasesForCache, I as parseThemeBlocks, J as planGlobalVarAliases, K as readGlobalVarScanCache, L as recordGlobalVarSourceFile, M as resolveCompileSourceDirs, N as resolveGlobalVarScanCacheDir, O as resolveNativeCacheIdentity, P as rewriteGlobalVarCssAliases, Q as rollupPlugin, R as scanCustomPropertyNames, S as scanGlobalVarCss, T as shouldEmitWarning, U as shouldTrackGlobalVarSources, V as shouldWarnMissingTailwindEntry, W as shouldWarnUnscopedMonorepo, X as skippedSzFilesMessage, u as unplugin, Y as unscopedMonorepoMessage, Z as validateGlobalVarAliasInputs, _ as vitePlugin, $ as webpackPlugin, a0 as writeGlobalVarScanCache } from './shared/unplugin.
|
|
2
|
+
export { a as appendTailwindSourceDirective, b as assertNoRSCBoundaryViolation, c as assertNoRSCGraphViolation, d as collectMangleHybridHazards, e as computeSafelistRelPath, f as createGlobalVarAliasValidationOptions, g as createGlobalVarMapAssetSource, h as createGlobalVarScanCacheKey, i as createRSCModuleRecord, j as cssHasContentScope, k as cssImportsTailwind, u as default, l as deleteRSCModuleRecord, m as esbuildPlugin, n as extractGlobalVarAliasesForManifest, o as fileMayContainSafelistableSz, p as findLocalImportSources, q as findRSCBoundaryViolation, r as findRSCGraphViolation, s as hasInjectableTailwindCandidate, t as hasTokens, v as hasUseClientDirective, w as hasUseServerDirective, x as isCompileSourceOptedIn, y as isHardIgnoredPath, z as isMonorepoPackage, A as isPackagesSkippedSource, B as isRSCServerModule, C as isTailwindReservedGlobalVar, D as mangleCodeClassesSync, E as mangleHybridHazardMessage, F as mergeThemes, G as missingTailwindEntryMessage, H as normalizeGlobalVarAliasesForCache, I as parseThemeBlocks, J as planGlobalVarAliases, K as readGlobalVarScanCache, L as recordGlobalVarSourceFile, M as resolveCompileSourceDirs, N as resolveGlobalVarScanCacheDir, O as resolveNativeCacheIdentity, P as rewriteGlobalVarCssAliases, Q as rollupPlugin, R as scanCustomPropertyNames, S as scanGlobalVarCss, T as shouldEmitWarning, U as shouldTrackGlobalVarSources, V as shouldWarnMissingTailwindEntry, W as shouldWarnUnscopedMonorepo, X as skippedSzFilesMessage, u as unplugin, Y as unscopedMonorepoMessage, Z as validateGlobalVarAliasInputs, _ as vitePlugin, $ as webpackPlugin, a0 as writeGlobalVarScanCache } from './shared/unplugin.CtHwCYxE.mjs';
|
|
3
3
|
export { CSSZYX_GLOBAL_ALIAS_PREFIX, TAILWIND_RESERVED_PREFIXES } from '@csszyx/types';
|
|
4
4
|
import 'postcss';
|
|
5
5
|
import 'postcss-selector-parser';
|
|
@@ -17,5 +17,5 @@ import '@csszyx/vue-adapter';
|
|
|
17
17
|
import 'unplugin';
|
|
18
18
|
import './shared/unplugin.B1mblcm-.mjs';
|
|
19
19
|
import './shared/unplugin.B3RHYokB.mjs';
|
|
20
|
-
import './shared/unplugin.
|
|
20
|
+
import './shared/unplugin.CwcOd1q3.mjs';
|
|
21
21
|
import 'postcss-value-parser';
|
package/dist/next-prebuild.cjs
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
const node_crypto = require('node:crypto');
|
|
4
4
|
const fs = require('node:fs');
|
|
5
5
|
const path = require('node:path');
|
|
6
|
-
const nextTransformMetadata = require('./shared/unplugin.
|
|
7
|
-
const nextWatcherCycle = require('./shared/unplugin.
|
|
8
|
-
const transformCache = require('./shared/unplugin.
|
|
6
|
+
const nextTransformMetadata = require('./shared/unplugin.CZKUWN1J.cjs');
|
|
7
|
+
const nextWatcherCycle = require('./shared/unplugin.D6hes1O8.cjs');
|
|
8
|
+
const transformCache = require('./shared/unplugin.D8vSG36M.cjs');
|
|
9
9
|
require('@csszyx/compiler');
|
|
10
10
|
require('./shared/unplugin.BCwRIUs_.cjs');
|
|
11
11
|
require('node:os');
|
package/dist/next-prebuild.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
-
import { r as readPackageVersion, t as transformNextSource, c as collectNextTransformMetadata, a as createNextSafelistShardFromMetadata } from './shared/unplugin.
|
|
5
|
-
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle } from './shared/unplugin.
|
|
6
|
-
import { r as resolveTransformCacheDir } from './shared/unplugin.
|
|
4
|
+
import { r as readPackageVersion, t as transformNextSource, c as collectNextTransformMetadata, a as createNextSafelistShardFromMetadata } from './shared/unplugin.VSslRpfN.mjs';
|
|
5
|
+
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle } from './shared/unplugin.Dqt1aLCX.mjs';
|
|
6
|
+
import { r as resolveTransformCacheDir } from './shared/unplugin.CwcOd1q3.mjs';
|
|
7
7
|
import '@csszyx/compiler';
|
|
8
8
|
import './shared/unplugin.B1mblcm-.mjs';
|
|
9
9
|
import 'node:os';
|
|
@@ -4,10 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
const node_crypto = require('node:crypto');
|
|
6
6
|
const path = require('node:path');
|
|
7
|
-
const nextWatcherCycle = require('./shared/unplugin.
|
|
8
|
-
const nextTransformMetadata = require('./shared/unplugin.
|
|
7
|
+
const nextWatcherCycle = require('./shared/unplugin.D6hes1O8.cjs');
|
|
8
|
+
const nextTransformMetadata = require('./shared/unplugin.CZKUWN1J.cjs');
|
|
9
9
|
const runtimeImportScan = require('./shared/unplugin.Rov-j_Wm.cjs');
|
|
10
|
-
const transformCache = require('./shared/unplugin.
|
|
10
|
+
const transformCache = require('./shared/unplugin.D8vSG36M.cjs');
|
|
11
11
|
require('node:fs');
|
|
12
12
|
require('node:os');
|
|
13
13
|
require('proper-lockfile');
|
|
@@ -66,6 +66,12 @@ function runtimeHelpersFromUsage(usage) {
|
|
|
66
66
|
if (usage.usesColorVar) {
|
|
67
67
|
helpers.push("__szColorVar");
|
|
68
68
|
}
|
|
69
|
+
if (usage.usesSpacingVar) {
|
|
70
|
+
helpers.push("__szSpacingVar");
|
|
71
|
+
}
|
|
72
|
+
if (usage.usesUnitVar) {
|
|
73
|
+
helpers.push("__szUnitVar");
|
|
74
|
+
}
|
|
69
75
|
return helpers;
|
|
70
76
|
}
|
|
71
77
|
function insertRuntimeImport(code, importStmt) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle, v as validateNextGenerationManifest, a as readNextGenerationManifest } from './shared/unplugin.
|
|
4
|
-
import { r as readPackageVersion, t as transformNextSource, c as collectNextTransformMetadata, a as createNextSafelistShardFromMetadata } from './shared/unplugin.
|
|
3
|
+
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle, v as validateNextGenerationManifest, a as readNextGenerationManifest } from './shared/unplugin.Dqt1aLCX.mjs';
|
|
4
|
+
import { r as readPackageVersion, t as transformNextSource, c as collectNextTransformMetadata, a as createNextSafelistShardFromMetadata } from './shared/unplugin.VSslRpfN.mjs';
|
|
5
5
|
import { i as importsRuntimeHelper } from './shared/unplugin.B3RHYokB.mjs';
|
|
6
|
-
import { r as resolveTransformCacheDir } from './shared/unplugin.
|
|
6
|
+
import { r as resolveTransformCacheDir } from './shared/unplugin.CwcOd1q3.mjs';
|
|
7
7
|
import 'node:fs';
|
|
8
8
|
import 'node:os';
|
|
9
9
|
import 'proper-lockfile';
|
|
@@ -47,6 +47,12 @@ function runtimeHelpersFromUsage(usage) {
|
|
|
47
47
|
if (usage.usesColorVar) {
|
|
48
48
|
helpers.push("__szColorVar");
|
|
49
49
|
}
|
|
50
|
+
if (usage.usesSpacingVar) {
|
|
51
|
+
helpers.push("__szSpacingVar");
|
|
52
|
+
}
|
|
53
|
+
if (usage.usesUnitVar) {
|
|
54
|
+
helpers.push("__szUnitVar");
|
|
55
|
+
}
|
|
50
56
|
return helpers;
|
|
51
57
|
}
|
|
52
58
|
function insertRuntimeImport(code, importStmt) {
|
package/dist/next-watcher.cjs
CHANGED
package/dist/next-watcher.mjs
CHANGED