@weapp-tailwindcss/engine 0.1.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.
@@ -0,0 +1,3874 @@
1
+ import { createRequire } from "node:module";
2
+ import { promises, realpathSync } from "node:fs";
3
+ import path from "node:path";
4
+ import process from "node:process";
5
+ import { pathToFileURL } from "node:url";
6
+ import micromatch from "micromatch";
7
+ import { stat } from "node:fs/promises";
8
+ import postcss from "postcss";
9
+ //#region src/v4/node-adapter.ts
10
+ const nodeModulePromiseCache = /* @__PURE__ */ new Map();
11
+ const designSystemPromiseCache = /* @__PURE__ */ new Map();
12
+ function unique(values) {
13
+ return Array.from(new Set(Array.from(values).filter(Boolean).map((value) => path.resolve(value))));
14
+ }
15
+ function createRequireBase(base) {
16
+ return path.join(base, "package.json");
17
+ }
18
+ function isRelativeSpecifier(id) {
19
+ return id.startsWith("./") || id.startsWith("../") || id === "." || id === "..";
20
+ }
21
+ function isAbsoluteSpecifier(id) {
22
+ return path.isAbsolute(id);
23
+ }
24
+ function isCssSpecifier(id) {
25
+ return path.extname(id) === ".css";
26
+ }
27
+ function createCssResolutionCandidates(id) {
28
+ if (isCssSpecifier(id)) return [id];
29
+ return [`${id}/index.css`, id];
30
+ }
31
+ function createFallbackCssResolver(baseCandidates) {
32
+ const bases = unique(baseCandidates);
33
+ return async (id) => {
34
+ if (isRelativeSpecifier(id) || isAbsoluteSpecifier(id)) return;
35
+ for (const base of bases) {
36
+ const requireFromBase = createRequire(createRequireBase(base));
37
+ for (const candidate of createCssResolutionCandidates(id)) try {
38
+ return requireFromBase.resolve(candidate);
39
+ } catch {}
40
+ }
41
+ };
42
+ }
43
+ async function importResolvedModule(resolved) {
44
+ return import(pathToFileURL(resolved).href);
45
+ }
46
+ async function importTailwindNodeFromBase(base) {
47
+ try {
48
+ return await importResolvedModule(createRequire(createRequireBase(base)).resolve("@tailwindcss/node"));
49
+ } catch {
50
+ return;
51
+ }
52
+ }
53
+ async function importFallbackTailwindNode() {
54
+ return import("@tailwindcss/node");
55
+ }
56
+ async function loadTailwindV4NodeModule(baseCandidates) {
57
+ const bases = unique(baseCandidates);
58
+ const cacheKey = JSON.stringify(bases);
59
+ const cached = nodeModulePromiseCache.get(cacheKey);
60
+ if (cached) return cached;
61
+ const promise = (async () => {
62
+ for (const base of bases) {
63
+ const loaded = await importTailwindNodeFromBase(base);
64
+ if (loaded) return loaded;
65
+ }
66
+ return importFallbackTailwindNode();
67
+ })();
68
+ nodeModulePromiseCache.set(cacheKey, promise);
69
+ promise.catch(() => {
70
+ if (nodeModulePromiseCache.get(cacheKey) === promise) nodeModulePromiseCache.delete(cacheKey);
71
+ });
72
+ return promise;
73
+ }
74
+ function createDesignSystemCacheKey(css, bases) {
75
+ return JSON.stringify({
76
+ css,
77
+ bases: unique(bases)
78
+ });
79
+ }
80
+ function getTailwindV4DesignSystemCacheKey(source) {
81
+ return createDesignSystemCacheKey(source.css, [source.base, ...source.baseFallbacks]);
82
+ }
83
+ async function createTailwindV4DesignSystem(source) {
84
+ const bases = unique([source.base, ...source.baseFallbacks]);
85
+ if (bases.length === 0) throw new Error("No base directories provided for Tailwind CSS v4 design system.");
86
+ const node = await loadTailwindV4NodeModule([source.projectRoot, ...bases]);
87
+ let lastError;
88
+ for (const base of bases) try {
89
+ return await node.__unstable__loadDesignSystem(source.css, { base });
90
+ } catch (error) {
91
+ lastError = error;
92
+ }
93
+ if (lastError instanceof Error) throw lastError;
94
+ throw new Error("Failed to load Tailwind CSS v4 design system.");
95
+ }
96
+ async function loadTailwindV4DesignSystem(source, options) {
97
+ if (options?.cache === false) return createTailwindV4DesignSystem(source);
98
+ const cacheKey = getTailwindV4DesignSystemCacheKey(source);
99
+ const cached = designSystemPromiseCache.get(cacheKey);
100
+ if (cached) return cached;
101
+ const promise = createTailwindV4DesignSystem(source);
102
+ designSystemPromiseCache.set(cacheKey, promise);
103
+ promise.catch(() => {
104
+ if (designSystemPromiseCache.get(cacheKey) === promise) designSystemPromiseCache.delete(cacheKey);
105
+ });
106
+ return promise;
107
+ }
108
+ async function compileTailwindV4Source(source) {
109
+ const bases = unique([source.base, ...source.baseFallbacks]);
110
+ if (bases.length === 0) throw new Error("No base directories provided for Tailwind CSS v4 compiler.");
111
+ const node = await loadTailwindV4NodeModule([source.projectRoot, ...bases]);
112
+ let lastError;
113
+ for (const base of bases) {
114
+ const dependencies = new Set(source.dependencies);
115
+ try {
116
+ return {
117
+ compiled: await node.compile(source.css, {
118
+ base,
119
+ customCssResolver: createFallbackCssResolver([source.projectRoot, ...bases]),
120
+ onDependency(dependency) {
121
+ dependencies.add(path.resolve(dependency));
122
+ }
123
+ }),
124
+ dependencies
125
+ };
126
+ } catch (error) {
127
+ lastError = error;
128
+ }
129
+ }
130
+ if (lastError instanceof Error) throw lastError;
131
+ throw new Error("Failed to compile Tailwind CSS v4 source.");
132
+ }
133
+ //#endregion
134
+ //#region src/v4/source-scan/sources.ts
135
+ const TAILWIND_V4_IGNORED_CONTENT_DIRS = [
136
+ ".git",
137
+ ".hg",
138
+ ".jj",
139
+ ".next",
140
+ ".parcel-cache",
141
+ ".pnpm-store",
142
+ ".svelte-kit",
143
+ ".svn",
144
+ ".turbo",
145
+ ".venv",
146
+ ".vercel",
147
+ ".yarn",
148
+ "__pycache__",
149
+ "node_modules",
150
+ "venv"
151
+ ];
152
+ const TAILWIND_V4_IGNORED_EXTENSIONS = [
153
+ "less",
154
+ "lock",
155
+ "sass",
156
+ "scss",
157
+ "styl",
158
+ "log"
159
+ ];
160
+ const TAILWIND_V4_IGNORED_FILES = [
161
+ "package-lock.json",
162
+ "pnpm-lock.yaml",
163
+ "bun.lockb",
164
+ ".gitignore",
165
+ ".env",
166
+ ".env.*"
167
+ ];
168
+ const TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN = "**/*";
169
+ function uniqueResolvedPaths(values) {
170
+ const result = [];
171
+ for (const value of values) {
172
+ if (!value) continue;
173
+ const resolved = path.resolve(value);
174
+ if (!result.includes(resolved)) result.push(resolved);
175
+ }
176
+ return result;
177
+ }
178
+ function toPosixPath(value) {
179
+ return value.replaceAll(path.sep, "/");
180
+ }
181
+ function resolveSourceScanPath(value) {
182
+ const resolved = path.resolve(value);
183
+ try {
184
+ return realpathSync.native(resolved);
185
+ } catch {
186
+ return resolved;
187
+ }
188
+ }
189
+ function normalizeGlobPattern(pattern) {
190
+ return pattern.startsWith("./") ? pattern.slice(2) : pattern;
191
+ }
192
+ function hasGlobMagic(value) {
193
+ return /[*?[\]{}()!+@]/.test(value);
194
+ }
195
+ function splitStaticGlobPrefix(pattern) {
196
+ const segments = normalizeGlobPattern(pattern).split(/[\\/]+/);
197
+ const prefix = [];
198
+ const rest = [];
199
+ let reachedGlob = false;
200
+ for (const segment of segments) {
201
+ if (!reachedGlob && segment && !hasGlobMagic(segment)) {
202
+ prefix.push(segment);
203
+ continue;
204
+ }
205
+ reachedGlob = true;
206
+ rest.push(segment);
207
+ }
208
+ return {
209
+ prefix,
210
+ rest
211
+ };
212
+ }
213
+ async function pathExistsAsDirectory(file) {
214
+ try {
215
+ return (await stat(file)).isDirectory();
216
+ } catch {
217
+ return false;
218
+ }
219
+ }
220
+ function createTailwindV4DefaultIgnoreSources(base) {
221
+ return [
222
+ ...TAILWIND_V4_IGNORED_CONTENT_DIRS.map((pattern) => ({
223
+ base,
224
+ pattern: `**/${pattern}/**`,
225
+ negated: true
226
+ })),
227
+ ...TAILWIND_V4_IGNORED_EXTENSIONS.map((extension) => ({
228
+ base,
229
+ pattern: `**/*.${extension}`,
230
+ negated: true
231
+ })),
232
+ ...TAILWIND_V4_IGNORED_FILES.map((pattern) => ({
233
+ base,
234
+ pattern: `**/${pattern}`,
235
+ negated: true
236
+ }))
237
+ ];
238
+ }
239
+ function createTailwindV4RootSources(root, fallbackBase) {
240
+ if (root === "none") return [];
241
+ if (root === null) return [{
242
+ base: fallbackBase,
243
+ pattern: TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN,
244
+ negated: false
245
+ }];
246
+ return [{
247
+ ...root,
248
+ negated: false
249
+ }];
250
+ }
251
+ function createTailwindV4CompiledSourceEntries(root, sources, fallbackBase) {
252
+ return [...createTailwindV4RootSources(root, fallbackBase), ...sources];
253
+ }
254
+ async function resolveTailwindV4SourceEntry(sourcePath, base, negated, defaultPattern = TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN) {
255
+ const absoluteSource = path.isAbsolute(sourcePath) ? path.resolve(sourcePath) : path.resolve(base, sourcePath);
256
+ if (await pathExistsAsDirectory(absoluteSource)) return {
257
+ base: absoluteSource,
258
+ negated,
259
+ pattern: normalizeGlobPattern(defaultPattern)
260
+ };
261
+ if (path.isAbsolute(sourcePath)) return {
262
+ base: path.dirname(absoluteSource),
263
+ negated,
264
+ pattern: normalizeGlobPattern(path.basename(absoluteSource))
265
+ };
266
+ const { prefix, rest } = splitStaticGlobPrefix(sourcePath);
267
+ if (prefix.length > 0 && rest.length > 0) return {
268
+ base: path.resolve(base, ...prefix),
269
+ negated,
270
+ pattern: normalizeGlobPattern(rest.join("/"))
271
+ };
272
+ return {
273
+ base,
274
+ negated,
275
+ pattern: normalizeGlobPattern(sourcePath)
276
+ };
277
+ }
278
+ async function normalizeTailwindV4SourceEntries(sources, options = {}) {
279
+ const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
280
+ return Promise.all(sources.map((source) => resolveTailwindV4SourceEntry(source.pattern, source.base ? path.resolve(source.base) : cwd, source.negated, options.defaultPattern)));
281
+ }
282
+ function expandBracePattern(pattern) {
283
+ const index = pattern.indexOf("{");
284
+ if (index === -1) return [pattern];
285
+ const rest = pattern.slice(index);
286
+ let depth = 0;
287
+ let endIndex = -1;
288
+ for (let i = 0; i < rest.length; i++) {
289
+ const char = rest[i];
290
+ if (char === "\\") {
291
+ i += 1;
292
+ continue;
293
+ }
294
+ if (char === "{") {
295
+ depth += 1;
296
+ continue;
297
+ }
298
+ if (char === "}") {
299
+ depth -= 1;
300
+ if (depth === 0) {
301
+ endIndex = i;
302
+ break;
303
+ }
304
+ }
305
+ }
306
+ if (endIndex === -1) return [pattern];
307
+ const prefix = pattern.slice(0, index);
308
+ const inner = rest.slice(1, endIndex);
309
+ const suffix = rest.slice(endIndex + 1);
310
+ const parts = [];
311
+ const stack = [];
312
+ let lastPos = 0;
313
+ for (let i = 0; i < inner.length; i++) {
314
+ const char = inner[i];
315
+ if (char === "\\") {
316
+ i += 1;
317
+ continue;
318
+ }
319
+ if (char === "{") {
320
+ stack.push("}");
321
+ continue;
322
+ }
323
+ if (char === "}" && stack[stack.length - 1] === "}") {
324
+ stack.pop();
325
+ continue;
326
+ }
327
+ if (char === "," && stack.length === 0) {
328
+ parts.push(inner.slice(lastPos, i));
329
+ lastPos = i + 1;
330
+ }
331
+ }
332
+ parts.push(inner.slice(lastPos));
333
+ return parts.flatMap((part) => expandBracePattern(`${prefix}${part}${suffix}`));
334
+ }
335
+ function expandTailwindV4SourceEntryBraces(sources) {
336
+ return sources.flatMap((source) => {
337
+ const base = path.resolve(source.base);
338
+ return expandBracePattern(source.pattern).map((pattern) => ({
339
+ base,
340
+ pattern,
341
+ negated: source.negated
342
+ }));
343
+ });
344
+ }
345
+ function normalizeTailwindV4ScannerSources(sources, cwd, ignoredSources = []) {
346
+ return expandTailwindV4SourceEntryBraces([...sources?.length ? sources : [{
347
+ base: cwd,
348
+ pattern: TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN,
349
+ negated: false
350
+ }], ...ignoredSources]);
351
+ }
352
+ function resolveTailwindV4SourceBaseCandidates(projectRoot, base, baseFallbacks) {
353
+ return uniqueResolvedPaths([
354
+ base,
355
+ projectRoot,
356
+ ...baseFallbacks
357
+ ]);
358
+ }
359
+ //#endregion
360
+ //#region src/v4/source-scan/matcher.ts
361
+ function normalizeEntryPattern(entry) {
362
+ return path.isAbsolute(entry.pattern) ? toPosixPath(path.relative(resolveSourceScanPath(entry.base), entry.pattern)) : normalizeGlobPattern(entry.pattern);
363
+ }
364
+ function isFileMatchedByTailwindV4SourceEntry(file, entry) {
365
+ const relative = toPosixPath(path.relative(resolveSourceScanPath(entry.base), file));
366
+ return Boolean(relative) && !relative.startsWith("../") && !path.isAbsolute(relative) && micromatch.isMatch(relative, normalizeEntryPattern(entry));
367
+ }
368
+ function isFileExcludedByTailwindV4SourceEntries(file, entries) {
369
+ if (!entries?.length) return false;
370
+ const resolvedFile = resolveSourceScanPath(file);
371
+ return entries.some((entry) => entry.negated && isFileMatchedByTailwindV4SourceEntry(resolvedFile, entry));
372
+ }
373
+ function isFileMatchedByTailwindV4SourceEntries(file, entries) {
374
+ if (!entries?.length) return true;
375
+ const positiveEntries = entries.filter((entry) => !entry.negated);
376
+ const negativeEntries = entries.filter((entry) => entry.negated);
377
+ if (positiveEntries.length === 0) return false;
378
+ const resolvedFile = resolveSourceScanPath(file);
379
+ if (!positiveEntries.some((entry) => isFileMatchedByTailwindV4SourceEntry(resolvedFile, entry))) return false;
380
+ return !negativeEntries.some((entry) => isFileMatchedByTailwindV4SourceEntry(resolvedFile, entry));
381
+ }
382
+ function createTailwindV4SourceEntryMatcher(entries) {
383
+ if (!entries?.length) return;
384
+ return (file) => isFileMatchedByTailwindV4SourceEntries(file, entries);
385
+ }
386
+ function createTailwindV4SourceExclusionMatcher(entries) {
387
+ if (!entries?.length) return;
388
+ return (file) => isFileExcludedByTailwindV4SourceEntries(file, entries);
389
+ }
390
+ function groupTailwindV4SourceEntriesByBase(entries) {
391
+ const entriesByBase = /* @__PURE__ */ new Map();
392
+ for (const entry of entries) {
393
+ const base = path.resolve(entry.base);
394
+ const group = entriesByBase.get(base) ?? [];
395
+ group.push({
396
+ ...entry,
397
+ base,
398
+ pattern: normalizeGlobPattern(entry.pattern)
399
+ });
400
+ entriesByBase.set(base, group);
401
+ }
402
+ return entriesByBase;
403
+ }
404
+ async function expandTailwindV4SourceEntries(entries, resolveFiles) {
405
+ if (entries.length === 0) return [];
406
+ const files = /* @__PURE__ */ new Set();
407
+ await Promise.all([...groupTailwindV4SourceEntriesByBase(entries).entries()].map(async ([base, group]) => {
408
+ const matched = await resolveFiles({
409
+ cwd: base,
410
+ sources: group
411
+ });
412
+ for (const file of matched) files.add(path.resolve(file));
413
+ }));
414
+ return [...files].filter((file) => !isFileExcludedByTailwindV4SourceEntries(file, entries));
415
+ }
416
+ function mergeTailwindV4SourceEntries(...entries) {
417
+ const result = [];
418
+ const seen = /* @__PURE__ */ new Set();
419
+ for (const group of entries) for (const entry of group ?? []) {
420
+ const normalized = {
421
+ base: path.resolve(entry.base),
422
+ pattern: normalizeGlobPattern(entry.pattern),
423
+ negated: entry.negated
424
+ };
425
+ const key = JSON.stringify(normalized);
426
+ if (seen.has(key)) continue;
427
+ seen.add(key);
428
+ result.push(normalized);
429
+ }
430
+ return result;
431
+ }
432
+ //#endregion
433
+ //#region src/extraction/oxide.ts
434
+ let oxideImportPromise;
435
+ function createOxideRuntimeDependencyError(cause) {
436
+ return new Error([
437
+ "@weapp-tailwindcss/engine could not load @tailwindcss/oxide, which is required for source candidate scanning.",
438
+ "This dependency should be installed automatically by @weapp-tailwindcss/engine.",
439
+ "Reinstall dependencies without disabling optional dependencies, or install @tailwindcss/oxide@^4.3.3 manually if your package manager omitted it."
440
+ ].join(" "), { cause });
441
+ }
442
+ async function importOxide() {
443
+ try {
444
+ return await import("@tailwindcss/oxide");
445
+ } catch (error) {
446
+ throw createOxideRuntimeDependencyError(error);
447
+ }
448
+ }
449
+ function getOxideModule() {
450
+ oxideImportPromise ??= importOxide();
451
+ oxideImportPromise.catch(() => {
452
+ oxideImportPromise = void 0;
453
+ });
454
+ return oxideImportPromise;
455
+ }
456
+ //#endregion
457
+ //#region src/extraction/project-report.ts
458
+ function buildLineOffsets(content) {
459
+ const offsets = [0];
460
+ for (let i = 0; i < content.length; i++) if (content[i] === "\n") offsets.push(i + 1);
461
+ if (offsets[offsets.length - 1] !== content.length) offsets.push(content.length);
462
+ return offsets;
463
+ }
464
+ function resolveLineMeta(content, offsets, index) {
465
+ let low = 0;
466
+ let high = offsets.length - 1;
467
+ while (low <= high) {
468
+ const mid = Math.floor((low + high) / 2);
469
+ const start = offsets[mid];
470
+ if (start === void 0) break;
471
+ const nextStart = offsets[mid + 1] ?? content.length;
472
+ if (index < start) {
473
+ high = mid - 1;
474
+ continue;
475
+ }
476
+ if (index >= nextStart) {
477
+ low = mid + 1;
478
+ continue;
479
+ }
480
+ const line = mid + 1;
481
+ const column = index - start + 1;
482
+ const lineEnd = content.indexOf("\n", start);
483
+ return {
484
+ line,
485
+ column,
486
+ lineText: content.slice(start, lineEnd === -1 ? content.length : lineEnd)
487
+ };
488
+ }
489
+ const lastStart = offsets[offsets.length - 2] ?? 0;
490
+ return {
491
+ line: offsets.length - 1,
492
+ column: index - lastStart + 1,
493
+ lineText: content.slice(lastStart)
494
+ };
495
+ }
496
+ function toExtension(filename) {
497
+ return path.extname(filename).replace(/^\./, "") || "txt";
498
+ }
499
+ function toRelativeFile(cwd, filename) {
500
+ const relative = path.relative(cwd, filename).replaceAll(path.sep, "/");
501
+ return relative === "" ? path.basename(filename) : relative;
502
+ }
503
+ function createTokenLocation(input) {
504
+ const info = resolveLineMeta(input.content, input.offsets, input.position);
505
+ const relativeFile = toRelativeFile(input.cwd, input.file);
506
+ return {
507
+ rawCandidate: input.candidate,
508
+ file: input.file,
509
+ relativeFile,
510
+ extension: input.extension,
511
+ start: input.position,
512
+ end: input.position + input.candidate.length,
513
+ length: input.candidate.length,
514
+ line: info.line,
515
+ column: info.column,
516
+ lineText: info.lineText
517
+ };
518
+ }
519
+ //#endregion
520
+ //#region src/v4/bare-arbitrary-values/escape.ts
521
+ function escapeCssClassName(value) {
522
+ let result = "";
523
+ for (let index = 0; index < value.length; index++) {
524
+ const codeUnit = value.charCodeAt(index);
525
+ const character = value.charAt(index);
526
+ if (codeUnit === 0) {
527
+ result += "�";
528
+ continue;
529
+ }
530
+ if (codeUnit >= 1 && codeUnit <= 31 || codeUnit === 127 || index === 0 && codeUnit >= 48 && codeUnit <= 57 || index === 1 && codeUnit >= 48 && codeUnit <= 57 && value.charCodeAt(0) === 45) {
531
+ result += `\\${codeUnit.toString(16)} `;
532
+ continue;
533
+ }
534
+ if (codeUnit >= 128 || codeUnit === 45 || codeUnit === 95 || codeUnit >= 48 && codeUnit <= 57 || codeUnit >= 65 && codeUnit <= 90 || codeUnit >= 97 && codeUnit <= 122) {
535
+ result += character;
536
+ continue;
537
+ }
538
+ result += `\\${character}`;
539
+ }
540
+ return result;
541
+ }
542
+ //#endregion
543
+ //#region src/v4/bare-arbitrary-values/syntax.ts
544
+ const HEX_ESCAPE_RE = /^[\da-f]$/i;
545
+ function splitVariantPrefix(candidate) {
546
+ let depth = 0;
547
+ let quote;
548
+ let lastSeparator = -1;
549
+ for (let index = 0; index < candidate.length; index++) {
550
+ const character = candidate[index];
551
+ if (character === "\\") {
552
+ index++;
553
+ continue;
554
+ }
555
+ if (quote) {
556
+ if (character === quote) quote = void 0;
557
+ continue;
558
+ }
559
+ if (character === "\"" || character === "'") {
560
+ quote = character;
561
+ continue;
562
+ }
563
+ if (character === "[" || character === "(" || character === "{") {
564
+ depth++;
565
+ continue;
566
+ }
567
+ if (character === "]" || character === ")" || character === "}") {
568
+ depth = Math.max(0, depth - 1);
569
+ continue;
570
+ }
571
+ if (depth === 0 && character === ":") lastSeparator = index;
572
+ }
573
+ if (lastSeparator === -1) return {
574
+ prefix: "",
575
+ body: candidate
576
+ };
577
+ return {
578
+ prefix: candidate.slice(0, lastSeparator + 1),
579
+ body: candidate.slice(lastSeparator + 1)
580
+ };
581
+ }
582
+ function isBalancedFunctionValue(value) {
583
+ let depth = 0;
584
+ let quote;
585
+ for (let index = 0; index < value.length; index++) {
586
+ const character = value[index];
587
+ if (character === "\\") {
588
+ index++;
589
+ continue;
590
+ }
591
+ if (quote) {
592
+ if (character === quote) quote = void 0;
593
+ continue;
594
+ }
595
+ if (character === "\"" || character === "'") {
596
+ quote = character;
597
+ continue;
598
+ }
599
+ if (character === "(") {
600
+ depth++;
601
+ continue;
602
+ }
603
+ if (character === ")") {
604
+ depth--;
605
+ if (depth < 0) return false;
606
+ }
607
+ }
608
+ return depth === 0 && quote === void 0;
609
+ }
610
+ function isEscapedAt(value, index) {
611
+ let slashCount = 0;
612
+ for (let slashIndex = index - 1; slashIndex >= 0 && value[slashIndex] === "\\"; slashIndex--) slashCount++;
613
+ return slashCount % 2 === 1;
614
+ }
615
+ function isBalancedBareArbitraryBody(value) {
616
+ let depth = 0;
617
+ let quote;
618
+ for (let index = 0; index < value.length; index++) {
619
+ const character = value[index];
620
+ if (isEscapedAt(value, index)) continue;
621
+ if (quote) {
622
+ if (character === quote) quote = void 0;
623
+ continue;
624
+ }
625
+ if (character === "\"" || character === "'") {
626
+ quote = character;
627
+ continue;
628
+ }
629
+ if (character === "(" || character === "{") {
630
+ depth++;
631
+ continue;
632
+ }
633
+ if (character === ")" || character === "}") {
634
+ depth--;
635
+ if (depth < 0) return false;
636
+ }
637
+ }
638
+ return depth === 0 && quote === void 0;
639
+ }
640
+ function isHexColorValue(value) {
641
+ return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6,8})$/i.test(value);
642
+ }
643
+ function isQuotedValue(value) {
644
+ const quote = value[0];
645
+ if (quote !== "\"" && quote !== "'" || value[value.length - 1] !== quote) return false;
646
+ let escaped = false;
647
+ for (let index = 1; index < value.length - 1; index++) {
648
+ const character = value[index];
649
+ if (escaped) {
650
+ escaped = false;
651
+ continue;
652
+ }
653
+ if (character === "\\") escaped = true;
654
+ }
655
+ return !escaped;
656
+ }
657
+ function normalizeEscapedValue(value) {
658
+ let result = "";
659
+ for (let index = 0; index < value.length; index++) {
660
+ const character = value[index];
661
+ if (character !== "\\") {
662
+ result += character;
663
+ continue;
664
+ }
665
+ const nextCharacter = value[index + 1];
666
+ if (nextCharacter === void 0) {
667
+ result += character;
668
+ continue;
669
+ }
670
+ if (HEX_ESCAPE_RE.test(nextCharacter)) {
671
+ let hex = "";
672
+ let nextIndex = index + 1;
673
+ while (nextIndex < value.length && hex.length < 6) {
674
+ const hexCharacter = value[nextIndex];
675
+ if (hexCharacter === void 0 || !HEX_ESCAPE_RE.test(hexCharacter)) break;
676
+ hex += hexCharacter;
677
+ nextIndex++;
678
+ }
679
+ if (/[\t\n\f\r ]/.test(value[nextIndex] ?? "")) nextIndex++;
680
+ const decoded = String.fromCodePoint(Number.parseInt(hex, 16));
681
+ result += decoded === "_" ? "\\_" : decoded;
682
+ index = nextIndex - 1;
683
+ continue;
684
+ }
685
+ result += nextCharacter === "_" ? "\\_" : nextCharacter;
686
+ index++;
687
+ }
688
+ return result;
689
+ }
690
+ //#endregion
691
+ //#region src/v4/bare-arbitrary-values/resolve.ts
692
+ const DEFAULT_BARE_ARBITRARY_VALUE_UNITS = [
693
+ "%",
694
+ "px",
695
+ "rpx",
696
+ "rem",
697
+ "em",
698
+ "vw",
699
+ "vh",
700
+ "vmin",
701
+ "vmax",
702
+ "dvw",
703
+ "dvh",
704
+ "svw",
705
+ "svh",
706
+ "lvw",
707
+ "lvh",
708
+ "ch",
709
+ "ex",
710
+ "lh",
711
+ "rlh",
712
+ "fr",
713
+ "deg",
714
+ "rad",
715
+ "turn",
716
+ "s",
717
+ "ms"
718
+ ];
719
+ const NUMBER_RE = /^-?(?:\d+|\d*\.\d+)$/;
720
+ const FUNCTION_VALUE_RE = /^[a-z_-][\w-]*\(/i;
721
+ const ASPECT_RATIO_RE = /^\d+\/\d+$/;
722
+ function normalizeBareArbitraryValueOptions(options) {
723
+ if (options === false || options === void 0 || options === null) return;
724
+ const units = options === true ? DEFAULT_BARE_ARBITRARY_VALUE_UNITS : options.units ?? DEFAULT_BARE_ARBITRARY_VALUE_UNITS;
725
+ const normalizedUnits = [...new Set(units.filter((unit) => typeof unit === "string" && unit.length > 0))];
726
+ if (normalizedUnits.length === 0) return;
727
+ return { units: normalizedUnits.sort((a, b) => b.length - a.length) };
728
+ }
729
+ function isBareArbitraryValuesEnabled(options) {
730
+ return normalizeBareArbitraryValueOptions(options) !== void 0;
731
+ }
732
+ function resolveValueWithUnit(body, units) {
733
+ const value = normalizeEscapedValue(body);
734
+ for (const unit of units) {
735
+ if (!value.endsWith(unit)) continue;
736
+ const numberPart = value.slice(0, -unit.length);
737
+ if (NUMBER_RE.test(numberPart)) return `${numberPart}${unit}`;
738
+ }
739
+ }
740
+ function resolveArbitraryValue(utility, body, units) {
741
+ const value = normalizeEscapedValue(body);
742
+ const withUnit = resolveValueWithUnit(value, units);
743
+ if (withUnit) return withUnit;
744
+ if (utility === "aspect" && ASPECT_RATIO_RE.test(value)) return value;
745
+ if (isHexColorValue(value)) return value;
746
+ if (isQuotedValue(value)) return value;
747
+ if (FUNCTION_VALUE_RE.test(value) && value.endsWith(")") && isBalancedFunctionValue(value)) {
748
+ if (utility === "text" && /^var\(/i.test(value)) return `color:${value}`;
749
+ return value;
750
+ }
751
+ }
752
+ function resolveUtilityAndValue(body, units) {
753
+ let depth = 0;
754
+ let quote;
755
+ for (let index = body.length - 1; index > 0; index--) {
756
+ const character = body[index];
757
+ if (isEscapedAt(body, index)) continue;
758
+ if (quote) {
759
+ if (character === quote) quote = void 0;
760
+ continue;
761
+ }
762
+ if (character === "\"" || character === "'") {
763
+ quote = character;
764
+ continue;
765
+ }
766
+ if (character === ")" || character === "}") {
767
+ depth++;
768
+ continue;
769
+ }
770
+ if (character === "(" || character === "{") {
771
+ depth = Math.max(0, depth - 1);
772
+ continue;
773
+ }
774
+ if (depth > 0 || character !== "-") continue;
775
+ const utility = body.slice(0, index);
776
+ const rawValue = body.slice(index + 1);
777
+ if (!utility || !rawValue) continue;
778
+ const value = resolveArbitraryValue(utility, rawValue, units);
779
+ if (value) return {
780
+ utility,
781
+ value
782
+ };
783
+ }
784
+ }
785
+ function resolveBareArbitraryValueCandidate(candidate, options) {
786
+ const normalizedOptions = normalizeBareArbitraryValueOptions(options);
787
+ if (!normalizedOptions || !candidate || candidate.includes("[") || candidate.includes("]")) return;
788
+ const { prefix, body } = splitVariantPrefix(candidate);
789
+ const important = body.startsWith("!") ? "!" : "";
790
+ let normalizedBody = important ? body.slice(1) : body;
791
+ const negative = normalizedBody.startsWith("-") ? "-" : "";
792
+ if (negative) normalizedBody = normalizedBody.slice(1);
793
+ if (!isBalancedBareArbitraryBody(normalizedBody)) return;
794
+ const resolved = resolveUtilityAndValue(normalizedBody, normalizedOptions.units);
795
+ if (!resolved) return;
796
+ return {
797
+ candidate,
798
+ canonicalCandidate: `${prefix}${important}${negative}${resolved.utility}-[${resolved.value}]`
799
+ };
800
+ }
801
+ //#endregion
802
+ //#region src/v4/bare-arbitrary-values/extract.ts
803
+ const ESCAPED_WHITESPACE_RE = /\\[nrt]/g;
804
+ function isBareArbitrarySourceSplitter(char) {
805
+ return /\s/.test(char);
806
+ }
807
+ function isQuoteBoundary(content, start, index) {
808
+ const tokenPrefix = content.slice(start, index);
809
+ return tokenPrefix.length === 0 || !tokenPrefix.endsWith("-");
810
+ }
811
+ function trimBareArbitrarySourceToken(token, start) {
812
+ let nextToken = token;
813
+ let nextStart = start;
814
+ while (nextToken.length > 0 && /^[<{([]$/.test(nextToken[0])) {
815
+ nextToken = nextToken.slice(1);
816
+ nextStart++;
817
+ }
818
+ while (nextToken.length > 0 && /^[>\],;]$/.test(nextToken[nextToken.length - 1])) nextToken = nextToken.slice(0, -1);
819
+ return {
820
+ token: nextToken,
821
+ start: nextStart
822
+ };
823
+ }
824
+ function pushBareArbitrarySourceCandidate(result, token, start, options) {
825
+ const trimmed = trimBareArbitrarySourceToken(token, start);
826
+ if (!trimmed.token || trimmed.token.includes("=") || trimmed.token.includes("[") || trimmed.token.includes("]")) return;
827
+ if (!resolveBareArbitraryValueCandidate(trimmed.token, options)) return;
828
+ result.push({
829
+ rawCandidate: trimmed.token,
830
+ start: trimmed.start,
831
+ end: trimmed.start + trimmed.token.length
832
+ });
833
+ }
834
+ function extractBareArbitraryValueSourceCandidatesWithPositions(content, options) {
835
+ if (!isBareArbitraryValuesEnabled(options)) return [];
836
+ const normalized = content.includes("\\") ? content.replace(ESCAPED_WHITESPACE_RE, " ") : content;
837
+ const result = [];
838
+ let depth = 0;
839
+ let quote;
840
+ let start = 0;
841
+ for (let index = 0; index < normalized.length; index++) {
842
+ const char = normalized[index];
843
+ if (char === void 0) continue;
844
+ if (char === "\\") {
845
+ index++;
846
+ continue;
847
+ }
848
+ if (quote) {
849
+ if (char === quote) quote = void 0;
850
+ } else if ((char === "\"" || char === "'" || char === "`") && !isQuoteBoundary(normalized, start, index)) quote = char;
851
+ else if (char === "(" || char === "{" || char === "[") depth++;
852
+ else if (char === ")" || char === "}" || char === "]") depth = Math.max(0, depth - 1);
853
+ if (!isBareArbitrarySourceSplitter(char) && !((char === "\"" || char === "'" || char === "`") && depth === 0 && isQuoteBoundary(normalized, start, index))) continue;
854
+ pushBareArbitrarySourceCandidate(result, normalized.slice(start, index), start, options);
855
+ start = index + 1;
856
+ }
857
+ pushBareArbitrarySourceCandidate(result, normalized.slice(start), start, options);
858
+ return result;
859
+ }
860
+ function extractBareArbitraryValueSourceCandidates(content, options) {
861
+ return [...new Set(extractBareArbitraryValueSourceCandidatesWithPositions(content, options).map((candidate) => candidate.rawCandidate))];
862
+ }
863
+ //#endregion
864
+ //#region src/extraction/segments.ts
865
+ function createBareArbitraryValueCandidateContexts(content, extension, offset, options) {
866
+ return extractBareArbitraryValueSourceCandidatesWithPositions(content, options?.bareArbitraryValues).map((candidate) => ({
867
+ content,
868
+ extension,
869
+ localStart: candidate.start,
870
+ rawCandidate: candidate.rawCandidate,
871
+ start: candidate.start + offset,
872
+ end: candidate.end + offset
873
+ }));
874
+ }
875
+ function joinSourceSegments(segments) {
876
+ const joinedSegments = [];
877
+ const parts = [];
878
+ let joinedStart = 0;
879
+ for (const segment of segments) {
880
+ if (parts.length > 0) {
881
+ parts.push("\n");
882
+ joinedStart++;
883
+ }
884
+ parts.push(segment.content);
885
+ joinedSegments.push({
886
+ ...segment,
887
+ joinedStart
888
+ });
889
+ joinedStart += segment.content.length;
890
+ }
891
+ return {
892
+ content: parts.join(""),
893
+ segments: joinedSegments
894
+ };
895
+ }
896
+ function findJoinedSourceSegment(segments, start) {
897
+ let low = 0;
898
+ let high = segments.length - 1;
899
+ while (low <= high) {
900
+ const mid = Math.floor((low + high) / 2);
901
+ const segment = segments[mid];
902
+ if (segment === void 0) break;
903
+ if (start < segment.joinedStart) {
904
+ high = mid - 1;
905
+ continue;
906
+ }
907
+ if (start >= segment.joinedStart + segment.content.length) {
908
+ low = mid + 1;
909
+ continue;
910
+ }
911
+ return segment;
912
+ }
913
+ }
914
+ async function extractBatchedSourceSegmentCandidates(segments, extension, extractRawCandidatesWithPositions, options) {
915
+ if (segments.length === 0) return [];
916
+ const joined = joinSourceSegments(segments);
917
+ const rawCandidates = await extractRawCandidatesWithPositions(joined.content, extension, options);
918
+ const candidates = [];
919
+ for (const candidate of rawCandidates) {
920
+ const segment = findJoinedSourceSegment(joined.segments, candidate.start);
921
+ if (segment === void 0 || candidate.end > segment.joinedStart + segment.content.length) continue;
922
+ const segmentOffset = candidate.start - segment.joinedStart;
923
+ candidates.push({
924
+ content: joined.content,
925
+ extension,
926
+ localStart: candidate.start,
927
+ rawCandidate: candidate.rawCandidate,
928
+ skipHtmlContextChecks: true,
929
+ start: segment.start + segmentOffset,
930
+ end: segment.start + segmentOffset + candidate.rawCandidate.length
931
+ });
932
+ }
933
+ return candidates;
934
+ }
935
+ //#endregion
936
+ //#region src/extraction/css.ts
937
+ const CSS_APPLY_RE = /@apply\s+([^;{}]+)/g;
938
+ async function extractCssApplyCandidates(content, extension, extractRawCandidatesWithPositions, options) {
939
+ const candidates = [];
940
+ CSS_APPLY_RE.lastIndex = 0;
941
+ let match = CSS_APPLY_RE.exec(content);
942
+ while (match !== null) {
943
+ const applyParams = match[1] ?? "";
944
+ const applyParamsStart = match.index + match[0].indexOf(applyParams);
945
+ const applyCandidates = await extractRawCandidatesWithPositions(applyParams, extension);
946
+ candidates.push(...applyCandidates.map((candidate) => ({
947
+ content: applyParams,
948
+ extension: "html",
949
+ localStart: candidate.start,
950
+ rawCandidate: candidate.rawCandidate,
951
+ skipHtmlContextChecks: true,
952
+ start: candidate.start + applyParamsStart,
953
+ end: candidate.end + applyParamsStart
954
+ })));
955
+ candidates.push(...createBareArbitraryValueCandidateContexts(applyParams, "html", applyParamsStart, options));
956
+ match = CSS_APPLY_RE.exec(content);
957
+ }
958
+ return candidates;
959
+ }
960
+ //#endregion
961
+ //#region src/extraction/js-string-ranges.ts
962
+ function skipQuotedJsContent(content, index, quote) {
963
+ index++;
964
+ while (index < content.length) {
965
+ const char = content[index];
966
+ if (char === "\\") {
967
+ index += 2;
968
+ continue;
969
+ }
970
+ if (char === quote) return index + 1;
971
+ index++;
972
+ }
973
+ return index;
974
+ }
975
+ function createJsStringStaticRanges(content) {
976
+ const ranges = [];
977
+ let quote;
978
+ let stringStart = -1;
979
+ let templateExpressionDepth = 0;
980
+ for (let index = 0; index < content.length; index++) {
981
+ const char = content[index];
982
+ const next = content[index + 1];
983
+ if (quote && char === "\\") {
984
+ index++;
985
+ continue;
986
+ }
987
+ if (quote === "`" && templateExpressionDepth > 0) {
988
+ if (char === "\"" || char === "'") {
989
+ index = skipQuotedJsContent(content, index, char) - 1;
990
+ continue;
991
+ }
992
+ if (char === "`") {
993
+ index = skipQuotedJsContent(content, index, "`") - 1;
994
+ continue;
995
+ }
996
+ if (char === "{") {
997
+ templateExpressionDepth++;
998
+ continue;
999
+ }
1000
+ if (char === "}") {
1001
+ templateExpressionDepth--;
1002
+ continue;
1003
+ }
1004
+ continue;
1005
+ }
1006
+ if (quote) {
1007
+ if (quote === "`" && char === "$" && next === "{") {
1008
+ ranges.push({
1009
+ start: stringStart,
1010
+ end: index
1011
+ });
1012
+ templateExpressionDepth = 1;
1013
+ index++;
1014
+ continue;
1015
+ }
1016
+ if (char === quote) {
1017
+ ranges.push({
1018
+ start: stringStart,
1019
+ end: index
1020
+ });
1021
+ quote = void 0;
1022
+ stringStart = -1;
1023
+ }
1024
+ continue;
1025
+ }
1026
+ if (char === "\"" || char === "'" || char === "`") {
1027
+ quote = char;
1028
+ stringStart = index + 1;
1029
+ }
1030
+ }
1031
+ if (quote !== void 0 && templateExpressionDepth === 0) ranges.push({
1032
+ start: stringStart,
1033
+ end: content.length
1034
+ });
1035
+ return ranges;
1036
+ }
1037
+ function isCandidateInsideJsStringStaticRanges(ranges, start) {
1038
+ let low = 0;
1039
+ let high = ranges.length - 1;
1040
+ while (low <= high) {
1041
+ const mid = Math.floor((low + high) / 2);
1042
+ const range = ranges[mid];
1043
+ if (range === void 0) break;
1044
+ if (start < range.start) {
1045
+ high = mid - 1;
1046
+ continue;
1047
+ }
1048
+ if (start >= range.end) {
1049
+ low = mid + 1;
1050
+ continue;
1051
+ }
1052
+ return true;
1053
+ }
1054
+ return false;
1055
+ }
1056
+ function createJsStringSourceSegments(content, offset) {
1057
+ return createJsStringStaticRanges(content).filter((range) => range.end > range.start).map((range) => ({
1058
+ content: content.slice(range.start, range.end),
1059
+ start: offset + range.start
1060
+ }));
1061
+ }
1062
+ //#endregion
1063
+ //#region src/extraction/raw-candidate-cache.ts
1064
+ const DEFAULT_RAW_CANDIDATE_CACHE_LIMIT = 64;
1065
+ function resolveRawCandidateCacheLimit(rawLimit) {
1066
+ if (rawLimit === void 0) return DEFAULT_RAW_CANDIDATE_CACHE_LIMIT;
1067
+ const limit = Number.parseInt(rawLimit, 10);
1068
+ return Number.isFinite(limit) && limit > 0 ? limit : DEFAULT_RAW_CANDIDATE_CACHE_LIMIT;
1069
+ }
1070
+ const RAW_CANDIDATE_CACHE_LIMIT = resolveRawCandidateCacheLimit(process.env["TWM_ENGINE_RAW_CANDIDATE_CACHE_LIMIT"]);
1071
+ const rawCandidateCache = /* @__PURE__ */ new Map();
1072
+ function createRawCandidateCacheKey(sources, options) {
1073
+ return JSON.stringify({
1074
+ sources: sources ?? null,
1075
+ bareArbitraryValues: options?.bareArbitraryValues ?? null
1076
+ });
1077
+ }
1078
+ async function createRawCandidateFileFingerprint(files) {
1079
+ if (!files?.length) return "";
1080
+ return (await Promise.all(files.map(async (file) => {
1081
+ try {
1082
+ const stats = await promises.stat(file);
1083
+ return `${file}:${stats.size}:${stats.mtimeMs}`;
1084
+ } catch {
1085
+ return `${file}:missing`;
1086
+ }
1087
+ }))).sort().join("|");
1088
+ }
1089
+ function getRawCandidateCacheEntry(cacheKey, fingerprint) {
1090
+ const cached = rawCandidateCache.get(cacheKey);
1091
+ if (cached?.fingerprint !== fingerprint) return;
1092
+ rawCandidateCache.delete(cacheKey);
1093
+ rawCandidateCache.set(cacheKey, cached);
1094
+ return cached;
1095
+ }
1096
+ function setRawCandidateCacheEntry(cacheKey, fingerprint, candidates) {
1097
+ rawCandidateCache.set(cacheKey, {
1098
+ fingerprint,
1099
+ candidates
1100
+ });
1101
+ while (rawCandidateCache.size > RAW_CANDIDATE_CACHE_LIMIT) {
1102
+ const oldestKey = rawCandidateCache.keys().next().value;
1103
+ if (oldestKey === void 0) break;
1104
+ rawCandidateCache.delete(oldestKey);
1105
+ }
1106
+ }
1107
+ //#endregion
1108
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/decode-codepoint.js
1109
+ const decodeMap = /* @__PURE__ */ new Map([
1110
+ [0, 65533],
1111
+ [128, 8364],
1112
+ [130, 8218],
1113
+ [131, 402],
1114
+ [132, 8222],
1115
+ [133, 8230],
1116
+ [134, 8224],
1117
+ [135, 8225],
1118
+ [136, 710],
1119
+ [137, 8240],
1120
+ [138, 352],
1121
+ [139, 8249],
1122
+ [140, 338],
1123
+ [142, 381],
1124
+ [145, 8216],
1125
+ [146, 8217],
1126
+ [147, 8220],
1127
+ [148, 8221],
1128
+ [149, 8226],
1129
+ [150, 8211],
1130
+ [151, 8212],
1131
+ [152, 732],
1132
+ [153, 8482],
1133
+ [154, 353],
1134
+ [155, 8250],
1135
+ [156, 339],
1136
+ [158, 382],
1137
+ [159, 376]
1138
+ ]);
1139
+ /**
1140
+ * Replace the given code point with a replacement character if it is a
1141
+ * surrogate or is outside the valid range. Otherwise return the code
1142
+ * point unchanged.
1143
+ * @param codePoint Unicode code point to convert.
1144
+ */
1145
+ function replaceCodePoint(codePoint) {
1146
+ if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) return 65533;
1147
+ return decodeMap.get(codePoint) ?? codePoint;
1148
+ }
1149
+ //#endregion
1150
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/internal/decode-shared.js
1151
+ /**
1152
+ * Shared base64 decode helper for generated decode data.
1153
+ * Assumes global atob is available.
1154
+ * @param input Input string to encode or decode.
1155
+ */
1156
+ function decodeBase64(input) {
1157
+ const binary = atob(input);
1158
+ const evenLength = binary.length & -2;
1159
+ const out = new Uint16Array(evenLength / 2);
1160
+ for (let index = 0, outIndex = 0; index < evenLength; index += 2) {
1161
+ const lo = binary.charCodeAt(index);
1162
+ const hi = binary.charCodeAt(index + 1);
1163
+ out[outIndex++] = lo | hi << 8;
1164
+ }
1165
+ return out;
1166
+ }
1167
+ //#endregion
1168
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/generated/decode-data-html.js
1169
+ /** Packed HTML decode trie data. */
1170
+ const htmlDecodeTree = /* #__PURE__ */ decodeBase64("QR08ALkAAgH6AYsDNQR2BO0EPgXZBQEGLAbdBxMISQrvCmQLfQurDKQNLw4fD4YPpA+6D/IPAAAAAAAAAAAAAAAAKhBMEY8TmxUWF2EYLBkxGuAa3RsJHDscWR8YIC8jSCSIJcMl6ie3Ku8rEC0CLjoupS7kLgAIRU1hYmNmZ2xtbm9wcnN0dVQAWgBeAGUAaQBzAHcAfgCBAIQAhwCSAJoAoACsALMAbABpAGcAO4DGAMZAUAA7gCYAJkBjAHUAdABlADuAwQDBQHIiZXZlAAJhAAFpeW0AcgByAGMAO4DCAMJAEGRyAADgNdgE3XIAYQB2AGUAO4DAAMBA8CFoYZFj4SFjcgBhZAAAoFMqAAFncIsAjgBvAG4ABGFmAADgNdg43fAlbHlGdW5jdGlvbgCgYSBpAG4AZwA7gMUAxUAAAWNzpACoAHIAAOA12Jzc6SFnbgCgVCJpAGwAZABlADuAwwDDQG0AbAA7gMQAxEAABGFjZWZvcnN1xQDYANoA7QDxAPYA+QD8AAABY3LJAM8AayNzbGFzaAAAoBYidgHTANUAAKDnKmUAZAAAoAYjeQARZIABY3J0AOAA5QDrAGEidXNlAACgNSLuI291bGxpcwCgLCFhAJJjcgAA4DXYBd1wAGYAAOA12Dnd5SF2ZdhiYwDyAOoAbSJwZXEAAKBOIgAHSE9hY2RlZmhpbG9yc3UXARoBHwE6AVIBVQFiAWQBZgGCAakB6QHtAfIBYwB5ACdkUABZADuAqQCpQIABY3B5ACUBKAE1AfUhdGUGYWmg0iJ0KGFsRGlmZmVyZW50aWFsRAAAoEUhbCJleXMAAKAtIQACYWVpb0EBRAFKAU0B8iFvbgxhZABpAGwAO4DHAMdAcgBjAAhhbiJpbnQAAKAwIm8AdAAKYQABZG5ZAV0BaSJsbGEAuGB0I2VyRG90ALdg8gA5AWkAp2NyImNsZQAAAkRNUFRwAXQBeQF9AW8AdAAAoJkiaSJudXMAAKCWIuwhdXMAoJUiaSJtZXMAAKCXIm8AAAFjc4cBlAFrKndpc2VDb250b3VySW50ZWdyYWwAAKAyImUjQ3VybHkAAAFEUZwBpAFvJXVibGVRdW90ZQAAoB0gdSJvdGUAAKAZIAACbG5wdbABtgHNAdgBbwBuAGWgNyIAoHQqgAFnaXQAvAHBAcUB8iJ1ZW50AKBhIm4AdAAAoC8i7yV1ckludGVncmFsAKAuIgABZnLRAdMBAKACIe8iZHVjdACgECJuLnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbAAAoDMi7yFzcwCgLypjAHIAAOA12J7ccABDoNMiYQBwAACgTSKABURKU1phY2VmaW9zAAsCEgIVAhgCGwIsAjQCOQI9AnMCfwNvoEUh9CJyYWhkAKARKWMAeQACZGMAeQAFZGMAeQAPZIABZ3JzACECJQIoAuchZXIAoCEgcgAAoKEhaAB2AACg5CoAAWF5MAIzAvIhb24OYRRkbAB0oAciYQCUY3IAAOA12AfdAAFhZkECawIAAWNtRQJnAvIjaXRpY2FsAAJBREdUUAJUAl8CYwJjInV0ZQC0YG8AdAFZAloC2WJiJGxlQWN1dGUA3WJyImF2ZQBgYGkibGRlANxi7yFuZACgxCJmJWVyZW50aWFsRAAAoEYhcAR9AgAAAAAAAIECjgIAABoDZgAA4DXYO91EoagAhQKJAm8AdAAAoNwgcSJ1YWwAAKBQIuIhbGUAA0NETFJVVpkCqAK1Au8C/wIRA28AbgB0AG8AdQByAEkAbgB0AGUAZwByAGEA7ADEAW8AdAKvAgAAAACwAqhgbiNBcnJvdwAAoNMhAAFlb7kC0AJmAHQAgAFBUlQAwQLGAs0CciJyb3cAAKDQIekkZ2h0QXJyb3cAoNQhZQDlACsCbgBnAAABTFLWAugC5SFmdAABQVLcAuECciJyb3cAAKD4J+kkZ2h0QXJyb3cAoPon6SRnaHRBcnJvdwCg+SdpImdodAAAAUFU9gL7AnIicm93AACg0iFlAGUAAKCoInAAQQIGAwAAAAALA3Iicm93AACg0SFvJHduQXJyb3cAAKDVIWUlcnRpY2FsQmFyAACgJSJuAAADQUJMUlRhJAM2AzoDWgNxA3oDciJyb3cAAKGTIUJVLAMwA2EAcgAAoBMpcCNBcnJvdwAAoPUhciJldmUAEWPlIWZ00gJDAwAASwMAAFIDaSVnaHRWZWN0b3IAAKBQKWUkZVZlY3RvcgAAoF4p5SJjdG9yQqC9IWEAcgAAoFYpaSJnaHQA1AFiAwAAaQNlJGVWZWN0b3IAAKBfKeUiY3RvckKgwSFhAHIAAKBXKWUAZQBBoKQiciJyb3cAAKCnIXIAcgBvAPcAtAIAAWN0gwOHA3IA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YwAAoN8i4SFycnCgtiEAoD0pgKIqImJjZG9zACsVMBU6FT4VQRVyImNhcAAAoEgqAAFhdTQVNxVwAACgRipwAACgSipvAHQAAKCNInIAAKBFKgDgKiIA/gACYWxydksVURVuFXMVcgByAG2gtyEAoDwpeQCAAWV2dwBYFWUVaRVxAHACXxUAAAAAYxVyAGUA4wAXFXUA4wAZFWUAZQAAoM4iZSJkZ2UAAKDPImUAbgA7gKQApEBlI2Fycm93AAABbHJ7FX8V5SFmdACgtiFpImdodAAAoLchZQDkAG0VAAFjaYsVkRVvAG4AaQBuAPQAkwFuAHQAAKAxImwiY3R5AACgLSOACUFIYWJjZGVmaGlqbG9yc3R1d3oAuBW7Fb8V1RXgFegV+RUKFhUWHxZUFlcWZRbFFtsW7xb7FgUXChdyAPIAtAJhAHIAAKBlKQACZ2xyc8YVyhXOFdAV5yFlcgCgICDlIXRoAKA4IfIA9QxoAHagECAAoKMiawHZFd4VYSJyb3cAAKAPKWEA4wBfAgABYXnkFecV8iFvbg9hNGQAoUYhYW/tFfQVAAFnciEC8RVyAACgyiF0InNlcQAAoHcqgAFnbG0A/xUCFgUWO4CwALBAdABhALRjcCJ0eXYAAKCxKQABaXIOFhIW8yFodACgfykA4DXYId1hAHIAAAFschsWHRYAoMMhAKDCIYACYWVnc3YAKBauAjYWOhY+Fm0AAKHEIm9zLhY0Fm4AZABzoMQi9SFpdACgZiZhIm1tYQDdY2kAbgAAoPIiAKH3AGlvQxZRFmQAZQAAgfcAO29KFksW90BuI3RpbWVzAACgxyJuAPgAUBZjAHkAUmRjAG8CXhYAAAAAYhZyAG4AAKAeI28AcAAAoA0jgAJscHR1dwBuFnEWdRaSFp4W7CFhciRgZgAA4DXYVd0AotkCZW1wc30WhBaJFo0WcQBkoFAibwB0AACgUSJpIm51cwAAoDgi7CF1cwCgFCLxInVhcmUAoKEiYgBsAGUAYgBhAHIAdwBlAGQAZwDlANcAbgCAAWFkaAClFqoWtBZyAHIAbwD3APUMbwB3AG4AYQByAHIAbwB3APMA8xVhI3Jwb29uAAABbHK8FsAWZQBmAPQAHBZpAGcAaAD0AB4WYgHJFs8WawBhAHIAbwD3AJILbwLUFgAAAADYFnIAbgAAoB8jbwBwAACgDCOAAWNvdADhFukW7BYAAXJ55RboFgDgNdi53FVkbAAAoPYp8iFvaxFhAAFkcvMW9xZvAHQAAKDxImkA5qC/JVsSAAFhaP8WAhdyAPIANQNhAPIA1wvhIm5nbGUAoKYpAAFjaQ4XEBd5AF9k5yJyYXJyAKD/JwAJRGFjZGVmZ2xtbm9wcXJzdHV4MRc4F0YXWxcyBF4XaRd5F40XrBe0F78X2RcVGCEYLRg1GEAYAAFEbzUXgRZvAPQA+BUAAWNzPBdCF3UAdABlADuA6QDpQPQhZXIAoG4qAAJhaW95TRdQF1YXWhfyIW9uG2FyAGOgViI7gOoA6kDsIW9uAKBVIk1kbwB0ABdhAAFEcmIXZhdvAHQAAKBSIgDgNdgi3XKhmipuF3QXYQB2AGUAO4DoAOhAZKCWKm8AdAAAoJgqgKGZKmlscwCAF4UXhxfuInRlcnMAoOcjAKATIWSglSpvAHQAAKCXKoABYXBzAJMXlheiF2MAcgATYXQAeQBzogUinxcAAAAAoRdlAHQAAKAFInAAMaADIDMBqRerFwCgBCAAoAUgAAFnc7AXsRdLYXAAAKACIAABZ3C4F7sXbwBuABlhZgAA4DXYVt2AAWFscwDFF8sXzxdyAHOg1SJsAACg4yl1AHMAAKBxKmkAAKG1A2x21RfYF28AbgC1Y/VjAAJjc3V24BfoF/0XEBgAAWlv5BdWF3IAYwAAoFYiaQLuFwAAAADwF+0ADQThIW50AAFnbPUX+Rd0AHIAAKCWKuUhc3MAoJUqgAFhZWkAAxgGGAoYbABzAD1gcwB0AACgXyJ2AESgYSJEAACgeCrwImFyc2wAoOUpAAFEYRkYHRhvAHQAAKBTInIAcgAAoHEpgAFjZGkAJxgqGO0XcgAAoC8hbwD0AIwCAAFhaDEYMhi3YzuA8ADwQAABbXI5GD0YbAA7gOsA60BvAACgrCCAAWNpcABGGEgYSxhsACFgcwD0ACwEAAFlb08YVxhjAHQAYQB0AGkAbwDuABoEbgBlAG4AdABpAGEAbADlADME4Ql1GAAAgRgAAIMYiBgAAAAAoRilGAAAqhgAALsYvhjRGAAA1xgnGWwAbABpAG4AZwBkAG8AdABzAGUA8QBlF3kARGRtImFsZQAAoEAmgAFpbHIAjRiRGJ0Y7CFpZwCgA/tpApcYAAAAAJoYZwAAoAD7aQBnAACgBPsA4DXYI93sIWlnAKAB++whaWcA4GYAagCAAWFsdACvGLIYthh0AACgbSZpAGcAAKAC+24AcwAAoLElbwBmAJJh8AHCGAAAxhhmAADgNdhX3QABYWvJGMwYbADsAGsEdqDUIgCg2SphI3J0aW50AACgDSoAAWFv2hgiGQABY3PeGB8ZsQPnGP0YBRkSGRUZAAAdGbID7xjyGPQY9xj5GAAA+xg7gL0AvUAAoFMhO4C8ALxAAKBVIQCgWSEAoFshswEBGQAAAxkAoFQhAKBWIbQCCxkOGQAAAAAQGTuAvgC+QACgVyEAoFwhNQAAoFghtgEZGQAAGxkAoFohAKBdITgAAKBeIWwAAKBEIHcAbgAAoCIjYwByAADgNdi73IAIRWFiY2RlZmdpamxub3JzdHYARhlKGVoZXhlmGWkZkhmWGZkZnRmgGa0ZxhnLGc8Z4BkjGmygZyIAoIwqgAFjbXAAUBlTGVgZ9SF0ZfVhbQBhAOSgswM6FgCghipyImV2ZQAfYQABaXliGWUZcgBjAB1hM2RvAHQAIWGAoWUibHFzAMYEcBl6GfGhZSLOBAAAdhlsAGEAbgD0AN8EgKF+KmNkbACBGYQZjBljAACgqSpvAHQAb6CAKmyggioAoIQqZeDbIgD+cwAAoJQqcgAA4DXYJN3noGsirATtIWVsAKA3IWMAeQBTZIChdyJFYWoApxmpGasZAKCSKgCgpSoAoKQqAAJFYWVztBm2Gb0ZwhkAoGkicABwoIoq8iFveACgiipxoIgq8aCIKrUZaQBtAACg5yJwAGYAAOA12FjdYQB2AOUAYwIAAWNp0xnWGXIAAKAKIW0AAKFzImVs3BneGQCgjioAoJAqAIM+ADtjZGxxco0E6xn0GfgZ/BkBGgABY2nvGfEZAKCnKnIAAKB6Km8AdAAAoNci0CFhcgCglSl1ImVzdAAAoHwqgAJhZGVscwAKGvQZFhrVBCAa8AEPGgAAFBpwAHIAbwD4AFkZcgAAoHgpcQAAAWxxxAQbGmwAZQBzAPMASRlpAO0A5AQAAWVuJxouGnIjdG5lcXEAAOBpIgD+xQAsGgAFQWFiY2Vma29zeUAaQxpmGmoabRqDGocalhrCGtMacgDyAMwCAAJpbG1yShpOGlAaVBpyAHMA8ABxD2YAvWBpAGwA9AASBQABZHJYGlsaYwB5AEpkAKGUIWN3YBpkGmkAcgAAoEgpAKCtIWEAcgAAoA8h6SFyYyVhgAFhbHIAcxp7Gn8a8iF0c3WgZSZpAHQAAKBlJuwhaXAAoCYg4yFvbgCguSJyAADgNdgl3XMAAAFld4wakRphInJvdwAAoCUpYSJyb3cAAKAmKYACYW1vcHIAnxqjGqcauhq+GnIAcgAAoP8h9CFodACgOyJrAAABbHKsGrMaZSRmdGFycm93AACgqSHpJGdodGFycm93AKCqIWYAAOA12Fnd4iFhcgCgFSCAAWNsdADIGswa0BpyAADgNdi93GEAcwDoAGka8iFvaydhAAFicNca2xr1IWxsAKBDIOghZW4AoBAg4Qr2GgAA/RoAAAgbExsaGwAAIRs7GwAAAAA+G2IbmRuVG6sbAACyG80b0htjAHUAdABlADuA7QDtQAChYyBpeQEbBhtyAGMAO4DuAO5AOGQAAWN4CxsNG3kANWRjAGwAO4ChAKFAAAFmcssCFhsA4DXYJt1yAGEAdgBlADuA7ADsQIChSCFpbm8AJxsyGzYbAAFpbisbLxtuAHQAAKAMKnQAAKAtIuYhaW4AoNwpdABhAACgKSHsIWlnM2GAAWFvcABDG1sbXhuAAWNndABJG0sbWRtyACthgAFlbHAAcQVRG1UbaQBuAOUAyAVhAHIA9AByBWgAMWFmAACgtyJlAGQAtWEAoggiY2ZvdGkbbRt1G3kb4SFyZQCgBSFpAG4AdKAeImkAZQAAoN0pZABvAPQAWxsAoisiY2VscIEbhRuPG5QbYQBsAACguiIAAWdyiRuNG2UAcgDzACMQ4wCCG2EicmhrAACgFyryIW9kAKA8KgACY2dwdJ8boRukG6gbeQBRZG8AbgAvYWYAAOA12FrdYQC5Y3UAZQBzAHQAO4C/AL9AAAFjabUbuRtyAADgNdi+3G4AAKIIIkVkc3bCG8QbyBvQAwCg+SJvAHQAAKD1Inag9CIAoPMiaaBiIOwhZGUpYesB1hsAANkbYwB5AFZkbAA7gO8A70AAA2NmbW9zdeYb7hvyG/Ub+hsFHAABaXnqG+0bcgBjADVhOWRyAADgNdgn3eEhdGg3YnAAZgAA4DXYW93jAf8bAAADHHIAAOA12L/c8iFjeVhk6yFjeVRkAARhY2ZnaGpvcxUcGhwiHCYcKhwtHDAcNRzwIXBhdqC6A/BjAAFleR4cIRzkIWls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ZmdobG1vcHJzdHV3CiwNLBEsHSwnLDEsQCxLLFIsYix6LIQsjyzLLOgs7Sz/LAotcgDyAAkDYQByAACgYykAAWNyFSwbLHUAdABlADuA+gD6QPIACQ1yAOMBIywAACUseQBeZHYAZQBtYQABaXkrLDAscgBjADuA+wD7QENkgAFhYmgANyw6LD0scgDyANEO7CFhY3FhYQDyAOAOAAFpckQsSCzzIWh0AKB+KQDgNdgy3XIAYQB2AGUAO4D5APlAYQFWLF8scgAAAWxyWixcLACgvyEAoL4hbABrAACggCUAAWN0Zix2LG8CbCwAAAAAcyxyAG4AZaAcI3IAAKAcI28AcAAAoA8jcgBpAACg+CUAAWFsfiyBLGMAcgBrYTuAqACoQAABZ3CILIssbwBuAHNhZgAA4DXYZt0AA2FkaGxzdZksniynLLgsuyzFLHIAcgBvAPcACQ1vAHcAbgBhAHIAcgBvAPcA2A5hI3Jwb29uAAABbHKvLLMsZQBmAPQAWyxpAGcAaAD0AF0sdQDzAKYOaQAAocUDaGzBLMIs0mNvAG4AxWPwI2Fycm93cwCgyCGAAWNpdADRLOEs5CxvAtcsAAAAAN4scgBuAGWgHSNyAACgHSNvAHAAAKAOI24AZwBvYXIAaQAAoPklYwByAADgNdjK3IABZGlyAPMs9yz6LG8AdAAAoPAi7CFkZWlhaQBmoLUlAKC0JQABYW0DLQYtcgDyAMosbAA7gPwA/EDhIm5nbGUAoKcpgAdBQkRhY2RlZmxub3Byc3oAJy0qLTAtNC2bLZ0toS2/LcMtxy3TLdgt3C3gLfwtcgDyABADYQByAHag6CoAoOkqYQBzAOgA/gIAAW5yOC08LechcnQAoJwpgANla25wcnN0AJkpSC1NLVQtXi1iLYItYQBwAHAA4QAaHG8AdABoAGkAbgDnAKEXgAFoaXIAoSmzJFotbwBwAPQAdCVooJUh7wD4JgABaXVmLWotZwBtAOEAuygAAWJwbi14LXMjZXRuZXEAceCKIgD+AODLKgD+cyNldG5lcQBx4IsiAP4A4MwqAP4AAWhyhi2KLWUAdADhABIraSNhbmdsZQAAAWxyki2WLeUhZnQAoLIiaSJnaHQAAKCzInkAMmThIXNoAKCiIoABZWxyAKcttC24LWKiKCKuLQAAAACyLWEAcgAAoLsicQAAoFoi7CFpcACg7iIAAWJ0vC1eD2EA8gBfD3IAAOA12DPddAByAOkAlS1zAHUAAAFicM0t0C0A4IIi0iAA4IMi0iBwAGYAAOA12GfdcgBvAPAAWQt0AHIA6QCaLQABY3XkLegtcgAA4DXYy9wAAWJw7C30LW4AAAFFZXUt8S0A4IoiAP5uAAABRWV/LfktAOCLIgD+6SJnemFnAKCaKYADY2Vmb3BycwANLhAuJS4pLiMuLi40LukhcmN1YQABZGkULiEuAAFiZxguHC5hAHIAAKBfKmUAcaAnIgCgWSLlIXJwAKAYIXIAAOA12DTdcABmAADgNdho3WWgQCJhAHQA6ABqD2MAcgAA4DXYzNzjCuQRUC4AAFQuAABYLmIuAAAAAGMubS5wLnQuAAAAAIguki4AAJouJxIqEnQAcgDpAB0ScgAA4DXYNd0AAUFhWy5eLnIA8gDnAnIA8gCTB75jAAFBYWYuaS5yAPIA4AJyAPIAjAdhAPAAeh5pAHMAAKD7IoABZHB0APgReS6DLgABZmx9LoAuAOA12GnddQDzAP8RaQBtAOUABBIAAUFhiy6OLnIA8gDuAnIA8gCaBwABY3GVLgoScgAA4DXYzdwAAXB0nS6hLmwAdQDzACUScgDpACASAARhY2VmaW9zdbEuvC7ELsguzC7PLtQu2S5jAAABdXm2LrsudABlADuA/QD9QE9kAAFpecAuwy5yAGMAd2FLZG4AO4ClAKVAcgAA4DXYNt1jAHkAV2RwAGYAAOA12GrdYwByAADgNdjO3AABY23dLt8ueQBOZGwAO4D/AP9AAAVhY2RlZmhpb3N38y73Lv8uAi8MLxAvEy8YLx0vIi9jInV0ZQB6YQABYXn7Lv4u8iFvbn5hN2RvAHQAfGEAAWV0Bi8KL3QAcgDmAB8QYQC2Y3IAAOA12DfdYwB5ADZk5yJyYXJyAKDdIXAAZgAA4DXYa91jAHIAAOA12M/cAAFqbiYvKC8AoA0gagAAoAwg");
1171
+ //#endregion
1172
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/generated/decode-data-xml.js
1173
+ /** Packed XML decode trie data. */
1174
+ const xmlDecodeTree = /* #__PURE__ */ decodeBase64("AAJhZ2xxBwARABMAFQBtAg0AAAAAAA8AcAAmYG8AcwAnYHQAPmB0ADxg9SFvdCJg");
1175
+ //#endregion
1176
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/internal/bin-trie-flags.js
1177
+ /**
1178
+ * Bit flags & masks for the binary trie encoding used for entity decoding.
1179
+ *
1180
+ * Bit layout (16 bits total):
1181
+ * 15..14 VALUE_LENGTH (+1 encoding; 0 => no value)
1182
+ * 13 FLAG13. If valueLength>0: semicolon required flag (implicit ';').
1183
+ * If valueLength==0: compact run flag.
1184
+ * 12..7 BRANCH_LENGTH Branch length (0 => single branch in 6..0 if jumpOffset==char) OR run length (when compact run)
1185
+ * 6..0 JUMP_TABLE Jump offset (jump table) OR single-branch char code OR first run char
1186
+ */
1187
+ var BinTrieFlags;
1188
+ (function(BinTrieFlags) {
1189
+ BinTrieFlags[BinTrieFlags["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
1190
+ BinTrieFlags[BinTrieFlags["FLAG13"] = 8192] = "FLAG13";
1191
+ BinTrieFlags[BinTrieFlags["BRANCH_LENGTH"] = 8064] = "BRANCH_LENGTH";
1192
+ BinTrieFlags[BinTrieFlags["JUMP_TABLE"] = 127] = "JUMP_TABLE";
1193
+ })(BinTrieFlags || (BinTrieFlags = {}));
1194
+ //#endregion
1195
+ //#region ../../node_modules/.pnpm/entities@8.0.0/node_modules/entities/dist/decode.js
1196
+ var CharCodes$1;
1197
+ (function(CharCodes) {
1198
+ CharCodes[CharCodes["NUM"] = 35] = "NUM";
1199
+ CharCodes[CharCodes["SEMI"] = 59] = "SEMI";
1200
+ CharCodes[CharCodes["EQUALS"] = 61] = "EQUALS";
1201
+ CharCodes[CharCodes["ZERO"] = 48] = "ZERO";
1202
+ CharCodes[CharCodes["NINE"] = 57] = "NINE";
1203
+ CharCodes[CharCodes["LOWER_A"] = 97] = "LOWER_A";
1204
+ CharCodes[CharCodes["LOWER_F"] = 102] = "LOWER_F";
1205
+ CharCodes[CharCodes["LOWER_X"] = 120] = "LOWER_X";
1206
+ CharCodes[CharCodes["LOWER_Z"] = 122] = "LOWER_Z";
1207
+ CharCodes[CharCodes["UPPER_A"] = 65] = "UPPER_A";
1208
+ CharCodes[CharCodes["UPPER_F"] = 70] = "UPPER_F";
1209
+ CharCodes[CharCodes["UPPER_Z"] = 90] = "UPPER_Z";
1210
+ })(CharCodes$1 || (CharCodes$1 = {}));
1211
+ /** Bit that needs to be set to convert an upper case ASCII character to lower case */
1212
+ const TO_LOWER_BIT = 32;
1213
+ function isNumber(code) {
1214
+ return code >= CharCodes$1.ZERO && code <= CharCodes$1.NINE;
1215
+ }
1216
+ function isHexadecimalCharacter(code) {
1217
+ return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_F || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_F;
1218
+ }
1219
+ function isAsciiAlphaNumeric(code) {
1220
+ return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_Z || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_Z || isNumber(code);
1221
+ }
1222
+ /**
1223
+ * Checks if the given character is a valid end character for an entity in an attribute.
1224
+ *
1225
+ * Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.
1226
+ * See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state
1227
+ * @param code Code point to decode.
1228
+ */
1229
+ function isEntityInAttributeInvalidEnd(code) {
1230
+ return code === CharCodes$1.EQUALS || isAsciiAlphaNumeric(code);
1231
+ }
1232
+ var EntityDecoderState;
1233
+ (function(EntityDecoderState) {
1234
+ EntityDecoderState[EntityDecoderState["EntityStart"] = 0] = "EntityStart";
1235
+ EntityDecoderState[EntityDecoderState["NumericStart"] = 1] = "NumericStart";
1236
+ EntityDecoderState[EntityDecoderState["NumericDecimal"] = 2] = "NumericDecimal";
1237
+ EntityDecoderState[EntityDecoderState["NumericHex"] = 3] = "NumericHex";
1238
+ EntityDecoderState[EntityDecoderState["NamedEntity"] = 4] = "NamedEntity";
1239
+ })(EntityDecoderState || (EntityDecoderState = {}));
1240
+ /**
1241
+ * Decoding mode for named entities.
1242
+ */
1243
+ var DecodingMode;
1244
+ (function(DecodingMode) {
1245
+ /** Entities in text nodes that can end with any character. */
1246
+ DecodingMode[DecodingMode["Legacy"] = 0] = "Legacy";
1247
+ /** Only allow entities terminated with a semicolon. */
1248
+ DecodingMode[DecodingMode["Strict"] = 1] = "Strict";
1249
+ /** Entities in attributes have limitations on ending characters. */
1250
+ DecodingMode[DecodingMode["Attribute"] = 2] = "Attribute";
1251
+ })(DecodingMode || (DecodingMode = {}));
1252
+ /**
1253
+ * Token decoder with support of writing partial entities.
1254
+ */
1255
+ var EntityDecoder = class {
1256
+ decodeTree;
1257
+ emitCodePoint;
1258
+ errors;
1259
+ constructor(decodeTree, emitCodePoint, errors) {
1260
+ this.decodeTree = decodeTree;
1261
+ this.emitCodePoint = emitCodePoint;
1262
+ this.errors = errors;
1263
+ }
1264
+ /** The current state of the decoder. */
1265
+ state = EntityDecoderState.EntityStart;
1266
+ /** Characters that were consumed while parsing an entity. */
1267
+ consumed = 1;
1268
+ /**
1269
+ * The result of the entity.
1270
+ *
1271
+ * Either the result index of a numeric entity, or the codepoint of a
1272
+ * numeric entity.
1273
+ */
1274
+ result = 0;
1275
+ /** The current index in the decode tree. */
1276
+ treeIndex = 0;
1277
+ /** The number of characters that were consumed in excess. */
1278
+ excess = 1;
1279
+ /** The mode in which the decoder is operating. */
1280
+ decodeMode = DecodingMode.Strict;
1281
+ /** The number of characters that have been consumed in the current run. */
1282
+ runConsumed = 0;
1283
+ /**
1284
+ * Resets the instance to make it reusable.
1285
+ * @param decodeMode Entity decoding mode to use.
1286
+ */
1287
+ startEntity(decodeMode) {
1288
+ this.decodeMode = decodeMode;
1289
+ this.state = EntityDecoderState.EntityStart;
1290
+ this.result = 0;
1291
+ this.treeIndex = 0;
1292
+ this.excess = 1;
1293
+ this.consumed = 1;
1294
+ this.runConsumed = 0;
1295
+ }
1296
+ /**
1297
+ * Write an entity to the decoder. This can be called multiple times with partial entities.
1298
+ * If the entity is incomplete, the decoder will return -1.
1299
+ *
1300
+ * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
1301
+ * entity is incomplete, and resume when the next string is written.
1302
+ * @param input The string containing the entity (or a continuation of the entity).
1303
+ * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
1304
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
1305
+ */
1306
+ write(input, offset) {
1307
+ switch (this.state) {
1308
+ case EntityDecoderState.EntityStart:
1309
+ if (input.charCodeAt(offset) === CharCodes$1.NUM) {
1310
+ this.state = EntityDecoderState.NumericStart;
1311
+ this.consumed += 1;
1312
+ return this.stateNumericStart(input, offset + 1);
1313
+ }
1314
+ this.state = EntityDecoderState.NamedEntity;
1315
+ return this.stateNamedEntity(input, offset);
1316
+ case EntityDecoderState.NumericStart: return this.stateNumericStart(input, offset);
1317
+ case EntityDecoderState.NumericDecimal: return this.stateNumericDecimal(input, offset);
1318
+ case EntityDecoderState.NumericHex: return this.stateNumericHex(input, offset);
1319
+ case EntityDecoderState.NamedEntity: return this.stateNamedEntity(input, offset);
1320
+ }
1321
+ }
1322
+ /**
1323
+ * Switches between the numeric decimal and hexadecimal states.
1324
+ *
1325
+ * Equivalent to the `Numeric character reference state` in the HTML spec.
1326
+ * @param input The string containing the entity (or a continuation of the entity).
1327
+ * @param offset The current offset.
1328
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
1329
+ */
1330
+ stateNumericStart(input, offset) {
1331
+ if (offset >= input.length) return -1;
1332
+ if ((input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes$1.LOWER_X) {
1333
+ this.state = EntityDecoderState.NumericHex;
1334
+ this.consumed += 1;
1335
+ return this.stateNumericHex(input, offset + 1);
1336
+ }
1337
+ this.state = EntityDecoderState.NumericDecimal;
1338
+ return this.stateNumericDecimal(input, offset);
1339
+ }
1340
+ /**
1341
+ * Parses a hexadecimal numeric entity.
1342
+ *
1343
+ * Equivalent to the `Hexademical character reference state` in the HTML spec.
1344
+ * @param input The string containing the entity (or a continuation of the entity).
1345
+ * @param offset The current offset.
1346
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
1347
+ */
1348
+ stateNumericHex(input, offset) {
1349
+ while (offset < input.length) {
1350
+ const char = input.charCodeAt(offset);
1351
+ if (isNumber(char) || isHexadecimalCharacter(char)) {
1352
+ const digit = char <= CharCodes$1.NINE ? char - CharCodes$1.ZERO : (char | TO_LOWER_BIT) - CharCodes$1.LOWER_A + 10;
1353
+ this.result = this.result * 16 + digit;
1354
+ this.consumed++;
1355
+ offset++;
1356
+ } else return this.emitNumericEntity(char, 3);
1357
+ }
1358
+ return -1;
1359
+ }
1360
+ /**
1361
+ * Parses a decimal numeric entity.
1362
+ *
1363
+ * Equivalent to the `Decimal character reference state` in the HTML spec.
1364
+ * @param input The string containing the entity (or a continuation of the entity).
1365
+ * @param offset The current offset.
1366
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
1367
+ */
1368
+ stateNumericDecimal(input, offset) {
1369
+ while (offset < input.length) {
1370
+ const char = input.charCodeAt(offset);
1371
+ if (isNumber(char)) {
1372
+ this.result = this.result * 10 + (char - CharCodes$1.ZERO);
1373
+ this.consumed++;
1374
+ offset++;
1375
+ } else return this.emitNumericEntity(char, 2);
1376
+ }
1377
+ return -1;
1378
+ }
1379
+ /**
1380
+ * Validate and emit a numeric entity.
1381
+ *
1382
+ * Implements the logic from the `Hexademical character reference start
1383
+ * state` and `Numeric character reference end state` in the HTML spec.
1384
+ * @param lastCp The last code point of the entity. Used to see if the
1385
+ * entity was terminated with a semicolon.
1386
+ * @param expectedLength The minimum number of characters that should be
1387
+ * consumed. Used to validate that at least one digit
1388
+ * was consumed.
1389
+ * @returns The number of characters that were consumed.
1390
+ */
1391
+ emitNumericEntity(lastCp, expectedLength) {
1392
+ if (this.consumed <= expectedLength) {
1393
+ this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
1394
+ return 0;
1395
+ }
1396
+ if (lastCp === CharCodes$1.SEMI) this.consumed += 1;
1397
+ else if (this.decodeMode === DecodingMode.Strict) return 0;
1398
+ this.emitCodePoint(replaceCodePoint(this.result), this.consumed);
1399
+ if (this.errors) {
1400
+ if (lastCp !== CharCodes$1.SEMI) this.errors.missingSemicolonAfterCharacterReference();
1401
+ this.errors.validateNumericCharacterReference(this.result);
1402
+ }
1403
+ return this.consumed;
1404
+ }
1405
+ /**
1406
+ * Parses a named entity.
1407
+ *
1408
+ * Equivalent to the `Named character reference state` in the HTML spec.
1409
+ * @param input The string containing the entity (or a continuation of the entity).
1410
+ * @param offset The current offset.
1411
+ * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
1412
+ */
1413
+ stateNamedEntity(input, offset) {
1414
+ const { decodeTree } = this;
1415
+ let current = decodeTree[this.treeIndex];
1416
+ let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
1417
+ while (offset < input.length) {
1418
+ if (valueLength === 0 && (current & BinTrieFlags.FLAG13) !== 0) {
1419
+ const runLength = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
1420
+ if (this.runConsumed === 0) {
1421
+ const firstChar = current & BinTrieFlags.JUMP_TABLE;
1422
+ if (input.charCodeAt(offset) !== firstChar) return this.result === 0 ? 0 : this.emitNotTerminatedNamedEntity();
1423
+ offset++;
1424
+ this.excess++;
1425
+ this.runConsumed++;
1426
+ }
1427
+ while (this.runConsumed < runLength) {
1428
+ if (offset >= input.length) return -1;
1429
+ const charIndexInPacked = this.runConsumed - 1;
1430
+ const packedWord = decodeTree[this.treeIndex + 1 + (charIndexInPacked >> 1)];
1431
+ const expectedChar = charIndexInPacked % 2 === 0 ? packedWord & 255 : packedWord >> 8 & 255;
1432
+ if (input.charCodeAt(offset) !== expectedChar) {
1433
+ this.runConsumed = 0;
1434
+ return this.result === 0 ? 0 : this.emitNotTerminatedNamedEntity();
1435
+ }
1436
+ offset++;
1437
+ this.excess++;
1438
+ this.runConsumed++;
1439
+ }
1440
+ this.runConsumed = 0;
1441
+ this.treeIndex += 1 + (runLength >> 1);
1442
+ current = decodeTree[this.treeIndex];
1443
+ valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
1444
+ }
1445
+ if (offset >= input.length) break;
1446
+ const char = input.charCodeAt(offset);
1447
+ if (char === CharCodes$1.SEMI && valueLength !== 0 && (current & BinTrieFlags.FLAG13) !== 0) return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
1448
+ this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
1449
+ if (this.treeIndex < 0) return this.result === 0 || this.decodeMode === DecodingMode.Attribute && (valueLength === 0 || isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();
1450
+ current = decodeTree[this.treeIndex];
1451
+ valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
1452
+ if (valueLength !== 0) {
1453
+ if (char === CharCodes$1.SEMI) return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
1454
+ if (this.decodeMode !== DecodingMode.Strict && (current & BinTrieFlags.FLAG13) === 0) {
1455
+ this.result = this.treeIndex;
1456
+ this.consumed += this.excess;
1457
+ this.excess = 0;
1458
+ }
1459
+ }
1460
+ offset++;
1461
+ this.excess++;
1462
+ }
1463
+ return -1;
1464
+ }
1465
+ /**
1466
+ * Emit a named entity that was not terminated with a semicolon.
1467
+ * @returns The number of characters consumed.
1468
+ */
1469
+ emitNotTerminatedNamedEntity() {
1470
+ const { result, decodeTree } = this;
1471
+ const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;
1472
+ this.emitNamedEntityData(result, valueLength, this.consumed);
1473
+ this.errors?.missingSemicolonAfterCharacterReference();
1474
+ return this.consumed;
1475
+ }
1476
+ /**
1477
+ * Emit a named entity.
1478
+ * @param result The index of the entity in the decode tree.
1479
+ * @param valueLength The number of bytes in the entity.
1480
+ * @param consumed The number of characters consumed.
1481
+ * @returns The number of characters consumed.
1482
+ */
1483
+ emitNamedEntityData(result, valueLength, consumed) {
1484
+ const { decodeTree } = this;
1485
+ this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~(BinTrieFlags.VALUE_LENGTH | BinTrieFlags.FLAG13) : decodeTree[result + 1], consumed);
1486
+ if (valueLength === 3) this.emitCodePoint(decodeTree[result + 2], consumed);
1487
+ return consumed;
1488
+ }
1489
+ /**
1490
+ * Signal to the parser that the end of the input was reached.
1491
+ *
1492
+ * Remaining data will be emitted and relevant errors will be produced.
1493
+ * @returns The number of characters consumed.
1494
+ */
1495
+ end() {
1496
+ switch (this.state) {
1497
+ case EntityDecoderState.NamedEntity: return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;
1498
+ case EntityDecoderState.NumericDecimal: return this.emitNumericEntity(0, 2);
1499
+ case EntityDecoderState.NumericHex: return this.emitNumericEntity(0, 3);
1500
+ case EntityDecoderState.NumericStart:
1501
+ this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed);
1502
+ return 0;
1503
+ case EntityDecoderState.EntityStart: return 0;
1504
+ }
1505
+ }
1506
+ };
1507
+ /**
1508
+ * Determines the branch of the current node that is taken given the current
1509
+ * character. This function is used to traverse the trie.
1510
+ * @param decodeTree The trie.
1511
+ * @param current The current node.
1512
+ * @param nodeIndex Index immediately after the current node header.
1513
+ * @param char The current character.
1514
+ * @returns The index of the next node, or -1 if no branch is taken.
1515
+ */
1516
+ function determineBranch(decodeTree, current, nodeIndex, char) {
1517
+ const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
1518
+ const jumpOffset = current & BinTrieFlags.JUMP_TABLE;
1519
+ if (branchCount === 0) return jumpOffset !== 0 && char === jumpOffset ? nodeIndex : -1;
1520
+ if (jumpOffset) {
1521
+ const value = char - jumpOffset;
1522
+ return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIndex + value] - 1;
1523
+ }
1524
+ const packedKeySlots = branchCount + 1 >> 1;
1525
+ let lo = 0;
1526
+ let hi = branchCount - 1;
1527
+ while (lo <= hi) {
1528
+ const mid = lo + hi >>> 1;
1529
+ const midKey = decodeTree[nodeIndex + (mid >> 1)] >> (mid & 1) * 8 & 255;
1530
+ if (midKey < char) lo = mid + 1;
1531
+ else if (midKey > char) hi = mid - 1;
1532
+ else return decodeTree[nodeIndex + packedKeySlots + mid];
1533
+ }
1534
+ return -1;
1535
+ }
1536
+ //#endregion
1537
+ //#region ../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Tokenizer.js
1538
+ var CharCodes;
1539
+ (function(CharCodes) {
1540
+ CharCodes[CharCodes["Tab"] = 9] = "Tab";
1541
+ CharCodes[CharCodes["NewLine"] = 10] = "NewLine";
1542
+ CharCodes[CharCodes["FormFeed"] = 12] = "FormFeed";
1543
+ CharCodes[CharCodes["CarriageReturn"] = 13] = "CarriageReturn";
1544
+ CharCodes[CharCodes["Space"] = 32] = "Space";
1545
+ CharCodes[CharCodes["ExclamationMark"] = 33] = "ExclamationMark";
1546
+ CharCodes[CharCodes["Number"] = 35] = "Number";
1547
+ CharCodes[CharCodes["Amp"] = 38] = "Amp";
1548
+ CharCodes[CharCodes["SingleQuote"] = 39] = "SingleQuote";
1549
+ CharCodes[CharCodes["DoubleQuote"] = 34] = "DoubleQuote";
1550
+ CharCodes[CharCodes["Dash"] = 45] = "Dash";
1551
+ CharCodes[CharCodes["Slash"] = 47] = "Slash";
1552
+ CharCodes[CharCodes["Zero"] = 48] = "Zero";
1553
+ CharCodes[CharCodes["Nine"] = 57] = "Nine";
1554
+ CharCodes[CharCodes["Semi"] = 59] = "Semi";
1555
+ CharCodes[CharCodes["Lt"] = 60] = "Lt";
1556
+ CharCodes[CharCodes["Eq"] = 61] = "Eq";
1557
+ CharCodes[CharCodes["Gt"] = 62] = "Gt";
1558
+ CharCodes[CharCodes["Questionmark"] = 63] = "Questionmark";
1559
+ CharCodes[CharCodes["UpperA"] = 65] = "UpperA";
1560
+ CharCodes[CharCodes["LowerA"] = 97] = "LowerA";
1561
+ CharCodes[CharCodes["UpperF"] = 70] = "UpperF";
1562
+ CharCodes[CharCodes["LowerF"] = 102] = "LowerF";
1563
+ CharCodes[CharCodes["UpperZ"] = 90] = "UpperZ";
1564
+ CharCodes[CharCodes["LowerZ"] = 122] = "LowerZ";
1565
+ CharCodes[CharCodes["LowerX"] = 120] = "LowerX";
1566
+ CharCodes[CharCodes["OpeningSquareBracket"] = 91] = "OpeningSquareBracket";
1567
+ })(CharCodes || (CharCodes = {}));
1568
+ /** All the states the tokenizer can be in. */
1569
+ var State;
1570
+ (function(State) {
1571
+ State[State["Text"] = 1] = "Text";
1572
+ State[State["BeforeTagName"] = 2] = "BeforeTagName";
1573
+ State[State["InTagName"] = 3] = "InTagName";
1574
+ State[State["InSelfClosingTag"] = 4] = "InSelfClosingTag";
1575
+ State[State["BeforeClosingTagName"] = 5] = "BeforeClosingTagName";
1576
+ State[State["InClosingTagName"] = 6] = "InClosingTagName";
1577
+ State[State["AfterClosingTagName"] = 7] = "AfterClosingTagName";
1578
+ State[State["BeforeAttributeName"] = 8] = "BeforeAttributeName";
1579
+ State[State["InAttributeName"] = 9] = "InAttributeName";
1580
+ State[State["AfterAttributeName"] = 10] = "AfterAttributeName";
1581
+ State[State["BeforeAttributeValue"] = 11] = "BeforeAttributeValue";
1582
+ State[State["InAttributeValueDq"] = 12] = "InAttributeValueDq";
1583
+ State[State["InAttributeValueSq"] = 13] = "InAttributeValueSq";
1584
+ State[State["InAttributeValueNq"] = 14] = "InAttributeValueNq";
1585
+ State[State["BeforeDeclaration"] = 15] = "BeforeDeclaration";
1586
+ State[State["InDeclaration"] = 16] = "InDeclaration";
1587
+ State[State["InProcessingInstruction"] = 17] = "InProcessingInstruction";
1588
+ State[State["BeforeComment"] = 18] = "BeforeComment";
1589
+ State[State["CDATASequence"] = 19] = "CDATASequence";
1590
+ State[State["DeclarationSequence"] = 20] = "DeclarationSequence";
1591
+ State[State["InSpecialComment"] = 21] = "InSpecialComment";
1592
+ State[State["InCommentLike"] = 22] = "InCommentLike";
1593
+ State[State["SpecialStartSequence"] = 23] = "SpecialStartSequence";
1594
+ State[State["InSpecialTag"] = 24] = "InSpecialTag";
1595
+ State[State["InPlainText"] = 25] = "InPlainText";
1596
+ State[State["InEntity"] = 26] = "InEntity";
1597
+ })(State || (State = {}));
1598
+ function isWhitespace$1(c) {
1599
+ return c === CharCodes.Space || c === CharCodes.NewLine || c === CharCodes.Tab || c === CharCodes.FormFeed || c === CharCodes.CarriageReturn;
1600
+ }
1601
+ function isEndOfTagSection(c) {
1602
+ return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace$1(c);
1603
+ }
1604
+ function isASCIIAlpha(c) {
1605
+ return c >= CharCodes.LowerA && c <= CharCodes.LowerZ || c >= CharCodes.UpperA && c <= CharCodes.UpperZ;
1606
+ }
1607
+ /**
1608
+ * Quote style used for parsed attributes.
1609
+ */
1610
+ var QuoteType;
1611
+ (function(QuoteType) {
1612
+ QuoteType[QuoteType["NoValue"] = 0] = "NoValue";
1613
+ QuoteType[QuoteType["Unquoted"] = 1] = "Unquoted";
1614
+ QuoteType[QuoteType["Single"] = 2] = "Single";
1615
+ QuoteType[QuoteType["Double"] = 3] = "Double";
1616
+ })(QuoteType || (QuoteType = {}));
1617
+ /**
1618
+ * Sequences used to match longer strings.
1619
+ *
1620
+ * We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End
1621
+ * sequences with an increased offset.
1622
+ */
1623
+ const Sequences = {
1624
+ Empty: /* @__PURE__ */ new Uint8Array(0),
1625
+ Cdata: new Uint8Array([
1626
+ 67,
1627
+ 68,
1628
+ 65,
1629
+ 84,
1630
+ 65,
1631
+ 91
1632
+ ]),
1633
+ CdataEnd: new Uint8Array([
1634
+ 93,
1635
+ 93,
1636
+ 62
1637
+ ]),
1638
+ CommentEnd: new Uint8Array([
1639
+ 45,
1640
+ 45,
1641
+ 33,
1642
+ 62
1643
+ ]),
1644
+ Doctype: new Uint8Array([
1645
+ 100,
1646
+ 111,
1647
+ 99,
1648
+ 116,
1649
+ 121,
1650
+ 112,
1651
+ 101
1652
+ ]),
1653
+ IframeEnd: new Uint8Array([
1654
+ 60,
1655
+ 47,
1656
+ 105,
1657
+ 102,
1658
+ 114,
1659
+ 97,
1660
+ 109,
1661
+ 101
1662
+ ]),
1663
+ NoembedEnd: new Uint8Array([
1664
+ 60,
1665
+ 47,
1666
+ 110,
1667
+ 111,
1668
+ 101,
1669
+ 109,
1670
+ 98,
1671
+ 101,
1672
+ 100
1673
+ ]),
1674
+ NoframesEnd: new Uint8Array([
1675
+ 60,
1676
+ 47,
1677
+ 110,
1678
+ 111,
1679
+ 102,
1680
+ 114,
1681
+ 97,
1682
+ 109,
1683
+ 101,
1684
+ 115
1685
+ ]),
1686
+ Plaintext: new Uint8Array([
1687
+ 60,
1688
+ 47,
1689
+ 112,
1690
+ 108,
1691
+ 97,
1692
+ 105,
1693
+ 110,
1694
+ 116,
1695
+ 101,
1696
+ 120,
1697
+ 116
1698
+ ]),
1699
+ ScriptEnd: new Uint8Array([
1700
+ 60,
1701
+ 47,
1702
+ 115,
1703
+ 99,
1704
+ 114,
1705
+ 105,
1706
+ 112,
1707
+ 116
1708
+ ]),
1709
+ StyleEnd: new Uint8Array([
1710
+ 60,
1711
+ 47,
1712
+ 115,
1713
+ 116,
1714
+ 121,
1715
+ 108,
1716
+ 101
1717
+ ]),
1718
+ TitleEnd: new Uint8Array([
1719
+ 60,
1720
+ 47,
1721
+ 116,
1722
+ 105,
1723
+ 116,
1724
+ 108,
1725
+ 101
1726
+ ]),
1727
+ TextareaEnd: new Uint8Array([
1728
+ 60,
1729
+ 47,
1730
+ 116,
1731
+ 101,
1732
+ 120,
1733
+ 116,
1734
+ 97,
1735
+ 114,
1736
+ 101,
1737
+ 97
1738
+ ]),
1739
+ XmpEnd: new Uint8Array([
1740
+ 60,
1741
+ 47,
1742
+ 120,
1743
+ 109,
1744
+ 112
1745
+ ])
1746
+ };
1747
+ /**
1748
+ * Maps the first lowercase character of an HTML tag name to the sequence
1749
+ * used for special-tag detection. All sequences share a common layout
1750
+ * where index 2 is the first tag-name character, so matching always
1751
+ * continues from offset 3.
1752
+ */
1753
+ const specialStartSequences = /* @__PURE__ */ new Map([
1754
+ [Sequences.IframeEnd[2], Sequences.IframeEnd],
1755
+ [Sequences.NoembedEnd[2], Sequences.NoembedEnd],
1756
+ [Sequences.Plaintext[2], Sequences.Plaintext],
1757
+ [Sequences.ScriptEnd[2], Sequences.ScriptEnd],
1758
+ [Sequences.TitleEnd[2], Sequences.TitleEnd],
1759
+ [Sequences.XmpEnd[2], Sequences.XmpEnd]
1760
+ ]);
1761
+ /**
1762
+ * Tokenizer implementation used by `Parser`.
1763
+ */
1764
+ var Tokenizer = class {
1765
+ cbs;
1766
+ /** The current state the tokenizer is in. */
1767
+ state = State.Text;
1768
+ /** The read buffer. */
1769
+ buffer = "";
1770
+ /** The beginning of the section that is currently being read. */
1771
+ sectionStart = 0;
1772
+ /** The index within the buffer that we are currently looking at. */
1773
+ index = 0;
1774
+ /** The start of the last entity. */
1775
+ entityStart = 0;
1776
+ /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */
1777
+ baseState = State.Text;
1778
+ /** For special parsing behavior inside of script and style tags. */
1779
+ isSpecial = false;
1780
+ /** Indicates whether the tokenizer has been paused. */
1781
+ running = true;
1782
+ /** The offset of the current buffer. */
1783
+ offset = 0;
1784
+ xmlMode;
1785
+ decodeEntities;
1786
+ recognizeSelfClosing;
1787
+ entityDecoder;
1788
+ constructor({ xmlMode = false, decodeEntities = true, recognizeSelfClosing = xmlMode }, cbs) {
1789
+ this.cbs = cbs;
1790
+ this.xmlMode = xmlMode;
1791
+ this.decodeEntities = decodeEntities;
1792
+ this.recognizeSelfClosing = recognizeSelfClosing;
1793
+ this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));
1794
+ }
1795
+ reset() {
1796
+ this.state = State.Text;
1797
+ this.buffer = "";
1798
+ this.sectionStart = 0;
1799
+ this.index = 0;
1800
+ this.baseState = State.Text;
1801
+ this.isSpecial = false;
1802
+ this.currentSequence = Sequences.Empty;
1803
+ this.sequenceIndex = 0;
1804
+ this.running = true;
1805
+ this.offset = 0;
1806
+ }
1807
+ write(chunk) {
1808
+ this.offset += this.buffer.length;
1809
+ this.buffer = chunk;
1810
+ this.parse();
1811
+ }
1812
+ end() {
1813
+ if (this.running) this.finish();
1814
+ }
1815
+ pause() {
1816
+ this.running = false;
1817
+ }
1818
+ resume() {
1819
+ this.running = true;
1820
+ if (this.index < this.buffer.length + this.offset) this.parse();
1821
+ }
1822
+ stateText(c) {
1823
+ if (c === CharCodes.Lt || !this.decodeEntities && this.fastForwardTo(CharCodes.Lt)) {
1824
+ if (this.index > this.sectionStart) this.cbs.ontext(this.sectionStart, this.index);
1825
+ this.state = State.BeforeTagName;
1826
+ this.sectionStart = this.index;
1827
+ } else if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
1828
+ }
1829
+ currentSequence = Sequences.Empty;
1830
+ sequenceIndex = 0;
1831
+ enterTagBody() {
1832
+ if (this.currentSequence === Sequences.Plaintext) {
1833
+ this.currentSequence = Sequences.Empty;
1834
+ this.state = State.InPlainText;
1835
+ } else if (this.isSpecial) {
1836
+ this.state = State.InSpecialTag;
1837
+ this.sequenceIndex = 0;
1838
+ } else this.state = State.Text;
1839
+ }
1840
+ /**
1841
+ * Match the opening tag name against an HTML text-only tag sequence.
1842
+ *
1843
+ * Some tags share an initial prefix (`script`/`style`, `title`/`textarea`,
1844
+ * `noembed`/`noframes`), so we may switch to an alternate sequence at the
1845
+ * first distinguishing byte. On a successful full match we fall back to
1846
+ * the normal tag-name state; a later `>` will enter raw-text, RCDATA, or
1847
+ * plaintext mode based on `currentSequence` / `isSpecial`.
1848
+ * @param c Current character code point.
1849
+ */
1850
+ stateSpecialStartSequence(c) {
1851
+ const lower = c | 32;
1852
+ if (this.sequenceIndex < this.currentSequence.length) {
1853
+ if (lower === this.currentSequence[this.sequenceIndex]) {
1854
+ this.sequenceIndex++;
1855
+ return;
1856
+ }
1857
+ if (this.sequenceIndex === 3) {
1858
+ if (this.currentSequence === Sequences.ScriptEnd && lower === Sequences.StyleEnd[3]) {
1859
+ this.currentSequence = Sequences.StyleEnd;
1860
+ this.sequenceIndex = 4;
1861
+ return;
1862
+ }
1863
+ if (this.currentSequence === Sequences.TitleEnd && lower === Sequences.TextareaEnd[3]) {
1864
+ this.currentSequence = Sequences.TextareaEnd;
1865
+ this.sequenceIndex = 4;
1866
+ return;
1867
+ }
1868
+ } else if (this.sequenceIndex === 4 && this.currentSequence === Sequences.NoembedEnd && lower === Sequences.NoframesEnd[4]) {
1869
+ this.currentSequence = Sequences.NoframesEnd;
1870
+ this.sequenceIndex = 5;
1871
+ return;
1872
+ }
1873
+ } else if (isEndOfTagSection(c)) {
1874
+ this.sequenceIndex = 0;
1875
+ this.state = State.InTagName;
1876
+ this.stateInTagName(c);
1877
+ return;
1878
+ }
1879
+ this.isSpecial = false;
1880
+ this.currentSequence = Sequences.Empty;
1881
+ this.sequenceIndex = 0;
1882
+ this.state = State.InTagName;
1883
+ this.stateInTagName(c);
1884
+ }
1885
+ stateCDATASequence(c) {
1886
+ if (c === Sequences.Cdata[this.sequenceIndex]) {
1887
+ if (++this.sequenceIndex === Sequences.Cdata.length) {
1888
+ this.state = State.InCommentLike;
1889
+ this.currentSequence = Sequences.CdataEnd;
1890
+ this.sequenceIndex = 0;
1891
+ this.sectionStart = this.index + 1;
1892
+ }
1893
+ } else {
1894
+ this.sequenceIndex = 0;
1895
+ if (this.xmlMode) {
1896
+ this.state = State.InDeclaration;
1897
+ this.stateInDeclaration(c);
1898
+ } else {
1899
+ this.state = State.InSpecialComment;
1900
+ this.stateInSpecialComment(c);
1901
+ }
1902
+ }
1903
+ }
1904
+ /**
1905
+ * When we wait for one specific character, we can speed things up
1906
+ * by skipping through the buffer until we find it.
1907
+ * @param c Current character code point.
1908
+ * @returns Whether the character was found.
1909
+ */
1910
+ fastForwardTo(c) {
1911
+ while (++this.index < this.buffer.length + this.offset) if (this.buffer.charCodeAt(this.index - this.offset) === c) return true;
1912
+ this.index = this.buffer.length + this.offset - 1;
1913
+ return false;
1914
+ }
1915
+ /**
1916
+ * Emit a comment token and return to the text state.
1917
+ * @param offset Number of characters in the end sequence that have already been matched.
1918
+ */
1919
+ emitComment(offset) {
1920
+ this.cbs.oncomment(this.sectionStart, this.index, offset);
1921
+ this.sequenceIndex = 0;
1922
+ this.sectionStart = this.index + 1;
1923
+ this.state = State.Text;
1924
+ }
1925
+ /**
1926
+ * Comments and CDATA end with `-->` and `]]>`.
1927
+ *
1928
+ * Their common qualities are:
1929
+ * - Their end sequences have a distinct character they start with.
1930
+ * - That character is then repeated, so we have to check multiple repeats.
1931
+ * - All characters but the start character of the sequence can be skipped.
1932
+ * @param c Current character code point.
1933
+ */
1934
+ stateInCommentLike(c) {
1935
+ if (!this.xmlMode && this.currentSequence === Sequences.CommentEnd && this.sequenceIndex <= 1 && this.index === this.sectionStart + this.sequenceIndex && c === CharCodes.Gt) this.emitComment(this.sequenceIndex);
1936
+ else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === 2 && c === CharCodes.Gt) this.emitComment(2);
1937
+ else if (this.currentSequence === Sequences.CommentEnd && this.sequenceIndex === this.currentSequence.length - 1 && c !== CharCodes.Gt) this.sequenceIndex = Number(c === CharCodes.Dash);
1938
+ else if (c === this.currentSequence[this.sequenceIndex]) {
1939
+ if (++this.sequenceIndex === this.currentSequence.length) {
1940
+ if (this.currentSequence === Sequences.CdataEnd) this.cbs.oncdata(this.sectionStart, this.index, 2);
1941
+ else this.cbs.oncomment(this.sectionStart, this.index, 3);
1942
+ this.sequenceIndex = 0;
1943
+ this.sectionStart = this.index + 1;
1944
+ this.state = State.Text;
1945
+ }
1946
+ } else if (this.sequenceIndex === 0) {
1947
+ if (this.fastForwardTo(this.currentSequence[0])) this.sequenceIndex = 1;
1948
+ } else if (c !== this.currentSequence[this.sequenceIndex - 1]) this.sequenceIndex = 0;
1949
+ }
1950
+ /**
1951
+ * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
1952
+ *
1953
+ * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
1954
+ * We allow anything that wouldn't end the tag.
1955
+ * @param c Current character code point.
1956
+ */
1957
+ isTagStartChar(c) {
1958
+ return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
1959
+ }
1960
+ /**
1961
+ * Scan raw-text / RCDATA content for the matching end tag.
1962
+ *
1963
+ * For RCDATA tags (`<title>`, `<textarea>`) entities are decoded inline.
1964
+ * For raw-text tags (`<script>`, `<style>`, etc.) we fast-forward to `<`.
1965
+ * @param c Current character code point.
1966
+ */
1967
+ stateInSpecialTag(c) {
1968
+ if (this.sequenceIndex === this.currentSequence.length) {
1969
+ if (isEndOfTagSection(c)) {
1970
+ const endOfText = this.index - this.currentSequence.length;
1971
+ if (this.sectionStart < endOfText) {
1972
+ const actualIndex = this.index;
1973
+ this.index = endOfText;
1974
+ this.cbs.ontext(this.sectionStart, endOfText);
1975
+ this.index = actualIndex;
1976
+ }
1977
+ this.isSpecial = false;
1978
+ this.sectionStart = endOfText + 2;
1979
+ this.stateInClosingTagName(c);
1980
+ return;
1981
+ }
1982
+ this.sequenceIndex = 0;
1983
+ }
1984
+ if ((c | 32) === this.currentSequence[this.sequenceIndex]) this.sequenceIndex += 1;
1985
+ else if (this.sequenceIndex === 0) {
1986
+ if (this.currentSequence === Sequences.TitleEnd || this.currentSequence === Sequences.TextareaEnd) {
1987
+ if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
1988
+ } else if (this.fastForwardTo(CharCodes.Lt)) this.sequenceIndex = 1;
1989
+ } else this.sequenceIndex = Number(c === CharCodes.Lt);
1990
+ }
1991
+ stateBeforeTagName(c) {
1992
+ if (c === CharCodes.ExclamationMark) {
1993
+ this.state = State.BeforeDeclaration;
1994
+ this.sectionStart = this.index + 1;
1995
+ } else if (c === CharCodes.Questionmark) {
1996
+ if (this.xmlMode) {
1997
+ this.state = State.InProcessingInstruction;
1998
+ this.sequenceIndex = 0;
1999
+ this.sectionStart = this.index + 1;
2000
+ } else {
2001
+ this.state = State.InSpecialComment;
2002
+ this.sectionStart = this.index;
2003
+ }
2004
+ } else if (this.isTagStartChar(c)) {
2005
+ this.sectionStart = this.index;
2006
+ const special = this.xmlMode || this.cbs.isInForeignContext?.() ? void 0 : specialStartSequences.get(c | 32);
2007
+ if (special === void 0) this.state = State.InTagName;
2008
+ else {
2009
+ this.isSpecial = true;
2010
+ this.currentSequence = special;
2011
+ this.sequenceIndex = 3;
2012
+ this.state = State.SpecialStartSequence;
2013
+ }
2014
+ } else if (c === CharCodes.Slash) this.state = State.BeforeClosingTagName;
2015
+ else {
2016
+ this.state = State.Text;
2017
+ this.stateText(c);
2018
+ }
2019
+ }
2020
+ stateInTagName(c) {
2021
+ if (isEndOfTagSection(c)) {
2022
+ this.cbs.onopentagname(this.sectionStart, this.index);
2023
+ this.sectionStart = -1;
2024
+ this.state = State.BeforeAttributeName;
2025
+ this.stateBeforeAttributeName(c);
2026
+ }
2027
+ }
2028
+ stateBeforeClosingTagName(c) {
2029
+ if (isWhitespace$1(c)) {
2030
+ if (this.xmlMode) {} else {
2031
+ this.state = State.InSpecialComment;
2032
+ this.sectionStart = this.index;
2033
+ }
2034
+ } else if (c === CharCodes.Gt) {
2035
+ this.state = State.Text;
2036
+ if (!this.xmlMode) this.sectionStart = this.index + 1;
2037
+ } else {
2038
+ this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment;
2039
+ this.sectionStart = this.index;
2040
+ }
2041
+ }
2042
+ stateInClosingTagName(c) {
2043
+ if (isEndOfTagSection(c)) {
2044
+ this.cbs.onclosetag(this.sectionStart, this.index);
2045
+ this.sectionStart = -1;
2046
+ this.state = State.AfterClosingTagName;
2047
+ this.stateAfterClosingTagName(c);
2048
+ }
2049
+ }
2050
+ stateAfterClosingTagName(c) {
2051
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
2052
+ this.state = State.Text;
2053
+ this.sectionStart = this.index + 1;
2054
+ }
2055
+ }
2056
+ stateBeforeAttributeName(c) {
2057
+ if (c === CharCodes.Gt) {
2058
+ this.cbs.onopentagend(this.index);
2059
+ this.enterTagBody();
2060
+ this.sectionStart = this.index + 1;
2061
+ } else if (c === CharCodes.Slash) this.state = State.InSelfClosingTag;
2062
+ else if (!isWhitespace$1(c)) {
2063
+ this.state = State.InAttributeName;
2064
+ this.sectionStart = this.index;
2065
+ }
2066
+ }
2067
+ /**
2068
+ * Handle `/` before `>` in an opening tag.
2069
+ *
2070
+ * In HTML mode, text-only tags ignore the self-closing flag and still enter
2071
+ * their raw-text/RCDATA/plaintext state unless self-closing tags are being
2072
+ * recognized. In XML mode, or for ordinary tags, the tokenizer returns to
2073
+ * regular text parsing after emitting the self-closing callback.
2074
+ * @param c Current character code point.
2075
+ */
2076
+ stateInSelfClosingTag(c) {
2077
+ if (c === CharCodes.Gt) {
2078
+ this.cbs.onselfclosingtag(this.index);
2079
+ this.sectionStart = this.index + 1;
2080
+ if (!this.recognizeSelfClosing) {
2081
+ this.enterTagBody();
2082
+ return;
2083
+ }
2084
+ this.state = State.Text;
2085
+ this.isSpecial = false;
2086
+ this.currentSequence = Sequences.Empty;
2087
+ } else if (!isWhitespace$1(c)) {
2088
+ this.state = State.BeforeAttributeName;
2089
+ this.stateBeforeAttributeName(c);
2090
+ }
2091
+ }
2092
+ stateInAttributeName(c) {
2093
+ if (c === CharCodes.Eq || isEndOfTagSection(c)) {
2094
+ this.cbs.onattribname(this.sectionStart, this.index);
2095
+ this.sectionStart = this.index;
2096
+ this.state = State.AfterAttributeName;
2097
+ this.stateAfterAttributeName(c);
2098
+ }
2099
+ }
2100
+ stateAfterAttributeName(c) {
2101
+ if (c === CharCodes.Eq) this.state = State.BeforeAttributeValue;
2102
+ else if (c === CharCodes.Slash || c === CharCodes.Gt) {
2103
+ this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
2104
+ this.sectionStart = -1;
2105
+ this.state = State.BeforeAttributeName;
2106
+ this.stateBeforeAttributeName(c);
2107
+ } else if (!isWhitespace$1(c)) {
2108
+ this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
2109
+ this.state = State.InAttributeName;
2110
+ this.sectionStart = this.index;
2111
+ }
2112
+ }
2113
+ stateBeforeAttributeValue(c) {
2114
+ if (c === CharCodes.DoubleQuote) {
2115
+ this.state = State.InAttributeValueDq;
2116
+ this.sectionStart = this.index + 1;
2117
+ } else if (c === CharCodes.SingleQuote) {
2118
+ this.state = State.InAttributeValueSq;
2119
+ this.sectionStart = this.index + 1;
2120
+ } else if (!isWhitespace$1(c)) {
2121
+ this.sectionStart = this.index;
2122
+ this.state = State.InAttributeValueNq;
2123
+ this.stateInAttributeValueNoQuotes(c);
2124
+ }
2125
+ }
2126
+ handleInAttributeValue(c, quote) {
2127
+ if (c === quote || !this.decodeEntities && this.fastForwardTo(quote)) {
2128
+ this.cbs.onattribdata(this.sectionStart, this.index);
2129
+ this.sectionStart = -1;
2130
+ this.cbs.onattribend(quote === CharCodes.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index + 1);
2131
+ this.state = State.BeforeAttributeName;
2132
+ } else if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
2133
+ }
2134
+ stateInAttributeValueDoubleQuotes(c) {
2135
+ this.handleInAttributeValue(c, CharCodes.DoubleQuote);
2136
+ }
2137
+ stateInAttributeValueSingleQuotes(c) {
2138
+ this.handleInAttributeValue(c, CharCodes.SingleQuote);
2139
+ }
2140
+ stateInAttributeValueNoQuotes(c) {
2141
+ if (isWhitespace$1(c) || c === CharCodes.Gt) {
2142
+ this.cbs.onattribdata(this.sectionStart, this.index);
2143
+ this.sectionStart = -1;
2144
+ this.cbs.onattribend(QuoteType.Unquoted, this.index);
2145
+ this.state = State.BeforeAttributeName;
2146
+ this.stateBeforeAttributeName(c);
2147
+ } else if (this.decodeEntities && c === CharCodes.Amp) this.startEntity();
2148
+ }
2149
+ /**
2150
+ * Distinguish between CDATA, declarations, HTML comments, and HTML bogus
2151
+ * comments after `<!`.
2152
+ *
2153
+ * In HTML mode, only real comments and doctypes stay on declaration paths;
2154
+ * everything else becomes a bogus comment terminated by the next `>`.
2155
+ * @param c Current character code point.
2156
+ */
2157
+ stateBeforeDeclaration(c) {
2158
+ if (c === CharCodes.OpeningSquareBracket) {
2159
+ this.state = State.CDATASequence;
2160
+ this.sequenceIndex = 0;
2161
+ } else if (this.xmlMode) this.state = c === CharCodes.Dash ? State.BeforeComment : State.InDeclaration;
2162
+ else if ((c | 32) === Sequences.Doctype[0]) {
2163
+ this.state = State.DeclarationSequence;
2164
+ this.currentSequence = Sequences.Doctype;
2165
+ this.sequenceIndex = 1;
2166
+ } else if (c === CharCodes.Gt) {
2167
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2168
+ this.state = State.Text;
2169
+ this.sectionStart = this.index + 1;
2170
+ } else if (c === CharCodes.Dash) this.state = State.BeforeComment;
2171
+ else this.state = State.InSpecialComment;
2172
+ }
2173
+ /**
2174
+ * Continue matching `doctype` after `<!d`.
2175
+ *
2176
+ * A full `doctype` match stays on the declaration path; any other name falls
2177
+ * back to an HTML bogus comment, which matches browser behavior for
2178
+ * non-doctype `<!...>` constructs.
2179
+ * @param c Current character code point.
2180
+ */
2181
+ stateDeclarationSequence(c) {
2182
+ if (this.sequenceIndex === this.currentSequence.length) {
2183
+ this.state = State.InDeclaration;
2184
+ this.stateInDeclaration(c);
2185
+ } else if ((c | 32) === this.currentSequence[this.sequenceIndex]) this.sequenceIndex += 1;
2186
+ else if (c === CharCodes.Gt) {
2187
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2188
+ this.state = State.Text;
2189
+ this.sectionStart = this.index + 1;
2190
+ } else this.state = State.InSpecialComment;
2191
+ }
2192
+ stateInDeclaration(c) {
2193
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
2194
+ this.cbs.ondeclaration(this.sectionStart, this.index);
2195
+ this.state = State.Text;
2196
+ this.sectionStart = this.index + 1;
2197
+ }
2198
+ }
2199
+ /**
2200
+ * XML processing instructions (`<?...?>`).
2201
+ *
2202
+ * In HTML mode `<?` is routed to `InSpecialComment` instead, so this
2203
+ * state is only reachable in XML mode.
2204
+ * @param c Current character code point.
2205
+ */
2206
+ stateInProcessingInstruction(c) {
2207
+ if (c === CharCodes.Questionmark) this.sequenceIndex = 1;
2208
+ else if (c === CharCodes.Gt && this.sequenceIndex === 1) {
2209
+ this.cbs.onprocessinginstruction(this.sectionStart, this.index - 1);
2210
+ this.sequenceIndex = 0;
2211
+ this.state = State.Text;
2212
+ this.sectionStart = this.index + 1;
2213
+ } else this.sequenceIndex = Number(this.fastForwardTo(CharCodes.Questionmark));
2214
+ }
2215
+ stateBeforeComment(c) {
2216
+ if (c === CharCodes.Dash) {
2217
+ this.state = State.InCommentLike;
2218
+ this.currentSequence = Sequences.CommentEnd;
2219
+ this.sequenceIndex = 0;
2220
+ this.sectionStart = this.index + 1;
2221
+ } else if (this.xmlMode) this.state = State.InDeclaration;
2222
+ else if (c === CharCodes.Gt) {
2223
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2224
+ this.state = State.Text;
2225
+ this.sectionStart = this.index + 1;
2226
+ } else this.state = State.InSpecialComment;
2227
+ }
2228
+ stateInSpecialComment(c) {
2229
+ if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
2230
+ this.cbs.oncomment(this.sectionStart, this.index, 0);
2231
+ this.state = State.Text;
2232
+ this.sectionStart = this.index + 1;
2233
+ }
2234
+ }
2235
+ startEntity() {
2236
+ this.baseState = this.state;
2237
+ this.state = State.InEntity;
2238
+ this.entityStart = this.index;
2239
+ this.entityDecoder.startEntity(this.xmlMode ? DecodingMode.Strict : this.baseState === State.Text || this.baseState === State.InSpecialTag ? DecodingMode.Legacy : DecodingMode.Attribute);
2240
+ }
2241
+ stateInEntity() {
2242
+ const indexInBuffer = this.index - this.offset;
2243
+ const length = this.entityDecoder.write(this.buffer, indexInBuffer);
2244
+ if (length >= 0) {
2245
+ this.state = this.baseState;
2246
+ if (length === 0) this.index -= 1;
2247
+ } else {
2248
+ if (indexInBuffer < this.buffer.length && this.buffer.charCodeAt(indexInBuffer) === CharCodes.Amp) {
2249
+ this.state = this.baseState;
2250
+ this.index -= 1;
2251
+ return;
2252
+ }
2253
+ this.index = this.offset + this.buffer.length - 1;
2254
+ }
2255
+ }
2256
+ /**
2257
+ * Remove data that has already been consumed from the buffer.
2258
+ */
2259
+ cleanup() {
2260
+ if (this.running && this.sectionStart !== this.index) {
2261
+ if (this.state === State.Text || this.state === State.InPlainText || this.state === State.InSpecialTag && this.sequenceIndex === 0) {
2262
+ this.cbs.ontext(this.sectionStart, this.index);
2263
+ this.sectionStart = this.index;
2264
+ } else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) {
2265
+ this.cbs.onattribdata(this.sectionStart, this.index);
2266
+ this.sectionStart = this.index;
2267
+ }
2268
+ }
2269
+ }
2270
+ shouldContinue() {
2271
+ return this.index < this.buffer.length + this.offset && this.running;
2272
+ }
2273
+ /**
2274
+ * Iterates through the buffer, calling the function corresponding to the current state.
2275
+ *
2276
+ * States that are more likely to be hit are higher up, as a performance improvement.
2277
+ */
2278
+ parse() {
2279
+ while (this.shouldContinue()) {
2280
+ const c = this.buffer.charCodeAt(this.index - this.offset);
2281
+ switch (this.state) {
2282
+ case State.Text:
2283
+ this.stateText(c);
2284
+ break;
2285
+ case State.InPlainText:
2286
+ this.index = this.buffer.length + this.offset - 1;
2287
+ break;
2288
+ case State.SpecialStartSequence:
2289
+ this.stateSpecialStartSequence(c);
2290
+ break;
2291
+ case State.InSpecialTag:
2292
+ this.stateInSpecialTag(c);
2293
+ break;
2294
+ case State.CDATASequence:
2295
+ this.stateCDATASequence(c);
2296
+ break;
2297
+ case State.DeclarationSequence:
2298
+ this.stateDeclarationSequence(c);
2299
+ break;
2300
+ case State.InAttributeValueDq:
2301
+ this.stateInAttributeValueDoubleQuotes(c);
2302
+ break;
2303
+ case State.InAttributeName:
2304
+ this.stateInAttributeName(c);
2305
+ break;
2306
+ case State.InCommentLike:
2307
+ this.stateInCommentLike(c);
2308
+ break;
2309
+ case State.InSpecialComment:
2310
+ this.stateInSpecialComment(c);
2311
+ break;
2312
+ case State.BeforeAttributeName:
2313
+ this.stateBeforeAttributeName(c);
2314
+ break;
2315
+ case State.InTagName:
2316
+ this.stateInTagName(c);
2317
+ break;
2318
+ case State.InClosingTagName:
2319
+ this.stateInClosingTagName(c);
2320
+ break;
2321
+ case State.BeforeTagName:
2322
+ this.stateBeforeTagName(c);
2323
+ break;
2324
+ case State.AfterAttributeName:
2325
+ this.stateAfterAttributeName(c);
2326
+ break;
2327
+ case State.InAttributeValueSq:
2328
+ this.stateInAttributeValueSingleQuotes(c);
2329
+ break;
2330
+ case State.BeforeAttributeValue:
2331
+ this.stateBeforeAttributeValue(c);
2332
+ break;
2333
+ case State.BeforeClosingTagName:
2334
+ this.stateBeforeClosingTagName(c);
2335
+ break;
2336
+ case State.AfterClosingTagName:
2337
+ this.stateAfterClosingTagName(c);
2338
+ break;
2339
+ case State.InAttributeValueNq:
2340
+ this.stateInAttributeValueNoQuotes(c);
2341
+ break;
2342
+ case State.InSelfClosingTag:
2343
+ this.stateInSelfClosingTag(c);
2344
+ break;
2345
+ case State.InDeclaration:
2346
+ this.stateInDeclaration(c);
2347
+ break;
2348
+ case State.BeforeDeclaration:
2349
+ this.stateBeforeDeclaration(c);
2350
+ break;
2351
+ case State.BeforeComment:
2352
+ this.stateBeforeComment(c);
2353
+ break;
2354
+ case State.InProcessingInstruction:
2355
+ this.stateInProcessingInstruction(c);
2356
+ break;
2357
+ case State.InEntity: this.stateInEntity();
2358
+ }
2359
+ this.index++;
2360
+ }
2361
+ this.cleanup();
2362
+ }
2363
+ finish() {
2364
+ if (this.state === State.InEntity) {
2365
+ this.entityDecoder.end();
2366
+ this.state = this.baseState;
2367
+ }
2368
+ this.handleTrailingData();
2369
+ this.cbs.onend();
2370
+ }
2371
+ handleTrailingCommentLikeData(endIndex) {
2372
+ if (this.state !== State.InCommentLike) return false;
2373
+ if (this.currentSequence === Sequences.CdataEnd) {
2374
+ if (this.xmlMode) {
2375
+ if (this.sectionStart < endIndex) this.cbs.oncdata(this.sectionStart, endIndex, 0);
2376
+ } else {
2377
+ const cdataStart = this.sectionStart - Sequences.Cdata.length - 1;
2378
+ this.cbs.oncomment(cdataStart, endIndex, 0);
2379
+ }
2380
+ } else {
2381
+ const offset = this.xmlMode ? 0 : Math.min(this.sequenceIndex, Sequences.CommentEnd.length - 1);
2382
+ this.cbs.oncomment(this.sectionStart, endIndex, offset);
2383
+ }
2384
+ return true;
2385
+ }
2386
+ handleTrailingMarkupDeclaration(endIndex) {
2387
+ if (this.xmlMode) switch (this.state) {
2388
+ case State.InSpecialComment:
2389
+ case State.BeforeComment:
2390
+ case State.CDATASequence:
2391
+ case State.DeclarationSequence:
2392
+ case State.InDeclaration:
2393
+ this.cbs.ontext(this.sectionStart, endIndex);
2394
+ return true;
2395
+ default: return false;
2396
+ }
2397
+ switch (this.state) {
2398
+ case State.BeforeDeclaration:
2399
+ case State.InSpecialComment:
2400
+ case State.BeforeComment:
2401
+ case State.CDATASequence:
2402
+ this.cbs.oncomment(this.sectionStart, endIndex, 0);
2403
+ return true;
2404
+ case State.DeclarationSequence:
2405
+ if (this.sequenceIndex !== Sequences.Doctype.length) this.cbs.oncomment(this.sectionStart, endIndex, 0);
2406
+ return true;
2407
+ case State.InDeclaration: return true;
2408
+ default: return false;
2409
+ }
2410
+ }
2411
+ /** Handle any trailing data. */
2412
+ handleTrailingData() {
2413
+ const endIndex = this.buffer.length + this.offset;
2414
+ if (this.handleTrailingCommentLikeData(endIndex) || this.handleTrailingMarkupDeclaration(endIndex)) return;
2415
+ if (this.sectionStart >= endIndex) return;
2416
+ switch (this.state) {
2417
+ case State.InTagName:
2418
+ case State.BeforeAttributeName:
2419
+ case State.BeforeAttributeValue:
2420
+ case State.AfterAttributeName:
2421
+ case State.InAttributeName:
2422
+ case State.InAttributeValueSq:
2423
+ case State.InAttributeValueDq:
2424
+ case State.InAttributeValueNq:
2425
+ case State.InClosingTagName: break;
2426
+ default: this.cbs.ontext(this.sectionStart, endIndex);
2427
+ }
2428
+ }
2429
+ emitCodePoint(cp, consumed) {
2430
+ if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) {
2431
+ if (this.sectionStart < this.entityStart) this.cbs.onattribdata(this.sectionStart, this.entityStart);
2432
+ this.sectionStart = this.entityStart + consumed;
2433
+ this.index = this.sectionStart - 1;
2434
+ this.cbs.onattribentity(cp);
2435
+ } else {
2436
+ if (this.sectionStart < this.entityStart) this.cbs.ontext(this.sectionStart, this.entityStart);
2437
+ this.sectionStart = this.entityStart + consumed;
2438
+ this.index = this.sectionStart - 1;
2439
+ this.cbs.ontextentity(cp, this.sectionStart);
2440
+ }
2441
+ }
2442
+ };
2443
+ //#endregion
2444
+ //#region ../../node_modules/.pnpm/htmlparser2@12.0.0/node_modules/htmlparser2/dist/Parser.js
2445
+ const { fromCodePoint } = String;
2446
+ const formTags = /* @__PURE__ */ new Set([
2447
+ "input",
2448
+ "option",
2449
+ "optgroup",
2450
+ "select",
2451
+ "button",
2452
+ "datalist",
2453
+ "textarea"
2454
+ ]);
2455
+ const pTag = /* @__PURE__ */ new Set(["p"]);
2456
+ const headingTags = /* @__PURE__ */ new Set([
2457
+ "h1",
2458
+ "h2",
2459
+ "h3",
2460
+ "h4",
2461
+ "h5",
2462
+ "h6",
2463
+ "p"
2464
+ ]);
2465
+ const tableSectionTags = /* @__PURE__ */ new Set(["thead", "tbody"]);
2466
+ const ddtTags = /* @__PURE__ */ new Set(["dd", "dt"]);
2467
+ const rtpTags = /* @__PURE__ */ new Set(["rt", "rp"]);
2468
+ const openImpliesClose = /* @__PURE__ */ new Map([
2469
+ ["tr", /* @__PURE__ */ new Set([
2470
+ "tr",
2471
+ "th",
2472
+ "td"
2473
+ ])],
2474
+ ["th", /* @__PURE__ */ new Set(["th"])],
2475
+ ["td", /* @__PURE__ */ new Set([
2476
+ "thead",
2477
+ "th",
2478
+ "td"
2479
+ ])],
2480
+ ["body", /* @__PURE__ */ new Set([
2481
+ "head",
2482
+ "link",
2483
+ "script"
2484
+ ])],
2485
+ ["a", /* @__PURE__ */ new Set(["a"])],
2486
+ ["li", /* @__PURE__ */ new Set(["li"])],
2487
+ ["p", pTag],
2488
+ ["h1", headingTags],
2489
+ ["h2", headingTags],
2490
+ ["h3", headingTags],
2491
+ ["h4", headingTags],
2492
+ ["h5", headingTags],
2493
+ ["h6", headingTags],
2494
+ ["select", formTags],
2495
+ ["input", formTags],
2496
+ ["output", formTags],
2497
+ ["button", formTags],
2498
+ ["datalist", formTags],
2499
+ ["textarea", formTags],
2500
+ ["option", /* @__PURE__ */ new Set(["option"])],
2501
+ ["optgroup", /* @__PURE__ */ new Set(["optgroup", "option"])],
2502
+ ["dd", ddtTags],
2503
+ ["dt", ddtTags],
2504
+ ["address", pTag],
2505
+ ["article", pTag],
2506
+ ["aside", pTag],
2507
+ ["blockquote", pTag],
2508
+ ["details", pTag],
2509
+ ["div", pTag],
2510
+ ["dl", pTag],
2511
+ ["fieldset", pTag],
2512
+ ["figcaption", pTag],
2513
+ ["figure", pTag],
2514
+ ["footer", pTag],
2515
+ ["form", pTag],
2516
+ ["header", pTag],
2517
+ ["hr", pTag],
2518
+ ["main", pTag],
2519
+ ["nav", pTag],
2520
+ ["ol", pTag],
2521
+ ["pre", pTag],
2522
+ ["section", pTag],
2523
+ ["table", pTag],
2524
+ ["ul", pTag],
2525
+ ["rt", rtpTags],
2526
+ ["rp", rtpTags],
2527
+ ["tbody", tableSectionTags],
2528
+ ["tfoot", tableSectionTags]
2529
+ ]);
2530
+ const DOCUMENT_TYPE = "doctype";
2531
+ const voidElements = /* @__PURE__ */ new Set([
2532
+ "area",
2533
+ "base",
2534
+ "basefont",
2535
+ "br",
2536
+ "col",
2537
+ "command",
2538
+ "embed",
2539
+ "frame",
2540
+ "hr",
2541
+ "img",
2542
+ "input",
2543
+ "isindex",
2544
+ "keygen",
2545
+ "link",
2546
+ "meta",
2547
+ "param",
2548
+ "source",
2549
+ "track",
2550
+ "wbr"
2551
+ ]);
2552
+ const foreignContextElements = /* @__PURE__ */ new Set(["math", "svg"]);
2553
+ /**
2554
+ * Elements that can be used to integrate HTML content within foreign namespaces (e.g., SVG or MathML).
2555
+ *
2556
+ * Entries must use the SVG-adjusted casing (e.g. "foreignObject" not
2557
+ * "foreignobject") since they are compared against adjusted tag names.
2558
+ */
2559
+ const htmlIntegrationElements = /* @__PURE__ */ new Set([
2560
+ "mi",
2561
+ "mo",
2562
+ "mn",
2563
+ "ms",
2564
+ "mtext",
2565
+ "annotation-xml",
2566
+ "foreignObject",
2567
+ "desc",
2568
+ "title"
2569
+ ]);
2570
+ const svgTagNameAdjustments = /* @__PURE__ */ new Map([
2571
+ ["altglyph", "altGlyph"],
2572
+ ["altglyphdef", "altGlyphDef"],
2573
+ ["altglyphitem", "altGlyphItem"],
2574
+ ["animatecolor", "animateColor"],
2575
+ ["animatemotion", "animateMotion"],
2576
+ ["animatetransform", "animateTransform"],
2577
+ ["clippath", "clipPath"],
2578
+ ["feblend", "feBlend"],
2579
+ ["fecolormatrix", "feColorMatrix"],
2580
+ ["fecomponenttransfer", "feComponentTransfer"],
2581
+ ["fecomposite", "feComposite"],
2582
+ ["feconvolvematrix", "feConvolveMatrix"],
2583
+ ["fediffuselighting", "feDiffuseLighting"],
2584
+ ["fedisplacementmap", "feDisplacementMap"],
2585
+ ["fedistantlight", "feDistantLight"],
2586
+ ["fedropshadow", "feDropShadow"],
2587
+ ["feflood", "feFlood"],
2588
+ ["fefunca", "feFuncA"],
2589
+ ["fefuncb", "feFuncB"],
2590
+ ["fefuncg", "feFuncG"],
2591
+ ["fefuncr", "feFuncR"],
2592
+ ["fegaussianblur", "feGaussianBlur"],
2593
+ ["feimage", "feImage"],
2594
+ ["femerge", "feMerge"],
2595
+ ["femergenode", "feMergeNode"],
2596
+ ["femorphology", "feMorphology"],
2597
+ ["feoffset", "feOffset"],
2598
+ ["fepointlight", "fePointLight"],
2599
+ ["fespecularlighting", "feSpecularLighting"],
2600
+ ["fespotlight", "feSpotLight"],
2601
+ ["fetile", "feTile"],
2602
+ ["feturbulence", "feTurbulence"],
2603
+ ["foreignobject", "foreignObject"],
2604
+ ["glyphref", "glyphRef"],
2605
+ ["lineargradient", "linearGradient"],
2606
+ ["radialgradient", "radialGradient"],
2607
+ ["textpath", "textPath"]
2608
+ ]);
2609
+ var ForeignContext;
2610
+ (function(ForeignContext) {
2611
+ ForeignContext[ForeignContext["None"] = 0] = "None";
2612
+ ForeignContext[ForeignContext["Svg"] = 1] = "Svg";
2613
+ ForeignContext[ForeignContext["MathML"] = 2] = "MathML";
2614
+ })(ForeignContext || (ForeignContext = {}));
2615
+ const reNameEnd = /\s|\//;
2616
+ /**
2617
+ * Incremental parser implementation.
2618
+ */
2619
+ var Parser = class {
2620
+ options;
2621
+ /** The start index of the last event. */
2622
+ startIndex = 0;
2623
+ /** The end index of the last event. */
2624
+ endIndex = 0;
2625
+ /**
2626
+ * Store the start index of the current open tag,
2627
+ * so we can update the start index for attributes.
2628
+ */
2629
+ openTagStart = 0;
2630
+ tagname = "";
2631
+ attribname = "";
2632
+ attribvalue = "";
2633
+ attribs = null;
2634
+ stack = [];
2635
+ foreignContext;
2636
+ cbs;
2637
+ lowerCaseTagNames;
2638
+ lowerCaseAttributeNames;
2639
+ recognizeSelfClosing;
2640
+ /** We are parsing HTML. Inverse of the `xmlMode` option. */
2641
+ htmlMode;
2642
+ tokenizer;
2643
+ buffers = [];
2644
+ bufferOffset = 0;
2645
+ /** The index of the last written buffer. Used when resuming after a `pause()`. */
2646
+ writeIndex = 0;
2647
+ /** Indicates whether the parser has finished running / `.end` has been called. */
2648
+ ended = false;
2649
+ constructor(cbs, options = {}) {
2650
+ this.options = options;
2651
+ this.cbs = cbs ?? {};
2652
+ this.htmlMode = !this.options.xmlMode;
2653
+ this.lowerCaseTagNames = options.lowerCaseTags ?? this.htmlMode;
2654
+ this.lowerCaseAttributeNames = options.lowerCaseAttributeNames ?? this.htmlMode;
2655
+ this.recognizeSelfClosing = options.recognizeSelfClosing ?? !this.htmlMode;
2656
+ this.tokenizer = new (options.Tokenizer ?? Tokenizer)(this.options, this);
2657
+ this.foreignContext = [ForeignContext.None];
2658
+ this.cbs.onparserinit?.(this);
2659
+ }
2660
+ /**
2661
+ * @param start Start index for the current parser event.
2662
+ * @param endIndex End index for the current parser event.
2663
+ * @internal
2664
+ */
2665
+ ontext(start, endIndex) {
2666
+ const data = this.getSlice(start, endIndex);
2667
+ this.endIndex = endIndex - 1;
2668
+ this.cbs.ontext?.(data);
2669
+ this.startIndex = endIndex;
2670
+ }
2671
+ /**
2672
+ * @param cp Current Unicode code point.
2673
+ * @param endIndex End index for the current parser event.
2674
+ * @internal
2675
+ */
2676
+ ontextentity(cp, endIndex) {
2677
+ this.endIndex = endIndex - 1;
2678
+ this.cbs.ontext?.(fromCodePoint(cp));
2679
+ this.startIndex = endIndex;
2680
+ }
2681
+ /** @internal */
2682
+ isInForeignContext() {
2683
+ return this.foreignContext[0] !== ForeignContext.None;
2684
+ }
2685
+ /**
2686
+ * Checks if the current tag is a void element. Override this if you want
2687
+ * to specify your own additional void elements.
2688
+ * @param name Name of the pseudo selector.
2689
+ */
2690
+ isVoidElement(name) {
2691
+ return this.htmlMode && voidElements.has(name);
2692
+ }
2693
+ /**
2694
+ * Read a tag name from the buffer.
2695
+ *
2696
+ * When `lowerCaseTagNames` is enabled (the default in HTML mode), the name
2697
+ * is lowercased and may be adjusted for SVG casing or the `image` → `img`
2698
+ * alias.
2699
+ * @param start Start index of the tag name in the buffer.
2700
+ * @param endIndex End index of the tag name in the buffer.
2701
+ */
2702
+ readTagName(start, endIndex) {
2703
+ const name = this.lowerCaseTagNames ? this.getSlice(start, endIndex).toLowerCase() : this.getSlice(start, endIndex);
2704
+ if (!(this.lowerCaseTagNames && this.htmlMode)) return name;
2705
+ if (this.foreignContext[0] === ForeignContext.Svg) return svgTagNameAdjustments.get(name) ?? name;
2706
+ if (this.foreignContext.length > 1) {
2707
+ const adjusted = svgTagNameAdjustments.get(name);
2708
+ if (adjusted !== void 0 && this.stack.includes(adjusted)) return adjusted;
2709
+ }
2710
+ if (!this.isInForeignContext()) return name === "image" ? "img" : name;
2711
+ return name;
2712
+ }
2713
+ /**
2714
+ * @param start Start index for the current parser event.
2715
+ * @param endIndex End index for the current parser event.
2716
+ * @internal
2717
+ */
2718
+ onopentagname(start, endIndex) {
2719
+ this.endIndex = endIndex;
2720
+ this.emitOpenTag(this.readTagName(start, endIndex));
2721
+ }
2722
+ emitOpenTag(name) {
2723
+ this.openTagStart = this.startIndex;
2724
+ this.tagname = name;
2725
+ if (this.htmlMode && name === "form" && this.stack.includes("form")) {
2726
+ this.tagname = "";
2727
+ return;
2728
+ }
2729
+ const impliesClose = this.htmlMode && openImpliesClose.get(name);
2730
+ if (impliesClose) while (this.stack.length > 0 && impliesClose.has(this.stack[0])) this.popElement(true);
2731
+ if (!this.isVoidElement(name)) {
2732
+ this.stack.unshift(name);
2733
+ if (this.htmlMode) {
2734
+ if (name === "svg") this.foreignContext.unshift(ForeignContext.Svg);
2735
+ else if (name === "math") this.foreignContext.unshift(ForeignContext.MathML);
2736
+ else if (htmlIntegrationElements.has(name)) this.foreignContext.unshift(ForeignContext.None);
2737
+ }
2738
+ }
2739
+ this.cbs.onopentagname?.(name);
2740
+ if (this.cbs.onopentag) this.attribs = {};
2741
+ }
2742
+ endOpenTag(isImplied) {
2743
+ this.startIndex = this.openTagStart;
2744
+ if (this.attribs) {
2745
+ this.cbs.onopentag?.(this.tagname, this.attribs, isImplied);
2746
+ this.attribs = null;
2747
+ }
2748
+ if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) this.cbs.onclosetag(this.tagname, true);
2749
+ this.tagname = "";
2750
+ }
2751
+ /**
2752
+ * @param endIndex End index for the current parser event.
2753
+ * @internal
2754
+ */
2755
+ onopentagend(endIndex) {
2756
+ this.endIndex = endIndex;
2757
+ this.endOpenTag(false);
2758
+ this.startIndex = endIndex + 1;
2759
+ }
2760
+ /**
2761
+ * @param start Start index for the current parser event.
2762
+ * @param endIndex End index for the current parser event.
2763
+ * @internal
2764
+ */
2765
+ onclosetag(start, endIndex) {
2766
+ this.endIndex = endIndex;
2767
+ const name = this.readTagName(start, endIndex);
2768
+ if (!this.isVoidElement(name)) {
2769
+ const pos = this.stack.indexOf(name);
2770
+ if (pos !== -1) {
2771
+ for (let index = 0; index < pos; index++) this.popElement(true);
2772
+ this.popElement(false);
2773
+ } else if (this.htmlMode && name === "p") {
2774
+ this.emitOpenTag("p");
2775
+ this.closeCurrentTag(true);
2776
+ }
2777
+ } else if (this.htmlMode && name === "br") {
2778
+ this.cbs.onopentagname?.("br");
2779
+ this.cbs.onopentag?.("br", {}, true);
2780
+ this.cbs.onclosetag?.("br", false);
2781
+ }
2782
+ this.startIndex = endIndex + 1;
2783
+ }
2784
+ /**
2785
+ * @param endIndex End index for the current parser event.
2786
+ * @internal
2787
+ */
2788
+ onselfclosingtag(endIndex) {
2789
+ this.endIndex = endIndex;
2790
+ if (this.recognizeSelfClosing || this.isInForeignContext()) {
2791
+ this.closeCurrentTag(false);
2792
+ this.startIndex = endIndex + 1;
2793
+ } else this.onopentagend(endIndex);
2794
+ }
2795
+ /**
2796
+ * Pop the top element off the stack, emit a close event, and maintain
2797
+ * the foreign context stack.
2798
+ * @param implied Whether this close is implied (not from an explicit end tag).
2799
+ */
2800
+ popElement(implied) {
2801
+ const element = this.stack.shift();
2802
+ if (this.htmlMode && (foreignContextElements.has(element) || htmlIntegrationElements.has(element))) this.foreignContext.shift();
2803
+ this.cbs.onclosetag?.(element, implied);
2804
+ }
2805
+ closeCurrentTag(isOpenImplied) {
2806
+ const name = this.tagname;
2807
+ this.endOpenTag(isOpenImplied);
2808
+ if (this.stack[0] === name) this.popElement(!isOpenImplied);
2809
+ }
2810
+ /**
2811
+ * @param start Start index for the current parser event.
2812
+ * @param endIndex End index for the current parser event.
2813
+ * @internal
2814
+ */
2815
+ onattribname(start, endIndex) {
2816
+ this.startIndex = start;
2817
+ const name = this.getSlice(start, endIndex);
2818
+ this.attribname = this.lowerCaseAttributeNames ? name.toLowerCase() : name;
2819
+ }
2820
+ /**
2821
+ * @param start Start index for the current parser event.
2822
+ * @param endIndex End index for the current parser event.
2823
+ * @internal
2824
+ */
2825
+ onattribdata(start, endIndex) {
2826
+ this.attribvalue += this.getSlice(start, endIndex);
2827
+ }
2828
+ /**
2829
+ * @param cp Current Unicode code point.
2830
+ * @internal
2831
+ */
2832
+ onattribentity(cp) {
2833
+ this.attribvalue += fromCodePoint(cp);
2834
+ }
2835
+ /**
2836
+ * @param quote Quote type used for the current attribute.
2837
+ * @param endIndex End index for the current parser event.
2838
+ * @internal
2839
+ */
2840
+ onattribend(quote, endIndex) {
2841
+ this.endIndex = endIndex;
2842
+ this.cbs.onattribute?.(this.attribname, this.attribvalue, quote === QuoteType.Double ? "\"" : quote === QuoteType.Single ? "'" : quote === QuoteType.NoValue ? void 0 : null);
2843
+ if (this.attribs && !Object.hasOwn(this.attribs, this.attribname)) this.attribs[this.attribname] = this.attribvalue;
2844
+ this.attribvalue = "";
2845
+ }
2846
+ getInstructionName(value) {
2847
+ const index = value.search(reNameEnd);
2848
+ let name = index < 0 ? value : value.substr(0, index);
2849
+ if (this.lowerCaseTagNames) name = name.toLowerCase();
2850
+ return name;
2851
+ }
2852
+ /**
2853
+ * @param start Start index for the current parser event.
2854
+ * @param endIndex End index for the current parser event.
2855
+ * @internal
2856
+ */
2857
+ ondeclaration(start, endIndex) {
2858
+ this.endIndex = endIndex;
2859
+ const value = this.getSlice(start, endIndex);
2860
+ if (this.cbs.onprocessinginstruction) {
2861
+ const name = this.htmlMode ? this.lowerCaseTagNames ? DOCUMENT_TYPE : value.slice(0, 7) : this.getInstructionName(value);
2862
+ this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);
2863
+ }
2864
+ this.startIndex = endIndex + 1;
2865
+ }
2866
+ /**
2867
+ * @param start Start index for the current parser event.
2868
+ * @param endIndex End index for the current parser event.
2869
+ * @internal
2870
+ */
2871
+ onprocessinginstruction(start, endIndex) {
2872
+ this.endIndex = endIndex;
2873
+ const value = this.getSlice(start, endIndex);
2874
+ if (this.cbs.onprocessinginstruction) {
2875
+ const name = this.getInstructionName(value);
2876
+ this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);
2877
+ }
2878
+ this.startIndex = endIndex + 1;
2879
+ }
2880
+ /**
2881
+ * @param start Start index for the current parser event.
2882
+ * @param endIndex End index for the current parser event.
2883
+ * @param offset Offset applied when computing parser indices.
2884
+ * @internal
2885
+ */
2886
+ oncomment(start, endIndex, offset) {
2887
+ this.endIndex = endIndex;
2888
+ this.cbs.oncomment?.(this.getSlice(start, endIndex - offset));
2889
+ this.cbs.oncommentend?.();
2890
+ this.startIndex = endIndex + 1;
2891
+ }
2892
+ /**
2893
+ * @param start Start index for the current parser event.
2894
+ * @param endIndex End index for the current parser event.
2895
+ * @param offset Offset applied when computing parser indices.
2896
+ * @internal
2897
+ */
2898
+ oncdata(start, endIndex, offset) {
2899
+ this.endIndex = endIndex;
2900
+ const value = this.getSlice(start, endIndex - offset);
2901
+ if (!this.htmlMode || this.options.recognizeCDATA) {
2902
+ this.cbs.oncdatastart?.();
2903
+ this.cbs.ontext?.(value);
2904
+ this.cbs.oncdataend?.();
2905
+ } else if (this.isInForeignContext()) this.cbs.ontext?.(value);
2906
+ else {
2907
+ this.cbs.oncomment?.(`[CDATA[${value}]]`);
2908
+ this.cbs.oncommentend?.();
2909
+ }
2910
+ this.startIndex = endIndex + 1;
2911
+ }
2912
+ /** @internal */
2913
+ onend() {
2914
+ if (this.cbs.onclosetag) {
2915
+ this.endIndex = this.startIndex;
2916
+ for (let index = 0; index < this.stack.length; index++) this.cbs.onclosetag(this.stack[index], true);
2917
+ }
2918
+ this.cbs.onend?.();
2919
+ }
2920
+ /**
2921
+ * Resets the parser to a blank state, ready to parse a new HTML document
2922
+ */
2923
+ reset() {
2924
+ this.cbs.onreset?.();
2925
+ this.tokenizer.reset();
2926
+ this.tagname = "";
2927
+ this.attribname = "";
2928
+ this.attribvalue = "";
2929
+ this.attribs = null;
2930
+ this.stack.length = 0;
2931
+ this.startIndex = 0;
2932
+ this.endIndex = 0;
2933
+ this.cbs.onparserinit?.(this);
2934
+ this.buffers.length = 0;
2935
+ this.foreignContext.length = 0;
2936
+ this.foreignContext.unshift(ForeignContext.None);
2937
+ this.bufferOffset = 0;
2938
+ this.writeIndex = 0;
2939
+ this.ended = false;
2940
+ }
2941
+ /**
2942
+ * Resets the parser, then parses a complete document and
2943
+ * pushes it to the handler.
2944
+ * @param data Document to parse.
2945
+ */
2946
+ parseComplete(data) {
2947
+ this.reset();
2948
+ this.end(data);
2949
+ }
2950
+ getSlice(start, end) {
2951
+ if (start === end) return "";
2952
+ while (start - this.bufferOffset >= this.buffers[0].length) this.shiftBuffer();
2953
+ let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);
2954
+ while (end - this.bufferOffset > this.buffers[0].length) {
2955
+ this.shiftBuffer();
2956
+ slice += this.buffers[0].slice(0, end - this.bufferOffset);
2957
+ }
2958
+ return slice;
2959
+ }
2960
+ shiftBuffer() {
2961
+ this.bufferOffset += this.buffers[0].length;
2962
+ this.writeIndex--;
2963
+ this.buffers.shift();
2964
+ }
2965
+ /**
2966
+ * Parses a chunk of data and calls the corresponding callbacks.
2967
+ * @param chunk Chunk to parse.
2968
+ */
2969
+ write(chunk) {
2970
+ if (this.ended) {
2971
+ this.cbs.onerror?.(/* @__PURE__ */ new Error(".write() after done!"));
2972
+ return;
2973
+ }
2974
+ this.buffers.push(chunk);
2975
+ if (this.tokenizer.running) {
2976
+ this.tokenizer.write(chunk);
2977
+ this.writeIndex++;
2978
+ }
2979
+ }
2980
+ /**
2981
+ * Parses the end of the buffer and clears the stack, calls onend.
2982
+ * @param chunk Optional final chunk to parse.
2983
+ */
2984
+ end(chunk) {
2985
+ if (this.ended) {
2986
+ this.cbs.onerror?.(/* @__PURE__ */ new Error(".end() after done!"));
2987
+ return;
2988
+ }
2989
+ if (chunk) this.write(chunk);
2990
+ this.ended = true;
2991
+ this.tokenizer.end();
2992
+ }
2993
+ /**
2994
+ * Pauses parsing. The parser won't emit events until `resume` is called.
2995
+ */
2996
+ pause() {
2997
+ this.tokenizer.pause();
2998
+ }
2999
+ /**
3000
+ * Resumes parsing after `pause` was called.
3001
+ */
3002
+ resume() {
3003
+ this.tokenizer.resume();
3004
+ while (this.tokenizer.running && this.writeIndex < this.buffers.length) this.tokenizer.write(this.buffers[this.writeIndex++]);
3005
+ if (this.ended) this.tokenizer.end();
3006
+ }
3007
+ };
3008
+ //#endregion
3009
+ //#region src/extraction/source-filters.ts
3010
+ const HTML_ATTRIBUTE_NAME_CANDIDATE_RE$1 = /^(?:class|className|hover-class|hoverClass)$/;
3011
+ const CSS_DIRECTIVE_CANDIDATE_RE = /^@(?:apply|tailwind|source|config|plugin|theme|utility|custom-variant|variant)$/;
3012
+ const CSS_APPLY_IMPORTANT = "!important";
3013
+ const CLASS_LIKE_CANDIDATE_RE = /[:![\]#/%._\-\d]/;
3014
+ const JS_LIKE_SOURCE_EXTENSION_RE = /^[cm]?[jt]sx?$/;
3015
+ const MIXED_TEMPLATE_SOURCE_EXTENSION_RE = /^(?:vue|uvue|nvue|svelte|mpx)$/;
3016
+ const VUE_LIKE_SOURCE_EXTENSION_RE = /^(?:vue|uvue|nvue)$/;
3017
+ const CSS_LIKE_SOURCE_EXTENSION_RE = /^(?:css|wxss|acss|jxss|ttss|qss|tyss|scss|sass|less|styl|stylus)$/;
3018
+ function isWhitespace(value) {
3019
+ return value === " " || value === "\n" || value === "\r" || value === " " || value === "\f";
3020
+ }
3021
+ function isHtmlAttributeNameCandidate(content, candidate) {
3022
+ if (!HTML_ATTRIBUTE_NAME_CANDIDATE_RE$1.test(candidate.rawCandidate)) return false;
3023
+ let index = candidate.end;
3024
+ while (isWhitespace(content[index])) index++;
3025
+ return content[index] === "=";
3026
+ }
3027
+ function isInsideHtmlTagText(content, candidate) {
3028
+ if (content.lastIndexOf("<", candidate.start) > content.lastIndexOf(">", candidate.start)) return false;
3029
+ const nextOpen = content.indexOf("<", candidate.end);
3030
+ return nextOpen !== -1 && (nextOpen < content.indexOf(">", candidate.end) || !content.includes(">", candidate.end));
3031
+ }
3032
+ function isCssDirectiveCandidate(candidate) {
3033
+ return candidate === CSS_APPLY_IMPORTANT || CSS_DIRECTIVE_CANDIDATE_RE.test(candidate);
3034
+ }
3035
+ function isClassLikeCandidate(candidate) {
3036
+ return CLASS_LIKE_CANDIDATE_RE.test(candidate);
3037
+ }
3038
+ function isCandidateInCssApplyParams(content, candidate) {
3039
+ const apply = content.lastIndexOf("@apply", candidate.start);
3040
+ if (apply === -1) return false;
3041
+ const boundary = content.slice(apply + 6, candidate.start);
3042
+ return !/[;{}]/.test(boundary);
3043
+ }
3044
+ function shouldKeepSourceCandidate(content, extension, candidate, jsStringStaticRanges, skipHtmlContextChecks = false) {
3045
+ if (!candidate.rawCandidate || isCssDirectiveCandidate(candidate.rawCandidate)) return false;
3046
+ if (CSS_LIKE_SOURCE_EXTENSION_RE.test(extension) && !isCandidateInCssApplyParams(content, candidate)) return false;
3047
+ if (!skipHtmlContextChecks) {
3048
+ if (isHtmlAttributeNameCandidate(content, candidate)) return false;
3049
+ if (isInsideHtmlTagText(content, candidate)) return false;
3050
+ }
3051
+ if (JS_LIKE_SOURCE_EXTENSION_RE.test(extension) && !isCandidateInsideJsStringStaticRanges(jsStringStaticRanges ?? createJsStringStaticRanges(content), candidate.start)) return false;
3052
+ return true;
3053
+ }
3054
+ function createLocalCandidate(candidate) {
3055
+ return {
3056
+ rawCandidate: candidate.rawCandidate,
3057
+ start: candidate.localStart,
3058
+ end: candidate.localStart + candidate.rawCandidate.length
3059
+ };
3060
+ }
3061
+ function dedupeCandidatesWithPositions(candidates) {
3062
+ const seen = /* @__PURE__ */ new Set();
3063
+ return candidates.filter((candidate) => {
3064
+ const key = `${candidate.start}:${candidate.end}:${candidate.rawCandidate}`;
3065
+ if (seen.has(key)) return false;
3066
+ seen.add(key);
3067
+ return true;
3068
+ });
3069
+ }
3070
+ //#endregion
3071
+ //#region src/extraction/sfc.ts
3072
+ const HTML_ATTRIBUTE_NAME_CANDIDATE_RE = /^(?:class|className|hover-class|hoverClass)$/;
3073
+ const HTML_BOUND_ATTRIBUTE_PREFIX_RE = /^(?::|v-bind:|bind:)/;
3074
+ const VUE_HTML_TEMPLATE_LANG_RE = /^(?:html)?$/i;
3075
+ const SFC_SCRIPT_BLOCK_RE = /<script\b[^>]*>([\s\S]*?)<\/script>/gi;
3076
+ const SFC_STYLE_BLOCK_RE = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
3077
+ const SFC_TEMPLATE_BLOCK_RE = /<template\b([^>]*)>([\s\S]*?)<\/template>/gi;
3078
+ const SFC_LANG_ATTRIBUTE_RE = /\blang\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+))/i;
3079
+ function normalizeVueBoundAttributeName(name) {
3080
+ return name.replace(HTML_BOUND_ATTRIBUTE_PREFIX_RE, "");
3081
+ }
3082
+ function isVueClassAttributeNameCandidate(name) {
3083
+ return HTML_ATTRIBUTE_NAME_CANDIDATE_RE.test(normalizeVueBoundAttributeName(name));
3084
+ }
3085
+ function isVueBoundAttributeName(name) {
3086
+ return HTML_BOUND_ATTRIBUTE_PREFIX_RE.test(name);
3087
+ }
3088
+ function normalizeVueTemplateLang(lang) {
3089
+ return lang?.trim().toLowerCase() ?? "";
3090
+ }
3091
+ function getSfcBlockLang(attributes) {
3092
+ const match = SFC_LANG_ATTRIBUTE_RE.exec(attributes);
3093
+ return normalizeVueTemplateLang(match?.[1] ?? match?.[2] ?? match?.[3]);
3094
+ }
3095
+ function isVueHtmlTemplateLang(lang) {
3096
+ return VUE_HTML_TEMPLATE_LANG_RE.test(lang);
3097
+ }
3098
+ function findAttributeValueStart(attributeSource, value) {
3099
+ const equalIndex = attributeSource.indexOf("=");
3100
+ if (equalIndex === -1) return -1;
3101
+ let valueStart = equalIndex + 1;
3102
+ while (isWhitespace(attributeSource[valueStart])) valueStart++;
3103
+ const quote = attributeSource[valueStart];
3104
+ if (quote === "\"" || quote === "'") valueStart++;
3105
+ const valueIndex = attributeSource.indexOf(value, valueStart);
3106
+ return valueIndex === -1 ? valueStart : valueIndex;
3107
+ }
3108
+ async function extractJsStringSourceCandidates(content, offset, extractRawCandidatesWithPositions, options) {
3109
+ return extractBatchedSourceSegmentCandidates(createJsStringSourceSegments(content, offset), "html", extractRawCandidatesWithPositions, options);
3110
+ }
3111
+ async function extractMixedSourceScriptCandidates(content, extractRawCandidatesWithPositions, options) {
3112
+ const candidates = [];
3113
+ SFC_SCRIPT_BLOCK_RE.lastIndex = 0;
3114
+ let match = SFC_SCRIPT_BLOCK_RE.exec(content);
3115
+ while (match !== null) {
3116
+ const scriptContent = match[1] ?? "";
3117
+ const scriptStart = match.index + match[0].indexOf(scriptContent);
3118
+ candidates.push(...await extractJsStringSourceCandidates(scriptContent, scriptStart, extractRawCandidatesWithPositions, options));
3119
+ match = SFC_SCRIPT_BLOCK_RE.exec(content);
3120
+ }
3121
+ return candidates;
3122
+ }
3123
+ async function extractMixedSourceStyleCandidates(content, extractRawCandidatesWithPositions, options) {
3124
+ const candidates = [];
3125
+ SFC_STYLE_BLOCK_RE.lastIndex = 0;
3126
+ let match = SFC_STYLE_BLOCK_RE.exec(content);
3127
+ while (match !== null) {
3128
+ const styleContent = match[1] ?? "";
3129
+ const styleStart = match.index + match[0].indexOf(styleContent);
3130
+ const styleCandidates = await extractCssApplyCandidates(styleContent, "css", extractRawCandidatesWithPositions, options);
3131
+ candidates.push(...styleCandidates.map((candidate) => ({
3132
+ content: candidate.content,
3133
+ extension: candidate.extension,
3134
+ localStart: candidate.localStart,
3135
+ rawCandidate: candidate.rawCandidate,
3136
+ start: candidate.start + styleStart,
3137
+ end: candidate.end + styleStart
3138
+ })));
3139
+ match = SFC_STYLE_BLOCK_RE.exec(content);
3140
+ }
3141
+ return candidates;
3142
+ }
3143
+ async function extractVueTemplateAttributeCandidates(content, extractRawCandidatesWithPositions, options) {
3144
+ const htmlSegments = [];
3145
+ const jsSegments = [];
3146
+ const parser = new Parser({ onattribute(name, value) {
3147
+ if (!value || !isVueClassAttributeNameCandidate(name)) return;
3148
+ const attributeStart = parser.startIndex;
3149
+ const valueStartInAttribute = findAttributeValueStart(content.slice(attributeStart, parser.endIndex + 1), value);
3150
+ if (valueStartInAttribute === -1) return;
3151
+ const extension = isVueBoundAttributeName(name) ? "js" : "html";
3152
+ const valueStart = attributeStart + valueStartInAttribute;
3153
+ (extension === "js" ? jsSegments : htmlSegments).push({
3154
+ content: value,
3155
+ start: valueStart
3156
+ });
3157
+ } }, { lowerCaseAttributeNames: false });
3158
+ parser.write(content);
3159
+ parser.end();
3160
+ const jsStringSegments = jsSegments.flatMap((segment) => createJsStringSourceSegments(segment.content, segment.start));
3161
+ const [htmlCandidates, jsCandidates] = await Promise.all([extractBatchedSourceSegmentCandidates(htmlSegments, "html", extractRawCandidatesWithPositions, options), extractBatchedSourceSegmentCandidates(jsStringSegments, "html", extractRawCandidatesWithPositions, options)]);
3162
+ return [...htmlCandidates, ...jsCandidates];
3163
+ }
3164
+ async function extractVueNonHtmlTemplateCandidates(content, extractRawCandidatesWithPositions, options) {
3165
+ const candidates = [];
3166
+ SFC_TEMPLATE_BLOCK_RE.lastIndex = 0;
3167
+ let match = SFC_TEMPLATE_BLOCK_RE.exec(content);
3168
+ while (match !== null) {
3169
+ const attributes = match[1] ?? "";
3170
+ const templateContent = match[2] ?? "";
3171
+ const lang = getSfcBlockLang(attributes);
3172
+ if (isVueHtmlTemplateLang(lang)) {
3173
+ match = SFC_TEMPLATE_BLOCK_RE.exec(content);
3174
+ continue;
3175
+ }
3176
+ const templateStart = match.index + match[0].indexOf(templateContent);
3177
+ const templateCandidates = await extractRawCandidatesWithPositions(templateContent, lang, options);
3178
+ candidates.push(...templateCandidates.map((candidate) => ({
3179
+ content: templateContent,
3180
+ extension: lang,
3181
+ localStart: candidate.start,
3182
+ rawCandidate: candidate.rawCandidate,
3183
+ skipHtmlContextChecks: true,
3184
+ start: candidate.start + templateStart,
3185
+ end: candidate.end + templateStart
3186
+ })).filter((candidate) => isClassLikeCandidate(candidate.rawCandidate)));
3187
+ match = SFC_TEMPLATE_BLOCK_RE.exec(content);
3188
+ }
3189
+ return candidates;
3190
+ }
3191
+ async function extractVueLikeSourceCandidates(content, extractRawCandidatesWithPositions, options) {
3192
+ const [templateCandidates, preprocessedTemplateCandidates, scriptCandidates, styleCandidates] = await Promise.all([
3193
+ extractVueTemplateAttributeCandidates(content, extractRawCandidatesWithPositions, options),
3194
+ extractVueNonHtmlTemplateCandidates(content, extractRawCandidatesWithPositions, options),
3195
+ extractMixedSourceScriptCandidates(content, extractRawCandidatesWithPositions, options),
3196
+ extractMixedSourceStyleCandidates(content, extractRawCandidatesWithPositions, options)
3197
+ ]);
3198
+ return [
3199
+ ...templateCandidates,
3200
+ ...preprocessedTemplateCandidates,
3201
+ ...scriptCandidates,
3202
+ ...styleCandidates
3203
+ ];
3204
+ }
3205
+ //#endregion
3206
+ //#region src/extraction/candidate-extractor/raw.ts
3207
+ async function extractRawCandidatesWithPositions(content, extension = "html", options) {
3208
+ const { Scanner } = await getOxideModule();
3209
+ const candidates = new Scanner({}).getCandidatesWithPositions({
3210
+ content,
3211
+ extension
3212
+ }).map(({ candidate, position }) => ({
3213
+ rawCandidate: candidate,
3214
+ start: position,
3215
+ end: position + candidate.length
3216
+ }));
3217
+ candidates.push(...extractBareArbitraryValueSourceCandidatesWithPositions(content, options?.bareArbitraryValues));
3218
+ return dedupeCandidatesWithPositions(candidates);
3219
+ }
3220
+ async function extractSourceCandidatesWithPositions(content, extension = "html", options) {
3221
+ const normalizedExtension = extension.replace(/^\./, "");
3222
+ const candidates = VUE_LIKE_SOURCE_EXTENSION_RE.test(normalizedExtension) ? await extractVueLikeSourceCandidates(content, extractRawCandidatesWithPositions, options) : CSS_LIKE_SOURCE_EXTENSION_RE.test(normalizedExtension) ? await extractCssApplyCandidates(content, normalizedExtension, extractRawCandidatesWithPositions, options) : (await extractRawCandidatesWithPositions(content, normalizedExtension, options)).map((candidate) => ({
3223
+ ...candidate,
3224
+ content,
3225
+ extension: normalizedExtension,
3226
+ localStart: candidate.start
3227
+ }));
3228
+ if (!VUE_LIKE_SOURCE_EXTENSION_RE.test(normalizedExtension) && MIXED_TEMPLATE_SOURCE_EXTENSION_RE.test(normalizedExtension)) candidates.push(...await extractMixedSourceScriptCandidates(content, extractRawCandidatesWithPositions, options));
3229
+ const jsStringStaticRangesByContent = /* @__PURE__ */ new Map();
3230
+ function getJsStringStaticRanges(candidate) {
3231
+ if (!JS_LIKE_SOURCE_EXTENSION_RE.test(candidate.extension)) return;
3232
+ const cached = jsStringStaticRangesByContent.get(candidate.content);
3233
+ if (cached) return cached;
3234
+ const ranges = createJsStringStaticRanges(candidate.content);
3235
+ jsStringStaticRangesByContent.set(candidate.content, ranges);
3236
+ return ranges;
3237
+ }
3238
+ const seen = /* @__PURE__ */ new Set();
3239
+ return candidates.filter((candidate) => {
3240
+ if (!shouldKeepSourceCandidate(candidate.content, candidate.extension, createLocalCandidate(candidate), getJsStringStaticRanges(candidate), candidate.skipHtmlContextChecks)) return false;
3241
+ const key = `${candidate.start}:${candidate.end}:${candidate.rawCandidate}`;
3242
+ if (seen.has(key)) return false;
3243
+ seen.add(key);
3244
+ return true;
3245
+ }).map(({ rawCandidate, start, end }) => ({
3246
+ rawCandidate,
3247
+ start,
3248
+ end
3249
+ }));
3250
+ }
3251
+ async function extractSourceCandidates(content, extension = "html", options) {
3252
+ const candidates = await extractSourceCandidatesWithPositions(content, extension, options);
3253
+ return [...new Set(candidates.map((candidate) => candidate.rawCandidate))];
3254
+ }
3255
+ async function extractRawCandidates(sources, options) {
3256
+ const { Scanner } = await getOxideModule();
3257
+ const scanner = new Scanner(sources === void 0 ? {} : { sources });
3258
+ const files = scanner.files ?? [];
3259
+ const cacheKey = createRawCandidateCacheKey(sources, options);
3260
+ const fingerprint = await createRawCandidateFileFingerprint(files);
3261
+ const cached = getRawCandidateCacheEntry(cacheKey, fingerprint);
3262
+ if (cached) return [...cached.candidates];
3263
+ const scannedCandidates = scanner.scan();
3264
+ if (scannedCandidates.length === 0 && files.length > 0) {
3265
+ const changedContents = (await Promise.all(files.map(async (file) => {
3266
+ try {
3267
+ return {
3268
+ content: await promises.readFile(file, "utf8"),
3269
+ extension: toExtension(file)
3270
+ };
3271
+ } catch {
3272
+ return;
3273
+ }
3274
+ }))).filter((entry) => entry !== void 0);
3275
+ scannedCandidates.push(...scanner.scanFiles(changedContents));
3276
+ }
3277
+ const candidates = new Set(scannedCandidates);
3278
+ if (options?.bareArbitraryValues !== void 0 && options.bareArbitraryValues !== false) await Promise.all(files.map(async (file) => {
3279
+ try {
3280
+ const content = await promises.readFile(file, "utf8");
3281
+ const extension = toExtension(file);
3282
+ const jsStringStaticRanges = JS_LIKE_SOURCE_EXTENSION_RE.test(extension) ? createJsStringStaticRanges(content) : void 0;
3283
+ for (const candidate of extractBareArbitraryValueSourceCandidatesWithPositions(content, options.bareArbitraryValues)) if (shouldKeepSourceCandidate(content, extension, candidate, jsStringStaticRanges)) candidates.add(candidate.rawCandidate);
3284
+ } catch {}
3285
+ }));
3286
+ const result = [...candidates];
3287
+ setRawCandidateCacheEntry(cacheKey, fingerprint, result);
3288
+ return [...result];
3289
+ }
3290
+ //#endregion
3291
+ //#region src/v4/candidates/inline-source.ts
3292
+ function splitTopLevel(value, separator, options) {
3293
+ const result = [];
3294
+ let start = 0;
3295
+ let depth = 0;
3296
+ let quote;
3297
+ for (let index = 0; index < value.length; index++) {
3298
+ const character = value[index];
3299
+ if (character === "\\") {
3300
+ index++;
3301
+ continue;
3302
+ }
3303
+ if (quote) {
3304
+ if (character === quote) quote = void 0;
3305
+ continue;
3306
+ }
3307
+ if (character === "\"" || character === "'") {
3308
+ quote = character;
3309
+ continue;
3310
+ }
3311
+ if (character === "(" || character === "[" || character === "{") {
3312
+ depth++;
3313
+ continue;
3314
+ }
3315
+ if (character === ")" || character === "]" || character === "}") {
3316
+ depth = Math.max(0, depth - 1);
3317
+ continue;
3318
+ }
3319
+ if (depth === 0 && character === separator) {
3320
+ const item = value.slice(start, index).trim();
3321
+ if (item || options?.keepEmpty) result.push(item);
3322
+ start = index + 1;
3323
+ }
3324
+ }
3325
+ const item = value.slice(start).trim();
3326
+ if (item || options?.keepEmpty) result.push(item);
3327
+ return result;
3328
+ }
3329
+ const sequencePattern = /^(-?\d+)\.\.(-?\d+)(?:\.\.(-?\d+))?$/;
3330
+ function expandSequence(value) {
3331
+ const match = value.match(sequencePattern);
3332
+ if (!match) return [value];
3333
+ const [, startValue, endValue, stepValue] = match;
3334
+ if (startValue === void 0 || endValue === void 0) return [value];
3335
+ const start = Number.parseInt(startValue, 10);
3336
+ const end = Number.parseInt(endValue, 10);
3337
+ let step = stepValue === void 0 ? start <= end ? 1 : -1 : Number.parseInt(stepValue, 10);
3338
+ if (step === 0) throw new Error("Step cannot be zero in Tailwind CSS v4 inline source sequence.");
3339
+ const ascending = start < end;
3340
+ if (ascending && step < 0) step = -step;
3341
+ if (!ascending && step > 0) step = -step;
3342
+ const result = [];
3343
+ for (let current = start; ascending ? current <= end : current >= end; current += step) result.push(current.toString());
3344
+ return result;
3345
+ }
3346
+ function expandInlinePattern(pattern) {
3347
+ const openIndex = pattern.indexOf("{");
3348
+ if (openIndex === -1) return [pattern];
3349
+ const prefix = pattern.slice(0, openIndex);
3350
+ const rest = pattern.slice(openIndex);
3351
+ let depth = 0;
3352
+ let closeIndex = -1;
3353
+ for (let index = 0; index < rest.length; index++) {
3354
+ const character = rest[index];
3355
+ if (character === "{") depth++;
3356
+ else if (character === "}") {
3357
+ depth--;
3358
+ if (depth === 0) {
3359
+ closeIndex = index;
3360
+ break;
3361
+ }
3362
+ }
3363
+ }
3364
+ if (closeIndex === -1) throw new Error(`The Tailwind CSS v4 inline source pattern "${pattern}" is not balanced.`);
3365
+ const body = rest.slice(1, closeIndex);
3366
+ const suffix = rest.slice(closeIndex + 1);
3367
+ const parts = sequencePattern.test(body) ? expandSequence(body) : splitTopLevel(body, ",", { keepEmpty: true }).flatMap((part) => expandInlinePattern(part));
3368
+ const suffixes = expandInlinePattern(suffix);
3369
+ const result = [];
3370
+ for (const part of parts) for (const expandedSuffix of suffixes) result.push(`${prefix}${part}${expandedSuffix}`);
3371
+ return result;
3372
+ }
3373
+ function unquoteCssString(value) {
3374
+ const quote = value[0];
3375
+ if (quote !== "\"" && quote !== "'" || value[value.length - 1] !== quote) return;
3376
+ let result = "";
3377
+ for (let index = 1; index < value.length - 1; index++) {
3378
+ const character = value[index];
3379
+ if (character === "\\") {
3380
+ index++;
3381
+ result += value[index] ?? "";
3382
+ continue;
3383
+ }
3384
+ result += character;
3385
+ }
3386
+ return result;
3387
+ }
3388
+ function extractTailwindV4InlineSourceCandidates(css) {
3389
+ const included = /* @__PURE__ */ new Set();
3390
+ const excluded = /* @__PURE__ */ new Set();
3391
+ postcss.parse(css).walkAtRules("source", (rule) => {
3392
+ let params = rule.params.trim();
3393
+ if (!params) return;
3394
+ let negated = false;
3395
+ if (params.startsWith("not ")) {
3396
+ negated = true;
3397
+ params = params.slice(4).trim();
3398
+ }
3399
+ if (!params.startsWith("inline(") || !params.endsWith(")")) return;
3400
+ const inlineValue = unquoteCssString(params.slice(7, -1).trim());
3401
+ if (inlineValue === void 0) return;
3402
+ const target = negated ? excluded : included;
3403
+ for (const part of splitTopLevel(inlineValue, " ")) for (const candidate of expandInlinePattern(part)) target.add(candidate);
3404
+ });
3405
+ return {
3406
+ included,
3407
+ excluded
3408
+ };
3409
+ }
3410
+ //#endregion
3411
+ //#region src/v4/candidates.ts
3412
+ function resolveValidTailwindV4Candidates(designSystem, candidates, options) {
3413
+ const validCandidates = /* @__PURE__ */ new Set();
3414
+ const parsedCandidates = [];
3415
+ const originalCandidatesByCanonical = /* @__PURE__ */ new Map();
3416
+ for (const candidate of candidates) {
3417
+ if (!candidate) continue;
3418
+ const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options?.bareArbitraryValues);
3419
+ const candidateToCheck = bareArbitrary?.canonicalCandidate ?? candidate;
3420
+ if (bareArbitrary) {
3421
+ const originalCandidates = originalCandidatesByCanonical.get(candidateToCheck) ?? /* @__PURE__ */ new Set();
3422
+ originalCandidates.add(candidate);
3423
+ originalCandidatesByCanonical.set(candidateToCheck, originalCandidates);
3424
+ }
3425
+ if (parsedCandidates.includes(candidateToCheck)) continue;
3426
+ if (designSystem.parseCandidate(candidateToCheck).length > 0) parsedCandidates.push(candidateToCheck);
3427
+ }
3428
+ if (parsedCandidates.length === 0) return validCandidates;
3429
+ const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
3430
+ for (let index = 0; index < parsedCandidates.length; index++) {
3431
+ const candidate = parsedCandidates[index];
3432
+ const candidateCss = cssByCandidate[index];
3433
+ if (candidate && typeof candidateCss === "string" && candidateCss.trim().length > 0) {
3434
+ const originalCandidates = originalCandidatesByCanonical.get(candidate);
3435
+ if (originalCandidates) {
3436
+ for (const originalCandidate of originalCandidates) validCandidates.add(originalCandidate);
3437
+ continue;
3438
+ }
3439
+ validCandidates.add(candidate);
3440
+ }
3441
+ }
3442
+ return validCandidates;
3443
+ }
3444
+ function createSelectorAliasMap(candidates, options) {
3445
+ const aliases = /* @__PURE__ */ new Map();
3446
+ for (const candidate of candidates) {
3447
+ const bareArbitrary = resolveBareArbitraryValueCandidate(candidate, options);
3448
+ if (!bareArbitrary) continue;
3449
+ const canonicalSelector = escapeCssClassName(bareArbitrary.canonicalCandidate);
3450
+ const bareSelectors = aliases.get(canonicalSelector) ?? /* @__PURE__ */ new Set();
3451
+ bareSelectors.add(escapeCssClassName(bareArbitrary.candidate));
3452
+ aliases.set(canonicalSelector, bareSelectors);
3453
+ }
3454
+ return aliases;
3455
+ }
3456
+ function replaceBareArbitraryValueSelectors(css, candidates, options) {
3457
+ const aliases = createSelectorAliasMap(candidates, options);
3458
+ if (aliases.size === 0) return css;
3459
+ if (Array.from(aliases.values()).every((bareSelectors) => bareSelectors.size === 1)) {
3460
+ let result = css;
3461
+ for (const [canonicalSelector, bareSelectors] of aliases) {
3462
+ const bareSelector = Array.from(bareSelectors)[0];
3463
+ if (bareSelector !== void 0) result = result.replaceAll(canonicalSelector, bareSelector);
3464
+ }
3465
+ return result;
3466
+ }
3467
+ const root = postcss.parse(css);
3468
+ root.walkRules((rule) => {
3469
+ let selectors = rule.selectors;
3470
+ for (const [canonicalSelector, bareSelectors] of aliases) selectors = selectors.flatMap((selector) => {
3471
+ if (!selector.includes(canonicalSelector)) return selector;
3472
+ return Array.from(bareSelectors, (bareSelector) => selector.replaceAll(canonicalSelector, bareSelector));
3473
+ });
3474
+ rule.selectors = selectors;
3475
+ });
3476
+ return root.toString();
3477
+ }
3478
+ function canonicalizeBareArbitraryValueCandidates(candidates, options) {
3479
+ return Array.from(candidates, (candidate) => {
3480
+ return resolveBareArbitraryValueCandidate(candidate, options)?.canonicalCandidate ?? candidate;
3481
+ });
3482
+ }
3483
+ //#endregion
3484
+ //#region src/style-candidates.ts
3485
+ async function collectTailwindStyleCandidates(options = {}) {
3486
+ const candidates = /* @__PURE__ */ new Set();
3487
+ for (const candidate of options.candidates ?? []) candidates.add(candidate);
3488
+ const extractOptions = options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: options.bareArbitraryValues };
3489
+ for (const source of options.sources ?? []) {
3490
+ const sourceCandidates = await extractSourceCandidates(source.content, source.extension, extractOptions);
3491
+ for (const candidate of sourceCandidates) candidates.add(candidate);
3492
+ }
3493
+ return candidates;
3494
+ }
3495
+ //#endregion
3496
+ //#region src/v4/generation-artifact.ts
3497
+ function cloneSourceEntry(sourceEntry) {
3498
+ return {
3499
+ id: sourceEntry.id,
3500
+ content: sourceEntry.content,
3501
+ ...sourceEntry.extension === void 0 ? {} : { extension: sourceEntry.extension }
3502
+ };
3503
+ }
3504
+ function cloneTailwindGenerationArtifact(artifact) {
3505
+ return {
3506
+ fragments: artifact.fragments.map((fragment) => ({
3507
+ ...fragment,
3508
+ root: fragment.root.clone()
3509
+ })),
3510
+ classSet: new Set(artifact.classSet),
3511
+ rawCandidates: new Set(artifact.rawCandidates),
3512
+ dependencies: [...artifact.dependencies],
3513
+ sourceEntries: artifact.sourceEntries.map(cloneSourceEntry)
3514
+ };
3515
+ }
3516
+ function createTailwindGenerationArtifact(css, source, request, classSet, rawCandidates, dependencies) {
3517
+ const sourceId = source.dependencies[0] ?? source.base;
3518
+ return {
3519
+ fragments: [{
3520
+ id: `${sourceId}:tailwind`,
3521
+ kind: "tailwind",
3522
+ root: postcss.parse(css, { from: sourceId }),
3523
+ sourceId,
3524
+ order: 0
3525
+ }],
3526
+ classSet: new Set(classSet),
3527
+ rawCandidates: new Set(rawCandidates),
3528
+ dependencies: [...dependencies],
3529
+ sourceEntries: (request.sourceEntries ?? []).map(cloneSourceEntry)
3530
+ };
3531
+ }
3532
+ //#endregion
3533
+ //#region src/v4/generation-request.ts
3534
+ function toGenerationRequest(options) {
3535
+ return {
3536
+ ...options?.candidates === void 0 ? {} : { candidates: options.candidates },
3537
+ ...options?.sources === void 0 ? {} : { sourceEntries: options.sources.map((sourceEntry, index) => ({
3538
+ id: `source:${index}`,
3539
+ ...sourceEntry
3540
+ })) },
3541
+ ...options?.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: options.bareArbitraryValues },
3542
+ ...options?.scanSources === void 0 ? {} : { scanSources: options.scanSources }
3543
+ };
3544
+ }
3545
+ function toGenerateOptions(request) {
3546
+ return {
3547
+ ...request.candidates === void 0 ? {} : { candidates: request.candidates },
3548
+ ...request.sourceEntries === void 0 ? {} : { sources: request.sourceEntries },
3549
+ ...request.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: request.bareArbitraryValues },
3550
+ ...request.scanSources === void 0 ? {} : { scanSources: request.scanSources }
3551
+ };
3552
+ }
3553
+ function resolveScanSources(options, source, compiledRoot, compiledSources) {
3554
+ if (Array.isArray(options?.scanSources)) return options.scanSources;
3555
+ if (options?.scanSources === true) return createTailwindV4CompiledSourceEntries(compiledRoot, compiledSources, source.base);
3556
+ return [];
3557
+ }
3558
+ function shouldCompileSourceEntries(options) {
3559
+ return options?.scanSources === true;
3560
+ }
3561
+ function stripCompiledSourceEntries(source) {
3562
+ if (!source.css.includes("@source") && !source.css.includes("source(")) return source;
3563
+ try {
3564
+ const root = postcss.parse(source.css);
3565
+ let changed = false;
3566
+ root.walkAtRules((rule) => {
3567
+ if (rule.name === "source") {
3568
+ rule.remove();
3569
+ changed = true;
3570
+ return;
3571
+ }
3572
+ if (rule.name === "import" && /\bsource\(/.test(rule.params)) {
3573
+ rule.params = rule.params.replace(/\s+source\((?:[^()]|\([^()]*\))*\)/g, "");
3574
+ changed = true;
3575
+ }
3576
+ });
3577
+ return changed ? {
3578
+ ...source,
3579
+ css: root.toString()
3580
+ } : source;
3581
+ } catch {
3582
+ return source;
3583
+ }
3584
+ }
3585
+ async function collectRawCandidates(source, options, compiledRoot, compiledSources = []) {
3586
+ const rawCandidates = /* @__PURE__ */ new Set();
3587
+ const extractOptions = options?.bareArbitraryValues === void 0 ? void 0 : { bareArbitraryValues: options.bareArbitraryValues };
3588
+ for (const candidate of options?.candidates ?? []) rawCandidates.add(candidate);
3589
+ for (const candidateSource of options?.sources ?? []) {
3590
+ const candidates = await extractRawCandidatesWithPositions(candidateSource.content, candidateSource.extension, extractOptions);
3591
+ for (const candidate of candidates) rawCandidates.add(candidate.rawCandidate);
3592
+ }
3593
+ const filesystemSources = resolveScanSources(options, source, compiledRoot, compiledSources);
3594
+ if (filesystemSources.length > 0) for (const candidate of await extractRawCandidates(filesystemSources, extractOptions)) rawCandidates.add(candidate);
3595
+ const inlineSources = extractTailwindV4InlineSourceCandidates(source.css);
3596
+ for (const candidate of inlineSources.included) rawCandidates.add(candidate);
3597
+ for (const candidate of inlineSources.excluded) rawCandidates.delete(candidate);
3598
+ return rawCandidates;
3599
+ }
3600
+ //#endregion
3601
+ //#region src/v4/generation-session.ts
3602
+ var TailwindGenerationSessionImpl = class {
3603
+ currentSource;
3604
+ runtimes = /* @__PURE__ */ new Map();
3605
+ designSystemPromise;
3606
+ disposed = false;
3607
+ constructor(source) {
3608
+ this.currentSource = source;
3609
+ }
3610
+ get source() {
3611
+ return this.currentSource;
3612
+ }
3613
+ async generate(request = {}) {
3614
+ const generated = await this.generateInternal(request);
3615
+ return cloneTailwindGenerationArtifact(createTailwindGenerationArtifact(generated.css, this.currentSource, request, generated.classSet, generated.rawCandidates, generated.dependencies));
3616
+ }
3617
+ async generateLegacy(options) {
3618
+ const generated = await this.generateInternal(toGenerationRequest(options));
3619
+ return {
3620
+ css: generated.css,
3621
+ classSet: generated.classSet,
3622
+ rawCandidates: generated.rawCandidates,
3623
+ dependencies: generated.dependencies,
3624
+ sources: generated.sources,
3625
+ root: generated.root
3626
+ };
3627
+ }
3628
+ loadDesignSystem() {
3629
+ this.assertActive();
3630
+ this.designSystemPromise ??= loadTailwindV4DesignSystem(this.currentSource, { cache: false });
3631
+ return this.designSystemPromise;
3632
+ }
3633
+ async validateCandidates(candidates) {
3634
+ return resolveValidTailwindV4Candidates(await this.loadDesignSystem(), candidates);
3635
+ }
3636
+ invalidate(change) {
3637
+ if (this.disposed) return;
3638
+ if (change.type === "source") this.currentSource = change.source;
3639
+ this.runtimes.clear();
3640
+ this.designSystemPromise = void 0;
3641
+ }
3642
+ dispose() {
3643
+ this.runtimes.clear();
3644
+ this.designSystemPromise = void 0;
3645
+ this.disposed = true;
3646
+ }
3647
+ assertActive() {
3648
+ if (this.disposed) throw new Error("Tailwind generation session has been disposed.");
3649
+ }
3650
+ getRuntime(compileSourceEntries) {
3651
+ this.assertActive();
3652
+ const cached = this.runtimes.get(compileSourceEntries);
3653
+ if (cached) return cached;
3654
+ const source = compileSourceEntries ? this.currentSource : stripCompiledSourceEntries(this.currentSource);
3655
+ const promise = Promise.all([compileTailwindV4Source(source), loadTailwindV4DesignSystem(source, { cache: false })]).then(([compiledSource, designSystem]) => ({
3656
+ compiled: compiledSource.compiled,
3657
+ dependencies: compiledSource.dependencies,
3658
+ designSystem,
3659
+ builtCandidates: /* @__PURE__ */ new Set()
3660
+ }));
3661
+ this.runtimes.set(compileSourceEntries, promise);
3662
+ promise.catch(() => {
3663
+ if (this.runtimes.get(compileSourceEntries) === promise) this.runtimes.delete(compileSourceEntries);
3664
+ });
3665
+ return promise;
3666
+ }
3667
+ async resetRuntime(compileSourceEntries) {
3668
+ this.runtimes.delete(compileSourceEntries);
3669
+ return this.getRuntime(compileSourceEntries);
3670
+ }
3671
+ async generateInternal(request) {
3672
+ this.assertActive();
3673
+ const options = toGenerateOptions(request);
3674
+ const compileSourceEntries = shouldCompileSourceEntries(options);
3675
+ let runtime = await this.getRuntime(compileSourceEntries);
3676
+ const rawCandidates = await collectRawCandidates(this.currentSource, options, runtime.compiled.root, runtime.compiled.sources);
3677
+ const classSet = resolveValidTailwindV4Candidates(runtime.designSystem, rawCandidates, { ...options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: options.bareArbitraryValues } });
3678
+ const inlineSources = extractTailwindV4InlineSourceCandidates(this.currentSource.css);
3679
+ for (const candidate of inlineSources.excluded) classSet.delete(candidate);
3680
+ const buildCandidates = new Set(canonicalizeBareArbitraryValueCandidates(classSet, options.bareArbitraryValues));
3681
+ if ([...runtime.builtCandidates].some((candidate) => !buildCandidates.has(candidate))) runtime = await this.resetRuntime(compileSourceEntries);
3682
+ const css = replaceBareArbitraryValueSelectors(runtime.compiled.build([...buildCandidates]), classSet, options.bareArbitraryValues);
3683
+ runtime.builtCandidates = new Set(buildCandidates);
3684
+ return {
3685
+ css,
3686
+ classSet,
3687
+ rawCandidates,
3688
+ dependencies: Array.from(runtime.dependencies),
3689
+ sources: runtime.compiled.sources,
3690
+ root: runtime.compiled.root
3691
+ };
3692
+ }
3693
+ };
3694
+ function createTailwindGenerationSession(source) {
3695
+ return new TailwindGenerationSessionImpl(source);
3696
+ }
3697
+ function createTailwindV4EngineGenerationSession(source) {
3698
+ return new TailwindGenerationSessionImpl(source);
3699
+ }
3700
+ //#endregion
3701
+ //#region src/v4/engine.ts
3702
+ function createTailwindV4Engine(source) {
3703
+ const session = createTailwindV4EngineGenerationSession(source);
3704
+ return {
3705
+ source,
3706
+ loadDesignSystem() {
3707
+ return session.loadDesignSystem();
3708
+ },
3709
+ async validateCandidates(candidates) {
3710
+ return session.validateCandidates(candidates);
3711
+ },
3712
+ generate(options) {
3713
+ return session.generateLegacy(options);
3714
+ }
3715
+ };
3716
+ }
3717
+ //#endregion
3718
+ //#region src/v4/source.ts
3719
+ function resolveBase(value, fallback) {
3720
+ return value === void 0 ? fallback : path.isAbsolute(value) ? path.resolve(value) : path.resolve(fallback, value);
3721
+ }
3722
+ function uniquePaths(values) {
3723
+ const result = [];
3724
+ for (const value of values) {
3725
+ if (!value) continue;
3726
+ const resolved = path.resolve(value);
3727
+ if (!result.includes(resolved)) result.push(resolved);
3728
+ }
3729
+ return result;
3730
+ }
3731
+ function toCssImportPath(value) {
3732
+ return value.replaceAll("\\", "/");
3733
+ }
3734
+ function quoteCssImport(value) {
3735
+ return value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
3736
+ }
3737
+ function isPostcssPluginSpecifier(packageName) {
3738
+ return packageName === "@tailwindcss/postcss" || /(?:^|[/\\])@tailwindcss[/\\]postcss(?:[/\\]|$)/.test(packageName) || /(?:^|[/\\])postcss(?:[/\\]|$)/i.test(packageName) || /postcss\.config\.[cm]?[jt]s$/i.test(packageName);
3739
+ }
3740
+ function createDefaultCss(packageName) {
3741
+ return `@import "${quoteCssImport(toCssImportPath(packageName && !isPostcssPluginSpecifier(packageName) ? packageName : "tailwindcss"))}";`;
3742
+ }
3743
+ async function pathExists(filePath) {
3744
+ try {
3745
+ await promises.access(filePath);
3746
+ return true;
3747
+ } catch {
3748
+ return false;
3749
+ }
3750
+ }
3751
+ async function resolveCssEntries(entries, projectRoot, base) {
3752
+ const resolvedEntries = entries.map((entry) => ({
3753
+ original: entry,
3754
+ absolute: path.isAbsolute(entry) ? path.resolve(entry) : path.resolve(projectRoot, entry)
3755
+ }));
3756
+ const resolvedBase = base ?? path.dirname(resolvedEntries[0]?.absolute ?? projectRoot);
3757
+ const dependencies = resolvedEntries.map((entry) => entry.absolute);
3758
+ const cssParts = [];
3759
+ for (const entry of resolvedEntries) {
3760
+ if (await pathExists(entry.absolute)) {
3761
+ cssParts.push(await promises.readFile(entry.absolute, "utf8"));
3762
+ continue;
3763
+ }
3764
+ const importPath = path.isAbsolute(entry.original) ? entry.absolute : path.relative(resolvedBase, entry.absolute);
3765
+ cssParts.push(`@import "${quoteCssImport(toCssImportPath(importPath))}";`);
3766
+ }
3767
+ return {
3768
+ base: resolvedBase,
3769
+ css: cssParts.join("\n"),
3770
+ dependencies
3771
+ };
3772
+ }
3773
+ function resolveCssSources(sources, projectRoot, base) {
3774
+ const resolvedSources = sources.map((source) => ({
3775
+ ...source,
3776
+ base: source.base === void 0 ? void 0 : resolveBase(source.base, projectRoot),
3777
+ file: source.file === void 0 ? void 0 : path.isAbsolute(source.file) ? path.resolve(source.file) : path.resolve(projectRoot, source.file),
3778
+ dependencies: source.dependencies?.map((dependency) => path.isAbsolute(dependency) ? path.resolve(dependency) : path.resolve(projectRoot, dependency)) ?? []
3779
+ }));
3780
+ const firstSource = resolvedSources[0];
3781
+ const resolvedBase = base ?? firstSource?.base ?? (firstSource?.file ? path.dirname(firstSource.file) : projectRoot);
3782
+ const dependencies = resolvedSources.flatMap((source) => [source.file, ...source.dependencies]).filter((dependency) => Boolean(dependency));
3783
+ return {
3784
+ base: resolvedBase,
3785
+ css: resolvedSources.map((source) => source.css).join("\n"),
3786
+ dependencies
3787
+ };
3788
+ }
3789
+ function normalizeResolvedSource(source) {
3790
+ const baseFallbacks = uniquePaths([
3791
+ ...source.baseFallbacks,
3792
+ source.projectRoot,
3793
+ source.cwd
3794
+ ]).filter((base) => base !== source.base);
3795
+ return {
3796
+ projectRoot: source.projectRoot,
3797
+ base: source.base,
3798
+ baseFallbacks,
3799
+ css: source.css,
3800
+ dependencies: Array.from(new Set(source.dependencies.map((dependency) => path.resolve(dependency))))
3801
+ };
3802
+ }
3803
+ async function resolveTailwindV4Source(options = {}) {
3804
+ const projectRoot = resolveBase(options.projectRoot, process.cwd());
3805
+ const cwd = resolveBase(options.cwd, projectRoot);
3806
+ const configuredBase = options.base === void 0 ? void 0 : resolveBase(options.base, projectRoot);
3807
+ const baseFallbacks = uniquePaths(options.baseFallbacks?.map((base) => resolveBase(base, projectRoot)) ?? []);
3808
+ if (options.css !== void 0) return normalizeResolvedSource({
3809
+ projectRoot,
3810
+ cwd,
3811
+ base: configuredBase ?? cwd,
3812
+ baseFallbacks,
3813
+ css: options.css,
3814
+ dependencies: []
3815
+ });
3816
+ if (options.cssEntries?.length || options.cssSources?.length) {
3817
+ const entries = options.cssEntries?.length ? await resolveCssEntries(options.cssEntries, projectRoot, configuredBase) : void 0;
3818
+ const sources = options.cssSources?.length ? resolveCssSources(options.cssSources, projectRoot, configuredBase) : void 0;
3819
+ const css = [entries?.css, sources?.css].filter(Boolean).join("\n");
3820
+ return normalizeResolvedSource({
3821
+ projectRoot,
3822
+ cwd,
3823
+ base: configuredBase ?? entries?.base ?? sources?.base ?? cwd,
3824
+ baseFallbacks,
3825
+ css,
3826
+ dependencies: [...entries?.dependencies ?? [], ...sources?.dependencies ?? []]
3827
+ });
3828
+ }
3829
+ return normalizeResolvedSource({
3830
+ projectRoot,
3831
+ cwd,
3832
+ base: configuredBase ?? cwd,
3833
+ baseFallbacks,
3834
+ css: createDefaultCss(options.packageName),
3835
+ dependencies: []
3836
+ });
3837
+ }
3838
+ //#endregion
3839
+ //#region src/v4/style-generator.ts
3840
+ function createSourceOptions(options) {
3841
+ return {
3842
+ ...options.projectRoot === void 0 ? {} : { projectRoot: options.projectRoot },
3843
+ ...options.cwd === void 0 ? {} : { cwd: options.cwd },
3844
+ ...options.base === void 0 ? {} : { base: options.base },
3845
+ ...options.baseFallbacks === void 0 ? {} : { baseFallbacks: options.baseFallbacks },
3846
+ ...options.css === void 0 ? {} : { css: options.css },
3847
+ ...options.cssSources === void 0 ? {} : { cssSources: options.cssSources },
3848
+ ...options.cssEntries === void 0 ? {} : { cssEntries: options.cssEntries },
3849
+ ...options.packageName === void 0 ? {} : { packageName: options.packageName }
3850
+ };
3851
+ }
3852
+ async function collectTailwindV4StyleCandidates(options) {
3853
+ return collectTailwindStyleCandidates({
3854
+ ...options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: options.bareArbitraryValues },
3855
+ ...options.candidates === void 0 ? {} : { candidates: options.candidates },
3856
+ ...options.sources === void 0 ? {} : { sources: options.sources }
3857
+ });
3858
+ }
3859
+ async function generateTailwindV4Style(options = {}) {
3860
+ const source = options.source ?? await resolveTailwindV4Source(createSourceOptions(options));
3861
+ const candidates = await collectTailwindV4StyleCandidates(options);
3862
+ const result = await createTailwindV4Engine(source).generate({
3863
+ candidates,
3864
+ ...options.bareArbitraryValues === void 0 ? {} : { bareArbitraryValues: options.bareArbitraryValues },
3865
+ ...options.scanSources === void 0 ? {} : { scanSources: options.scanSources }
3866
+ });
3867
+ return {
3868
+ ...result,
3869
+ tokens: result.rawCandidates,
3870
+ source
3871
+ };
3872
+ }
3873
+ //#endregion
3874
+ export { mergeTailwindV4SourceEntries as A, normalizeTailwindV4ScannerSources as B, getOxideModule as C, groupTailwindV4SourceEntriesByBase as D, expandTailwindV4SourceEntries as E, createTailwindV4CompiledSourceEntries as F, toPosixPath as G, resolveSourceScanPath as H, createTailwindV4DefaultIgnoreSources as I, loadTailwindV4DesignSystem as J, compileTailwindV4Source as K, createTailwindV4RootSources as L, TAILWIND_V4_IGNORED_CONTENT_DIRS as M, TAILWIND_V4_IGNORED_EXTENSIONS as N, isFileExcludedByTailwindV4SourceEntries as O, TAILWIND_V4_IGNORED_FILES as P, expandTailwindV4SourceEntryBraces as R, toExtension as S, createTailwindV4SourceExclusionMatcher as T, resolveTailwindV4SourceBaseCandidates as U, normalizeTailwindV4SourceEntries as V, resolveTailwindV4SourceEntry as W, loadTailwindV4NodeModule as Y, isBareArbitraryValuesEnabled as _, createTailwindGenerationSession as a, buildLineOffsets as b, replaceBareArbitraryValueSelectors as c, extractRawCandidates as d, extractRawCandidatesWithPositions as f, extractBareArbitraryValueSourceCandidatesWithPositions as g, extractBareArbitraryValueSourceCandidates as h, createTailwindV4Engine as i, TAILWIND_V4_AUTO_SOURCE_SCAN_PATTERN as j, isFileMatchedByTailwindV4SourceEntries as k, resolveValidTailwindV4Candidates as l, extractSourceCandidatesWithPositions as m, generateTailwindV4Style as n, collectTailwindStyleCandidates as o, extractSourceCandidates as p, getTailwindV4DesignSystemCacheKey as q, resolveTailwindV4Source as r, canonicalizeBareArbitraryValueCandidates as s, collectTailwindV4StyleCandidates as t, extractTailwindV4InlineSourceCandidates as u, resolveBareArbitraryValueCandidate as v, createTailwindV4SourceEntryMatcher as w, createTokenLocation as x, escapeCssClassName as y, normalizeGlobPattern as z };