diff --git a/.github/workflows/build-preview.yaml b/.github/workflows/build-preview.yaml index 10b64fad7..7ba11fd14 100644 --- a/.github/workflows/build-preview.yaml +++ b/.github/workflows/build-preview.yaml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest name: Build Preview steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ce1c1305e..b7d4799d6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,7 +19,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 @@ -53,7 +53,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Setup Node diff --git a/.github/workflows/docker-build-push.yaml b/.github/workflows/docker-build-push.yaml index 25c4e0e0b..26cf223f9 100644 --- a/.github/workflows/docker-build-push.yaml +++ b/.github/workflows/docker-build-push.yaml @@ -21,11 +21,11 @@ jobs: echo "OWNER_LOWERCASE=${OWNER,,}" >> ${GITHUB_ENV} env: OWNER: "${{ github.repository_owner }}" - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 1 - name: Inject slug/short variables - uses: rlespinasse/github-slug-action@v5.3.0 + uses: rlespinasse/github-slug-action@v5.4.0 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx diff --git a/package-lock.json b/package-lock.json index 33be34521..6d3d718b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@tweenjs/tween.js": "^25.0.0", "ansi-truncate": "^1.4.0", "async-mutex": "^0.5.0", - "chokidar": "^4.0.3", + "chokidar": "^5.0.0", "cli-spinner": "^0.2.10", "d3": "^7.9.0", "esbuild-sass-plugin": "^3.3.1", @@ -31,12 +31,12 @@ "js-yaml": "^4.1.1", "lightningcss": "^1.30.2", "mdast-util-find-and-replace": "^3.0.2", - "mdast-util-to-hast": "^13.2.0", + "mdast-util-to-hast": "^13.2.1", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", "minimatch": "^10.1.1", - "pixi.js": "^8.14.1", - "preact": "^10.27.2", + "pixi.js": "^8.14.3", + "preact": "^10.28.0", "preact-render-to-string": "^6.6.3", "pretty-bytes": "^7.1.0", "pretty-time": "^1.1.0", @@ -67,7 +67,7 @@ "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", - "workerpool": "^10.0.0", + "workerpool": "^10.0.1", "ws": "^8.18.3", "yargs": "^18.0.0" }, @@ -84,8 +84,8 @@ "@types/ws": "^8.18.1", "@types/yargs": "^17.0.35", "esbuild": "^0.27.0", - "prettier": "^3.6.2", - "tsx": "^4.20.6", + "prettier": "^3.7.3", + "tsx": "^4.21.0", "typescript": "^5.9.3" }, "engines": { @@ -2370,14 +2370,15 @@ } }, "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "readdirp": "^5.0.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -4612,9 +4613,10 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -5490,9 +5492,9 @@ } }, "node_modules/pixi.js": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.14.1.tgz", - "integrity": "sha512-cwiY5VdzpbjoxW/n378bHBaPbZF8e81rYS36rfgUOSHyqLJ7AvC/YYUVfybnjJrT8/zVJ/gBIEpVSmt+A+FC6Q==", + "version": "8.14.3", + "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.14.3.tgz", + "integrity": "sha512-6xGYARV8D9E/fO1c2NmYn+k2dQ5oZldVm5tNlLQJ8obTlOQXdL5QpMc217qTpRyHVDFaw5eoFCLF1gr6p5ZcjQ==", "license": "MIT", "dependencies": { "@pixi/colord": "^2.9.6", @@ -5519,9 +5521,9 @@ "license": "MIT" }, "node_modules/preact": { - "version": "10.27.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz", - "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==", + "version": "10.28.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.0.tgz", + "integrity": "sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==", "license": "MIT", "peer": true, "funding": { @@ -5539,9 +5541,9 @@ } }, "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.3.tgz", + "integrity": "sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==", "dev": true, "license": "MIT", "bin": { @@ -5612,11 +5614,12 @@ } }, "node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", "engines": { - "node": ">= 14.16.0" + "node": ">= 20.19.0" }, "funding": { "type": "individual", @@ -6452,6 +6455,34 @@ "node": ">=14.0.0" } }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/satori": { "version": "0.18.3", "resolved": "https://registry.npmjs.org/satori/-/satori-0.18.3.tgz", @@ -6860,13 +6891,13 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsx": { - "version": "4.20.6", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", - "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.25.0", + "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -6879,490 +6910,6 @@ "fsevents": "~2.3.3" } }, - "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -7656,9 +7203,9 @@ "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==" }, "node_modules/workerpool": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-10.0.0.tgz", - "integrity": "sha512-q++kYpKoYSfe7myTA5bH8nov9XKpEj7ji3f/W2h4E8yrX42Fhdt6x3E5pgsmnL1+swBZXryUwudNQJmcuodqmw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-10.0.1.tgz", + "integrity": "sha512-NAnKwZJxWlj/U1cp6ZkEtPE+GQY1S6KtOS3AlCiPfPFLxV3m64giSp7g2LsNJxzYCocDT7TSl+7T0sgrDp3KoQ==", "license": "Apache-2.0" }, "node_modules/wrap-ansi": { diff --git a/package.json b/package.json index c6fae5c79..ebc3311ac 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@tweenjs/tween.js": "^25.0.0", "ansi-truncate": "^1.4.0", "async-mutex": "^0.5.0", - "chokidar": "^4.0.3", + "chokidar": "^5.0.0", "cli-spinner": "^0.2.10", "d3": "^7.9.0", "esbuild-sass-plugin": "^3.3.1", @@ -57,12 +57,12 @@ "js-yaml": "^4.1.1", "lightningcss": "^1.30.2", "mdast-util-find-and-replace": "^3.0.2", - "mdast-util-to-hast": "^13.2.0", + "mdast-util-to-hast": "^13.2.1", "mdast-util-to-string": "^4.0.0", "micromorph": "^0.4.5", "minimatch": "^10.1.1", - "pixi.js": "^8.14.1", - "preact": "^10.27.2", + "pixi.js": "^8.14.3", + "preact": "^10.28.0", "preact-render-to-string": "^6.6.3", "pretty-bytes": "^7.1.0", "pretty-time": "^1.1.0", @@ -93,7 +93,7 @@ "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", - "workerpool": "^10.0.0", + "workerpool": "^10.0.1", "ws": "^8.18.3", "yargs": "^18.0.0" }, @@ -107,8 +107,8 @@ "@types/ws": "^8.18.1", "@types/yargs": "^17.0.35", "esbuild": "^0.27.0", - "prettier": "^3.6.2", - "tsx": "^4.20.6", + "prettier": "^3.7.3", + "tsx": "^4.21.0", "typescript": "^5.9.3" } } diff --git a/quartz/components/renderPage.tsx b/quartz/components/renderPage.tsx index 2c1bf5e75..8cf54392c 100644 --- a/quartz/components/renderPage.tsx +++ b/quartz/components/renderPage.tsx @@ -294,7 +294,7 @@ export function renderPage( {pageResources.js .filter((resource) => resource.loadTime === "afterDOMReady") - .map((res) => JSResourceToScriptElement(res))} + .map((res) => JSResourceToScriptElement(res, true))} ) diff --git a/quartz/components/scripts/search.inline.ts b/quartz/components/scripts/search.inline.ts index 6a84a50e0..717f17f00 100644 --- a/quartz/components/scripts/search.inline.ts +++ b/quartz/components/scripts/search.inline.ts @@ -16,11 +16,49 @@ interface Item { type SearchType = "basic" | "tags" let searchType: SearchType = "basic" let currentSearchTerm: string = "" -const encoder = (str: string) => { - return str - .toLowerCase() - .split(/\s+/) - .filter((token) => token.length > 0) +const encoder = (str: string): string[] => { + const tokens: string[] = [] + let bufferStart = -1 + let bufferEnd = -1 + const lower = str.toLowerCase() + + let i = 0 + for (const char of lower) { + const code = char.codePointAt(0)! + + const isCJK = + (code >= 0x3040 && code <= 0x309f) || + (code >= 0x30a0 && code <= 0x30ff) || + (code >= 0x4e00 && code <= 0x9fff) || + (code >= 0xac00 && code <= 0xd7af) || + (code >= 0x20000 && code <= 0x2a6df) + + const isWhitespace = code === 32 || code === 9 || code === 10 || code === 13 + + if (isCJK) { + if (bufferStart !== -1) { + tokens.push(lower.slice(bufferStart, bufferEnd)) + bufferStart = -1 + } + tokens.push(char) + } else if (isWhitespace) { + if (bufferStart !== -1) { + tokens.push(lower.slice(bufferStart, bufferEnd)) + bufferStart = -1 + } + } else { + if (bufferStart === -1) bufferStart = i + bufferEnd = i + char.length + } + + i += char.length + } + + if (bufferStart !== -1) { + tokens.push(lower.slice(bufferStart)) + } + + return tokens } let index = new FlexSearch.Document({ diff --git a/quartz/components/scripts/search.test.ts b/quartz/components/scripts/search.test.ts new file mode 100644 index 000000000..221da8336 --- /dev/null +++ b/quartz/components/scripts/search.test.ts @@ -0,0 +1,163 @@ +import test, { describe } from "node:test" +import assert from "node:assert" + +// Inline the encoder function from search.inline.ts for testing +const encoder = (str: string): string[] => { + const tokens: string[] = [] + let bufferStart = -1 + let bufferEnd = -1 + const lower = str.toLowerCase() + + let i = 0 + for (const char of lower) { + const code = char.codePointAt(0)! + + const isCJK = + (code >= 0x3040 && code <= 0x309f) || + (code >= 0x30a0 && code <= 0x30ff) || + (code >= 0x4e00 && code <= 0x9fff) || + (code >= 0xac00 && code <= 0xd7af) || + (code >= 0x20000 && code <= 0x2a6df) + + const isWhitespace = code === 32 || code === 9 || code === 10 || code === 13 + + if (isCJK) { + if (bufferStart !== -1) { + tokens.push(lower.slice(bufferStart, bufferEnd)) + bufferStart = -1 + } + tokens.push(char) + } else if (isWhitespace) { + if (bufferStart !== -1) { + tokens.push(lower.slice(bufferStart, bufferEnd)) + bufferStart = -1 + } + } else { + if (bufferStart === -1) bufferStart = i + bufferEnd = i + char.length + } + + i += char.length + } + + if (bufferStart !== -1) { + tokens.push(lower.slice(bufferStart)) + } + + return tokens +} + +describe("search encoder", () => { + describe("English text", () => { + test("should tokenize simple English words", () => { + const result = encoder("hello world") + assert.deepStrictEqual(result, ["hello", "world"]) + }) + + test("should handle multiple spaces", () => { + const result = encoder("hello world") + assert.deepStrictEqual(result, ["hello", "world"]) + }) + + test("should handle tabs and newlines", () => { + const result = encoder("hello\tworld\ntest") + assert.deepStrictEqual(result, ["hello", "world", "test"]) + }) + + test("should lowercase all text", () => { + const result = encoder("Hello WORLD Test") + assert.deepStrictEqual(result, ["hello", "world", "test"]) + }) + }) + + describe("CJK text", () => { + test("should tokenize Japanese Hiragana character by character", () => { + const result = encoder("こんにちは") + assert.deepStrictEqual(result, ["こ", "ん", "に", "ち", "は"]) + }) + + test("should tokenize Japanese Katakana character by character", () => { + const result = encoder("コントロール") + assert.deepStrictEqual(result, ["コ", "ン", "ト", "ロ", "ー", "ル"]) + }) + + test("should tokenize Japanese Kanji character by character", () => { + const result = encoder("日本語") + assert.deepStrictEqual(result, ["日", "本", "語"]) + }) + + test("should tokenize Korean Hangul character by character", () => { + const result = encoder("안녕하세요") + assert.deepStrictEqual(result, ["안", "녕", "하", "세", "요"]) + }) + + test("should tokenize Chinese characters character by character", () => { + const result = encoder("你好世界") + assert.deepStrictEqual(result, ["你", "好", "世", "界"]) + }) + + test("should handle mixed Hiragana/Katakana/Kanji", () => { + const result = encoder("て以来") + assert.deepStrictEqual(result, ["て", "以", "来"]) + }) + }) + + describe("Mixed CJK and English", () => { + test("should handle Japanese with English words", () => { + const result = encoder("hello 世界") + assert.deepStrictEqual(result, ["hello", "世", "界"]) + }) + + test("should handle English with Japanese words", () => { + const result = encoder("世界 hello world") + assert.deepStrictEqual(result, ["世", "界", "hello", "world"]) + }) + + test("should handle complex mixed content", () => { + const result = encoder("これはtest文章です") + assert.deepStrictEqual(result, ["こ", "れ", "は", "test", "文", "章", "で", "す"]) + }) + + test("should handle mixed Korean and English", () => { + const result = encoder("hello 안녕 world") + assert.deepStrictEqual(result, ["hello", "안", "녕", "world"]) + }) + + test("should handle mixed Chinese and English", () => { + const result = encoder("你好 world") + assert.deepStrictEqual(result, ["你", "好", "world"]) + }) + }) + + describe("Edge cases", () => { + test("should handle empty string", () => { + const result = encoder("") + assert.deepStrictEqual(result, []) + }) + + test("should handle only whitespace", () => { + const result = encoder(" \t\n ") + assert.deepStrictEqual(result, []) + }) + + test("should handle single character", () => { + const result = encoder("a") + assert.deepStrictEqual(result, ["a"]) + }) + + test("should handle single CJK character", () => { + const result = encoder("あ") + assert.deepStrictEqual(result, ["あ"]) + }) + + test("should handle CJK with trailing whitespace", () => { + const result = encoder("日本語 ") + assert.deepStrictEqual(result, ["日", "本", "語"]) + }) + + test("should handle English with trailing whitespace", () => { + const result = encoder("hello ") + assert.deepStrictEqual(result, ["hello"]) + }) + }) +}) diff --git a/quartz/components/scripts/spa.inline.ts b/quartz/components/scripts/spa.inline.ts index 22fcd72b4..2898dc419 100644 --- a/quartz/components/scripts/spa.inline.ts +++ b/quartz/components/scripts/spa.inline.ts @@ -115,9 +115,9 @@ async function _navigate(url: URL, isBack: boolean = false) { } // now, patch head, re-executing scripts - const elementsToRemove = document.head.querySelectorAll(":not([spa-preserve])") + const elementsToRemove = document.head.querySelectorAll(":not([data-persist])") elementsToRemove.forEach((el) => el.remove()) - const elementsToAdd = html.head.querySelectorAll(":not([spa-preserve])") + const elementsToAdd = html.head.querySelectorAll(":not([data-persist])") elementsToAdd.forEach((el) => document.head.appendChild(el)) // delay setting the url until now diff --git a/quartz/i18n/locales/vi-VN.ts b/quartz/i18n/locales/vi-VN.ts index 26a58a50e..43eda8797 100644 --- a/quartz/i18n/locales/vi-VN.ts +++ b/quartz/i18n/locales/vi-VN.ts @@ -3,85 +3,83 @@ import { Translation } from "./definition" export default { propertyDefaults: { title: "Không có tiêu đề", - description: "Không có mô tả được cung cấp", + description: "Không có mô tả", }, components: { callout: { - note: "Ghi Chú", - abstract: "Tóm Tắt", + note: "Ghi chú", + abstract: "Tổng quan", info: "Thông tin", - todo: "Cần Làm", - tip: "Gợi Ý", - success: "Thành Công", - question: "Nghi Vấn", - warning: "Cảnh Báo", - failure: "Thất Bại", - danger: "Nguy Hiểm", + todo: "Cần phải làm", + tip: "Gợi ý", + success: "Thành công", + question: "Câu hỏi", + warning: "Cảnh báo", + failure: "Thất bại", + danger: "Nguy hiểm", bug: "Lỗi", - example: "Ví Dụ", - quote: "Trích Dẫn", + example: "Ví dụ", + quote: "Trích dẫn", }, backlinks: { - title: "Liên Kết Ngược", - noBacklinksFound: "Không có liên kết ngược được tìm thấy", + title: "Liên kết ngược", + noBacklinksFound: "Không có liên kết ngược nào", }, themeToggle: { - lightMode: "Sáng", - darkMode: "Tối", + lightMode: "Chế độ sáng", + darkMode: "Chế độ tối", }, readerMode: { title: "Chế độ đọc", }, explorer: { - title: "Trong bài này", + title: "Nội dung", }, footer: { - createdWith: "Được tạo bởi", + createdWith: "Được tạo bằng", }, graph: { - title: "Biểu Đồ", + title: "Sơ đồ", }, recentNotes: { - title: "Bài viết gần đây", - seeRemainingMore: ({ remaining }) => `Xem ${remaining} thêm →`, + title: "Ghi chú gần đây", + seeRemainingMore: ({ remaining }) => `Xem thêm ${remaining} ghi chú →`, }, transcludes: { - transcludeOf: ({ targetSlug }) => `Bao gồm ${targetSlug}`, - linkToOriginal: "Liên Kết Gốc", + transcludeOf: ({ targetSlug }) => `Trích dẫn toàn bộ từ ${targetSlug}`, + linkToOriginal: "Xem trang gốc", }, search: { - title: "Tìm Kiếm", + title: "Tìm", searchBarPlaceholder: "Tìm kiếm thông tin", }, tableOfContents: { - title: "Bảng Nội Dung", + title: "Mục lục", }, contentMeta: { - readingTime: ({ minutes }) => `đọc ${minutes} phút`, + readingTime: ({ minutes }) => `${minutes} phút đọc`, }, }, pages: { rss: { - recentNotes: "Những bài gần đây", - lastFewNotes: ({ count }) => `${count} Bài gần đây`, + recentNotes: "Ghi chú gần đây", + lastFewNotes: ({ count }) => `${count} Trang gần đây`, }, error: { - title: "Không Tìm Thấy", - notFound: "Trang này được bảo mật hoặc không tồn tại.", - home: "Trở về trang chủ", + title: "Không tìm thấy", + notFound: "Trang này riêng tư hoặc không tồn tại.", + home: "Về trang chủ", }, folderContent: { - folder: "Thư Mục", - itemsUnderFolder: ({ count }) => - count === 1 ? "1 mục trong thư mục này." : `${count} mục trong thư mục này.`, + folder: "Thư mục", + itemsUnderFolder: ({ count }) => `Có ${count} trang trong thư mục này.`, }, tagContent: { tag: "Thẻ", - tagIndex: "Thẻ Mục Lục", - itemsUnderTag: ({ count }) => - count === 1 ? "1 mục gắn thẻ này." : `${count} mục gắn thẻ này.`, - showingFirst: ({ count }) => `Hiển thị trước ${count} thẻ.`, - totalTags: ({ count }) => `Tìm thấy ${count} thẻ tổng cộng.`, + tagIndex: "Danh sách thẻ", + itemsUnderTag: ({ count }) => `Có ${count} trang gắn thẻ này.`, + showingFirst: ({ count }) => `Đang hiển thị ${count} trang đầu tiên.`, + totalTags: ({ count }) => `Có tổng cộng ${count} thẻ.`, }, }, } as const satisfies Translation diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index 391139cdd..0d642d60f 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -41,13 +41,17 @@ ul, .katex, .math, .typst-doc, -.typst-doc * { +g[class~="typst-text"] { color: var(--darkgray); fill: var(--darkgray); overflow-wrap: break-word; text-wrap: pretty; } +path[class~="typst-shape"] { + stroke: var(--darkgray); +} + .math { &.math-display { text-align: center; diff --git a/quartz/util/resources.tsx b/quartz/util/resources.tsx index d95333e8c..12dd77eee 100644 --- a/quartz/util/resources.tsx +++ b/quartz/util/resources.tsx @@ -26,9 +26,10 @@ export type CSSResource = { export function JSResourceToScriptElement(resource: JSResource, preserve?: boolean): JSX.Element { const scriptType = resource.moduleType ?? "application/javascript" const spaPreserve = preserve ?? resource.spaPreserve + if (resource.contentType === "external") { return ( - ) @@ -54,7 +55,7 @@ export function CSSResourceToStyleElement(resource: CSSResource, preserve?: bool href={resource.content} rel="stylesheet" type="text/css" - spa-preserve={spaPreserve} + data-persist={spaPreserve} /> ) }