31 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b9286a7346
|
fix: Drop invalid UTF-8 scanner candidates (#20389)
## Summary Replace the three unchecked scanner conversions in `crates/oxide/src/scanner/mod.rs` with checked conversions that omit only extracted slices that are not valid UTF-8. Apply the check in the shared `extract` pipeline so initial scans, incremental `scan_content` calls, and CSS-variable extraction cannot insert invalid strings into scanner state, and apply the same policy to both branches of `get_candidates_with_positions` while preserving byte offsets and the legacy `-[]` restoration. Keep the extractor's byte-oriented CSS identifier classification unchanged: accepting non-ASCII bytes during extraction is useful for valid multibyte code points, while the conversion boundary is the authoritative place to enforce the `String` contract. The scanner currently converts extracted byte slices with unchecked UTF-8 constructors at the shared extraction boundary and both candidate-with-position branches. A source file containing a stray continuation byte can therefore produce an invalid `String`, violating Rust's string invariant and allowing corrupted candidates to persist in a long-lived scanner. The thread provides a deterministic reproduction using invalid bytes inside an arbitrary value, so the problem no longer depends on reproducing the originally reported Turbopack race. Valid candidates found alongside malformed byte sequences must continue to be returned normally. Fixes #20368 ## Test plan Not applicable to this change. AI was used for assistance. --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Robin Malfait <malfait.robin@gmail.com> |
||
|
|
84bea42b6c
|
Visualize scanner related tests (#20412)
This PR improves the scanner related tests a bit. Right now all the
scanner tests (a lot of them) are somewhat hard to reason about and to
figure out whether these are actually correct or not.
With this PR, the existing are extended with a visualization of the file
system tree, but with indicators to know whether or not a file was
scanned or not. If a `.gitignore` is present, it's content is also shown
to make it easier to see why some files are included or not included.
One of the outputs look like this:
```
.
├── ✗ .gitignore
│ src/ignored-by-gitignore.html
└── ✓ src
├── ✗ ignore-by-extension.bin
├── ✓ ignored-by-gitignore.html
├── ✗ ignored-by-source-not.html
├── ✓ keep-me.html
└── ✓ new-file.html
```
I'm sure we can cleanup a lot of these tests, simplify, deduplicate, but
I didn't want to do that as part of this PR. This PR is purely adding
this visualization.
This uses the [insta.rs](https://insta.rs) library for (inline) snapshot
tests. If at some point the snapshots change, then you get a nice UI:
<img width="958" height="670" alt="image"
src="https://github.com/user-attachments/assets/652cf48f-e1b1-4fe5-a42a-29c5a888063a"
/>
## Test plan
1. All tests should pass [ci-all]
2. Nothing in the code itself changed, so nothing should break
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
|
||
|
|
b86a6e0a0d
|
Fix slow Vite rebuilds in projects with large gitignored directories (#20408)
Preface: For full transparency, I used AI (Claude) to help dig into this issue we're having and write some of the explanation below. Our local Laravel application (with Docker) takes between 2-6s seconds (re)building `app.css` after each Blade file update. After checking with Claude, there seems to be some potential unnecessary traversing of big (gitignored) directories, specifically `vendor` and `storage`. As far as I understand it, two scans happen in tailwindcss: - a first scan, the content scan. This one reads the project files (auto-detect). It respects .gitignore, so it correctly skips vendor/ and storage/. - a second scan, the glob resolution (resolve_globs() in the oxide crate). It builds watch patterns that the Vite plugin registers, so a file save can trigger a CSS rebuild. It walks the project again, but this walk does not respect .gitignore. It only skips a hardcoded list of directory names from `ignored-content-dirs.txt` (node_modules, .git, venv, ...). vendor/ and storage/ are not on that list, so it descends into them and stats every file. These directories can never produce a watch pattern, because the content scan never visited them. That work is perhaps wasted? Maybe why this went unnoticed: on a native filesystem a stat takes about 1µs, so 57k of them is around 0.06s. A Docker bind mount multiplies that by roughly 100. And the big directory in a typical JS project is `node_modules`, which the name list already catches; `vendor/` is the PHP ecosystem's `node_modules`, and it is not on that list. (#19616 / #19632 fixed the same problem for `scanner.files`; the CLI never reads `scanner.globs`, so it was never affected.) The fix: the second walk now skips any directory the scan never visited, the same pruning the first walk (line 73) already does. Measured on our local project: `get_globs()` after `scan()` went from 9.9s to somewhere between 0.2 and 1.0s across runs, with identical output (35 globs). A template save now reloads in about 0.3s instead of 4. ## Test plan - `cargo test` in `crates/oxide`: 66 tests pass, including the glob assertions for nested and gitignored directories in `tests/scanner.rs`. - Compared the sorted `get_globs()` output before and after on the project above: identical. I've also set up a repo that reproduces the issue in a fresh Laravel app: https://github.com/marickvantuil/tailwind-scan-reproduce The results: | Environment | vendor/ | scan | get_globs | syscalls under vendor/ | | --- | --- | --- | --- | --- | | GitHub Actions (native FS) | present | 5.0 ms | 48.8 ms | 11,410 | | GitHub Actions (native FS) | absent | 4.5 ms | 0.9 ms | n/a | | macOS, Docker bind mount | present | 15.8 ms | 599.4 ms | 11,410 | | macOS, Docker bind mount | absent | 16.5 ms | 6.5 ms | n/a | --------- Co-authored-by: Marick van Tuil <marick@dolphiq.nl> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Robin Malfait <malfait.robin@gmail.com> |
||
|
|
46df7ee2fc
|
Don't scan ignored folders using .gitignore safelist setup (#20397)
This PR fixes an issue where a folder containing a `.gitignore` that uses a whitelist setup results in too many folders being scanned: ```gitignore # .gitignore /* !/app ``` We want to make sure that we respect the `.gitignore` file, but we also need to make sure that `@source` directives 'win' from `.gitignore` files. For example: ```css @import 'tailwindcss'; @source "./node_modules/my-package/*.js"; ``` In this case, `node_modules` is likely ignored via `.gitignore`, but you _do_ want to include the files from the `my-package` folder, essentially overriding the `.gitignore` rules. To do this, we internally mark this folder as an `External` folder such that it gets read, because that's what we want. The current bug has a pattern like `/*` and then safelist/whitelist patterns to include certain folders. The problem with the `/*` pattern is that this convert the _current_ folder to an `External` folder. This is wrong. The current folder cannot be ignored by the current `.gitignore` file itself. You can ignore files and folders _inside_ the current folder, but not the folder itself. The current folder can only be ignored by parent `.gitignore` rules. Originally discussed in: https://github.com/tailwindlabs/tailwindcss/discussions/20382 Fixes: #20385 ## Test plan 1. Added regression tests 2. Added integration tests Manually tested, and logging the scanned files does result in some interesting results: <details> <summary>Before</summary> ``` Reading ".git/COMMIT_EDITMSG" Reading ".git/HEAD" Reading ".git/MERGE_RR" Reading ".git/config" Reading ".git/description" Reading ".git/hooks/applypatch-msg.sample" Reading ".git/hooks/commit-msg.sample" Reading ".git/hooks/fsmonitor-watchman.sample" Reading ".git/hooks/post-update.sample" Reading ".git/hooks/pre-applypatch.sample" Reading ".git/hooks/pre-commit.sample" Reading ".git/hooks/pre-merge-commit.sample" Reading ".git/hooks/pre-push.sample" Reading ".git/hooks/pre-rebase.sample" Reading ".git/hooks/pre-receive.sample" Reading ".git/hooks/prepare-commit-msg.sample" Reading ".git/hooks/push-to-checkout.sample" Reading ".git/hooks/sendemail-validate.sample" Reading ".git/hooks/update.sample" Reading ".git/index" Reading ".git/info/exclude" Reading ".git/logs/HEAD" Reading ".git/logs/refs/heads/main" Reading ".git/objects/02/2fe3aa1b28300c0146acdff4eb3240cd2a861b" Reading ".git/objects/17/45509b3ec34de9d8ddd6708c9d73f191c63c48" Reading ".git/objects/1e/d83f044a80cfec0843a0d68fa859c101e4e02f" Reading ".git/objects/60/76888f3ae7ecd2712c236933314e1c420e52f2" Reading ".git/objects/76/e5d55dc7d51e47bff78b27e39a13110e17c072" Reading ".git/objects/89/7b4529b9a3db489cc00e2cff4bbd1a2f09fb50" Reading ".git/objects/8c/781ce3374b53455c284bef51bffbee5ca88969" Reading ".git/objects/b2/ceaa157eef0b2a8d0231a1396b17684da71de7" Reading ".git/objects/da/7ef6439d0779bae07668b42d77dcbce2f84111" Reading ".git/refs/heads/main" Reading ".gitattributes" Reading ".gitignore" Reading "app/index.html" Reading "build/index.html" Reading "node_modules/.modules.yaml" Reading "node_modules/.package-map.json" Reading "node_modules/.pnpm-workspace-state-v1.json" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/LICENSE" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/README.md" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/package.json" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/src/strings.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/LICENSE" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/README.md" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/package.json" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/binary-search.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/by-source.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/flatten-map.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/resolve.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/sort.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/sourcemap-segment.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/strip-filename.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/trace-mapping.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/src/types.ts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sort.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sort.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sort.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sort.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/types.d.cts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/types.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/types.d.mts" Reading "node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/trace-mapping/types/types.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/LICENSE" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/README.md" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/types/gen-mapping.d.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/types/set-array.d.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/types/sourcemap-segment.d.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/dist/types/types.d.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/package.json" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/src/gen-mapping.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/src/set-array.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/src/sourcemap-segment.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/src/types.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/types.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/types.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/types.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/gen-mapping/types/types.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/LICENSE" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/README.md" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/dist/remapping.mjs" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/dist/remapping.mjs.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/dist/remapping.umd.js" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/dist/remapping.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/package.json" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/src/build-source-map-tree.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/src/remapping.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/src/source-map-tree.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/src/source-map.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/src/types.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/remapping.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/remapping.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/remapping.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/remapping.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map-tree.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map-tree.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map-tree.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map-tree.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/source-map.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/types.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/types.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/types.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/remapping/types/types.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/LICENSE" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/README.md" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/package.json" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/binary-search.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/by-source.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/flatten-map.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/resolve.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/sort.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/sourcemap-segment.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/strip-filename.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/trace-mapping.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/src/types.ts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sort.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sort.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sort.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sort.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/types.d.cts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/types.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/types.d.mts" Reading "node_modules/.pnpm/@jridgewell+remapping@2.3.5/node_modules/@jridgewell/trace-mapping/types/types.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/LICENSE" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/README.md" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts" Reading "node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/package.json" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/LICENSE" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/README.md" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/resolve-uri/package.json" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/LICENSE" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/README.md" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/package.json" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/src/strings.ts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts" Reading "node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map" Reading "node_modules/.pnpm/@parcel+watcher-darwin-arm64@2.6.0/node_modules/@parcel/watcher-darwin-arm64/LICENSE" Reading "node_modules/.pnpm/@parcel+watcher-darwin-arm64@2.6.0/node_modules/@parcel/watcher-darwin-arm64/README.md" Reading "node_modules/.pnpm/@parcel+watcher-darwin-arm64@2.6.0/node_modules/@parcel/watcher-darwin-arm64/package.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher-darwin-arm64/LICENSE" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher-darwin-arm64/README.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher-darwin-arm64/package.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/LICENSE" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/README.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/binding.gyp" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/index.d.ts" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/index.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/index.js.flow" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/package.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/scripts/build-from-source.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Backend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Backend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Debounce.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Debounce.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/DirTree.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/DirTree.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Event.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Glob.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Glob.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/PromiseRunner.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Signal.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Watcher.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/Watcher.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/binding.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/linux/InotifyBackend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/linux/InotifyBackend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/unix/fts.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/unix/legacy.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/wasm/WasmBackend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/wasm/WasmBackend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/wasm/include.h" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/watchman/BSER.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/watchman/BSER.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/watchman/IPC.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/windows/WindowsBackend.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/windows/WindowsBackend.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/windows/win_utils.cc" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/src/windows/win_utils.hh" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/@parcel/watcher/wrapper.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/LICENSE" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/README.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/index.d.ts" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/lib/detect-libc.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/lib/elf.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/lib/filesystem.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/lib/process.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/detect-libc/package.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/is-glob/LICENSE" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/is-glob/README.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/is-glob/index.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/is-glob/package.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/LICENSE.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/README.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/common.gypi" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/except.gypi" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/index.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/napi-inl.deprecated.h" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/napi-inl.h" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/napi.h" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/node_addon_api.gyp" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/node_api.gyp" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/noexcept.gypi" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/nothing.c" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/package-support.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/package.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/tools/README.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/tools/check-napi.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/tools/clang-format.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/tools/conversion.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/node-addon-api/tools/eslint-format.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/LICENSE" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/README.md" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/index.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/lib/constants.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/lib/parse.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/lib/picomatch.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/lib/scan.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/lib/utils.js" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/package.json" Reading "node_modules/.pnpm/@parcel+watcher@2.6.0/node_modules/picomatch/posix.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/graceful-fs/LICENSE" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/graceful-fs/README.md" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/graceful-fs/clone.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/graceful-fs/graceful-fs.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/graceful-fs/legacy-streams.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/graceful-fs/package.json" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/graceful-fs/polyfills.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/LICENSE" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/README.md" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/AsyncParallelBailHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/AsyncParallelHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/AsyncSeriesBailHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/AsyncSeriesHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/AsyncSeriesLoopHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/AsyncSeriesWaterfallHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/Hook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/HookCodeFactory.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/HookMap.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/MultiHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/SyncBailHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/SyncHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/SyncLoopHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/SyncWaterfallHook.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/index.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/lib/util-browser.js" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/package.json" Reading "node_modules/.pnpm/enhanced-resolve@5.24.5/node_modules/tapable/tapable.d.ts" Reading "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/LICENSE" Reading "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/README.md" Reading "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/clone.js" Reading "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js" Reading "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/legacy-streams.js" Reading "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/package.json" Reading "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/polyfills.js" Reading "node_modules/.pnpm/is-extglob@2.1.1/node_modules/is-extglob/LICENSE" Reading "node_modules/.pnpm/is-extglob@2.1.1/node_modules/is-extglob/README.md" Reading "node_modules/.pnpm/is-extglob@2.1.1/node_modules/is-extglob/index.js" Reading "node_modules/.pnpm/is-extglob@2.1.1/node_modules/is-extglob/package.json" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-extglob/LICENSE" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-extglob/README.md" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-extglob/index.js" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-extglob/package.json" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-glob/LICENSE" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-glob/README.md" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-glob/index.js" Reading "node_modules/.pnpm/is-glob@4.0.3/node_modules/is-glob/package.json" Reading "node_modules/.pnpm/lightningcss-darwin-arm64@1.33.0/node_modules/lightningcss-darwin-arm64/LICENSE" Reading "node_modules/.pnpm/lightningcss-darwin-arm64@1.33.0/node_modules/lightningcss-darwin-arm64/README.md" Reading "node_modules/.pnpm/lightningcss-darwin-arm64@1.33.0/node_modules/lightningcss-darwin-arm64/package.json" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/LICENSE" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/README.md" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/index.d.ts" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/lib/detect-libc.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/lib/elf.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/lib/filesystem.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/lib/process.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/detect-libc/package.json" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss-darwin-arm64/LICENSE" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss-darwin-arm64/README.md" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss-darwin-arm64/package.json" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/LICENSE" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/README.md" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/ast.d.ts" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/ast.js.flow" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/browserslistToTargets.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/composeVisitors.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/flags.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/index.d.ts" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/index.js" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/index.js.flow" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/index.mjs" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/targets.d.ts" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/node/targets.js.flow" Reading "node_modules/.pnpm/lightningcss@1.33.0/node_modules/lightningcss/package.json" Reading "node_modules/.pnpm/lock.yaml" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/LICENSE" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/README.md" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/package.json" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/src/strings.ts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/magic-string/LICENSE" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/magic-string/README.md" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/magic-string/dist/index.d.mts" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/magic-string/dist/index.mjs" Reading "node_modules/.pnpm/magic-string@1.1.0/node_modules/magic-string/package.json" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/LICENSE" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/README.md" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/types/gen-mapping.d.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/types/set-array.d.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/types/sourcemap-segment.d.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/dist/types/types.d.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/package.json" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/src/gen-mapping.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/src/set-array.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/src/sourcemap-segment.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/src/types.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/types.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/types.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/types.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/gen-mapping/types/types.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/LICENSE" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/README.md" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/dist/remapping.mjs" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/dist/remapping.mjs.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/dist/remapping.umd.js" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/dist/remapping.umd.js.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/package.json" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/src/build-source-map-tree.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/src/remapping.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/src/source-map-tree.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/src/source-map.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/src/types.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/build-source-map-tree.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/remapping.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/remapping.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/remapping.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/remapping.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map-tree.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map-tree.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map-tree.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map-tree.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/source-map.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/types.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/types.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/types.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/remapping/types/types.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/LICENSE" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/README.md" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/resolve-uri/package.json" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/LICENSE" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/README.md" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/package.json" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/src/strings.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/LICENSE" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/README.md" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/package.json" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/binary-search.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/by-source.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/flatten-map.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/resolve.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/sort.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/sourcemap-segment.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/strip-filename.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/trace-mapping.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/src/types.ts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sort.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sort.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sort.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sort.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/types.d.cts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/types.d.cts.map" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/types.d.mts" Reading "node_modules/.pnpm/node_modules/@jridgewell/trace-mapping/types/types.d.mts.map" Reading "node_modules/.pnpm/node_modules/@parcel/watcher-darwin-arm64/LICENSE" Reading "node_modules/.pnpm/node_modules/@parcel/watcher-darwin-arm64/README.md" Reading "node_modules/.pnpm/node_modules/@parcel/watcher-darwin-arm64/package.json" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/LICENSE" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/README.md" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/binding.gyp" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/index.d.ts" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/index.js" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/index.js.flow" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/package.json" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/scripts/build-from-source.js" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Backend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Backend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Debounce.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Debounce.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/DirTree.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/DirTree.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Event.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Glob.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Glob.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/PromiseRunner.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Signal.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Watcher.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/Watcher.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/binding.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/linux/InotifyBackend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/linux/InotifyBackend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/unix/fts.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/unix/legacy.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/wasm/WasmBackend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/wasm/WasmBackend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/wasm/include.h" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/watchman/BSER.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/watchman/BSER.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/watchman/IPC.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/windows/WindowsBackend.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/windows/WindowsBackend.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/windows/win_utils.cc" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/src/windows/win_utils.hh" Reading "node_modules/.pnpm/node_modules/@parcel/watcher/wrapper.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/LICENSE" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/esm-cache.loader.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/esm-cache.loader.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/index.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/index.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/index.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/require-cache.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/dist/require-cache.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/node/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-darwin-arm64/LICENSE" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-darwin-arm64/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-darwin-arm64/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/LICENSE" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.cjs.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.cjs.min.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.cjs.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.esm-bundler.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.min.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.min.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/dist/emnapi-core.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/LICENSE" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.cjs.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.cjs.min.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.cjs.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.esm-bundler.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.iife.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.iife.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.min.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.min.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/dist/emnapi.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/LICENSE" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.cjs.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.cjs.min.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.cjs.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.esm-bundler.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.min.d.mts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.min.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/dist/wasi-threads.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.cjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/dist/emnapi-plugins.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/dist/fs-proxy.cjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/dist/fs.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/fs-proxy.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/runtime.cjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/runtime.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/dist/tsdoc-metadata.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/dist/wasm-util.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/dist/wasm-util.esm-bundler.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/dist/wasm-util.esm.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/dist/wasm-util.esm.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/dist/wasm-util.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/dist/wasm-util.min.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/asyncify.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/jspi.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/load.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/memory.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/error.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/fd.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/fs.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/path.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/preview1.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/rights.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/types.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/wasi/util.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/cjs/webassembly.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/asyncify.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/index.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/jspi.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/load.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/memory.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/error.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/fd.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/fs.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/index.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/path.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/preview1.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/rights.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/types.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/wasi/util.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/lib/mjs/webassembly.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/CopyrightNotice.txt" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/LICENSE.txt" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/README.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/SECURITY.md" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/modules/index.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/modules/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/modules/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/tslib.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/tslib.es6.html" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/tslib.es6.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/tslib.es6.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/tslib.html" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib/tslib.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/package.json" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/tailwindcss-oxide.wasi-browser.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/tailwindcss-oxide.wasi.cjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/wasi-worker-browser.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide-wasm32-wasi/wasi-worker.mjs" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide/LICENSE" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide/index.d.ts" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide/index.js" Reading "node_modules/.pnpm/node_modules/@tailwindcss/oxide/package.json" Reading "node_modules/.pnpm/node_modules/detect-libc/LICENSE" Reading "node_modules/.pnpm/node_modules/detect-libc/README.md" Reading "node_modules/.pnpm/node_modules/detect-libc/index.d.ts" Reading "node_modules/.pnpm/node_modules/detect-libc/lib/detect-libc.js" Reading "node_modules/.pnpm/node_modules/detect-libc/lib/elf.js" Reading "node_modules/.pnpm/node_modules/detect-libc/lib/filesystem.js" Reading "node_modules/.pnpm/node_modules/detect-libc/lib/process.js" Reading "node_modules/.pnpm/node_modules/detect-libc/package.json" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/LICENSE" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/README.md" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/AliasFieldPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/AliasPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/AliasUtils.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/AppendPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/CloneBasenamePlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ConditionalPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/DirectoryExistsPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ExtensionAliasPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/FileExistsPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ImportsFieldPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/JoinRequestPartPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/JoinRequestPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/LogInfoPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/MainFieldPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ModulesInHierachicDirectoriesPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ModulesInHierarchicalDirectoriesPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ModulesUtils.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/NextPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ParsePlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/PnpPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/Resolver.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ResolverFactory.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/RestrictionsPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/ResultPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/RootsPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/SelfReferencePlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/SymlinkPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/SyncAsyncFileSystemDecorator.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/TryNextPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/TsconfigPathsPlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/UseFilePlugin.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/createInnerContext.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/forEachBail.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/getInnerRequest.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/getPaths.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/index.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/entrypoints.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/fileURLToPath.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/fs.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/graceful-fs-browser.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/identifier.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/memoize.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/module-browser.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/path-browser.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/path.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/process-browser.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/strip-json-comments.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/lib/util/url-browser.js" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/package.json" Reading "node_modules/.pnpm/node_modules/enhanced-resolve/types.d.ts" Reading "node_modules/.pnpm/node_modules/graceful-fs/LICENSE" Reading "node_modules/.pnpm/node_modules/graceful-fs/README.md" Reading "node_modules/.pnpm/node_modules/graceful-fs/clone.js" Reading "node_modules/.pnpm/node_modules/graceful-fs/graceful-fs.js" Reading "node_modules/.pnpm/node_modules/graceful-fs/legacy-streams.js" Reading "node_modules/.pnpm/node_modules/graceful-fs/package.json" Reading "node_modules/.pnpm/node_modules/graceful-fs/polyfills.js" Reading "node_modules/.pnpm/node_modules/is-extglob/LICENSE" Reading "node_modules/.pnpm/node_modules/is-extglob/README.md" Reading "node_modules/.pnpm/node_modules/is-extglob/index.js" Reading "node_modules/.pnpm/node_modules/is-extglob/package.json" Reading "node_modules/.pnpm/node_modules/is-glob/LICENSE" Reading "node_modules/.pnpm/node_modules/is-glob/README.md" Reading "node_modules/.pnpm/node_modules/is-glob/index.js" Reading "node_modules/.pnpm/node_modules/is-glob/package.json" Reading "node_modules/.pnpm/node_modules/jiti/LICENSE" Reading "node_modules/.pnpm/node_modules/jiti/README.md" Reading "node_modules/.pnpm/node_modules/jiti/dist/babel.cjs" Reading "node_modules/.pnpm/node_modules/jiti/dist/jiti.cjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti-cli.mjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti-hooks.mjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti-native.mjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti-register.d.mts" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti-register.mjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti-static.mjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti.cjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti.d.cts" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti.d.mts" Reading "node_modules/.pnpm/node_modules/jiti/lib/jiti.mjs" Reading "node_modules/.pnpm/node_modules/jiti/lib/types.d.ts" Reading "node_modules/.pnpm/node_modules/jiti/package.json" Reading "node_modules/.pnpm/node_modules/lightningcss-darwin-arm64/LICENSE" Reading "node_modules/.pnpm/node_modules/lightningcss-darwin-arm64/README.md" Reading "node_modules/.pnpm/node_modules/lightningcss-darwin-arm64/package.json" Reading "node_modules/.pnpm/node_modules/lightningcss/LICENSE" Reading "node_modules/.pnpm/node_modules/lightningcss/README.md" Reading "node_modules/.pnpm/node_modules/lightningcss/node/ast.d.ts" Reading "node_modules/.pnpm/node_modules/lightningcss/node/ast.js.flow" Reading "node_modules/.pnpm/node_modules/lightningcss/node/browserslistToTargets.js" Reading "node_modules/.pnpm/node_modules/lightningcss/node/composeVisitors.js" Reading "node_modules/.pnpm/node_modules/lightningcss/node/flags.js" Reading "node_modules/.pnpm/node_modules/lightningcss/node/index.d.ts" Reading "node_modules/.pnpm/node_modules/lightningcss/node/index.js" Reading "node_modules/.pnpm/node_modules/lightningcss/node/index.js.flow" Reading "node_modules/.pnpm/node_modules/lightningcss/node/index.mjs" Reading "node_modules/.pnpm/node_modules/lightningcss/node/targets.d.ts" Reading "node_modules/.pnpm/node_modules/lightningcss/node/targets.js.flow" Reading "node_modules/.pnpm/node_modules/lightningcss/package.json" Reading "node_modules/.pnpm/node_modules/magic-string/LICENSE" Reading "node_modules/.pnpm/node_modules/magic-string/README.md" Reading "node_modules/.pnpm/node_modules/magic-string/dist/index.d.mts" Reading "node_modules/.pnpm/node_modules/magic-string/dist/index.mjs" Reading "node_modules/.pnpm/node_modules/magic-string/package.json" Reading "node_modules/.pnpm/node_modules/mri/index.d.ts" Reading "node_modules/.pnpm/node_modules/mri/lib/index.js" Reading "node_modules/.pnpm/node_modules/mri/lib/index.mjs" Reading "node_modules/.pnpm/node_modules/mri/license.md" Reading "node_modules/.pnpm/node_modules/mri/package.json" Reading "node_modules/.pnpm/node_modules/mri/readme.md" Reading "node_modules/.pnpm/node_modules/node-addon-api/LICENSE.md" Reading "node_modules/.pnpm/node_modules/node-addon-api/README.md" Reading "node_modules/.pnpm/node_modules/node-addon-api/common.gypi" Reading "node_modules/.pnpm/node_modules/node-addon-api/except.gypi" Reading "node_modules/.pnpm/node_modules/node-addon-api/index.js" Reading "node_modules/.pnpm/node_modules/node-addon-api/napi-inl.deprecated.h" Reading "node_modules/.pnpm/node_modules/node-addon-api/napi-inl.h" Reading "node_modules/.pnpm/node_modules/node-addon-api/napi.h" Reading "node_modules/.pnpm/node_modules/node-addon-api/node_addon_api.gyp" Reading "node_modules/.pnpm/node_modules/node-addon-api/node_api.gyp" Reading "node_modules/.pnpm/node_modules/node-addon-api/noexcept.gypi" Reading "node_modules/.pnpm/node_modules/node-addon-api/nothing.c" Reading "node_modules/.pnpm/node_modules/node-addon-api/package-support.json" Reading "node_modules/.pnpm/node_modules/node-addon-api/package.json" Reading "node_modules/.pnpm/node_modules/node-addon-api/tools/README.md" Reading "node_modules/.pnpm/node_modules/node-addon-api/tools/check-napi.js" Reading "node_modules/.pnpm/node_modules/node-addon-api/tools/clang-format.js" Reading "node_modules/.pnpm/node_modules/node-addon-api/tools/conversion.js" Reading "node_modules/.pnpm/node_modules/node-addon-api/tools/eslint-format.js" Reading "node_modules/.pnpm/node_modules/picocolors/LICENSE" Reading "node_modules/.pnpm/node_modules/picocolors/README.md" Reading "node_modules/.pnpm/node_modules/picocolors/package.json" Reading "node_modules/.pnpm/node_modules/picocolors/picocolors.browser.js" Reading "node_modules/.pnpm/node_modules/picocolors/picocolors.d.ts" Reading "node_modules/.pnpm/node_modules/picocolors/picocolors.js" Reading "node_modules/.pnpm/node_modules/picocolors/types.d.ts" Reading "node_modules/.pnpm/node_modules/picomatch/LICENSE" Reading "node_modules/.pnpm/node_modules/picomatch/README.md" Reading "node_modules/.pnpm/node_modules/picomatch/index.js" Reading "node_modules/.pnpm/node_modules/picomatch/lib/constants.js" Reading "node_modules/.pnpm/node_modules/picomatch/lib/parse.js" Reading "node_modules/.pnpm/node_modules/picomatch/lib/picomatch.js" Reading "node_modules/.pnpm/node_modules/picomatch/lib/scan.js" Reading "node_modules/.pnpm/node_modules/picomatch/lib/utils.js" Reading "node_modules/.pnpm/node_modules/picomatch/package.json" Reading "node_modules/.pnpm/node_modules/picomatch/posix.js" Reading "node_modules/.pnpm/node_modules/source-map-js/LICENSE" Reading "node_modules/.pnpm/node_modules/source-map-js/README.md" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/array-set.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/base64-vlq.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/base64.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/binary-search.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/mapping-list.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/quick-sort.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/source-map-consumer.d.ts" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/source-map-consumer.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/source-map-generator.d.ts" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/source-map-generator.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/source-node.d.ts" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/source-node.js" Reading "node_modules/.pnpm/node_modules/source-map-js/lib/util.js" Reading "node_modules/.pnpm/node_modules/source-map-js/package.json" Reading "node_modules/.pnpm/node_modules/source-map-js/source-map.d.ts" Reading "node_modules/.pnpm/node_modules/source-map-js/source-map.js" Reading "node_modules/.pnpm/node_modules/tapable/LICENSE" Reading "node_modules/.pnpm/node_modules/tapable/README.md" Reading "node_modules/.pnpm/node_modules/tapable/lib/AsyncParallelBailHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/AsyncParallelHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/AsyncSeriesBailHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/AsyncSeriesHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/AsyncSeriesLoopHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/AsyncSeriesWaterfallHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/Hook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/HookCodeFactory.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/HookMap.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/MultiHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/SyncBailHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/SyncHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/SyncLoopHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/SyncWaterfallHook.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/index.js" Reading "node_modules/.pnpm/node_modules/tapable/lib/util-browser.js" Reading "node_modules/.pnpm/node_modules/tapable/package.json" Reading "node_modules/.pnpm/node_modules/tapable/tapable.d.ts" Reading "node_modules/@tailwindcss/cli/LICENSE" Reading "node_modules/@tailwindcss/cli/README.md" Reading "node_modules/@tailwindcss/cli/dist/index.mjs" Reading "node_modules/@tailwindcss/cli/package.json" Reading "node_modules/my-ui-lib/index.html" Reading "node_modules/tailwindcss/LICENSE" Reading "node_modules/tailwindcss/README.md" Reading "node_modules/tailwindcss/dist/chunk-5JIJA4QV.mjs" Reading "node_modules/tailwindcss/dist/chunk-C2OYBFIH.mjs" Reading "node_modules/tailwindcss/dist/chunk-DCG7AFIE.mjs" Reading "node_modules/tailwindcss/dist/colors-C__qRT83.d.ts" Reading "node_modules/tailwindcss/dist/colors.d.mts" Reading "node_modules/tailwindcss/dist/colors.d.ts" Reading "node_modules/tailwindcss/dist/colors.js" Reading "node_modules/tailwindcss/dist/colors.mjs" Reading "node_modules/tailwindcss/dist/default-theme.d.mts" Reading "node_modules/tailwindcss/dist/default-theme.d.ts" Reading "node_modules/tailwindcss/dist/default-theme.js" Reading "node_modules/tailwindcss/dist/default-theme.mjs" Reading "node_modules/tailwindcss/dist/flatten-color-palette.d.mts" Reading "node_modules/tailwindcss/dist/flatten-color-palette.d.ts" Reading "node_modules/tailwindcss/dist/flatten-color-palette.js" Reading "node_modules/tailwindcss/dist/flatten-color-palette.mjs" Reading "node_modules/tailwindcss/dist/lib.d.mts" Reading "node_modules/tailwindcss/dist/lib.d.ts" Reading "node_modules/tailwindcss/dist/lib.js" Reading "node_modules/tailwindcss/dist/lib.mjs" Reading "node_modules/tailwindcss/dist/plugin.d.mts" Reading "node_modules/tailwindcss/dist/plugin.d.ts" Reading "node_modules/tailwindcss/dist/plugin.js" Reading "node_modules/tailwindcss/dist/plugin.mjs" Reading "node_modules/tailwindcss/dist/resolve-config-B4yBzhca.d.ts" Reading "node_modules/tailwindcss/dist/resolve-config-QUZ9b-Gn.d.mts" Reading "node_modules/tailwindcss/dist/types-DWdTiksJ.d.mts" Reading "node_modules/tailwindcss/package.json" Reading "package.json" Reading "pnpm-lock.yaml" Reading "pnpm-workspace.yaml" Reading "public/index.html" Reading "tailwindcss-10742.log" ``` </details> <details> <summary>After</summary> ``` Reading "./app/index.html" Reading "./package.json" Reading "./public/index.html" ``` </details> |
||
|
|
6de87c62c4
|
Fix changes to symlinked files outside of the project works (#20356)
This PR fixes an issue where changes to a symlinked file wouldn't result in hot-reload when using `@tailwincdss/vite`. This issue also exists in the other packages such as `@tailwincdss/postcss`, `@tailwincdss/webpack` and `@tailwincdss/cli`. The issue is that we watch the symlinked file, but not the "real" file for changes. If the source of the symlinked file lives in another folder that is not covered by auto-source detection or by any of the `@source` directives, then changes to that file won't trigger a change. To solve this, if a file is symlinked or lives in a symlinked folder, then we will make sure that the `scanner.files` contains the real path / canonicalized path to the real file as well just so we can detect changes in that file. Fixes: #20346 Closes: #20347 ## Test plan 1. Added a regression test for `@tailwindcss/vite` 2. Added tests in the scanner code itself 3. Manually tested on the reproduction: | | Initial state | After change | | ---: | --- | --- | | **Before** | <img width="3200" height="1800" alt="file-f8616573eec3150ae484fd279204c6d7" src="https://github.com/user-attachments/assets/2734ecc3-b5b6-420e-820d-8a4a8fcdd7f5" /> | <img width="3200" height="1800" alt="file-0e93fd3c2c9694c844b098616a3208d2" src="https://github.com/user-attachments/assets/fd86859b-420b-476b-80f6-e94d02e8b07b" /> | | **After** | <img width="3200" height="1800" alt="file-f8616573eec3150ae484fd279204c6d7" src="https://github.com/user-attachments/assets/2734ecc3-b5b6-420e-820d-8a4a8fcdd7f5" /> | <img width="3200" height="1800" alt="file-eb7b37430ea1363dddeac7226007afe4" src="https://github.com/user-attachments/assets/0a95b1a4-a357-491d-b57f-78460c0fc9db" /> | [ci-all] --------- Co-authored-by: Nic <162764842+Nic-Polumeyv@users.noreply.github.com> |
||
|
|
7811d74f37
|
Ensure earlier @source is not accidentally ignored by later @source (#20335)
This PR fixes an issue where an `@source` pointing to a file in a nested
folder was not scanned when a later `@source` pointed to a file in a
parent folder.
E.g.:
```css
@source "./nested/index.html";
@source "./index.html";
```
When using `@source` pointing to a specific file, then we want to make
sure that we ignore _other_ files since they are not listed explicitly.
To ensure that these patterns don't read other files, we inject a `*`
ignore pattern before it. You can think of the above being expanded to:
```rs
Ignored { base: "/project/src/nested", pattern: "*" }
Pattern { base: "/project/src/nested", pattern: "/index.html" }
Ignored { base: "/project/src", pattern: "*" }
Pattern { base: "/project/src", pattern: "/index.html" }
```
The problem with this is that the `Ignored { base: "/project/src",
pattern: "*" }` pattern results in ignoring the `nested` folder as well.
This means that we never even walk into the `nested` folder, so the
earlier `@source "./nested/index.html"` never matches anything.
We could switch the order in user land, but that's going to be hard to
maintain (and order matters for undoing/redoing earlier rules, so we
can't re-order internally either). Instead, we can scope the ignore
pattern to the _current_ path only, and not deeply nested. In other
words, the pattern should become:
```diff
- *
+ /*
```
It's a very subtle difference, but the pattern from above will now
become:
```diff
Ignored { base: "/project/src/nested", pattern: "*" }
Pattern { base: "/project/src/nested", pattern: "/index.html" }
- Ignored { base: "/project/src", pattern: "*" }
+ Ignored { base: "/project/src", pattern: "/*" }
Pattern { base: "/project/src", pattern: "/index.html" }
```
We already do this when an unrestricted root (e.g. `@source "./nested"`)
lives inside the base of a restricted pattern. This works because every
source base is also its own walk root, and a `/*` pattern only matches
direct children so it can't ignore anything when walking from the nested
root itself.
This PR extends that same check to restricted pattern bases: if another
`@source` pattern has its base nested inside the current base, we emit
`/*` instead of `*`.
Note that we only relax the pattern to `/*` when such a nested root
actually exists. Sibling folders that no `@source` points into (e.g. an
`ignore-me` folder next to `nested`) are still direct children, so they
still match `/*` and are never walked.
Fixes: #20333
## Test plan
1. Added a regression test with the reproduction setup
2. Added a similar test with another sibling folder that should still be
ignored
3. Tested it against the actual reproduction:
Before:
<img width="797" height="463" alt="image"
src="https://github.com/user-attachments/assets/893bb872-f5cf-4c5a-bfb5-2dc1043b5a39"
/>
After:
<img width="794" height="460" alt="image"
src="https://github.com/user-attachments/assets/a59aae45-68ad-4fe3-b21f-b568f535d24f"
/>
Notice that the `text-green-500` now appears as expected.
|
||
|
|
39656f7d9a
|
Add --poll option to @tailwindcss/cli (#20297)
This PR re-adds the `--poll` option to the `@tailwindcss/cli` that we had in Tailwind CSS v3, but didn't in Tailwind CSS v4. In Tailwind CSS v4, we started using `@parcel/watcher` instead of chokidar for our watcher in the CLI. However, this currently doesn't support a `--poll` option. This PR implements our own `--poll` option such that you can use it in environments where fs events don't work properly (e.g. Docker). Polling can be enabled by using `--watch --poll`, in this case we will poll every `250ms` (I'm open for a different default value). You can also pick your own interval by using `--watch --poll 500` which is defined in milliseconds. The `--poll` option will be less efficient than a normal `--watch`. But if you are in a situation where you can't use `--watch` on its own then this is a good fallback. One thing you can do today is run the build command manually. If you do have some tooling that _does_ work on your machine (such as [`watchexec`](https://github.com/watchexec/watchexec)) then you can automatically perform a full build. The biggest downside of this approach is that you are doing a full build every time, instead of an incremental build. With this PR, we try to fix that by still allowing incremental builds. This should result in the same behavior as the normal `--watch` function: 1. First run, will trigger a full build 1. When any of the source files changes: - If all classes were already known, then it will be a no-op, but you will see a log in the terminal about it. - If a new class is detected, then the CSS will be updated, but it will be much more efficient than a full rebuild 1. When the input CSS file changes, or any of its dependencies, then a full rebuild will be triggered (such that your new `@utility` are available, and `@theme` values are updated). The implementation is a little bit more complex just because I didn't want to spam the terminal output even if we are polling every `250ms`. In the Oxide scanner we do track the modified times of each file. Every `250ms` we traverse the file system and skip the files that we know didn't change (since the mtime is the same). If the file was touched, then we will parse it again to extract possible Tailwind CSS classes. We will also track which files were scanned such that we can know whether we have to trigger a full-rebuild or not (in case the input.css file or any of its dependencies was changed). Fixes: #18109 Fixes: #18540 Fixes: #15750 ## Test plan 1. Existing tests pass 2. An integration test has been added for the `--poll` option 3. Tested it on the tailwindcss.com codebase: <img width="679" height="320" alt="image" src="https://github.com/user-attachments/assets/af858da5-3e07-448d-86bd-8eacdf3bf8d1" /> Annotated: ``` ≈ tailwindcss v4.3.2 Done in 105ms Initial build Done in 3ms Saved a file that resulted in a no-op Done in 2ms Saved a file that resulted in a no-op Done in 3ms Saved a file that resulted in a no-op Done in 53ms Saved a file with a new class Done in 2ms Saved a file that resulted in a no-op Done in 2ms Saved a file that resulted in a no-op Done in 3ms Saved a file that resulted in a no-op Done in 88ms Saved a the input.css file Done in 3ms Saved a file that resulted in a no-op Polling for changes… ``` We check the file system every `250ms` by default, but we won't log to prevent spamming the terminal. |
||
|
|
0fee7b55f9
|
Restrict walking sibling folders when using a pattern (#20263)
This PR fixes an issue where a `@source` pointing to a concrete file
could result in scanning the entire parent folder instead of only
looking for the file we are actually interested in.
When we optimize a `@source`, we move all the static parts of the
pattern to the `base`. This means that a `@source` like this:
```css
@source "../../app.config.ts";
```
Resolves to:
```rs
SourceEntry::Pattern { base: "/Users", pattern: "/app.config.ts" }
```
When walking the `base`, we would only emit an `!app.config.ts` rule.
This means that _everything_ in the `/Users` folder is still walked, and
the result is then thrown away. If you take a look at the `gitignore`
equivalent (which is what we build behind the scenes), then we would
essentially create the following:
```gitignore
!app.config.ts
```
But if you know how `gitignore` files work, then you know that this does
force `app.config.ts` to _not_ be ignored, but it doesn't say anything
about all the other files/folders.
The fix is to restrict the `base` so that we ignore everything in the
folder, and then explicitly re-include only the pattern we care about.
Fixing this would result in the following:
```gitignore
*
!foo.ts
```
In the reproduction from #20255 this takes the build from appearing to
hang (~22s) down to ~20ms on my machine.
There are a few edge cases we have to be careful about:
**Multiple patterns for the same base.** If we have multiple `@source`
directives for the same folder:
```css
@source "./src/foo.ts";
@source "./src/bar.ts";
```
Then blindly emitting `*` for each one would result in this `.gitignore`
equivalent:
```gitignore
*
!foo.ts
*
!bar.ts
```
Notice that the second `*` would end up ignoring `foo.ts` again. To
avoid this, we only emit the `*` rule once per `base`.
**Dynamic parts in intermediate folders.** If the pattern still contains
a `*` in one of its folders:
```css
@source "./src/ba*/*.html";
```
This resolves to:
```rs
SourceEntry::Pattern { base: "/src", pattern: "/ba*/*.html" }
```
If we now inject the `*` rule for `/src`, then we would never walk the
`ba*` folders (e.g. `bar` or `baz`). To fix this, we add inverse rules
for each parent segment of the pattern:
```gitignore
* ← ignore everything
!/ba*/ ← except for the `ba*/` folders, so we walk into them
!/ba*/*.html ← then scan the `*.html` files in them
```
**Bases already covered by a broader source.** If the `base` is already
included (or nested) under an unrestricted source (an `Auto`/`External`
source, or a `Pattern` containing `**`), then we leave it alone.
Restricting it would incorrectly hide siblings that the broader source
is supposed to pick up. For example:
```css
@source "**/*";
@source "./src/components/button.html";
```
Here the `**/*` source should keep auto-detecting every file, so we must
_not_ restrict `src/components` just because there's a more specific
`@source` pointing to it.
Source order is preserved throughout, so later `@source not …` rules can
still override an earlier restricted source.
Fixes: #20255
## Test plan
1. Added unit tests realted to this `sources` logic
2. Added integration like tests for the scanner itself
3. All other tests should pass as-s
4. Should work on each OS [ci-all]
|
||
|
|
34c2b04a35
|
Deleting files should not crash Vite HMR (#20259)
This PR fixes an issue where Vite crashes when a file is deleted. This is because we don't cleanup files/folders in the scanner when they are being deleted. This results in an issue where we would use Vite's `addWatchFile` API with deleted files. This PR fixes that by making sure that when we re-scan the filesystem that we clear out files/folders (and recompute globs). Note: `candidates` themselve are still append-only until a fresh compiler instance is created since the TypeScript based compiler relies on that behavior. Fixes: #17532 Closes: #20111 ## Test plan 1. Added an integration test based on the issue 2. Tested it directly in the reproduction repo Before deleting: <img width="988" height="1376" alt="image" src="https://github.com/user-attachments/assets/0f104ff3-0f88-415a-8311-1cf54ab75d21" /> Before: <img width="1389" height="1376" alt="file-1b446568bfad50e6a8105d7be33f15f0" src="https://github.com/user-attachments/assets/d2fbf03e-ca22-4bc4-9bb4-f3de10b90b99" /> Which results in: <img width="988" height="1376" alt="image" src="https://github.com/user-attachments/assets/8320d61c-4210-4aa8-aa8d-98c5327e9604" /> After: <img width="1389" height="1376" alt="file-c36ab0265856da5bb7c7a1e77427b821" src="https://github.com/user-attachments/assets/2ec4c4ea-aa79-4a51-900a-e247dcdb976c" /> Which results in: <img width="988" height="1376" alt="image" src="https://github.com/user-attachments/assets/8e8dec0d-40eb-4e54-b5fd-8d22abd55973" /> [ci-all] |
||
|
|
6b0eb5193e
|
Ensure @source globs ending in **/* preserve dynamic path segments to avoid scanning too many files (#20217)
This PR fixes an issue where we were over-scanning because we lost pattern information when a `@source` ended in `**/*` and contained other dynamic parts in the glob pattern. Noticed this while debugging and working on #20214. Let's say you have the following: ```css @source './blog/*/foo/bar/baz/**/*'; ``` We make sure that folders or patterns ending in `**/*` are converted to "auto sources", meaning that auto content detection should be used in these folders. However, when doing so, we would only take the `base` path of the glob. And since we have "dynamic" parts (the `*`) in the pattern, that should not be the case. So the `@source` from above, would be turned into: ```rs SourceEntry::Auto { base = "/Users/projects/project/blog" } ``` Notice that we lose all the information related to `/*/foo/bar/baz/`. While this would technically still work, it also means that we are scanning **too many files and folders** because we're only interested in folders in the `blog` folder that also contain `foo/bar/baz`. If the `*` wasn't there, then this would be correct, because then we would've moved the `/blog/foo/bar/baz` part to the `base` ahead of time, and the pattern would just be `/**/*`. That would result in: ```rs SourceEntry::Auto { base = "/Users/projects/project/blog/foo/bar/baz" } ``` This PR fixes that, by _not_ converting it to an auto-source, and instead convert it to a pattern: ```rs SourceEntry::Pattern { base: "/Users/projects/project/blog", pattern: "/*/foo/bar/baz/**/*" } ``` Notice that the static part `blog` is still moved to the base path. But the rest stays in the `pattern` part as expected. ## Test plan 1. Added a failing test to make sure this doesn't happen anymore 2. Existing tests pass 3. Tested this on the tailwindcss.com codebase using `@source "../blog/tailwindcss*/**/*";` ```diff diff --git a/./tailwindcss-55526.log b/./tailwindcss-55527.log index ce79c5da..03e97598 100644 --- a/./tailwindcss-55526.log +++ b/./tailwindcss-55527.log @@ -2,50 +2,9 @@ INFO tailwindcss_oxide::scanner: Provided sources: INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/app", pattern: "../blog/tailwindcss*/**/*", negated: false } INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/Users/robin/.bun/bin", pattern: "bun", negated: true } INFO tailwindcss_oxide::scanner: Optimized sources: -INFO tailwindcss_oxide::scanner: Source: Auto { base: "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog" } +INFO tailwindcss_oxide::scanner: Source: Pattern { base: "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog", pattern: "/tailwindcss*/**/*" } INFO tailwindcss_oxide::scanner: Source: Ignored { base: "/Users/robin/.bun/bin", pattern: "/bun" } INFO discover_sources: tailwindcss_oxide::scanner: enter -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2022-05-23-headless-ui-v1-6-tailwind-ui-team-management/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2022-06-23-tailwind-templates-and-all-access/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2022-08-17-tailwind-framer-motion-template-and-tailwind-jobs/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2022-09-09-new-personal-website-heroicons-2-headless-ui-v17/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2022-12-15-protocol-api-documentation-template/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2023-04-24-new-changelog-template-and-the-biggest-tailwind-ui-update-ever/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2023-07-18-tailwind-connect-2023-recap/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2023-08-07-meet-studio-our-new-agency-template/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2024-05-24-catalyst-application-layouts/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2024-05-30-prettier-plugin-collapse-whitespace/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2024-06-21-headless-ui-v2-1/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2024-09-12-radiant-a-beautiful-new-marketing-site-template/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/2025-05-14-compass-course-starter-kit/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/automatic-class-sorting-with-prettier/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/building-react-and-vue-support-for-tailwind-ui/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/building-the-tailwind-blog/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/designing-tailwind-ui-ecommerce/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/from-900-to-1-how-we-hired-robin-malfait/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-unstyled-accessible-ui-components/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v1-4/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v1-5/demo.tsx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v1-5/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v1/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v2/examples/HeadlessUIV2Examples.tsx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v2/examples/StateAttributesExample.tsx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v2/examples/anchor-positioning.tsx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/headless-ui-v2/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/heroicons-micro/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/heroicons-v1/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/hiring-a-design-engineer-and-staff-engineer/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/introducing-catalyst/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/introducing-heroicons/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/introducing-linting-for-tailwindcss-intellisense/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/introducing-tailwind-play/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/just-in-time-the-next-generation-of-tailwind-css/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/multi-line-truncation-with-tailwindcss-line-clamp/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/simon-vrachliotis-joins-tailwind-labs/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/standalone-cli/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwind-plus/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwind-ui-ecommerce/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwind-ui-now-with-react-and-vue-support/index.mdx" INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwindcss-1-5/index.mdx" INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwindcss-1-6/index.mdx" INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwindcss-1-7/index.mdx" @@ -68,10 +27,4 @@ INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/t INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwindcss-v4-beta/index.mdx" INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwindcss-v4/color-palette.tsx" INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/tailwindcss-v4/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/utility-friendly-transitions-with-tailwindui-react/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/vanilla-js-support-for-tailwind-plus/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/welcoming-brad-cornes-to-the-tailwind-team/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/welcoming-david-luhr-to-tailwind-labs/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/welcoming-james-mcdonald-to-tailwind-labs/index.mdx" -INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/tailwindlabs/tailwindcss.com/src/blog/whats-new-in-tailwindcss-on-youtube/index.mdx" INFO discover_sources: tailwindcss_oxide::scanner: exit ``` Notice now that a lot of files are skipped as expected since we-re not accidentally over-scanning now. [ci-all] |
||
|
|
1bf4291e85
|
Fix @source with folders that are ignored (#20214)
This PR fixes an issue where a `@source` that's pointing to a folder that is git ignored, is also ignored by the `@source` even if it's explicitly added. Internally, we convert `@source` directives from `PublicSourceEntry`s to `SourceEntry`s where we have dedicated enum branches for `Auto`, `Pattern`, `Ignored` and `External`. The `Auto` one accepts a `base` path, and will be used for auto content detection. However, these paths will make use of all the default auto content detection rules, which includes git ignore rules. We also have `External` where we link to something that's "external" to the current repo. We can probably improve this name, but it's external in the sense that it won't show up on GitHub for example, aka ignored. We have some content dirs that we ignore by default, such as the `node_modules` folder. When you do use `@source` with `node_modules` in the path, then we will mark it as an `external` resource which does not look at the `gitignore` related rules and allowing it to be included this way. The idea with this is that, even though the folder is ignored by default, you can still include files from the folder by explicitly using the `@source` directive. The issue as seen in #19844 is using `vendor/` instead of `node_modules/` which is _not_ ignored by default. While we can add `vendor/` to this same ignored dirs list, it will result in a breaking change because this folder is often used by the Laravel community to store some resources in. This PR fixes this problem by not only looking at the content dirs we ignore by default, but also looking at the actual git ignore state of this folder. If it turns out that this is ignored, then we promote the `Auto` source to an `External` source. Fixes: #19844 Closes: #20057 ## Test plan 1. Added integration tests for this situation 2. Ran the fix on the reproduction from #19844. If we run the CLI with the `DEBUG=*` environment variable, the log file produces these results: ```diff diff --git a/./tailwindcss-29207.log b/./tailwindcss-30381.log index bc3017c..921af0e 100644 --- a/./tailwindcss-29207.log +++ b/./tailwindcss-30381.log @@ -6,8 +6,9 @@ INFO tailwindcss_oxide::scanner: Source: PublicSourceEntry { base: "/Users/robin INFO tailwindcss_oxide::scanner: Optimized sources: INFO tailwindcss_oxide::scanner: Source: Pattern { base: "/Users/robin/github.com/GrimLink/tailwind-gitignore-bug/app/design/frontend/theme", pattern: "/**/*.phtml" } INFO tailwindcss_oxide::scanner: Source: Pattern { base: "/Users/robin/github.com/GrimLink/tailwind-gitignore-bug/app/design/frontend/theme", pattern: "/**/*.xml" } -INFO tailwindcss_oxide::scanner: Source: Auto { base: "/Users/robin/github.com/GrimLink/tailwind-gitignore-bug/vendor/acme/theme" } +INFO tailwindcss_oxide::scanner: Source: External { base: "/Users/robin/github.com/GrimLink/tailwind-gitignore-bug/vendor/acme/theme" } INFO tailwindcss_oxide::scanner: Source: Ignored { base: "/Users/robin/.fnm/node-versions/v26.1.0/installation/bin", pattern: "/node" } INFO discover_sources: tailwindcss_oxide::scanner: enter -INFO discover_sources: tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/GrimLink/tailwind-gitignore-bug/app/design/frontend/theme/index.phtml" +INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/GrimLink/tailwind-gitignore-bug/app/design/frontend/theme/index.phtml" +INFO tailwindcss_oxide::scanner: Reading "/Users/robin/github.com/GrimLink/tailwind-gitignore-bug/vendor/acme/theme/module/templates/component.phtml" INFO discover_sources: tailwindcss_oxide::scanner: exit ``` We're checking some `.gitignore` related files, so let's check on each OS [ci-all] |
||
|
|
3f58e52e36
|
Ensure @source globs with symlinks are preserved (#20203)
This PR fixes an issue when working with `@source` and `@source not`
that involves symlinks.
Internally our sources are mapped to a source entry where we have a
`base` path and a `pattern`. You can think about this where we insert a
`.gitignore` file in the `base` path for the given pattern.
However, we optimize these entries to move as many "static" parts into
the base path. For example:
```css
@source "./some/folder/here/*.html";
```
Is mapped to something like:
```ts
{ base: "/projects/my-project", pattern: "./some/folder/here/*.html" }
```
We then optimize it by turning it into:
```ts
{ base: "/projects/my-project/some/folder/here", pattern: "*.html" }
```
While doing this, we also use `dunce::canonicalize` to resolve the
actual paths on disk. This means that a symlink is resolved to their
real paths. This can cause issues because the "real" path is not what
you wrote in the `@source` directives.
So before, it could be that you have this:
```css
@source "./some/symlinked-folder/here/*.html";
```
Which was mapped to this on the Rust side:
```ts
{ base: "/projects/my-project", pattern: "./some/symlinked-folder/here/*.html" }
```
But was then optimized to:
```ts
{ base: "/projects/my-project/some/actual-folder/here", pattern: "*.html" }
```
...and we lost the `symlinked-folder` information. This causes issues as
seen in #17985.
With this PR, we keep the symlinked information in those globs since
that's what you wrote in those `@source` directives.
While setting up integration tests, I stumbled upon an issue because I
wanted to test that ignoring a symlinked folder, but including a single
particular file of that ignored folder resulted in that file being
ignored as well. Let's look at an example:
```css
@source '../lib';
@source not '../lib/ignored';
@source '../lib/ignored/except.html';
```
Earlier I mentioned that we create `.gitignore` files based on these
`@source` directives. In this case, when we're dealing with a folder, we
use `**/*` as the contents.
Looking at the example above, we should essentially have something like
this:
```gitignore
# lib/.gitignore
# @source '../lib'
!**/*
# lib/ignored/.gitignore
# @source '../lib/ignored'
**/*
# @source '../lib/ignored/except.html'
!except.html
```
Since it's a `.gitignore` file, we have to invert the globs. But the bug
I noticed is that in reality the result of those gitignores didn't look
like the above, it looked like:
```gitignore
# lib/.gitignore
# @source '../lib'
!**/*
# lib/ignored/.gitignore
# @source '../lib/ignored/except.html'
!except.html
# @source '../lib/ignored'
**/*
```
Notice how the `!except.html` and `**/*` are flipped. When dealing with
`.gitignore` files, the order is important.
This was caused because internally we kept a `BTreeMap` of `BTreeSet`s
where the map was the base path and a set of patterns. The patterns were
sorted because of the `BTreeSet`... which is not what we want.
Fixes: #17985
Closes: #20091
## Test plan
1. Added new tests in the scanner tests (on the Rust side)
2. Added integration tests with a symlink to another folder, outside of
the current folder
2. Added integration tests with a symlink to another folder, inside of
the current folder
2. Added integration tests to ensure that the order of `@source` files
with a folder + file is sorted correctly.
3. Since we're dealing with symlinks in these tests, let's test all OSes
[ci-all]
|
||
|
|
bbd916aaa0
|
Ignore binary extensions, except in folder names (#17595)
We generate a glob to ignore binary extensions that looks something like
this:
```
*.{mp4,pages,exe,…}
```
However, if you have a folder that happens to end in `.pages` for
example, then this folder will be ignored in its entirety.
To solve this, we added a new flag to the `Gitignore` struct so we can
register a bunch of ignore rules that _only_ apply to paths and not
folders.
Fixes: #17569
## Test plan
- Added a unit test
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
|
||
|
|
53801091a0
|
Watch CSS module files for changes (#17467)
This PR is a follow-up PR for: https://github.com/tailwindlabs/tailwindcss/pull/17433 In the other PR we allow scanning CSS files for extracting usages of CSS variables. This is important for `.module.css` files that reference these variables but aren't in the same big AST of the main CSS file. This PR also makes sure to watch for changes in those registered CSS files and re-extract the variables when they change. This PR took a bit longer than expected because I was trying to make sure that writing to `./dist/out.css` works without infinite-looping (e.g.: we had issues with this in Tailwind CSS v3 with webpack). But I couldn't reproduce the issue at all. I did had some code that tried to detect if the CSS file contained license headers and skip in (because then it's very likely an output CSS file) but even without it the tests were fine. I setup integration tests with `@tailwindcss/cli` itself, and with tools that use webpack. Added a test for Next.js, and a dedicated webpack test as well. Even without tests, locally, I couldn't reproduce an infinite loop due to changes in an output CSS file... Eventually dropped the code that tries to detect output CSS files. One thing to keep in mind is that if you change any of your "main" CSS files, then we will trigger a full rebuild anyway, so this change is only required for unrelated CSS files (like CSS module files) that use CSS variables. ## Test plan 1. Added integration tests for the CLI and Next.js 2. Added new dedicated test for webpack |
||
|
|
2af7c57983
|
Extract used CSS variables from .css files (#17433)
This PR fixes an issue where CSS variables could be used in CSS modules, but where never emitted in your final CSS. Some backstory, when Tailwind CSS v4 came out, we _always_ emitted all CSS variables whether they were used or not. Later, we added an optimization where we only emit the CSS variables that were actually used. The definition of "used" in this case is: 1. Used in your CSS file(s) — (we check the final CSS AST for this) 2. Used _somewhere_ in any of your source files (e.g.: a JavaScript file accessing a variable) The issue this PR tries to solve is with the very first point. If you are using CSS modules, then every CSS file is processed separately. This is not a choice Tailwind CSS made, but how other build tooling works (like Vite for example). To prevent emitting all of Tailwind's Preflight reset and all utilities per CSS file, you can use the `@reference` directive instead of repeating `@import "tailwindcss";`. This is explained here: https://tailwindcss.com/docs/compatibility#explicit-context-sharing But now we are just _referencing_ them, not emitting them. And since the CSS module is not connected in any way to the main `index.css` file that contains the `@import "tailwindcss";` directive, we don't even see the CSS variables while processing the `index.css` file. (or wherever your main CSS file is) This is where point 2 from above comes in. This is a situation where we rely on the extractor to find the used CSS variables so we can internally mark them as used. To finally get to the point of this PR, the extractor only scans `.html`, `.js`, ... files but not `.css` files. So all the CSS variables used inside of CSS modules will not be generated. This PR changes that behavior to also scan `.css` files. But _only_ for CSS variables (not any other type of class candidate). This is important, otherwise all your custom `@utility foo {}` definitions would always mark `foo` as a used class and include it in the CSS which is not always the case. On top extracting CSS variables, we will also make sure that the CSS variables we find are in usage positions (e.g.: `var(--color-red-500)`) and not in definition positions (e.g.: `--color-red-500: #ff0000;`). This is important because we only want to emit the variables that are actually used in the final CSS output. One future improvement not implemented here, is that technically we will also extract CSS variables that might not be used if defined in a `@utility`. ```css @utility never-used { color: var(--color-red-500); /* --color-red-500 will be emitted, even if it might not be used */ } ``` Fixes: #16904 Fixes: #17429 # Test plan 1. Added a test where CSS variables are defined in `.css` files (and ignored) 2. Added a test where CSS variables are used in `.css` files (and included) Testing on the reproduction defined in #16904, the `.module.css` file contains a reference to `var(--color-hot-pink)`, but generating a build shows that the variable definition is not available: <img width="1630" alt="image" src="https://github.com/user-attachments/assets/a0d5c37e-6813-4cd5-a677-6c356b5a73d4" /> When you run the build again with the changes from this PR, then we _do_ see the definition of the `--color-hot-pink` in the root CSS file: <img width="2876" alt="image" src="https://github.com/user-attachments/assets/beab7c11-a31b-4ea4-8235-4849a8e92859" /> |
||
|
|
eecb6f7476
|
A bit of cleanup (#17394)
Was working on another issue and noticed that I wanted these but they aren't related to any of the issues. So opening a separate PR to do some internal cleanup. |
||
|
|
b0c48c3de9
|
Fix symlink issues when resolving @source directives (#17391)
This PR fixes some issues related to symlinks when using them in the `@source` directive. Fixes: #16765 Fixes: #16038 ## Test plan 1. Added tests to prove this works - Added a recursive symlink test as well to make sure we don't hang 2. Existing tests still pass [ci-all] |
||
|
|
1ef97759e3
|
Add @source not support (#17255)
This PR adds a new source detection feature: `@source not "…"`. It can
be used to exclude files specifically from your source configuration
without having to think about creating a rule that matches all but the
requested file:
```css
@import "tailwindcss";
@source not "../src/my-tailwind-js-plugin.js";
```
While working on this feature, we noticed that there are multiple places
with different heuristics we used to scan the file system. These are:
- Auto source detection (so the default configuration or an `@source
"./my-dir"`)
- Custom sources ( e.g. `@source "./**/*.bin"` — these contain file
extensions)
- The code to detect updates on the file system
Because of the different heuristics, we were able to construct failing
cases (e.g. when you create a new file into `my-dir` that would be
thrown out by auto-source detection, it'd would actually be scanned). We
were also leaving a lot of performance on the table as the file system
is traversed multiple times for certain problems.
To resolve these issues, we're now unifying all of these systems into
one `ignore` crate walker setup. We also implemented features like
auto-source-detection and the `not` flag as additional _gitignore_ rules
only, avoid the need for a lot of custom code needed to make decisions.
High level, this is what happens after the now:
- We collect all non-negative `@source` rules into a list of _roots_
(that is the source directory for this rule) and optional _globs_ (that
is the actual rules for files in this file). For custom sources (i.e
with a custom `glob`), we add an allowlist rule to the gitignore setup,
so that we can be sure these files are always included.
- For every negative `@source` rule, we create respective ignore rules.
- Furthermore we have a custom filter that ensures files are only read
if they have been changed since the last time they were read.
So, consider the following setup:
```css
/* packages/web/src/index.css */
@import "tailwindcss";
@source "../../lib/ui/**/*.bin";
@source not "../../lib/ui/expensive.bin";
```
This creates a git ignore file that (simplified) looks like this:
```gitignore
# Auto-source rules
*.{exe,node,bin,…}
*.{css,scss,sass,…}
{node_modules,git}/
# Custom sources can overwrite auto-source rules
!lib/ui/**/*.bin
# Negative rules
lib/ui/expensive.bin
```
We then use this information _on top of your existing `.gitignore`
setup_ to resolve files (i.e so if your `.gitignore` contains rules e.g.
`dist/` this line is going to be added _before_ any of the rules lined
out in the example above. This allows negative rules to allow-list your
`.gitignore` rules.
To implement this, we're rely on the `ignore` crate but we had to make
various changes, very specific, to it so we decided to fork the crate.
All changes are prefixed with a `// CHANGED:` block but here are the
most-important ones:
- We added a way to add custom ignore rules that _extend_ (rather than
overwrite) your existing `.gitignore` rules
- We updated the order in which files are resolved and made it so that
more-specific files can allow-list more generic ignore rules.
- We resolved various issues related to adding more than one base path
to the traversal and ensured it works consistent for Linux, macOS, and
Windows.
## Behavioral changes
1. Any custom glob defined via `@source` now wins over your `.gitignore`
file and the auto-content rules.
- Resolves #16920
3. The `node_modules` and `.git` folders as well as the `.gitignore`
file are now ignored by default (but can be overridden by an explicit
`@source` rule).
- Resolves #17318
- Resolves #15882
4. Source paths into ignored-by-default folders (like `node_modules`)
now also win over your `.gitignore` configuration and auto-content
rules.
- Resolves #16669
5. Introduced `@source not "…"` to negate any previous rules.
- Resolves #17058
6. Negative `content` rules in your legacy JavaScript configuration
(e.g. `content: ['!./src']`) now work with v4.
- Resolves #15943
7. The order of `@source` definitions matter now, because you can
technically include or negate previous rules. This is similar to your
`.gitingore` file.
9. Rebuilds in watch mode now take the `@source` configuration into
account
- Resolves #15684
## Combining with other features
Note that the `not` flag is also already compatible with [`@source
inline(…)`](https://github.com/tailwindlabs/tailwindcss/pull/17147)
added in an earlier commit:
```css
@import "tailwindcss";
@source not inline("container");
```
## Test plan
- We added a bunch of oxide unit tests to ensure that the right files
are scanned
- We updated the existing integration tests with new `@source not "…"`
specific examples and updated the existing tests to match the subtle
behavior changes
- We also added a new special tag `[ci-all]` that, when added to the
description of a PR, causes the PR to run unit and integration tests on
all operating systems.
[ci-all]
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
|
||
|
|
b3c25563b7
|
Improve Oxide candidate extractor [0] (#16306)
This PR adds a new candidate[^candidate] extractor with 2 major goals in
mind:
1. It must be way easier to reason about and maintain.
2. It must have on-par performance or better than the current candidate
extractor.
### Problem
Candidate extraction is a bit of a wild west in Tailwind CSS and it's a
very critical step to make sure that all your classes are picked up
correctly to ensure that your website/app looks good.
One issue we run into is that Tailwind CSS is used in many different
"host" languages and frameworks with their own syntax. It's not only
used in HTML but also in JSX/TSX, Vue, Svelte, Angular, Pug, Rust, PHP,
Rails, Clojure, .NET, … the list goes on and all of these have different
syntaxes. Introducing dedicated parsers for each of these languages
would be a huge maintenance burden because there will be new languages
and frameworks coming up all the time. The best thing we can do is make
assumptions and so far we've done a pretty good job at that.
The only certainty we have is that there is at least _some_ structure to
the possible Tailwind classes used in a file. E.g.: `abc#def` is
definitely not a valid class, `hover:flex` definitely is. In a perfect
world we limit the characters that can be used and defined a formal
grammar that each candidate must follow, but that's not really an option
right now (maybe this is something we can implement in future major
versions).
The current candidate extractor we have has grown organically over time
and required patching things here and there to make it work in various
scenarios (and edge cases due to the different languages Tailwind is
used in).
While there is definitely some structure, we essentially work in 2
phases:
1. Try to extract `0..n` candidates. (This is the hard part)
2. Validate each candidate to make sure they are valid looking classes
(by validating against the few rules we have)
Another reason the current extractor is hard to reason about is that we
need it to be fast and that comes with some trade-offs to readability
and maintainability.
Unfortunately there will always be a lot of false positives, but if we
extract more classes than necessary then that's fine. It's only when we
pass the candidates to the core engine that we will know for sure if
they are valid or not. (we have some ideas to limit the amount of false
positives but that's for another time)
### Solution
Since the introduction of Tailwind CSS v4, we re-worked the internals
quite a bit and we have a dedicated internal AST structure for
candidates. For example, if you take a look at this:
```html
<div class="[@media(pointer:fine)]:data-[state=pending]:hover:text-red-500/(--my-opacity)"></div>
```
<details>
<summary>This will be parsed into the following AST:</summary>
```json
[
{
"kind": "functional",
"root": "text",
"value": {
"kind": "named",
"value": "red-500",
"fraction": null
},
"modifier": {
"kind": "arbitrary",
"value": "var(--my-opacity)"
},
"variants": [
{
"kind": "static",
"root": "hover"
},
{
"kind": "functional",
"root": "data",
"value": {
"kind": "arbitrary",
"value": "state=pending"
},
"modifier": null
},
{
"kind": "arbitrary",
"selector": "@media(pointer:fine)",
"relative": false
}
],
"important": false,
"raw": "[@media(pointer:fine)]:data-[state=pending]:hover:text-red-500/(--my-opacity)"
}
]
```
</details>
We have a lot of information here and we gave these patterns a name
internally. You'll see names like `functional`, `static`, `arbitrary`,
`modifier`, `variant`, `compound`, ...
Some of these patterns will be important for the new candidate extractor
as well:
| Name | Example | Description |
| -------------------------- | ----------------- |
---------------------------------------------------------------------------------------------------
|
| Static utility (named) | `flex` | A simple utility with no inputs
whatsoever |
| Functional utility (named) | `bg-red-500` | A utility `bg` with an
input that is named `red-500` |
| Arbitrary value | `bg-[#0088cc]` | A utility `bg` with an input that
is arbitrary, denoted by `[…]` |
| Arbitrary variable | `bg-(--my-color)` | A utility `bg` with an input
that is arbitrary and has a CSS variable shorthand, denoted by `(--…)` |
| Arbitrary property | `[color:red]` | A utility that sets a property to
a value on the fly |
A similar structure exist for modifiers, where each modifier must start
with `/`:
| Name | Example | Description |
| ------------------ | --------------------------- |
---------------------------------------- |
| Named modifier | bg-red-500`/20` | A named modifier |
| Arbitrary value | bg-red-500`/[20%]` | An arbitrary value, denoted by
`/[…]` |
| Arbitrary variable | bg-red-500`/(--my-opacity)` | An arbitrary
variable, denoted by `/(…)` |
Last but not least, we have variants. They have a very similar pattern
but they _must_ end in a `:`.
| Name | Example | Description |
| ------------------ | --------------------------- |
------------------------------------------------------------------------
|
| Named variant | `hover:` | A named variant |
| Arbitrary value | `data-[state=pending]:` | An arbitrary value,
denoted by `[…]` |
| Arbitrary variable | `supports-(--my-variable):` | An arbitrary
variable, denoted by `(…)` |
| Arbitrary variant | `[@media(pointer:fine)]:` | Similar to arbitrary
properties, this will generate a variant on the fly |
The goal with the new extractor is to encode these separate patterns in
dedicated pieces of code (we called them "machines" because they are
mostly state machine based and because I've been watching Person of
Interest but I digress).
This will allow us to focus on each pattern separately, so if there is a
bug or some new syntax we want to support we can add it to those
machines.
One nice benefit of this is that we can encode the rules and handle
validation as we go. The moment we know that some pattern is invalid, we
can bail out early.
At the time of writing this, there are a bunch of machines:
<details>
<summary>Overview of the machines</summary>
- `ArbitraryPropertyMachine`
Extracts candidates such as `[color:red]`. Some of the rules are:
1. There must be a property name
2. There must be a `:`
3. There must ba a value
There cannot be any spaces, the brackets are included, if the property
is a CSS variable, it must be a valid CSS variable (uses the
`CssVariableMachine`).
```
[color:red]
^^^^^^^^^^^
[--my-color:red]
^^^^^^^^^^^^^^^^
```
Depends on the `StringMachine` and `CssVariableMachine`.
- `ArbitraryValueMachine`
Extracts arbitrary values for utilities and modifiers including the
brackets:
```
bg-[#0088cc]
^^^^^^^^^
bg-red-500/[20%]
^^^^^
```
Depends on the `StringMachine`.
- `ArbitraryVariableMachine`
Extracts arbitrary variables including the parentheses. The first
argument must be a valid CSS variable, the other arguments are optional
fallback arguments.
```
(--my-value)
^^^^^^^^^^^^
bg-red-500/(--my-opacity)
^^^^^^^^^^^^^^
```
Depends on the `StringMachine` and `CssVariableMachine`.
- `CandidateMachine`
Uses the variant machine and utility machine. It will make sure that 0
or more variants are directly touching and followed by a utility.
```
hover:focus:flex
^^^^^^^^^^^^^^^^
aria-invalid:bg-red-500/(--my-opacity)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Depends on the `VariantMachine` and `UtilityMachine`.
- `CssVariableMachine`
Extracts CSS variables, they must start with `--` and must contain at
least one alphanumeric character or, `-`, `_` and can contain any
escaped character (except for whitespace).
```
bg-(--my-color)
^^^^^^^^^^
bg-red-500/(--my-opacity)
^^^^^^^^^^^^
bg-(--my-color)/(--my-opacity)
^^^^^^^^^^ ^^^^^^^^^^^^
```
- `ModifierMachine`
Extracts modifiers including the `/`
- `/[` will delegate to the `ArbitraryValueMachine`
- `/(` will delegate to the `ArbitraryVariableMachine`
```
bg-red-500/20
^^^
bg-red-500/[20%]
^^^^^^
bg-red-500/(--my-opacity)
^^^^^^^^^^^^^^^
```
Depends on the `ArbitraryValueMachine` and `ArbitraryVariableMachine`.
- `NamedUtilityMachine`
Extracts named utilities regardless of whether they are functional or
static.
```
flex
^^^^
px-2.5
^^^^^^
```
This includes rules like: A `.` must be surrounded by digits.
Depends on the `ArbitraryValueMachine` and `ArbitraryVariableMachine`.
- `NamedVariantMachine`
Extracts named variants regardless of whether they are functional or
static. This is very similar to the `NamedUtilityMachine` but with
different rules. We could combine them, but splitting things up makes it
easier to reason about.
Another rule is that the `:` must be included.
```
hover:flex
^^^^^^
data-[state=pending]:flex
^^^^^^^^^^^^^^^^^^^^^
supports-(--my-variable):flex
^^^^^^^^^^^^^^^^^^^^^^^^^
```
Depends on the `ArbitraryVariableMachine`, `ArbitraryValueMachine`, and
`ModifierMachine`.
- `StringMachine`
This is a low-level machine that is used by various other machines. The
only job this has is to extract strings that start with double quotes,
single quotes or backticks.
We have this because once you are in a string, we don't have to make
sure that brackets, parens and curlies are properly balanced. We have to
make sure that balancing brackets are properly handled in other
machines.
```
content-["Hello_World!"]
^^^^^^^^^^^^^^
bg-[url("https://example.com")]
^^^^^^^^^^^^^^^^^^^^^
```
- `UtilityMachine`
Extracts utilities, it will use the lower level `NamedUtilityMachine`,
`ArbitraryPropertyMachine` and `ModifierMachine` to extract the utility.
It will also handle important markers (including the legacy important
marker).
```
flex
^^^^
bg-red-500/20
^^^^^^^^^^^^^
!bg-red-500/20 Legacy important marker
^^^^^^^^^^^^^^
bg-red-500/20! New important marker
^^^^^^^^^^^^^^
!bg-red-500/20! Both, but this is considered invalid
^^^^^^^^^^^^^^^
```
Depends on the `ArbitraryPropertyMachine`, `NamedUtilityMachine`, and
`ModifierMachine`.
- `VariantMachine`
Extracts variants, it will use the lower level `NamedVariantMachine` and
`ArbitraryValueMachine` to extract the variant.
```
hover:focus:flex
^^^^^^
^^^^^^
```
Depends on the `NamedVariantMachine` and `ArbitraryValueMachine`.
</details>
One important thing to know here is that each machine runs to
completion. They all implement a `Machine` trait that has a
`next(cursor)` method and returns a `MachineState`.
The `MachineState` looks like this:
```rs
enum MachineState {
Idle,
Done(Span)
}
```
Where a `Span` is just the location in the input where the candidate was
found.
```rs
struct Span {
pub start: usize,
pub end: usize,
}
```
#### Complexities
**Boundary characters:**
When running these machines to completion, they don't typically check
for boundary characters, the wrapping `CandidateMachine` will check for
boundary characters.
A boundary character is where we know that even though the character is
touching the candidate it will not be part of the candidate.
```html
<div class="flex"></div>
<!-- ^ ^ -->
```
The quotes are touching the candidate `flex`, but they will not be part
of the candidate itself, so this is considered a valid candidate.
**What to pick?**
Let's imagine you are parsing this input:
```html
<div class="hover:flex"></div>
```
The `UtilityMachine` will find `hover` and `flex`. The `VariantMachine`
will find `hover:`. This means that at a certain point in the
`CandidateMachine` you will see something like this:
```rs
let variant_machine_state = variant_machine.next(cursor);
// MachineState::Done(Span { start: 12, end: 17 }) // `hover:`
let utility_machine_state = utility_machine.next(cursor);
// MachineState::Done(Span { start: 12, end: 16 }) // `hover`
```
They are both done, but which one do we pick? In this scenario we will
always pick the variant because its range will always be 1 character
longer than the utility.
Of course there is an exception to this rule and it has to do with the
fact that Tailwind CSS can be used in different languages and
frameworks. A lot of people use `clsx` for dynamically applying classes
to their React components. E.g.:
```tsx
<div
class={clsx({
underline: someCondition(),
})}
></div>
```
In this scenario, we will see `underline:` as a variant, and `underline`
as a utility. We will pick the utility in this scenario because the next
character is whitespace so this will never be a valid candidate
otherwise (variants and utilities must be touching). Another reason this
is valid, is because there wasn't a variant present prior to this
candidate.
E.g.:
```tsx
<div
class={clsx({
hover:underline: someCondition(),
})}
></div>
```
This will be considered invalid, if you do want this, you should use
quotes.
E.g.:
```tsx
<div
class={clsx({
'hover:underline': someCondition(),
})}
></div>
```
**Overlapping/covered spans:**
Another complexity is that the extracted spans for candidates can and
will overlap. Let's take a look at this C# example:
```csharp
public enum StackSpacing
{
[CssClass("gap-y-4")]
Small,
[CssClass("gap-y-6")]
Medium,
[CssClass("gap-y-8")]
Large
}
```
In this scenario, `[CssClass("gap-y-4")]` starts with a `[` so we have a
few options here:
1. It is an arbitrary property, e.g.: `[color:red]`
2. It is an arbitrary variant, e.g.: `[@media(pointer:fine)]:`
When running the parsers, both the `VariantMachine` and the
`UtilityMachine` will run to completion but end up in a
`MachineState::Idle` state.
- This is because it is not a valid variant because it didn't end with a
`:`.
- It's also not a valid arbitrary property, because it didn't include a
`:` to separate the property from the value.
Looking at the code as a human it's very clear what this is supposed to
be, but not from the individual machines perspective.
Obviously we want to extract the `gap-y-*` classes here.
To solve this problem, we will run over an additional slice of the
input, starting at the position before the machines started parsing
until the position where the machines stopped parsing.
That slice will be this one: `[CssClass("gap-y-6")]` (we already skipped
over the whitespace). Now, for every `[` character we see, will start a
new `CandidateMachine` right after the `[`'s position and run the
machines over that slice. This will now eventually extract the `gap-y-6`
class.
The next question is, what if there was a `:` (e.g.:
`[CssClass("gap-y-6")]:`), then the `VariantMachine` would complete, but
the `UtilityMachine` will not because not exists after it. We will apply
the same idea in this case.
Another issue is if we _do_ have actual overlapping ranges. E.g.: `let
classes = ['[color:red]'];`. This will extract both the `[color:red]`
and `color:red` classes. You have to use your imagination, but the last
one has the exact same structure as `hover:flex` (variant + utility).
In this case we will make sure to drop spans that are covered by other
spans.
The extracted `Span`s will be valid candidates therefore if the outer
most candidate is valid, we can throw away the inner candidate.
```
Position: 11112222222
67890123456
↓↓↓↓↓↓↓↓↓↓↓
Span { start: 17, end: 25 } // color:red
Span { start: 16, end: 26 } // [color:red]
```
#### Exceptions
**JavaScript keys as candidates:**
We already talked about the `clsx` scenario, but there are a few more
exceptions and that has to do with different syntaxes.
**CSS class shorthand in certain templating languages:**
In Pug and Slim, you can have a syntax like this:
```pug
.flex.underline
div Hello World
```
<details>
<summary>Generated HTML</summary>
```html
<div class="flex underline">
<div>Hello World</div>
</div>
```
</details>
We have to make sure that in these scenarios the `.` is a valid boundary
character. For this, we introduce a pre-processing step to massage the
input a little bit to improve the extraction of the data. We have to
make sure we don't make the input smaller or longer otherwise the
positions might be off.
In this scenario, we could simply replace the `.` with a space. But of
course, there are scenarios in these languages where it's not safe to do
that.
If you want to use `px-2.5` with this syntax, then you'd write:
```pug
.flex.px-2.5
div Hello World
```
But that's invalid because that technically means `flex`, `px-2`, and
`5` as classes.
You can use this syntax to get around that:
```pug
div(class="px-2.5")
div Hello World
```
<details>
<summary>Generated HTML</summary>
```html
<div class="px-2.5">
<div>Hello World</div>
</div>
```
</details>
Which means that we can't simply replace `.` with a space, but have to
parse the input. Luckily we only care about strings (and we have a
`StringMachine` for that) and ignore replacing `.` inside of strings.
**Ruby's weird string syntax:**
```ruby
%w[flex underline]
```
This is valid syntax and is shorthand for:
```ruby
["flex", "underline"]
```
Luckily this problem is solved by the running the sub-machines after
each `[` character.
### Performance
**Testing:**
Each machine has a `test_…_performance` test (that is ignored by
default) that allows you to test the throughput of that machine. If you
want to run them, you can use the following command:
```sh
cargo test test_variant_machine_performance --release -- --ignored
```
This will run the test in release mode and allows you to run the ignored
test.
> [!CAUTION]
> This test **_will_** fail, but it will print some output. E.g.:
```
tailwindcss_oxide::extractor::variant_machine::VariantMachine: Throughput: 737.75 MB/s over 0.02s
tailwindcss_oxide::extractor::variant_machine::VariantMachine: Duration: 500ns
```
**Readability:**
One thing to note when looking at the code is that it's not always
written in the cleanest way but we had to make some sacrifices for
performance reasons.
The `input` is of type `&[u8]`, so we are already dealing with bytes.
Luckily, Rust has some nice ergonomics to easily write `b'['` instead of
`0x5b`.
A concrete example where we had to sacrifice readability is the state
machines where we check the `previous`, `current` and `next` character
to make decisions. For a named utility one of the rules is that a `.`
must be preceded by and followed by a digit. This can be written as:
```rs
match (cursor.prev, cursor.curr, cursor.next) {
(b'0'..=b'9', b'.', b'0'..=b'9') => { /* … */ }
_ => { /* … */ }
}
```
But this is not very fast because Rust can't optimize the match
statement very well, especially because we are dealing with tuples
containing 3 values and each value is a `u8`.
To solve this we use some nesting, once we reach `b'.'` only then will
we check for the previous and next characters. We will also early return
in most places. If the previous character is not a digit, there is no
need to check the next character.
**Classification and jump tables:**
Another optimization we did is to classify the characters into a much
smaller `enum` such that Rust _can_ optimize all `match` arms and create
some jump tables behind the scenes.
E.g.:
```rs
#[derive(Debug, Clone, Copy, PartialEq)]
enum Class {
/// ', ", or `
Quote,
/// \
Escape,
/// Whitespace characters
Whitespace,
Other,
}
const CLASS_TABLE: [Class; 256] = {
let mut table = [Class::Other; 256];
macro_rules! set {
($class:expr, $($byte:expr),+ $(,)?) => {
$(table[$byte as usize] = $class;)+
};
}
set!(Class::Quote, b'"', b'\'', b'`');
set!(Class::Escape, b'\\');
set!(Class::Whitespace, b' ', b'\t', b'\n', b'\r', b'\x0C');
table
};
```
There are only 4 values in this enum, so Rust can optimize this very
well. The `CLASS_TABLE` is generated at compile time and must be exactly
256 elements long to fit all `u8` values.
**Inlining**:
Last but not least, sometimes we use functions to abstract some logic.
Luckily Rust will optimize and inline most of the functions
automatically. In some scenarios, explicitly adding a
`#[inline(always)]` improves performance, sometimes it doesn't improve
it at all.
You might notice that in some functions the annotation is added and in
some it's not. Every state machine was tested on its own and whenever
the performance was better with the annotation, it was added.
### Test Plan
1. Each machine has a dedicated set of tests to try and extract the
relevant part for that machine. Most machines don't even check boundary
characters or try to extract nested candidates. So keep that in mind
when adding new tests. Extracting inside of nested `[…]` is only handled
by the outer most `extractor/mod.rs`.
2. The main `extractor/mod.rs` has dedicated tests for recent bug
reports related to missing candidates.
3. You can test each machine's performance if you want to.
There is a chance that this new parser is missing candidates even though
a lot of tests are added and existing tests have been ported.
To double check, we ran the new extractor on our own projects to make
sure we didn't miss anything obvious.
#### Tailwind UI
On Tailwind UI the diff looks like this:
<details>
<summary>diff</summary>
```diff
diff --git a/./main.css b/./pr.css
index d83b0a506..b3dd94a1d 100644
--- a/./main.css
+++ b/./pr.css
@@ -5576,9 +5576,6 @@ @layer utilities {
--tw-saturate: saturate(0%);
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
- .\!filter {
- filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,) !important;
- }
.filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
```
</details>
The reason `!filter` is gone, is because it was used like this:
```js
getProducts.js
23: if (!filter) return true
```
And right now `(` and `)` are not considered valid boundary characters
for a candidate.
#### Catalyst
On Catalyst, the diff looks like this:
<details>
<summary>diff</summary>
```diff
diff --git a/./main.css b/./pr.css
index 9f8ed129..4aec992e 100644
--- a/./main.css
+++ b/./pr.css
@@ -2105,9 +2105,6 @@
.outline-transparent {
outline-color: transparent;
}
- .filter {
- filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
- }
.backdrop-blur-\[6px\] {
--tw-backdrop-blur: blur(6px);
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
@@ -7141,46 +7138,6 @@
inherits: false;
initial-value: solid;
}
-@property --tw-blur {
- syntax: "*";
- inherits: false;
-}
-@property --tw-brightness {
- syntax: "*";
- inherits: false;
-}
-@property --tw-contrast {
- syntax: "*";
- inherits: false;
-}
-@property --tw-grayscale {
- syntax: "*";
- inherits: false;
-}
-@property --tw-hue-rotate {
- syntax: "*";
- inherits: false;
-}
-@property --tw-invert {
- syntax: "*";
- inherits: false;
-}
-@property --tw-opacity {
- syntax: "*";
- inherits: false;
-}
-@property --tw-saturate {
- syntax: "*";
- inherits: false;
-}
-@property --tw-sepia {
- syntax: "*";
- inherits: false;
-}
-@property --tw-drop-shadow {
- syntax: "*";
- inherits: false;
-}
@property --tw-backdrop-blur {
syntax: "*";
inherits: false;
```
</details>
The reason for this is that `filter` was only used as a function call:
```tsx
src/app/docs/Code.tsx
31: .filter((x) => x !== null)
```
This was tested on all templates and they all remove a very small amount
of classes that aren't used.
The script to test this looks like this:
```sh
bun --bun ~/github.com/tailwindlabs/tailwindcss/packages/@tailwindcss-cli/src/index.t -- -i ./src/styles/tailwind.css -o pr.css
bun --bun ~/github.com/tailwindlabs/tailwindcss--main/packages/@tailwindcss-cli/src/index.t -- -i ./src/styles/tailwind.css -o main.css
git diff --no-index --patch ./{main,pr}.css
```
This is using git worktrees, so the `pr` branch lives in a `tailwindcss`
folder, and the `main` branch lives in a `tailwindcss--main` folder.
---
### Fixes:
- Fixes: https://github.com/tailwindlabs/tailwindcss/issues/15616
- Fixes: https://github.com/tailwindlabs/tailwindcss/issues/16750
- Fixes: https://github.com/tailwindlabs/tailwindcss/issues/16790
- Fixes: https://github.com/tailwindlabs/tailwindcss/issues/16801
- Fixes: https://github.com/tailwindlabs/tailwindcss/issues/16880 (due
to validating the arbitrary property)
---
### Ideas for in the future
1. Right now each machine takes in a `Cursor` object. One potential
improvement we can make is to rely on the `input` on its own instead of
going via the wrapping `Cursor` object.
2. If you take a look at the AST, you'll notice that utilities and
variants have a "root", these are basically prefixes of each available
utility and/or variant. We can use this information to filter out
candidates and bail out early if we know that a certain candidate will
never produce a valid class.
3. Passthrough the `prefix` information. Everything that doesn't start
with `tw:` can be skipped.
### Design decisions that didn't make it
Once you reach this part, you can stop reading if you want to, but this
is more like a brain dump of the things we tried and didn't work out.
Wanted to include them as a reference in case we want to look back at
this issue and know _why_ certain things are implemented the way they
are.
#### One character at a time
In an earlier implementation, the state machines were pure state
machines where the `next()` function was called on every single
character of the input. This had a lot of overhead because for every
character we had to:
1. Ask the `CandidateMachine` which state it was in.
2. Check the `cursor.curr` (and potentially the `cursor.prev` and
`cursor.next`) character.
3. If we were in a state where a nested state machine was running, we
had to check its current state as well and so on.
4. Once we did all of that we could go to the next character.
In this approach, the `MachineState` looked like this instead:
```rs
enum MachineState {
Idle,
Parsing,
Done(Span)
}
```
This had its own set of problems because now it's very hard to know
whether we are done or not.
```html
<div class="hover:flex"></div>
<!-- ^ -->
```
Let's look at the current position in the example above. At this point,
it's both a valid variant and valid utility, so there was a lot of
additional state we had to track to know whether we were done or not.
#### `Span` stitching
Another approach we tried was to just collect all valid variants and
utilities and throw them in a big `Vec<Span>`. This reduced the amount
of additional state to track and we could track a span the moment we saw
a `MachineState::Done(span)`.
The next thing we had to do was to make sure that:
1. Covered spans were removed. We still do this part in the current
implementation.
2. Combine all touching variant spans (where `span_a.end + 1 ==
span_b.start`).
3. For every combined variant span, find a corresponding utility span.
- If there is no utility span, the candidate is invalid.
- If there are multiple candidate spans (this is in theory not possible
because we dropped covered spans)
- If there is a candidate _but_ it is attached to another set of spans,
then the candidate is invalid. E.g.: `flex!block`
4. All left-over utility spans are candidates without variants.
This approach was slow, and still a bit hard to reason about.
#### Matching on tuples
While matching against the `prev`, `curr` and `next` characters was very
readable and easy to reason about. It was not very fast. Unfortunately
had to abandon this approach in favor of a more optimized approach.
In a perfect world, we would still write it this way, but have some
compile time macro that would optimize this for us.
#### Matching against `b'…'` instead of classification and jump tables
Similar to the previous point, while this is better for readability,
it's not fast enough. The jump tables are much faster.
Luckily for us, each machine has it's own set of rules and context, so
it's much easier to reason about a single problem and optimize a single
machine.
[^candidate]: A candidate is what a potential Tailwind CSS class _could_
be. It's a candidate because at this stage we don't know if it will
actually produce something but it looks like it could be a valid class.
E.g.: `hover:bg-red-500` is a candidate, but it will only produce
something if `--color-red-500` is defined in your theme.
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
|
||
|
|
08972f294f
|
Scan Next.js dynamic route segments with manual @source rules (#16457)
Part of #16287 ## Test plan Added unit and integration tests --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com> |
||
|
|
b492187c49
|
Fix Oxide scanner bugs (#15974)
Fixes #15632 Fixes #15740 This PR fixes a number of Oxide scanner bugs reported over various channels, specifically: - When using the Svelte class shorthand split over various lines, we weren't extracting class names properly: ```svelte <div class:underline={isUnderline}> </div> ``` - We now extract classes when using the class shortcut in Angular: ```html <div [class.underline]=\"bool\"></div> ``` - We now validate parentheses within arbitrary candidates so that we don't consume invalid arbitrary candidates anymore which allows us to parse the following case properly: ```js const classes = [wrapper("bg-red-500")] ``` ## Test plan Added unit tests --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com> Co-authored-by: Jordan Pittman <jordan@cryptica.me> |
||
|
|
e02a29fa94
|
Don’t look at ignore files outside initialized repos (#15941)
Right now, when Oxide is scanning for files, it considers ignore files in the "root" directory it is scanning as well as all parent directories. We honor .gitignore files even when not in a git repo as an optimization in case a project has been created, contains a .gitignore, but no repo has actually been initialized. However, this has an unintended side effect of including ignore files _ouside of a repo_ when there is one. This means that if you have a .gitignore file in your home folder it'll get applied even when you're inside a git repo which is not what you'd expect. This PR addresses this by checking to see the folder being scanned is inside a repo and turns on a flag that ensures .gitignore files from the repo are the only ones used (global ignore files configured in git still work tho). This still needs lots of tests to make sure things work as expected. Fixes #15876 --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com> |
||
|
|
92007a5b23
|
Fix crash when using @source containing .. (#14831)
This PR fixes an issue where a `@source` crashes when the path eventually resolves to a path ending in `..`. We have to make sure that we canonicalize the path to make sure that we are working with the real directory. --------- Co-authored-by: Jordan Pittman <jordan@cryptica.me> |
||
|
|
3b2ca85138
|
Fix new file detection in PostCSS plugin (#14829)
We broke this at some point — probably when we tried to optimize rebuilds in PostCSS by not performing a full auto-source detection scan. This PR addresses this problem by: 1. Storing a list of found directories 2. Comparing their mod times on every scan 3. If the mod time has changed we scan the directory for new files which we then store and scan |
||
|
|
f3786253f2
|
Fix integration tests on Windows (#14824)
This PR fixes Windows related path issues after merging #14820 --------- Co-authored-by: Jordan Pittman <jordan@cryptica.me> |
||
|
|
d68a780f98
|
Auto source detection improvements (#14820)
This PR introduces a new `source(…)` argument and improves on the
existing `@source`. The goal of this PR is to make the automatic source
detection configurable, let's dig in.
By default, we will perform automatic source detection starting at the
current working directory. Auto source detection will find plain text
files (no binaries, images, ...) and will ignore git-ignored files.
If you want to start from a different directory, you can use the new
`source(…)` next to the `@import "tailwindcss/utilities"
layer(utilities) source(…)`.
E.g.:
```css
/* ./src/styles/index.css */
@import 'tailwindcss/utilities' layer(utilities) source('../../');
```
Most people won't split their source files, and will just use the simple
`@import "tailwindcss";`, because of this reason, you can use
`source(…)` on the import as well:
E.g.:
```css
/* ./src/styles/index.css */
@import 'tailwindcss' source('../../');
```
Sometimes, you want to rely on auto source detection, but also want to
look in another directory for source files. In this case, yuo can use
the `@source` directive:
```css
/* ./src/index.css */
@import 'tailwindcss';
/* Look for `blade.php` files in `../resources/views` */
@source '../resources/views/**/*.blade.php';
```
However, you don't need to specify the extension, instead you can just
point the directory and all the same automatic source detection rules
will apply.
```css
/* ./src/index.css */
@import 'tailwindcss';
@source '../resources/views';
```
If, for whatever reason, you want to disable the default source
detection feature entirely, and only want to rely on very specific glob
patterns you define, then you can disable it via `source(none)`.
```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);
/* Only look at .blade.php files, nothing else */
@source "../resources/views/**/*.blade.php";
```
Note: even with `source(none)`, if your `@source` points to a directory,
then auto source detection will still be performed in that directory. If
you don't want that, then you can simply add explicit files in the globs
as seen in the previous example.
```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);
/* Run auto source detection in `../resources/views` */
@source "../resources/views";
```
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
|
||
|
|
a902128640
|
Improve Oxide scanner API (#14187)
This PR updates the API for interacting with the Oxide API. Until now,
we used the name `scanDir(…)` which is fine, but we do way more work
right now.
We now have features such as:
1. Auto source detection (can be turned off, e.g.: `@tailwindcss/vite`
doesn't need it)
2. Scan based on `@source`s found in CSS files
3. Do "incremental" rebuilds (which means that the `scanDir(…)` result
was stateful).
To solve these issues, this PR introduces a new `Scanner` class where
you can pass in the `detectSources` and `sources` options. E.g.:
```ts
let scanner = new Scanner({
// Optional, omitting `detectSources` field disables automatic source detection
detectSources: { base: __dirname },
// List of glob entries to scan. These come from `@source` directives in CSS.
sources: [
{ base: __dirname, pattern: "src/**/*.css" },
// …
],
});
```
The scanner object has the following API:
```ts
export interface ChangedContent {
/** File path to the changed file */
file?: string
/** Contents of the changed file */
content?: string
/** File extension */
extension: string
}
export interface DetectSources {
/** Base path to start scanning from */
base: string
}
export interface GlobEntry {
/** Base path of the glob */
base: string
/** Glob pattern */
pattern: string
}
export interface ScannerOptions {
/** Automatically detect sources in the base path */
detectSources?: DetectSources
/** Glob sources */
sources?: Array<GlobEntry>
}
export declare class Scanner {
constructor(opts: ScannerOptions)
scan(): Array<string>
scanFiles(input: Array<ChangedContent>): Array<string>
get files(): Array<string>
get globs(): Array<GlobEntry>
}
```
The `scanFiles(…)` method is used for incremental rebuilds. It takes the
`ChangedContent` array for all the new/changes files. It returns whether
we scanned any new candidates or not.
Note that the `scanner` object is stateful, this means that we don't
have to track candidates in a `Set` anymore. We can just call
`getCandidates()` when we need it.
This PR also removed some unused code that we had in the `scanDir(…)`
function to allow for sequential or parallel `IO`, and sequential or
parallel `Parsing`. We only used the same `IO` and `Parsing` strategies
for all files, so I just got rid of it.
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
|
||
|
|
cc4689deef
|
Add Glimmer template extensions to Oxide content detection (#14199)
Co-authored-by: Jordan Pittman <jordan@cryptica.me> |
||
|
|
541d84a3bb
|
Add @source support (#14078)
This PR is an umbrella PR where we will add support for the new `@source` directive. This will allow you to add explicit content glob patterns if you want to look for Tailwind classes in other files that are not automatically detected yet. Right now this is an addition to the existing auto content detection that is automatically enabled in the `@tailwindcss/postcss` and `@tailwindcss/cli` packages. The `@tailwindcss/vite` package doesn't use the auto content detection, but uses the module graph instead. From an API perspective there is not a lot going on. There are only a few things that you have to know when using the `@source` directive, and you probably already know the rules: 1. You can use multiple `@source` directives if you want. 2. The `@source` accepts a glob pattern so that you can match multiple files at once 3. The pattern is relative to the current file you are in 4. The pattern includes all files it is matching, even git ignored files 1. The motivation for this is so that you can explicitly point to a `node_modules` folder if you want to look at `node_modules` for whatever reason. 6. Right now we don't support negative globs (starting with a `!`) yet, that will be available in the near future. Usage example: ```css /* ./src/input.css */ @import "tailwindcss"; @source "../laravel/resources/views/**/*.blade.php"; @source "../../packages/monorepo-package/**/*.js"; ``` It looks like the PR introduced a lot of changes, but this is a side effect of all the other plumbing work we had to do to make this work. For example: 1. We added dedicated integration tests that run on Linux and Windows in CI (just to make sure that all the `path` logic is correct) 2. We Have to make sure that the glob patterns are always correct even if you are using `@import` in your CSS and use `@source` in an imported file. This is because we receive the flattened CSS contents where all `@import`s are inlined. 3. We have to make sure that we also listen for changes in the files that match any of these patterns and trigger a rebuild. PRs: - [x] https://github.com/tailwindlabs/tailwindcss/pull/14063 - [x] https://github.com/tailwindlabs/tailwindcss/pull/14085 - [x] https://github.com/tailwindlabs/tailwindcss/pull/14079 - [x] https://github.com/tailwindlabs/tailwindcss/pull/14067 - [x] https://github.com/tailwindlabs/tailwindcss/pull/14076 - [x] https://github.com/tailwindlabs/tailwindcss/pull/14080 - [x] https://github.com/tailwindlabs/tailwindcss/pull/14127 - [x] https://github.com/tailwindlabs/tailwindcss/pull/14135 Once all the PRs are merged, then this umbrella PR can be merged. > [!IMPORTANT] > Make sure to merge this without rebasing such that each individual PR ends up on the main branch. --------- Co-authored-by: Philipp Spiess <hello@philippspiess.com> Co-authored-by: Jordan Pittman <jordan@cryptica.me> Co-authored-by: Adam Wathan <adam.wathan@gmail.com> |
||
|
|
a2159e80f5
|
Add Windows CI (#14065)
This PR changes the GitHub action workflow for V4 to start running all unit tests and build on both Ubuntu (our current default) _and_ Windows. This is to ensure we catch issues with paths and other Windows-specific things sooner. It does, however, not replace testing on Windows. |
||
|
|
1c48683a23
|
Hoist oxide/crates to just crates (#13333)
* move `oxide/crates` to `crates` * ignore `target/` folder * ensure pnpm points to `crates` instead of `oxide/crates` * ensure all paths point to `crates` instead of `oxide/crates` * update `oxide/crates` -> `crates` path in workflows * use correct path in .prettierignore * rename `crates/core` to `crates/oxide` * remove oxide folder * fix test script to run `cargo test` directly |