diff --git a/demo/components/Playground.tsx b/demo/components/Playground.tsx index 073f11067..2b1d096df 100644 --- a/demo/components/Playground.tsx +++ b/demo/components/Playground.tsx @@ -307,6 +307,7 @@ export const Playground = memo((props) => { =18" + "node": ">=12" } }, "node_modules/@esbuild/android-arm": { @@ -3122,23 +3122,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/netbsd-x64": { "version": "0.19.3", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.3.tgz", @@ -3155,23 +3138,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/openbsd-x64": { "version": "0.19.3", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.3.tgz", @@ -4760,486 +4726,7 @@ "vite": "^5.2.8" }, "engines": { - "node": ">=18" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/@playwright/experimental-ct-core/node_modules/vite": { - "version": "5.4.14", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", - "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } + "node": ">=18" } }, "node_modules/@playwright/experimental-ct-react": { @@ -22684,21 +22171,21 @@ } }, "node_modules/vite": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.1.tgz", - "integrity": "sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", - "postcss": "^8.5.3", - "rollup": "^4.30.1" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -22707,25 +22194,19 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" + "terser": "^5.4.0" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, - "jiti": { - "optional": true - }, "less": { "optional": true }, @@ -22746,428 +22227,420 @@ }, "terser": { "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true } } }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], - "peer": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, - "peer": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=18" + "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/vite/node_modules/fsevents": { @@ -23180,7 +22653,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -23682,20 +23154,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 04d7862f8..0689acd0c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "prepublishOnly": "npm run lint && npm run build", "playwright:install": "playwright install chromium webkit --with-deps", "playwright": "playwright test --config=tests/playwright/playwright.config.ts", + "playwright:watch": "npm run playwright -- --ui", "playwright:update": "npm run playwright -- -u", "playwright:clear": "rm -rf ./tests/playwright/.cache", "playwright:report": "npx playwright show-report playwright-report", diff --git a/src/bundle/MarkdownEditorView.tsx b/src/bundle/MarkdownEditorView.tsx index faecadffd..345fcbaa0 100644 --- a/src/bundle/MarkdownEditorView.tsx +++ b/src/bundle/MarkdownEditorView.tsx @@ -8,7 +8,7 @@ import { useState, } from 'react'; -import {useToaster} from '@gravity-ui/uikit'; +import {type QAProps, useToaster} from '@gravity-ui/uikit'; import {ErrorBoundary} from 'react-error-boundary'; import {useEnsuredForwardedRef, useKey, useUpdate} from 'react-use'; @@ -37,32 +37,33 @@ import './MarkdownEditorView.scss'; // eslint-disable-line import/order export const cnEditorComponent = cn('editor-component'); const b = cnEditorComponent; -export type MarkdownEditorViewProps = ClassNameProps & { - editor?: Editor; - autofocus?: boolean; - toolbarsPreset?: ToolbarsPreset; - /** - * @deprecated use `toolbarsPreset` instead - */ - markupToolbarConfig?: MToolbarData; - /** - * @deprecated use `toolbarsPreset` instead - */ - wysiwygToolbarConfig?: WToolbarData; - /** - * @deprecated use `toolbarsPreset` instead - */ - markupHiddenActionsConfig?: MToolbarItemData[]; - /** - * @deprecated use `toolbarsPreset` instead - */ - wysiwygHiddenActionsConfig?: WToolbarItemData[]; - /** @default true */ - settingsVisible?: boolean; - stickyToolbar: boolean; - enableSubmitInPreview?: boolean; - hidePreviewAfterSubmit?: boolean; -}; +export type MarkdownEditorViewProps = ClassNameProps & + QAProps & { + editor?: Editor; + autofocus?: boolean; + toolbarsPreset?: ToolbarsPreset; + /** + * @deprecated use `toolbarsPreset` instead + */ + markupToolbarConfig?: MToolbarData; + /** + * @deprecated use `toolbarsPreset` instead + */ + wysiwygToolbarConfig?: WToolbarData; + /** + * @deprecated use `toolbarsPreset` instead + */ + markupHiddenActionsConfig?: MToolbarItemData[]; + /** + * @deprecated use `toolbarsPreset` instead + */ + wysiwygHiddenActionsConfig?: WToolbarItemData[]; + /** @default true */ + settingsVisible?: boolean; + stickyToolbar: boolean; + enableSubmitInPreview?: boolean; + hidePreviewAfterSubmit?: boolean; + }; export const MarkdownEditorView = forwardRef( (props, ref) => { @@ -83,6 +84,7 @@ export const MarkdownEditorView = forwardRef
((props) => { const { @@ -38,6 +41,7 @@ export const MarkupEditorView = memo((props) => { toolbarVisible, toolbarConfig, hiddenActionsConfig, + qa, className, toolbarClassName, children, @@ -57,7 +61,11 @@ export const MarkupEditorView = memo((props) => { }); return ( -
+
{toolbarVisible ? ( ((props) => { const { @@ -34,6 +37,7 @@ export const WysiwygEditorView = memo((props) => { toolbarVisible, toolbarConfig, hiddenActionsConfig, + qa, className, toolbarClassName, children, @@ -52,7 +56,11 @@ export const WysiwygEditorView = memo((props) => { }); }); return ( -
+
{toolbarVisible ? ( (function EditorSettings( pin="round-round" onClick={togglePopup} ref={setChevronElement} + qa="g-md-settings-button" className={bSettings('dropdown-button')} > @@ -125,9 +126,10 @@ const SettingsContent: React.FC = function SettingsContent showPreview, }) { return ( -
+
{ onModeChange('wysiwyg'); @@ -138,6 +140,7 @@ const SettingsContent: React.FC = function SettingsContent {i18n('settings_wysiwyg')} { onModeChange('markup'); diff --git a/tests/playwright/core/editor.ts b/tests/playwright/core/editor.ts new file mode 100644 index 000000000..a71718e90 --- /dev/null +++ b/tests/playwright/core/editor.ts @@ -0,0 +1,104 @@ +import type {Expect, Page} from '@playwright/test'; + +import type {DataTransferType, MarkdownEditorMode} from 'src'; + +class MarkdownEditorLocators { + readonly component; + readonly editor; + + readonly settingsButton; + readonly settingsContent; + + readonly contenteditable; + + constructor(page: Page) { + this.component = page.getByTestId('playground-md-editor'); + this.editor = page.getByTestId('g-md-editor-mode'); + + this.settingsButton = page.getByTestId('g-md-settings-button'); + this.settingsContent = page.getByTestId('g-md-settings-content'); + + this.contenteditable = this.editor.locator('[contenteditable=true]'); + } +} + +type PasteData = Partial>; + +export class MarkdownEditorPage { + protected readonly page: Page; + protected readonly expect: Expect; + protected readonly locators; + + constructor(page: Page, expect: Expect) { + this.page = page; + this.expect = expect; + + this.locators = new MarkdownEditorLocators(page); + } + + async getMode(): Promise { + const value = await this.locators.editor.getAttribute('data-mode'); + const mode = value as MarkdownEditorMode | null; + if (mode === 'wysiwyg' || mode === 'markup') return mode; + throw new Error(`MarkdownEditorPage.getMode(): unknown editor mode "${mode}"`); + } + + async openSettingsPopup() { + if (await this.locators.settingsContent.isVisible()) return; + + await this.locators.settingsButton.click(); + await this.locators.settingsContent.waitFor({state: 'visible'}); + } + + async switchMode(mode: MarkdownEditorMode) { + if ((await this.getMode()) === mode) return; + + await this.openSettingsPopup(); + await this.locators.settingsContent.getByTestId(`md-settings-mode-${mode}`).click(); + await this.assertMode(mode); + } + + async assertMode(mode: MarkdownEditorMode) { + await this.expect.poll(() => this.getMode()).toBe(mode); + } + + async blur() { + await this.locators.contenteditable.blur(); + } + + async press(key: string) { + await this.locators.contenteditable.press(key); + } + + async clearContent() { + await this.press('ControlOrMeta+A'); + await this.press('Backspace'); + } + + async paste(value: PasteData | string) { + const data: PasteData = typeof value === 'string' ? {'text/plain': value} : value; + + await this.locators.contenteditable.evaluate((element, data) => { + const clipboardData = new DataTransfer(); + + for (const [key, value] of Object.entries(data)) { + clipboardData.setData(key, value); + } + + element.focus(); + element.dispatchEvent(new ClipboardEvent('paste', {clipboardData})); + }, data); + } + + async fill(text: string) { + this.locators.contenteditable.fill(text); + } + + async selectTextIn(selector?: string) { + let loc = this.locators.contenteditable; + if (selector) loc = loc.locator(selector); + + loc.selectText(); + await this.page.waitForTimeout(100); + } +} diff --git a/tests/playwright/core/helpers.ts b/tests/playwright/core/helpers.ts new file mode 100644 index 000000000..6c4e00e48 --- /dev/null +++ b/tests/playwright/core/helpers.ts @@ -0,0 +1,33 @@ +import type {BrowserContext, Page} from '@playwright/test'; + +class Keymap { + readonly selectAll = 'ControlOrMeta+A'; + readonly copy = 'ControlOrMeta+C'; + readonly cut = 'ControlOrMeta+X'; + readonly paste = 'ControlOrMeta+V'; +} + +export class PlaywrightHelpers { + readonly keys = new Keymap(); + + private readonly page; + private readonly context; + + constructor({page, context}: {page: Page; context: BrowserContext}) { + this.page = page; + this.context = context; + } + + async getClipboardData() { + await this.context.grantPermissions(['clipboard-read']); + return this.page.evaluate(async () => { + const item = (await navigator.clipboard.read())[0]; + const data: Record = {}; + const types = Array.from(item.types); + for (const type of types) { + data[type] = await (await item.getType(type)).text(); + } + return data; + }); + } +} diff --git a/tests/playwright/core/index.ts b/tests/playwright/core/index.ts index ad250ae85..df3397ab5 100644 --- a/tests/playwright/core/index.ts +++ b/tests/playwright/core/index.ts @@ -1,6 +1,8 @@ -import {test as base} from '@playwright/experimental-ct-react'; +import {test as base, expect} from '@playwright/experimental-ct-react'; +import {MarkdownEditorPage} from './editor'; import {expectScreenshot} from './expectScreenshot'; +import {PlaywrightHelpers} from './helpers'; import {mount} from './mount'; import type {Fixtures} from './types'; import {wait} from './wait'; @@ -9,6 +11,15 @@ export const test = base.extend({ mount, expectScreenshot, wait, + editor: async ({page}, use) => { + const editor = new MarkdownEditorPage(page, expect); + await use(editor); + }, + helpers: async ({page, context}, use) => { + const helpers = new PlaywrightHelpers({page, context}); + await use(helpers); + }, + platform: [process.platform, {scope: 'test'}], }); export {expect} from '@playwright/experimental-ct-react'; diff --git a/tests/playwright/core/types.ts b/tests/playwright/core/types.ts index 00a547c7e..bd5ea7c7d 100644 --- a/tests/playwright/core/types.ts +++ b/tests/playwright/core/types.ts @@ -12,6 +12,9 @@ import type { TestFixture, } from '@playwright/test'; +import type {MarkdownEditorPage} from './editor'; +import type {PlaywrightHelpers} from './helpers'; + interface ComponentFixtures { mount( component: JSX.Element, @@ -31,6 +34,9 @@ export type Fixtures = { mount: MountFixture; expectScreenshot: ExpectScreenshotFixture; wait: WaitFixture; + editor: MarkdownEditorPage; + helpers: PlaywrightHelpers; + platform: NodeJS.Platform; }; export type MountFixture = ComponentFixtures['mount']; diff --git a/tests/playwright/playwright.config.ts b/tests/playwright/playwright.config.ts index 26d281bc1..1f856b997 100644 --- a/tests/playwright/playwright.config.ts +++ b/tests/playwright/playwright.config.ts @@ -2,28 +2,27 @@ import {resolve} from 'node:path'; import type {PlaywrightTestConfig} from '@playwright/experimental-ct-react'; import {defineConfig, devices} from '@playwright/experimental-ct-react'; +import type {InlineConfig} from 'vite'; // eslint-disable-line import/no-extraneous-dependencies -function pathFromRoot(p: string) { +import tsConfig from '../../tsconfig.json'; + +const pathFromRoot = (p: string) => { return resolve(__dirname, '../', p); -} +}; -const reporter: PlaywrightTestConfig['reporter'] = []; +const aliasesFromTsConf = (() => { + const baseUrl = resolve(__dirname, '..', '..', tsConfig.compilerOptions.baseUrl); + const paths = tsConfig.compilerOptions.paths; -reporter.push( - ['list'], - [ - 'html', - { - open: process.env.CI ? 'never' : 'on-failure', - outputFolder: resolve( - process.cwd(), - process.env.IS_DOCKER ? 'playwright-report-docker' : 'playwright-report', - ), - }, - ], -); + return Object.entries(paths).reduce>((acc, [key, value]) => { + const cleanKey = key.replace('/*', ''); + const cleanValue = value[0].replace('/*', ''); + acc[cleanKey] = resolve(baseUrl, cleanValue); + return acc; + }, {}); +})(); -const ctViteConfig = { +const ctViteConfig: InlineConfig = { css: { preprocessorOptions: { scss: { @@ -33,11 +32,7 @@ const ctViteConfig = { }, resolve: { alias: { - '#core': resolve(__dirname, '../../src/core'), - '#cm': resolve(__dirname, '../../src/cm'), - '#pm': resolve(__dirname, '../../src/pm'), - src: resolve(__dirname, '../../src'), - playwright: resolve(__dirname), + ...aliasesFromTsConf, '~@gravity-ui/uikit/styles/mixins': '@gravity-ui/uikit/styles/mixins', }, }, @@ -63,7 +58,19 @@ const config: PlaywrightTestConfig = { /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 2 : 2, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter, + reporter: [ + ['list'], + [ + 'html', + { + open: process.env.CI ? 'never' : 'on-failure', + outputFolder: resolve( + process.cwd(), + process.env.IS_DOCKER ? 'playwright-report-docker' : 'playwright-report', + ), + }, + ], + ], /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { testIdAttribute: 'data-qa', diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-dark-chromium-linux.png new file mode 100644 index 000000000..82be41506 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-dark-webkit-linux.png new file mode 100644 index 000000000..e0436652a Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-light-chromium-linux.png new file mode 100644 index 000000000..837eeb5e6 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-light-webkit-linux.png new file mode 100644 index 000000000..78d3b7c0f Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-into-inline-code-without-formatting-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-dark-chromium-linux.png new file mode 100644 index 000000000..8734aee33 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-dark-webkit-linux.png new file mode 100644 index 000000000..9fc72a937 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-light-chromium-linux.png new file mode 100644 index 000000000..6e8f095ff Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-light-webkit-linux.png new file mode 100644 index 000000000..bad49ec35 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-insert-link-from-ios-safari-share-button-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-dark-chromium-linux.png new file mode 100644 index 000000000..e4b41f571 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-dark-webkit-linux.png new file mode 100644 index 000000000..67f10466f Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-light-chromium-linux.png new file mode 100644 index 000000000..cc47a23b7 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-light-webkit-linux.png new file mode 100644 index 000000000..8e92e939c Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-markdown-markup-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-dark-chromium-linux.png new file mode 100644 index 000000000..e4b41f571 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-dark-webkit-linux.png new file mode 100644 index 000000000..67f10466f Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-light-chromium-linux.png new file mode 100644 index 000000000..cc47a23b7 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-light-webkit-linux.png new file mode 100644 index 000000000..8e92e939c Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-parse-pasting-text-as-markdown-markup-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-dark-chromium-linux.png new file mode 100644 index 000000000..0c61927ec Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-dark-webkit-linux.png new file mode 100644 index 000000000..014eb0773 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-light-chromium-linux.png new file mode 100644 index 000000000..a70a2979b Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-light-webkit-linux.png new file mode 100644 index 000000000..77944baa3 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-paste-to-code-block-without-as-is-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-dark-chromium-linux.png new file mode 100644 index 000000000..4a18dbea0 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-dark-webkit-linux.png new file mode 100644 index 000000000..02017255b Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-light-chromium-linux.png new file mode 100644 index 000000000..a01db3f98 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-light-webkit-linux.png new file mode 100644 index 000000000..f1f95e724 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-replace-selected-text-from-code-block-with-link-as-text-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-dark-chromium-linux.png new file mode 100644 index 000000000..670f5642c Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-dark-webkit-linux.png new file mode 100644 index 000000000..c8f18a7d3 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-light-chromium-linux.png new file mode 100644 index 000000000..759d696bd Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-light-webkit-linux.png new file mode 100644 index 000000000..37017aacb Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-Paste-should-wrap-text-to-link-from-clipboard-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-dark-chromium-linux.png new file mode 100644 index 000000000..61450eb93 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-dark-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-dark-webkit-linux.png new file mode 100644 index 000000000..67ff500f9 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-dark-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-light-chromium-linux.png new file mode 100644 index 000000000..7ec95760d Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-light-webkit-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-light-webkit-linux.png new file mode 100644 index 000000000..59a9bef81 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-WYSIWYG-mode-should-copy-and-paste-with-preserve-markup-light-webkit-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-markup-mode-and-paste-formatted-to-wysiwyg-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-markup-mode-and-paste-formatted-to-wysiwyg-dark-chromium-linux.png new file mode 100644 index 000000000..d3a2c82a3 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-markup-mode-and-paste-formatted-to-wysiwyg-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-markup-mode-and-paste-formatted-to-wysiwyg-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-markup-mode-and-paste-formatted-to-wysiwyg-light-chromium-linux.png new file mode 100644 index 000000000..67ab60595 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-markup-mode-and-paste-formatted-to-wysiwyg-light-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-wysiwyg-and-paste-formatted-to-markup-mode-dark-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-wysiwyg-and-paste-formatted-to-markup-mode-dark-chromium-linux.png new file mode 100644 index 000000000..b4cd83070 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-wysiwyg-and-paste-formatted-to-markup-mode-dark-chromium-linux.png differ diff --git a/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-wysiwyg-and-paste-formatted-to-markup-mode-light-chromium-linux.png b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-wysiwyg-and-paste-formatted-to-markup-mode-light-chromium-linux.png new file mode 100644 index 000000000..362ec4974 Binary files /dev/null and b/tests/visual-tests/__snapshots__/Clipboard.visual.test.tsx-snapshots/Clipboard-should-copy-from-wysiwyg-and-paste-formatted-to-markup-mode-light-chromium-linux.png differ diff --git a/tests/visual-tests/playground/Clipboard.visual.test.tsx b/tests/visual-tests/playground/Clipboard.visual.test.tsx new file mode 100644 index 000000000..cdc74798c --- /dev/null +++ b/tests/visual-tests/playground/Clipboard.visual.test.tsx @@ -0,0 +1,234 @@ +import dd from 'ts-dedent'; + +import {expect, test} from 'playwright/core'; + +import {Playground} from './Playground.helpers'; + +test.describe('Clipboard', () => { + test.beforeEach(async ({mount, editor}) => { + await mount(); + await editor.clearContent(); + }); + + const emphasisMarkup = dd` + ## Emphasis + + **This is bold text** + + *This is italic text* + + ~~Strikethrough~~ + `; + + test('should copy from wysiwyg and paste formatted to markup mode', async ({ + browserName, + expectScreenshot, + helpers: {keys}, + editor, + page, + }) => { + test.skip(browserName === 'webkit', 'Clipboard does not work correctly in webkit'); + + await editor.switchMode('wysiwyg'); + await editor.paste(emphasisMarkup); + await editor.press(keys.selectAll); + await editor.press(keys.copy); + await editor.clearContent(); + await editor.switchMode('markup'); + await editor.press(keys.paste); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test('should copy from markup mode and paste formatted to wysiwyg', async ({ + expectScreenshot, + browserName, + helpers: {keys}, + editor, + page, + }) => { + test.skip(browserName === 'webkit', 'Clipboard does not work correctly in webkit'); + + await editor.switchMode('markup'); + await editor.paste(emphasisMarkup); + await editor.press(keys.selectAll); + await editor.press(keys.copy); + await editor.clearContent(); + await editor.switchMode('wysiwyg'); + await editor.press(keys.paste); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test.describe('WYSIWYG mode', () => { + test.beforeEach(async ({editor}) => { + await editor.switchMode('wysiwyg'); + }); + + test('should copy and paste with preserve markup', async ({ + helpers: {keys}, + editor, + page, + expectScreenshot, + }) => { + await editor.paste(emphasisMarkup); + await editor.press(keys.selectAll); + await editor.press(keys.copy); + await editor.press('ArrowRight'); + await editor.press('Enter'); + await editor.press(keys.paste); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test.describe('Copy', () => { + test('should set data to clipboard buffer', async ({ + editor, + helpers, + browserName, + platform, + }) => { + test.skip( + browserName === 'webkit' && platform === 'linux', + 'Skip in webkit on linux, see https://github.com/microsoft/playwright/issues/34307', + ); + + await editor.paste('## Lorem *ipsum* **dolor** ~~sit~~ amet'); + await editor.press(helpers.keys.selectAll); + await editor.press(helpers.keys.copy); + + const data = await helpers.getClipboardData(); + + expect(data).toStrictEqual({ + 'text/plain': 'Lorem ipsum dolor sit amet', + 'text/html': + '

Lorem ipsum dolor sit amet

', + }); + }); + }); + + test.describe('Cut', () => { + test('should set data to clipboard buffer', async ({ + editor, + helpers, + browserName, + platform, + }) => { + test.skip( + browserName === 'webkit' && platform === 'linux', + 'Skip in webkit on linux, see https://github.com/microsoft/playwright/issues/34307', + ); + + await editor.paste('## Lorem *ipsum* **dolor** ~~sit~~ amet'); + await editor.press(helpers.keys.selectAll); + await editor.press(helpers.keys.cut); + + const data = await helpers.getClipboardData(); + + expect(data).toStrictEqual({ + 'text/plain': 'Lorem ipsum dolor sit amet', + 'text/html': + '

Lorem ipsum dolor sit amet

', + }); + }); + }); + + test.describe('Paste', () => { + test('should parse markdown markup', async ({page, editor, expectScreenshot}) => { + await editor.paste({ + 'text/plain': 'Lorem ipsum dolor sit amet', + 'text/yfm': '## Lorem *ipsum* **dolor** ~~sit~~ amet', + }); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test('should parse pasting text as markdown markup', async ({ + page, + editor, + expectScreenshot, + }) => { + await editor.paste('## Lorem *ipsum* **dolor** ~~sit~~ amet'); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test('should wrap text to link from clipboard', async ({ + page, + editor, + expectScreenshot, + }) => { + await editor.fill('Gravity UI'); + await editor.selectTextIn('p'); + await editor.paste('https://gravity-ui.com/'); + await editor.blur(); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test('should paste to code block without as is', async ({ + editor, + page, + expectScreenshot, + }) => { + await editor.fill('```'); + await editor.paste('## Lorem *ipsum* **dolor** ~~sit~~ amet'); + await editor.blur(); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test('should replace selected text from code block with link as text', async ({ + editor, + page, + expectScreenshot, + }) => { + await editor.fill('```'); + await editor.fill('Lorem ipsum dolor sit amet'); + await editor.selectTextIn('pre code'); + await editor.paste('https://gravity-ui.com/'); + await editor.blur(); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test('should insert into inline code without formatting', async ({ + editor, + page, + expectScreenshot, + }) => { + await editor.paste('`Code:`'); + await editor.press('ArrowLeft'); + await editor.press('Space'); + + await editor.paste('## Lorem *ipsum* **dolor** ~~sit~~ amet'); + await editor.blur(); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + + test('should insert link from ios safari share button', async ({ + editor, + page, + expectScreenshot, + }) => { + await editor.paste({ + 'text/uri-list': 'https://gravity-ui.com/', + }); + await editor.blur(); + + await page.waitForTimeout(500); + await expectScreenshot(); + }); + }); + }); +}); diff --git a/tests/visual-tests/playground/Playground.helpers.tsx b/tests/visual-tests/playground/Playground.helpers.tsx new file mode 100644 index 000000000..01b2e31b5 --- /dev/null +++ b/tests/visual-tests/playground/Playground.helpers.tsx @@ -0,0 +1,13 @@ +import {composeStories} from '@storybook/react'; + +import * as DefaultPlaygroundStories from '../../../demo/stories/playground/Playground.stories'; + +const PlaygroundStories = composeStories(DefaultPlaygroundStories, { + argsEnhancers: [ + () => ({ + stickyToolbar: false, + }), + ], +}); + +export const Playground = PlaygroundStories.Story;