diff --git a/v1-com-officielle/public/background-noise.png b/assets/background-noise.png
similarity index 100%
rename from v1-com-officielle/public/background-noise.png
rename to assets/background-noise.png
diff --git a/v1-com-officielle/public/background.webm b/assets/background.webm
similarity index 100%
rename from v1-com-officielle/public/background.webm
rename to assets/background.webm
diff --git a/v1-com-officielle/public/favicon.jpg b/assets/favicon.jpg
similarity index 100%
rename from v1-com-officielle/public/favicon.jpg
rename to assets/favicon.jpg
diff --git a/v1-com-officielle/src/assets/icons/2extra.svg b/assets/icons/2extra.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/2extra.svg
rename to assets/icons/2extra.svg
diff --git a/v1-com-officielle/src/assets/icons/2graff.svg b/assets/icons/2graff.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/2graff.svg
rename to assets/icons/2graff.svg
diff --git a/v1-com-officielle/src/assets/icons/about.svg b/assets/icons/about.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/about.svg
rename to assets/icons/about.svg
diff --git a/v1-com-officielle/src/assets/icons/afaG.svg b/assets/icons/afaG.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/afaG.svg
rename to assets/icons/afaG.svg
diff --git a/v1-com-officielle/src/assets/icons/afaN.svg b/assets/icons/afaN.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/afaN.svg
rename to assets/icons/afaN.svg
diff --git a/v1-com-officielle/src/assets/icons/back.svg b/assets/icons/back.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/back.svg
rename to assets/icons/back.svg
diff --git a/v0-appel-projet/src/assets/close.svg b/assets/icons/close.svg
similarity index 100%
rename from v0-appel-projet/src/assets/close.svg
rename to assets/icons/close.svg
diff --git a/v1-com-officielle/src/assets/icons/contact.svg b/assets/icons/contact.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/contact.svg
rename to assets/icons/contact.svg
diff --git a/v1-com-officielle/src/assets/icons/day.svg b/assets/icons/day.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/day.svg
rename to assets/icons/day.svg
diff --git a/v1-com-officielle/src/assets/icons/file.svg b/assets/icons/file.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/file.svg
rename to assets/icons/file.svg
diff --git a/v1-com-officielle/src/assets/icons/folder.svg b/assets/icons/folder.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/folder.svg
rename to assets/icons/folder.svg
diff --git a/v1-com-officielle/src/assets/icons/img.svg b/assets/icons/img.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/img.svg
rename to assets/icons/img.svg
diff --git a/v1-com-officielle/src/assets/icons/info.svg b/assets/icons/info.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/info.svg
rename to assets/icons/info.svg
diff --git a/v1-com-officielle/src/assets/icons/insta.svg b/assets/icons/insta.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/insta.svg
rename to assets/icons/insta.svg
diff --git a/v1-com-officielle/src/assets/icons/like.svg b/assets/icons/like.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/like.svg
rename to assets/icons/like.svg
diff --git a/v1-com-officielle/src/assets/icons/link.svg b/assets/icons/link.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/link.svg
rename to assets/icons/link.svg
diff --git a/v1-com-officielle/src/assets/icons/live.svg b/assets/icons/live.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/live.svg
rename to assets/icons/live.svg
diff --git a/v1-com-officielle/src/assets/icons/loveG.svg b/assets/icons/loveG.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/loveG.svg
rename to assets/icons/loveG.svg
diff --git a/v1-com-officielle/src/assets/icons/loveN.svg b/assets/icons/loveN.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/loveN.svg
rename to assets/icons/loveN.svg
diff --git a/v1-com-officielle/src/assets/icons/msg.svg b/assets/icons/msg.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/msg.svg
rename to assets/icons/msg.svg
diff --git a/v1-com-officielle/src/assets/icons/next.svg b/assets/icons/next.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/next.svg
rename to assets/icons/next.svg
diff --git a/v1-com-officielle/src/assets/icons/night.svg b/assets/icons/night.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/night.svg
rename to assets/icons/night.svg
diff --git a/v1-com-officielle/src/assets/icons/pause.svg b/assets/icons/pause.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/pause.svg
rename to assets/icons/pause.svg
diff --git a/v1-com-officielle/src/assets/icons/people.svg b/assets/icons/people.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/people.svg
rename to assets/icons/people.svg
diff --git a/v1-com-officielle/src/assets/icons/play.svg b/assets/icons/play.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/play.svg
rename to assets/icons/play.svg
diff --git a/v1-com-officielle/src/assets/icons/prev.svg b/assets/icons/prev.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/prev.svg
rename to assets/icons/prev.svg
diff --git a/v1-com-officielle/src/assets/icons/reload.svg b/assets/icons/reload.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/reload.svg
rename to assets/icons/reload.svg
diff --git a/v1-com-officielle/src/assets/icons/text.svg b/assets/icons/text.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/text.svg
rename to assets/icons/text.svg
diff --git a/v1-com-officielle/src/assets/icons/tsG.svg b/assets/icons/tsG.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/tsG.svg
rename to assets/icons/tsG.svg
diff --git a/v1-com-officielle/src/assets/icons/tsN.svg b/assets/icons/tsN.svg
similarity index 100%
rename from v1-com-officielle/src/assets/icons/tsN.svg
rename to assets/icons/tsN.svg
diff --git a/assets/webRings/DNNwebring.gif b/assets/webRings/DNNwebring.gif
new file mode 100644
index 0000000..2a716d9
Binary files /dev/null and b/assets/webRings/DNNwebring.gif differ
diff --git a/assets/webRings/berthe.cc.png b/assets/webRings/berthe.cc.png
new file mode 100644
index 0000000..9723f00
Binary files /dev/null and b/assets/webRings/berthe.cc.png differ
diff --git a/assets/webRings/labolyon.fr.png b/assets/webRings/labolyon.fr.png
new file mode 100644
index 0000000..1d93e93
Binary files /dev/null and b/assets/webRings/labolyon.fr.png differ
diff --git a/assets/webRings/murmure-cafe-webring.png b/assets/webRings/murmure-cafe-webring.png
new file mode 100644
index 0000000..99583ab
Binary files /dev/null and b/assets/webRings/murmure-cafe-webring.png differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..4c25ac7
--- /dev/null
+++ b/index.html
@@ -0,0 +1,110 @@
+
+
+
- Drag shows, musique électronique, synthés vidéos et autre performances nerds
-
- drag
- nerd
- drags
- nerds
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/v0-appel-projet/package-lock.json b/v0-appel-projet/package-lock.json
deleted file mode 100644
index bfc068f..0000000
--- a/v0-appel-projet/package-lock.json
+++ /dev/null
@@ -1,1579 +0,0 @@
-{
- "name": "v0-appel-projet",
- "version": "0.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "v0-appel-projet",
- "version": "0.0.0",
- "dependencies": {
- "vite-svg-loader": "^5.1.1",
- "vue": "^3.5.25"
- },
- "devDependencies": {
- "@vitejs/plugin-vue": "^6.0.2",
- "vite": "^7.3.1"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
- "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
- "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
- "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
- "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
- "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
- "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
- "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
- "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
- "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
- "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
- "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
- "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
- "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
- "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
- "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
- "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
- "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
- "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
- "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
- "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
- "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
- "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
- "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
- "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
- "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "license": "MIT"
- },
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.2",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz",
- "integrity": "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
- "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
- "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
- "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
- "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
- "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
- "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
- "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
- "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
- "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
- "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
- "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
- "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
- "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
- "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
- "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
- "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
- "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
- "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
- "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
- "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
- "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
- "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
- "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
- "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
- "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@types/estree": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@vitejs/plugin-vue": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.4.tgz",
- "integrity": "sha512-uM5iXipgYIn13UUQCZNdWkYk+sysBeA97d5mHsAoAt1u/wpN3+zxOmsVJWosuzX+IMGRzeYUNytztrYznboIkQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@rolldown/pluginutils": "1.0.0-rc.2"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "peerDependencies": {
- "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0",
- "vue": "^3.2.25"
- }
- },
- "node_modules/@vue/compiler-core": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz",
- "integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.29.0",
- "@vue/shared": "3.5.30",
- "entities": "^7.0.1",
- "estree-walker": "^2.0.2",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/@vue/compiler-dom": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz",
- "integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-core": "3.5.30",
- "@vue/shared": "3.5.30"
- }
- },
- "node_modules/@vue/compiler-sfc": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz",
- "integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.29.0",
- "@vue/compiler-core": "3.5.30",
- "@vue/compiler-dom": "3.5.30",
- "@vue/compiler-ssr": "3.5.30",
- "@vue/shared": "3.5.30",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.30.21",
- "postcss": "^8.5.8",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/@vue/compiler-ssr": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz",
- "integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-dom": "3.5.30",
- "@vue/shared": "3.5.30"
- }
- },
- "node_modules/@vue/reactivity": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz",
- "integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==",
- "license": "MIT",
- "dependencies": {
- "@vue/shared": "3.5.30"
- }
- },
- "node_modules/@vue/runtime-core": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz",
- "integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==",
- "license": "MIT",
- "dependencies": {
- "@vue/reactivity": "3.5.30",
- "@vue/shared": "3.5.30"
- }
- },
- "node_modules/@vue/runtime-dom": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz",
- "integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==",
- "license": "MIT",
- "dependencies": {
- "@vue/reactivity": "3.5.30",
- "@vue/runtime-core": "3.5.30",
- "@vue/shared": "3.5.30",
- "csstype": "^3.2.3"
- }
- },
- "node_modules/@vue/server-renderer": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz",
- "integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-ssr": "3.5.30",
- "@vue/shared": "3.5.30"
- },
- "peerDependencies": {
- "vue": "3.5.30"
- }
- },
- "node_modules/@vue/shared": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz",
- "integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==",
- "license": "MIT"
- },
- "node_modules/boolbase": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
- "license": "ISC"
- },
- "node_modules/commander": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
- "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/css-select": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
- "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "boolbase": "^1.0.0",
- "css-what": "^6.1.0",
- "domhandler": "^5.0.2",
- "domutils": "^3.0.1",
- "nth-check": "^2.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
- "node_modules/css-tree": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
- "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
- "license": "MIT",
- "dependencies": {
- "mdn-data": "2.0.30",
- "source-map-js": "^1.0.1"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
- }
- },
- "node_modules/css-what": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
- "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">= 6"
- },
- "funding": {
- "url": "https://github.com/sponsors/fb55"
- }
- },
- "node_modules/csso": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
- "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
- "license": "MIT",
- "dependencies": {
- "css-tree": "~2.2.0"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
- "npm": ">=7.0.0"
- }
- },
- "node_modules/csso/node_modules/css-tree": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
- "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
- "license": "MIT",
- "dependencies": {
- "mdn-data": "2.0.28",
- "source-map-js": "^1.0.1"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
- "npm": ">=7.0.0"
- }
- },
- "node_modules/csso/node_modules/mdn-data": {
- "version": "2.0.28",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
- "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
- "license": "CC0-1.0"
- },
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "license": "MIT"
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/dom-serializer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
- "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
- "entities": "^4.2.0"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
- }
- },
- "node_modules/dom-serializer/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/domelementtype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "BSD-2-Clause"
- },
- "node_modules/domhandler": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
- "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "domelementtype": "^2.3.0"
- },
- "engines": {
- "node": ">= 4"
- },
- "funding": {
- "url": "https://github.com/fb55/domhandler?sponsor=1"
- }
- },
- "node_modules/domutils": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
- "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "dom-serializer": "^2.0.0",
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3"
- },
- "funding": {
- "url": "https://github.com/fb55/domutils?sponsor=1"
- }
- },
- "node_modules/entities": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
- "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/esbuild": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
- "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.3",
- "@esbuild/android-arm": "0.27.3",
- "@esbuild/android-arm64": "0.27.3",
- "@esbuild/android-x64": "0.27.3",
- "@esbuild/darwin-arm64": "0.27.3",
- "@esbuild/darwin-x64": "0.27.3",
- "@esbuild/freebsd-arm64": "0.27.3",
- "@esbuild/freebsd-x64": "0.27.3",
- "@esbuild/linux-arm": "0.27.3",
- "@esbuild/linux-arm64": "0.27.3",
- "@esbuild/linux-ia32": "0.27.3",
- "@esbuild/linux-loong64": "0.27.3",
- "@esbuild/linux-mips64el": "0.27.3",
- "@esbuild/linux-ppc64": "0.27.3",
- "@esbuild/linux-riscv64": "0.27.3",
- "@esbuild/linux-s390x": "0.27.3",
- "@esbuild/linux-x64": "0.27.3",
- "@esbuild/netbsd-arm64": "0.27.3",
- "@esbuild/netbsd-x64": "0.27.3",
- "@esbuild/openbsd-arm64": "0.27.3",
- "@esbuild/openbsd-x64": "0.27.3",
- "@esbuild/openharmony-arm64": "0.27.3",
- "@esbuild/sunos-x64": "0.27.3",
- "@esbuild/win32-arm64": "0.27.3",
- "@esbuild/win32-ia32": "0.27.3",
- "@esbuild/win32-x64": "0.27.3"
- }
- },
- "node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "license": "MIT"
- },
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "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,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/mdn-data": {
- "version": "2.0.30",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
- "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
- "license": "CC0-1.0"
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/nth-check": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
- "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "boolbase": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/fb55/nth-check?sponsor=1"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.8",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
- "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.11",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/rollup": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
- "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "1.0.8"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.59.0",
- "@rollup/rollup-android-arm64": "4.59.0",
- "@rollup/rollup-darwin-arm64": "4.59.0",
- "@rollup/rollup-darwin-x64": "4.59.0",
- "@rollup/rollup-freebsd-arm64": "4.59.0",
- "@rollup/rollup-freebsd-x64": "4.59.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.59.0",
- "@rollup/rollup-linux-arm64-gnu": "4.59.0",
- "@rollup/rollup-linux-arm64-musl": "4.59.0",
- "@rollup/rollup-linux-loong64-gnu": "4.59.0",
- "@rollup/rollup-linux-loong64-musl": "4.59.0",
- "@rollup/rollup-linux-ppc64-gnu": "4.59.0",
- "@rollup/rollup-linux-ppc64-musl": "4.59.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.59.0",
- "@rollup/rollup-linux-riscv64-musl": "4.59.0",
- "@rollup/rollup-linux-s390x-gnu": "4.59.0",
- "@rollup/rollup-linux-x64-gnu": "4.59.0",
- "@rollup/rollup-linux-x64-musl": "4.59.0",
- "@rollup/rollup-openbsd-x64": "4.59.0",
- "@rollup/rollup-openharmony-arm64": "4.59.0",
- "@rollup/rollup-win32-arm64-msvc": "4.59.0",
- "@rollup/rollup-win32-ia32-msvc": "4.59.0",
- "@rollup/rollup-win32-x64-gnu": "4.59.0",
- "@rollup/rollup-win32-x64-msvc": "4.59.0",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/sax": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz",
- "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=11.0.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/svgo": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz",
- "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==",
- "license": "MIT",
- "dependencies": {
- "commander": "^7.2.0",
- "css-select": "^5.1.0",
- "css-tree": "^2.3.1",
- "css-what": "^6.1.0",
- "csso": "^5.0.5",
- "picocolors": "^1.0.0",
- "sax": "^1.5.0"
- },
- "bin": {
- "svgo": "bin/svgo"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/svgo"
- }
- },
- "node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/vite": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
- "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.27.0",
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3",
- "postcss": "^8.5.6",
- "rollup": "^4.43.0",
- "tinyglobby": "^0.2.15"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^20.19.0 || >=22.12.0",
- "jiti": ">=1.21.0",
- "less": "^4.0.0",
- "lightningcss": "^1.21.0",
- "sass": "^1.70.0",
- "sass-embedded": "^1.70.0",
- "stylus": ">=0.54.8",
- "sugarss": "^5.0.0",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/vite-svg-loader": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/vite-svg-loader/-/vite-svg-loader-5.1.1.tgz",
- "integrity": "sha512-RPzcXA/EpKJA0585x58DBgs7my2VfeJ+j2j1EoHY4Zh82Y7hV4cR1fElgy2aZi85+QSrcLLoTStQ5uZjD68u+Q==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4",
- "svgo": "^3.3.3"
- },
- "peerDependencies": {
- "vue": ">=3.2.13"
- }
- },
- "node_modules/vue": {
- "version": "3.5.30",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz",
- "integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-dom": "3.5.30",
- "@vue/compiler-sfc": "3.5.30",
- "@vue/runtime-dom": "3.5.30",
- "@vue/server-renderer": "3.5.30",
- "@vue/shared": "3.5.30"
- },
- "peerDependencies": {
- "typescript": "*"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- }
- }
-}
diff --git a/v0-appel-projet/package.json b/v0-appel-projet/package.json
deleted file mode 100644
index 1d82068..0000000
--- a/v0-appel-projet/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "v0-appel-projet",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview"
- },
- "dependencies": {
- "vite-svg-loader": "^5.1.1",
- "vue": "^3.5.25"
- },
- "devDependencies": {
- "@vitejs/plugin-vue": "^6.0.2",
- "vite": "^7.3.1"
- }
-}
diff --git a/v0-appel-projet/public/LICENSE.txt b/v0-appel-projet/public/LICENSE.txt
deleted file mode 100644
index 7325ff5..0000000
--- a/v0-appel-projet/public/LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2025 Alan Ang
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/v0-appel-projet/public/background_styles.css b/v0-appel-projet/public/background_styles.css
deleted file mode 100644
index 0c17d0e..0000000
--- a/v0-appel-projet/public/background_styles.css
+++ /dev/null
@@ -1,29 +0,0 @@
-html, body{
- margin: 0;
- padding: 0;
- inset: 0;
- position: absolute;
- z-index: 0;
- background-color: #FFFFFF;
- height: 100%;
- width: 100%;
- overflow: hidden;
- display: block;
-}
-
-canvas {
- display: block;
- max-width: 100%;
- margin: 0 auto;
- padding: 0;
- /* margin-top: 0vh; */
- text-align: center;
- /* height: 100vh; */
-}
-
-
-.dg{
- display: none !important;
- height: 0;
- overflow: hidden;
-}
diff --git a/v0-appel-projet/public/canvasVideoExport.js b/v0-appel-projet/public/canvasVideoExport.js
deleted file mode 100644
index 15fd839..0000000
--- a/v0-appel-projet/public/canvasVideoExport.js
+++ /dev/null
@@ -1,265 +0,0 @@
-let projectName = "komorebi"; //to be updated
-
-//detect user browser
-var ua = navigator.userAgent;
-var isSafari = false;
-var isFirefox = false;
-var isIOS = false;
-var isAndroid = false;
-if(ua.includes("Safari")){
- isSafari = true;
-}
-if(ua.includes("Firefox")){
- isFirefox = true;
-}
-if(ua.includes("iPhone") || ua.includes("iPad") || ua.includes("iPod")){
- isIOS = true;
-}
-if(ua.includes("Android")){
- isAndroid = true;
-}
-console.log("isSafari: "+isSafari+", isFirefox: "+isFirefox+", isIOS: "+isIOS+", isAndroid: "+isAndroid);
-
-let useMobileRecord = false;
-if(isIOS || isAndroid || isFirefox){
- useMobileRecord = true;
-}
-
-var mediaRecorder;
-var recordedChunks;
-var finishedBlob;
-var recordingMessageDiv = document.getElementById("videoRecordingMessageDiv");
-var recordVideoState = false;
-var videoRecordInterval;
-var videoEncoder;
-var muxer;
-var mobileRecorder;
-var videofps = 30;
-let bitrate = 16_000_000;
-
-function saveImage() {
- console.log("Export png image");
-
- // Create a temporary canvas with the same dimensions
- const tempCanvas = document.createElement('canvas');
- tempCanvas.width = canvas.width;
- tempCanvas.height = canvas.height;
- const tempContext = tempCanvas.getContext('2d', {
- willReadFrequently: true,
- alpha: true // Enable alpha for transparency
- });
-
- // Skip filling the background, leaving it transparent
-
- // Force a render frame to ensure latest content
- drawScene();
- gl.flush();
- gl.finish();
-
- // Draw the WebGL canvas onto the temporary canvas
- tempContext.drawImage(canvas, 0, 0);
-
- // Create download link
- const link = document.createElement('a');
- link.href = tempCanvas.toDataURL('image/png');
-
- const date = new Date();
- const filename = projectName + `_${date.toLocaleDateString()}_${date.toLocaleTimeString()}.png`;
- link.download = filename;
- link.click();
-
- // Cleanup
- tempCanvas.remove();
-}
-
-function toggleVideoRecord(){
-
- if(recordVideoState == false){
- recordVideoState = true;
- chooseRecordingFunction();
- } else {
- recordVideoState = false;
- chooseEndRecordingFunction();
- }
-}
-
-function chooseRecordingFunction(){
- //resetAnimation();
- if(useMobileRecord){
- startMobileRecording();
- }else {
- recordVideoMuxer();
- }
-}
-
-function chooseEndRecordingFunction(){
- if(useMobileRecord){
- mobileRecorder.stop();
- }else {
- finalizeVideo();
- }
-}
-
-//record html canvas element and export as mp4 video
-//source: https://devtails.xyz/adam/how-to-save-html-canvas-to-mp4-using-web-codecs-api
-async function recordVideoMuxer() {
-console.log("start muxer video recording");
-
-var videoWidth = Math.floor(canvas.width/2)*2;
-var videoHeight = Math.floor(canvas.height/4)*4; //force a number which is divisible by 4
-
-console.log("Video dimensions: "+videoWidth+", "+videoHeight);
-
-//display user message
-recordingMessageDiv.classList.remove("hidden");
-
-recordVideoState = true;
-const ctx = canvas.getContext("2d", {
- // This forces the use of a software (instead of hardware accelerated) 2D canvas
- // This isn't necessary, but produces quicker results
- willReadFrequently: true,
- // Desynchronizes the canvas paint cycle from the event loop
- // Should be less necessary with OffscreenCanvas, but with a real canvas you will want this
- desynchronized: true,
-});
-
-muxer = new Mp4Muxer.Muxer({
- target: new Mp4Muxer.ArrayBufferTarget(),
- video: {
- // If you change this, make sure to change the VideoEncoder codec as well
- codec: "avc",
- width: videoWidth,
- height: videoHeight,
- },
-
- firstTimestampBehavior: 'offset',
-
- // mp4-muxer docs claim you should always use this with ArrayBufferTarget
- fastStart: "in-memory",
-});
-
-videoEncoder = new VideoEncoder({
- output: (chunk, meta) => muxer.addVideoChunk(chunk, meta),
- error: (e) => console.error(e),
-});
-
-// This codec should work in most browsers
-// See https://dmnsgn.github.io/media-codecs for list of codecs and see if your browser supports
-videoEncoder.configure({
- codec: "avc1.4d0032",
- width: videoWidth,
- height: videoHeight,
- bitrate: bitrate,
- bitrateMode: "variable",
-});
-//NEW codec: "avc1.4d0032",
-//ORIGINAL codec: "avc1.42003e",
-
-var frameNumber = 0;
-
-//take a snapshot of the canvas every x miliseconds and encode to video
-
-videoRecordInterval = setInterval(
- function(){
- if(recordVideoState == true){
- //gl.flush();
- //gl.finish();
- drawScene();
- renderCanvasToVideoFrameAndEncode({
- canvas,
- videoEncoder,
- frameNumber,
- videofps
- })
- frameNumber++;
- }else{
- }
- } , 1000/videofps);
-
-}
-
-//finish and export video
-async function finalizeVideo(){
- console.log("finalize muxer video");
- togglePlayPause();
- clearInterval(videoRecordInterval);
- //playAnimationToggle = false;
- recordVideoState = false;
-
- // Forces all pending encodes to complete
- await videoEncoder.flush();
- muxer.finalize();
- let buffer = muxer.target.buffer;
- finishedBlob = new Blob([buffer]);
- downloadBlob(new Blob([buffer]));
-
- //hide user message
- recordingMessageDiv.classList.add("hidden");
- togglePlayPause();
-}
-
-async function renderCanvasToVideoFrameAndEncode({
- canvas,
- videoEncoder,
- frameNumber,
- videofps,
- }) {
- let frame = new VideoFrame(canvas, {
- // Equally spaces frames out depending on frames per second
- timestamp: (frameNumber * 1e6) / videofps,
- });
-
- // The encode() method of the VideoEncoder interface asynchronously encodes a VideoFrame
- videoEncoder.encode(frame);
-
- // The close() method of the VideoFrame interface clears all states and releases the reference to the media resource.
- frame.close();
-}
-
-function downloadBlob() {
- console.log("download video");
- let url = window.URL.createObjectURL(finishedBlob);
- let a = document.createElement("a");
- a.style.display = "none";
- a.href = url;
- const date = new Date();
- const filename = projectName+`_${date.toLocaleDateString()}_${date.toLocaleTimeString()}.mp4`;
- a.download = filename;
- document.body.appendChild(a);
- a.click();
- window.URL.revokeObjectURL(url);
-}
-
-//record and download videos on mobile devices
-function startMobileRecording(){
- var stream = canvas.captureStream(videofps);
- mobileRecorder = new MediaRecorder(stream, { 'type': 'video/mp4' });
- mobileRecorder.addEventListener('dataavailable', finalizeMobileVideo);
-
- console.log("start simple video recording");
- console.log("Video dimensions: "+canvas.width+", "+canvas.height);
-
- recordingMessageDiv.classList.remove("hidden");
-
- recordVideoState = true;
- mobileRecorder.start(); //start mobile video recording
-
-}
-
-function finalizeMobileVideo(e) {
- setTimeout(function(){
- console.log("finish simple video recording");
- togglePlayPause();
- recordVideoState = false;
- /*
- mobileRecorder.stop();*/
- var videoData = [ e.data ];
- finishedBlob = new Blob(videoData, { 'type': 'video/mp4' });
- downloadBlob(finishedBlob);
-
- //hide user message
- recordingMessageDiv.classList.add("hidden");
- togglePlayPause();
-
- },500);
-}
\ No newline at end of file
diff --git a/v0-appel-projet/public/dnn-screen.png b/v0-appel-projet/public/dnn-screen.png
deleted file mode 100644
index 81a4f2e..0000000
Binary files a/v0-appel-projet/public/dnn-screen.png and /dev/null differ
diff --git a/v0-appel-projet/public/helperFunctions.js b/v0-appel-projet/public/helperFunctions.js
deleted file mode 100644
index 677ddf1..0000000
--- a/v0-appel-projet/public/helperFunctions.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// Toggle play/pause
-function togglePlayPause() {
-
- if (isPlaying) {
- cancelAnimationFrame(animationID);
- isPlaying = false;
- } else {
- isPlaying = true;
- animationID = requestAnimationFrame(render);
- }
-}
-
-// Function to refresh the pattern with a new random seed
-const selectedSeeds = [53, 118, 506];
-var seedCount = 1;
-function refreshPattern() {
- timeOffset = performance.now();
- //randomSeed = Math.floor(Math.random() * 1000,0);
- randomSeed = selectedSeeds[seedCount];
- gl.uniform1f(seedLocation, randomSeed);
- if(!isPlaying){
- isPlaying = true;
- animationID = requestAnimationFrame(render);
- }
- console.log('seed:', randomSeed);
-}
-
-function startFromZeroTime(){
- console.log("Restarting animation from time = 0");
-
- // Cancel current animation if running
- if (animationID) {
- cancelAnimationFrame(animationID);
- }
-
- // Set the time offset to the current time
- // This will be subtracted in the render function
- timeOffset = performance.now();
-
- // Reset frame counter for FPS calculation
- frameCount = 0;
- lastTime = performance.now();
-
- // Make sure all other uniforms are updated
- updateUniforms();
-
- // Ensure animation is playing
- isPlaying = true;
-
- // Start the animation loop from the beginning
- animationID = requestAnimationFrame(render);
-}
-
-// Add this function to handle canvas resizing
-function updateCanvasSize() {
- // Update canvas dimensions to window size
- canvas.width = window.innerWidth;
- canvas.height = window.innerHeight;
-
- // Update the WebGL viewport to match
- gl.viewport(0, 0, canvas.width, canvas.height);
-
- // Re-render if not already playing
- if (!isPlaying) {
- drawScene();
- }
-
- // If recording is active, we need to handle that
- if (recordVideoState) {
- stopRecording();
- startRecording();
- }
-}
-
-//intro overlay info screen
-
-let musicPlaying = false;
-
-let isZenMode = false;
diff --git a/v0-appel-projet/public/main.js b/v0-appel-projet/public/main.js
deleted file mode 100644
index 79f3634..0000000
--- a/v0-appel-projet/public/main.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-To do:
-Press z for zen mode (hides all control and other display on top of the canvas)
-Ability to add this shader effect on top of an image?
-Presets / seed choice??
-Allow user to upload a song, and then it becomes audio reactive?
-Generate perfect loops in x seconds
-*/
-
-// Initialize WebGL context
-const canvas = document.getElementById('canvas');
-let startingWidth = window.innerWidth;
-let startingHeight = window.innerHeight;
-canvas.width = startingWidth;
-canvas.height = startingHeight;
-console.log("canvas width/height: "+canvas.width+" / "+canvas.height);
-
-const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
-let isPlaying = false;
-let animationID = null;
-let randomSeed;
-let time;
-let timeOffset = 0;
-
-// FPS tracking variables
-let frameCount = 0;
-let lastTime = 0;
-let fps = 0;
-
-if (!gl) {
- alert('WebGL not supported');
-}
-
-// Compile shaders
-function compileShader(source, type) {
- const shader = gl.createShader(type);
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- console.error('Shader compilation error:', gl.getShaderInfoLog(shader));
- gl.deleteShader(shader);
- return null;
- }
-
- return shader;
-}
-
-// Create program
-const vertexShader = compileShader(document.getElementById('vertexShader').textContent, gl.VERTEX_SHADER);
-const fragmentShader = compileShader(document.getElementById('fragmentShader').textContent, gl.FRAGMENT_SHADER);
-
-const program = gl.createProgram();
-gl.attachShader(program, vertexShader);
-gl.attachShader(program, fragmentShader);
-gl.linkProgram(program);
-
-if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
- console.error('Program linking error:', gl.getProgramInfoLog(program));
-}
-
-gl.useProgram(program);
-
-// Create rectangle covering the entire canvas
-const positionBuffer = gl.createBuffer();
-gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
-gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
- -1.0, -1.0,
- 1.0, -1.0,
- -1.0, 1.0,
- 1.0, 1.0
-]), gl.STATIC_DRAW);
-
-// Set up attributes and uniforms
-const positionLocation = gl.getAttribLocation(program, 'position');
-gl.enableVertexAttribArray(positionLocation);
-gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
-
-const timeLocation = gl.getUniformLocation(program, 'time');
-const resolutionLocation = gl.getUniformLocation(program, 'resolution');
-const seedLocation = gl.getUniformLocation(program, 'seed');
-
-// GUI-controlled uniform locations
-const timeScaleLocation = gl.getUniformLocation(program, 'timeScale');
-const bloomStrengthLocation = gl.getUniformLocation(program, 'bloomStrength');
-const saturationLocation = gl.getUniformLocation(program, 'saturation');
-const grainAmountLocation = gl.getUniformLocation(program, 'grainAmount');
-const colorTintLocation = gl.getUniformLocation(program, 'colorTint');
-const minCircleSizeLocation = gl.getUniformLocation(program, 'minCircleSize');
-const circleStrengthLocation = gl.getUniformLocation(program, 'circleStrength');
-const distortXLocation = gl.getUniformLocation(program, 'distortX');
-const distortYLocation = gl.getUniformLocation(program, 'distortY');
-
-const patternAmpLocation = gl.getUniformLocation(program, 'patternAmp');
-const patternFreqLocation = gl.getUniformLocation(program, 'patternFreq');
-
-// Initialize parameters object for dat.gui
-const params = {
- canvasWidth: startingWidth,
- canvasHeight: startingHeight,
- timeScale: .666,
- patternAmp: 2,
- patternFreq: 0.4,
- bloomStrength: 0.777,
- saturation: 1.74,
- grainAmount: 0.161,
- colorTintR: 1.5,
- colorTintG: 1.0,
- colorTintB: 1.0,
- minCircleSize: 2.8,
- circleStrength: 0,
- distortX: 1,
- distortY: 1,
-};
-
-// Also refresh on page load
-window.addEventListener('load', refreshPattern);
-window.addEventListener('resize', updateCanvasSize);
-
-// Initialize dat.gui
-const gui = new dat.GUI({ autoplace: false });
-gui.close();
-
-// Add GUI controls with folders for organization
-const canvasFolder = gui.addFolder('Canvas Size');
-canvasFolder.add(params, 'canvasWidth', 100, 4000).step(10).name('Width').onChange(updateCanvasSize);
-canvasFolder.add(params, 'canvasHeight', 100, 4000).step(10).name('Height').onChange(updateCanvasSize);
-canvasFolder.open();
-
-const timeFolder = gui.addFolder('Animation');
-timeFolder.add(params, 'timeScale', 0.1, 3.0).name('Speed').onChange(updateUniforms);
-timeFolder.open();
-
-const patternFolder = gui.addFolder('Pattern');
-patternFolder.add(params, 'patternAmp', 1.0, 50.0).step(0.1).name('Pattern Amp').onChange(updateUniforms);
-patternFolder.add(params, 'patternFreq', 0.2, 10.0).step(0.1).name('Pattern Freq').onChange(updateUniforms);
-patternFolder.open();
-
-const visualFolder = gui.addFolder('Visual Effects');
-visualFolder.add(params, 'bloomStrength', 0.0, 5.0).name('Bloom').onChange(updateUniforms);
-visualFolder.add(params, 'saturation', 0.0, 2.0).name('Saturation').onChange(updateUniforms);
-visualFolder.add(params, 'grainAmount', 0.0, 0.5).name('Grain').onChange(updateUniforms);
-visualFolder.add(params, 'minCircleSize', 0.0, 10.0).name('Circle Size').onChange(updateUniforms);
-visualFolder.add(params, 'circleStrength', 0.0, 3.0).name('Circle Strength').onChange(updateUniforms);
-visualFolder.add(params, 'distortX', 0.0, 50.0).name('Distort-X').onChange(updateUniforms);
-visualFolder.add(params, 'distortY', 0.0, 50.0).name('Distort-Y').onChange(updateUniforms);
-
-visualFolder.open();
-
-const colorFolder = gui.addFolder('Color Tint');
-colorFolder.add(params, 'colorTintR', 0.0, 1.5).name('Red').onChange(updateUniforms);
-colorFolder.add(params, 'colorTintG', 0.0, 1.5).name('Green').onChange(updateUniforms);
-colorFolder.add(params, 'colorTintB', 0.0, 1.5).name('Blue').onChange(updateUniforms);
-colorFolder.open();
-
-// Function to update shader uniforms from GUI values
-function updateUniforms() {
- gl.uniform1f(timeScaleLocation, params.timeScale);
- gl.uniform1f(patternAmpLocation, params.patternAmp);
- gl.uniform1f(patternFreqLocation, params.patternFreq);
- gl.uniform1f(bloomStrengthLocation, params.bloomStrength);
- gl.uniform1f(saturationLocation, params.saturation);
- gl.uniform1f(grainAmountLocation, params.grainAmount);
- gl.uniform3f(colorTintLocation, params.colorTintR, params.colorTintG, params.colorTintB);
- gl.uniform1f(minCircleSizeLocation, params.minCircleSize);
- gl.uniform1f(circleStrengthLocation, params.circleStrength);
- gl.uniform1f(distortXLocation, params.distortX);
- gl.uniform1f(distortYLocation, params.distortY);
-}
-
-function drawScene(){
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-}
-
-// Animation loop
-function render(timestamp) {
- if (isPlaying) {
- // Calculate adjusted time by subtracting the offset
- const adjustedTime = timestamp - timeOffset;
- time = timestamp;
-
- const timeInSeconds = adjustedTime * 0.0035;
- gl.uniform1f(timeLocation, timeInSeconds);
- gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
-
-
- // If video recording is ongoing, drawScene is called already
- if (!recordVideoState || useMobileRecord) {
- drawScene();
- }
-
- animationID = requestAnimationFrame(render);
- }
-}
-
-// Start the animation loop
-isPlaying = true;
-refreshPattern();
-updateUniforms();
-animationID = requestAnimationFrame(render);
diff --git a/v0-appel-projet/public/mp4-muxer-main/LICENSE b/v0-appel-projet/public/mp4-muxer-main/LICENSE
deleted file mode 100644
index 06808a5..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2023 Vanilagy
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/v0-appel-projet/public/mp4-muxer-main/README.md b/v0-appel-projet/public/mp4-muxer-main/README.md
deleted file mode 100644
index c097a89..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/README.md
+++ /dev/null
@@ -1,358 +0,0 @@
-# mp4-muxer - JavaScript MP4 multiplexer
-
-[](https://www.npmjs.com/package/mp4-muxer)
-[](https://bundlephobia.com/package/mp4-muxer)
-[](https://www.npmjs.com/package/mp4-muxer)
-
-The WebCodecs API provides low-level access to media codecs, but provides no way of actually packaging (multiplexing)
-the encoded media into a playable file. This project implements an MP4 multiplexer in pure TypeScript, which is
-high-quality, fast and tiny, and supports both video and audio as well as various internal layouts such as Fast Start or
-fragmented MP4.
-
-[Demo: Muxing into a file](https://vanilagy.github.io/mp4-muxer/demo/)
-
-[Demo: Live streaming](https://vanilagy.github.io/mp4-muxer/demo-streaming)
-
-> **Note:** If you're looking to create **WebM** files, check out [webm-muxer](https://github.com/Vanilagy/webm-muxer),
-the sister library to mp4-muxer.
-
-> Consider [donating](https://ko-fi.com/vanilagy) if you've found this library useful and wish to support it ❤️
-
-## Quick start
-The following is an example for a common usage of this library:
-```js
-import { Muxer, ArrayBufferTarget } from 'mp4-muxer';
-
-let muxer = new Muxer({
- target: new ArrayBufferTarget(),
- video: {
- codec: 'avc',
- width: 1280,
- height: 720
- },
- fastStart: 'in-memory'
-});
-
-let videoEncoder = new VideoEncoder({
- output: (chunk, meta) => muxer.addVideoChunk(chunk, meta),
- error: e => console.error(e)
-});
-videoEncoder.configure({
- codec: 'avc1.42001f',
- width: 1280,
- height: 720,
- bitrate: 1e6
-});
-
-/* Encode some frames... */
-
-await videoEncoder.flush();
-muxer.finalize();
-
-let { buffer } = muxer.target; // Buffer contains final MP4 file
-```
-
-## Motivation
-After [webm-muxer](https://github.com/Vanilagy/webm-muxer) gained traction for its ease of use and integration with the
-WebCodecs API, this library was created to now also allow the creation of MP4 files while maintaining the same DX.
-While WebM is a more modern format, MP4 is an established standard and supported on way more devices.
-
-## Installation
-Using NPM, simply install this package using
-```
-npm install mp4-muxer
-```
-You can import all exported classes like so:
-```js
-import * as Mp4Muxer from 'mp4-muxer';
-// Or, using CommonJS:
-const Mp4Muxer = require('mp4-muxer');
-```
-Alternatively, you can simply include the library as a script in your HTML, which will add an `Mp4Muxer` object,
-containing all the exported classes, to the global object, like so:
-```html
-
-```
-
-## Usage
-### Initialization
-For each MP4 file you wish to create, create an instance of `Muxer` like so:
-```js
-import { Muxer } from 'mp4-muxer';
-
-let muxer = new Muxer(options);
-```
-The available options are defined by the following interface:
-```ts
-interface MuxerOptions {
- target:
- | ArrayBufferTarget
- | StreamTarget
- | FileSystemWritableFileStreamTarget,
-
- video?: {
- codec: 'avc' | 'hevc' | 'vp9' | 'av1',
- width: number,
- height: number,
-
- // Adds rotation metadata to the file
- rotation?: 0 | 90 | 180 | 270 | TransformationMatrix
- },
-
- audio?: {
- codec: 'aac' | 'opus',
- numberOfChannels: number,
- sampleRate: number
- },
-
- fastStart:
- | false
- | 'in-memory'
- | 'fragmented'
- | { expectedVideoChunks?: number, expectedAudioChunks?: number }
-
- firstTimestampBehavior?: 'strict' | 'offset' | 'cross-track-offset'
-}
-```
-Codecs currently supported by this library are AVC/H.264, HEVC/H.265, VP9 and AV1 for video, and AAC and Opus for audio.
-#### `target` (required)
-This option specifies where the data created by the muxer will be written. The options are:
-- `ArrayBufferTarget`: The file data will be written into a single large buffer, which is then stored in the target.
-
- ```js
- import { Muxer, ArrayBufferTarget } from 'mp4-muxer';
-
- let muxer = new Muxer({
- target: new ArrayBufferTarget(),
- fastStart: 'in-memory',
- // ...
- });
-
- // ...
-
- muxer.finalize();
- let { buffer } = muxer.target;
- ```
-- `StreamTarget`: This target defines callbacks that will get called whenever there is new data available - this is
- useful if you want to stream the data, e.g. pipe it somewhere else. The constructor has the following signature:
-
- ```ts
- constructor(options: {
- onData?: (data: Uint8Array, position: number) => void,
- chunked?: boolean,
- chunkSize?: number
- });
- ```
-
- `onData` is called for each new chunk of available data. The `position` argument specifies the offset in bytes at
- which the data has to be written. Since the data written by the muxer is not always sequential, **make sure to
- respect this argument**.
-
- When using `chunked: true`, data created by the muxer will first be accumulated and only written out once it has
- reached sufficient size. This is useful for reducing the total amount of writes, at the cost of latency. It using a
- default chunk size of 16 MiB, which can be overridden by manually setting `chunkSize` to the desired byte length.
-
- If you want to use this target for *live-streaming*, i.e. playback before muxing has finished, you also need to set
- `fastStart: 'fragmented'`.
-
- Usage example:
- ```js
- import { Muxer, StreamTarget } from 'mp4-muxer';
-
- let muxer = new Muxer({
- target: new StreamTarget({
- onData: (data, position) => { /* Do something with the data */ }
- }),
- fastStart: false,
- // ...
- });
- ```
-- `FileSystemWritableFileStreamTarget`: This is essentially a wrapper around a chunked `StreamTarget` with the intention
- of simplifying the use of this library with the File System Access API. Writing the file directly to disk as it's
- being created comes with many benefits, such as creating files way larger than the available RAM.
-
- You can optionally override the default `chunkSize` of 16 MiB.
- ```ts
- constructor(
- stream: FileSystemWritableFileStream,
- options?: { chunkSize?: number }
- );
- ```
-
- Usage example:
- ```js
- import { Muxer, FileSystemWritableFileStreamTarget } from 'mp4-muxer';
-
- let fileHandle = await window.showSaveFilePicker({
- suggestedName: `video.mp4`,
- types: [{
- description: 'Video File',
- accept: { 'video/mp4': ['.mp4'] }
- }],
- });
- let fileStream = await fileHandle.createWritable();
- let muxer = new Muxer({
- target: new FileSystemWritableFileStreamTarget(fileStream),
- fastStart: false,
- // ...
- });
-
- // ...
-
- muxer.finalize();
- await fileStream.close(); // Make sure to close the stream
- ```
-#### `fastStart` (required)
-By default, MP4 metadata (track info, sample timing, etc.) is stored at the end of the file - this makes writing the
-file faster and easier. However, placing this metadata at the _start_ of the file instead (known as "Fast Start")
-provides certain benefits: The file becomes easier to stream over the web without range requests, and sites like YouTube
-can start processing the video while it's uploading. This library provides full control over the placement of metadata
-setting `fastStart` to one of these options:
-- `false`: Disables Fast Start, placing all metadata at the end of the file. This option is the fastest and uses the
- least memory. This option is recommended for large, unbounded files that are streamed directly to disk.
-- `'in-memory'`: Produces a file with Fast Start by keeping all media chunks in memory until the file is finalized. This
- option produces the most compact output possible at the cost of a more expensive finalization step and higher memory
- requirements. This is the preferred option when using `ArrayBufferTarget` as it will result in a higher-quality
- output with no change in memory footprint.
-- `'fragmented'`: Produces a _fragmented MP4 (fMP4)_ file, evenly placing sample metadata throughout the file by
- grouping it into "fragments" (short sections of media), while placing general metadata at the beginning of the file.
- Fragmented files are ideal for streaming, as they are optimized for random access with minimal to no seeking.
- Furthermore, they remain lightweight to create no matter how large the file becomes, as they don't require media to
- be kept in memory for very long. While fragmented files are not as widely supported as regular MP4 files, this
- option provides powerful benefits with very little downsides. Further details
- [here](#additional-notes-about-fragmented-mp4-files).
-- `object`: Produces a file with Fast Start by reserving space for metadata when muxing begins. To know
- how many bytes need to be reserved to be safe, you'll have to provide the following data:
- ```ts
- {
- expectedVideoChunks?: number,
- expectedAudioChunks?: number
- }
- ```
- Note that the property `expectedVideoChunks` is _required_ if you have a video track - the same goes for audio. With
- this option set, you cannot mux more chunks than the number you've specified (although less is fine).
-
- This option is faster than `'in-memory'` and uses no additional memory, but results in a slightly larger output,
- making it useful for when you want to stream the file to disk while still retaining Fast Start.
-#### `firstTimestampBehavior` (optional)
-Specifies how to deal with the first chunk in each track having a non-zero timestamp. In the default strict mode,
-timestamps must start with 0 to ensure proper playback. However, when directly piping video frames or audio data
-from a MediaTrackStream into the encoder and then the muxer, the timestamps are usually relative to the age of
-the document or the computer's clock, which is typically not what we want. Handling of these timestamps must be
-set explicitly:
-- Use `'offset'` to offset the timestamp of each track by that track's first chunk's timestamp. This way, it
-starts at 0.
-- Use `'cross-track-offset'` to offset the timestamp of each track by the _minimum of all tracks' first chunk timestamp_.
-This works like `'offset'`, but should be used when the all tracks use the same clock.
-
-### Muxing media chunks
-Then, with VideoEncoder and AudioEncoder set up, send encoded chunks to the muxer using the following methods:
-```ts
-addVideoChunk(
- chunk: EncodedVideoChunk,
- meta?: EncodedVideoChunkMetadata,
- timestamp?: number,
- compositionTimeOffset?: number
-): void;
-
-addAudioChunk(
- chunk: EncodedAudioChunk,
- meta?: EncodedAudioChunkMetadata,
- timestamp?: number
-): void;
-```
-
-Both methods accept an optional, third argument `timestamp` (microseconds) which, if specified, overrides
-the `timestamp` property of the passed-in chunk.
-
-The metadata comes from the second parameter of the `output` callback given to the
-VideoEncoder or AudioEncoder's constructor and needs to be passed into the muxer, like so:
-```js
-let videoEncoder = new VideoEncoder({
- output: (chunk, meta) => muxer.addVideoChunk(chunk, meta),
- error: e => console.error(e)
-});
-videoEncoder.configure(/* ... */);
-```
-
-The optional field `compositionTimeOffset` can be used when the decode time of the chunk doesn't equal its presentation
-time; this is the case when [B-frames](https://en.wikipedia.org/wiki/Video_compression_picture_types) are present.
-B-frames don't occur when using the WebCodecs API for encoding. The decode time is calculated by subtracting
-`compositionTimeOffset` from `timestamp`, meaning `timestamp` dictates the presentation time.
-
-Should you have obtained your encoded media data from a source other than the WebCodecs API, you can use these following
-methods to directly send your raw data to the muxer:
-```ts
-addVideoChunkRaw(
- data: Uint8Array,
- type: 'key' | 'delta',
- timestamp: number, // in microseconds
- duration: number, // in microseconds
- meta?: EncodedVideoChunkMetadata,
- compositionTimeOffset?: number // in microseconds
-): void;
-
-addAudioChunkRaw(
- data: Uint8Array,
- type: 'key' | 'delta',
- timestamp: number, // in microseconds
- duration: number, // in microseconds
- meta?: EncodedAudioChunkMetadata
-): void;
-```
-
-### Finishing up
-When encoding is finished and all the encoders have been flushed, call `finalize` on the `Muxer` instance to finalize
-the MP4 file:
-```js
-muxer.finalize();
-```
-When using an ArrayBufferTarget, the final buffer will be accessible through it:
-```js
-let { buffer } = muxer.target;
-```
-When using a FileSystemWritableFileStreamTarget, make sure to close the stream after calling `finalize`:
-```js
-await fileStream.close();
-```
-
-## Details
-### Variable frame rate
-MP4 files support variable frame rate, however some players (such as QuickTime) have been observed not to behave well
-when the timestamps are irregular. Therefore, whenever possible, try aiming for a fixed frame rate.
-
-### Additional notes about fragmented MP4 files
-By breaking up the media and related metadata into small fragments, fMP4 files optimize for random access and are ideal
-for streaming, while remaining cheap to write even for long files. However, you should keep these things in mind:
-- **Media chunk buffering:**
- When muxing a file with a video **and** an audio track, the muxer needs to wait for the chunks from _both_ media
- to finalize any given fragment. In other words, it must buffer chunks of one medium if the other medium has not yet
- encoded chunks up to that timestamp. For example, should you first encode all your video frames and then encode the
- audio afterward, the multiplexer will have to hold all those video frames in memory until the audio chunks start
- coming in. This might lead to memory exhaustion should your video be very long. When there is only one media track,
- this issue does not arise. So, when muxing a multimedia file, make sure it is somewhat limited in size or the chunks
- are encoded in a somewhat interleaved way (like is the case for live media). This will keep memory usage at a
- constant low.
-- **Video key frame frequency:**
- Every track's first sample in a fragment must be a key frame in order to be able to play said fragment without the
- knowledge of previous ones. However, this means that the muxer needs to wait for a video key frame to begin a new
- fragment. If these key frames are too infrequent, fragments become too large, harming random access. Therefore,
- every 5–10 seconds, you should force a video key frame like so:
- ```js
- videoEncoder.encode(frame, { keyFrame: true });
- ```
-
-## Implementation & development
-MP4 files are based on the ISO Base Media Format, which structures its files as a hierarchy of boxes (or atoms). The
-standards used to implement this library were
-[ISO/IEC 14496-1](http://netmedia.zju.edu.cn/multimedia2013/mpeg-4/ISO%20IEC%2014496-1%20MPEG-4%20System%20Standard.pdf),
-[ISO/IEC 14496-12](https://web.archive.org/web/20231123030701/https://b.goeswhere.com/ISO_IEC_14496-12_2015.pdf)
-and
-[ISO/IEC 14496-14](https://github.com/OpenAnsible/rust-mp4/raw/master/docs/ISO_IEC_14496-14_2003-11-15.pdf).
-Additionally, the
-[QuickTime MP4 Specification](https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFPreface/qtffPreface.html)
-was a very useful resource.
-
-For development, clone this repository, install everything with `npm install`, then run `npm run watch` to bundle the
-code into the `build` directory. Run `npm run check` to run the TypeScript type checker, and `npm run lint` to run
-ESLint.
diff --git a/v0-appel-projet/public/mp4-muxer-main/build.mjs b/v0-appel-projet/public/mp4-muxer-main/build.mjs
deleted file mode 100644
index 70e4c7f..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/build.mjs
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as esbuild from 'esbuild';
-
-const baseConfig = {
- entryPoints: ['src/index.ts'],
- bundle: true,
- logLevel: 'info'
-};
-
-const umdConfig = {
- ...baseConfig,
- format: 'iife',
-
- // The following are hacks to basically make this an UMD module. No native support for that in esbuild as of today
- globalName: 'Mp4Muxer',
-
- footer: {
- js:
-`if (typeof module === "object" && typeof module.exports === "object") Object.assign(module.exports, Mp4Muxer)`
- }
-};
-
-const esmConfig = {
- ...baseConfig,
- format: 'esm'
-};
-
-let ctxUmd = await esbuild.context({
- ...umdConfig,
- outfile: 'build/mp4-muxer.js'
-});
-let ctxEsm = await esbuild.context({
- ...esmConfig,
- outfile: 'build/mp4-muxer.mjs'
-});
-let ctxUmdMinified = await esbuild.context({
- ...umdConfig,
- outfile: 'build/mp4-muxer.min.js',
- minify: true
-});
-let ctxEsmMinified = await esbuild.context({
- ...esmConfig,
- outfile: 'build/mp4-muxer.min.mjs',
- minify: true
-});
-
-await Promise.all([ctxUmd.watch(), ctxEsm.watch(), ctxUmdMinified.watch(), ctxEsmMinified.watch()]);
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.d.ts b/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.d.ts
deleted file mode 100644
index 303f545..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.d.ts
+++ /dev/null
@@ -1,226 +0,0 @@
-declare type TransformationMatrix = [number, number, number, number, number, number, number, number, number];
-
-declare interface VideoOptions {
- /**
- * The codec of the encoded video chunks.
- */
- codec: 'avc' | 'hevc' | 'vp9' | 'av1',
- /**
- * The width of the video in pixels.
- */
- width: number,
- /**
- * The height of the video in pixels.
- */
- height: number,
- /**
- * The clockwise rotation of the video in degrees, or a transformation matrix.
- */
- rotation?: 0 | 90 | 180 | 270 | TransformationMatrix
-}
-
-declare interface AudioOptions {
- /**
- * The codec of the encoded audio chunks.
- */
- codec: 'aac' | 'opus',
- /**
- * The number of audio channels in the audio track.
- */
- numberOfChannels: number,
- /**
- * The sample rate of the audio track in samples per second per channel.
- */
- sampleRate: number
-}
-
-/**
- * Describes the properties used to configure an instance of `Muxer`.
- */
-declare type MuxerOptions = {
- /**
- * Specifies what happens with the data created by the muxer.
- */
- target: T,
-
- /**
- * When set, declares the existence of a video track in the MP4 file and configures that video track.
- */
- video?: VideoOptions,
-
- /**
- * When set, declares the existence of an audio track in the MP4 file and configures that audio track.
- */
- audio?: AudioOptions,
-
- /**
- * Controls the placement of metadata in the file. Placing metadata at the start of the file is known as "Fast
- * Start", which results in better playback at the cost of more required processing or memory.
- *
- * Use `false` to disable Fast Start, placing the metadata at the end of the file. Fastest and uses the least
- * memory.
- *
- * Use `'in-memory'` to produce a file with Fast Start by keeping all media chunks in memory until the file is
- * finalized. This produces a high-quality and compact output at the cost of a more expensive finalization step and
- * higher memory requirements.
- *
- * Use `'fragmented'` to place metadata at the start of the file by creating a fragmented "fMP4" file. In a
- * fragmented file, chunks of media and their metadata are written to the file in "fragments", eliminating the need
- * to put all metadata in one place. Fragmented files are useful for streaming, as they allow for better random
- * access. Furthermore, they remain lightweight to create even for very large files, as they don't require all media
- * to be kept in memory. However, fragmented files are not as widely supported as regular MP4 files.
- *
- * Use an object to produce a file with Fast Start by reserving space for metadata when muxing starts. In order to
- * know how much space needs to be reserved, you'll need to tell it the upper bound of how many media chunks will be
- * muxed. Do this by setting `expectedVideoChunks` and/or `expectedAudioChunks`.
- */
- fastStart: false | 'in-memory' | 'fragmented' | {
- expectedVideoChunks?: number,
- expectedAudioChunks?: number
- },
-
- /**
- * Specifies how to deal with the first chunk in each track having a non-zero timestamp. In the default strict mode,
- * timestamps must start with 0 to ensure proper playback. However, when directly piping video frames or audio data
- * from a MediaTrackStream into the encoder and then the muxer, the timestamps are usually relative to the age of
- * the document or the computer's clock, which is typically not what we want. Handling of these timestamps must be
- * set explicitly:
- *
- * Use `'offset'` to offset the timestamp of each video track by that track's first chunk's timestamp. This way, it
- * starts at 0.
- *
- * Use `'cross-track-offset'` to offset the timestamp of _both_ tracks by whichever track's first chunk timestamp is
- * earliest. This is designed for cases when both tracks' timestamps come from the same clock source.
- */
- firstTimestampBehavior?: 'strict' | 'offset' | 'cross-track-offset'
-};
-
-declare type Target = ArrayBufferTarget | StreamTarget | FileSystemWritableFileStreamTarget;
-
-/** The file data will be written into a single large buffer, which is then stored in `buffer` upon finalization.. */
-declare class ArrayBufferTarget {
- buffer: ArrayBuffer;
-}
-
-/**
- * This target defines callbacks that will get called whenever there is new data available - this is useful if
- * you want to stream the data, e.g. pipe it somewhere else.
- *
- * When using `chunked: true` in the options, data created by the muxer will first be accumulated and only written out
- * once it has reached sufficient size, using a default chunk size of 16 MiB. This is useful for reducing the total
- * amount of writes, at the cost of latency.
- */
-declare class StreamTarget {
- constructor(options: {
- onData?: (data: Uint8Array, position: number) => void,
- chunked?: boolean,
- chunkSize?: number
- });
-}
-
-/**
- * This is essentially a wrapper around a chunked `StreamTarget` with the intention of simplifying the use of this
- * library with the File System Access API. Writing the file directly to disk as it's being created comes with many
- * benefits, such as creating files way larger than the available RAM.
- */
-declare class FileSystemWritableFileStreamTarget {
- constructor(
- stream: FileSystemWritableFileStream,
- options?: { chunkSize?: number }
- );
-}
-
-/**
- * Used to multiplex video and audio chunks into a single MP4 file. For each MP4 file you want to create, create
- * one instance of `Muxer`.
- */
-declare class Muxer {
- target: T;
-
- /**
- * Creates a new instance of `Muxer`.
- * @param options Specifies configuration and metadata for the MP4 file.
- */
- constructor(options: MuxerOptions);
-
- /**
- * Adds a new, encoded video chunk to the MP4 file.
- * @param chunk The encoded video chunk. Can be obtained through a `VideoEncoder`.
- * @param meta The metadata about the encoded video, also provided by `VideoEncoder`.
- * @param timestamp Optionally, the presentation timestamp to use for the video chunk. When not provided, it will
- * use the one specified in `chunk`.
- * @param compositionTimeOffset Optionally, the composition time offset (i.e. presentation timestamp minus decode
- * timestamp) to use for the video chunk. When not provided, it will be zero.
- */
- addVideoChunk(
- chunk: EncodedVideoChunk,
- meta?: EncodedVideoChunkMetadata,
- timestamp?: number,
- compositionTimeOffset?: number
- ): void;
- /**
- * Adds a new, encoded audio chunk to the MP4 file.
- * @param chunk The encoded audio chunk. Can be obtained through an `AudioEncoder`.
- * @param meta The metadata about the encoded audio, also provided by `AudioEncoder`.
- * @param timestamp Optionally, the timestamp to use for the audio chunk. When not provided, it will use the one
- * specified in `chunk`.
- */
- addAudioChunk(chunk: EncodedAudioChunk, meta?: EncodedAudioChunkMetadata, timestamp?: number): void;
-
- /**
- * Adds a raw video chunk to the MP4 file. This method should be used when the encoded video is not obtained
- * through a `VideoEncoder` but through some other means, where no instance of `EncodedVideoChunk`is available.
- * @param data The raw data of the video chunk.
- * @param type Whether the video chunk is a keyframe or delta frame.
- * @param timestamp The timestamp of the video chunk.
- * @param duration The duration of the video chunk.
- * @param meta Optionally, any encoder metadata.
- * @param compositionTimeOffset The composition time offset (i.e. presentation timestamp minus decode timestamp) of
- * the video chunk.
- */
- addVideoChunkRaw(
- data: Uint8Array,
- type: 'key' | 'delta',
- timestamp: number,
- duration: number,
- meta?: EncodedVideoChunkMetadata,
- compositionTimeOffset?: number
- ): void;
- /**
- * Adds a raw audio chunk to the MP4 file. This method should be used when the encoded audio is not obtained
- * through an `AudioEncoder` but through some other means, where no instance of `EncodedAudioChunk`is available.
- * @param data The raw data of the audio chunk.
- * @param type Whether the audio chunk is a keyframe or delta frame.
- * @param timestamp The timestamp of the audio chunk.
- * @param duration The duration of the audio chunk.
- * @param meta Optionally, any encoder metadata.
- */
- addAudioChunkRaw(
- data: Uint8Array,
- type: 'key' | 'delta',
- timestamp: number,
- duration: number,
- meta?: EncodedAudioChunkMetadata
- ): void;
-
- /**
- * Is to be called after all media chunks have been added to the muxer. Make sure to call and await the `flush`
- * method on your `VideoEncoder` and/or `AudioEncoder` before calling this method to ensure all encoding has
- * finished. This method will then finish up the writing process of the MP4 file.
- */
- finalize(): void;
-}
-
-declare global {
- let Mp4Muxer: typeof Mp4Muxer;
-}
-
-export {
- Muxer,
- MuxerOptions,
- ArrayBufferTarget,
- StreamTarget,
- FileSystemWritableFileStreamTarget,
- TransformationMatrix
-};
-export as namespace Mp4Muxer;
diff --git a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.js b/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.js
deleted file mode 100644
index 67b8c8d..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.js
+++ /dev/null
@@ -1,1718 +0,0 @@
-"use strict";
-var Mp4Muxer = (() => {
- var __defProp = Object.defineProperty;
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
- var __getOwnPropNames = Object.getOwnPropertyNames;
- var __hasOwnProp = Object.prototype.hasOwnProperty;
- var __export = (target, all) => {
- for (var name in all)
- __defProp(target, name, { get: all[name], enumerable: true });
- };
- var __copyProps = (to, from, except, desc) => {
- if (from && typeof from === "object" || typeof from === "function") {
- for (let key of __getOwnPropNames(from))
- if (!__hasOwnProp.call(to, key) && key !== except)
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
- }
- return to;
- };
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
- var __accessCheck = (obj, member, msg) => {
- if (!member.has(obj))
- throw TypeError("Cannot " + msg);
- };
- var __privateGet = (obj, member, getter) => {
- __accessCheck(obj, member, "read from private field");
- return getter ? getter.call(obj) : member.get(obj);
- };
- var __privateAdd = (obj, member, value) => {
- if (member.has(obj))
- throw TypeError("Cannot add the same private member more than once");
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
- };
- var __privateSet = (obj, member, value, setter) => {
- __accessCheck(obj, member, "write to private field");
- setter ? setter.call(obj, value) : member.set(obj, value);
- return value;
- };
- var __privateWrapper = (obj, member, setter, getter) => ({
- set _(value) {
- __privateSet(obj, member, value, setter);
- },
- get _() {
- return __privateGet(obj, member, getter);
- }
- });
- var __privateMethod = (obj, member, method) => {
- __accessCheck(obj, member, "access private method");
- return method;
- };
-
- // src/index.ts
- var src_exports = {};
- __export(src_exports, {
- ArrayBufferTarget: () => ArrayBufferTarget,
- FileSystemWritableFileStreamTarget: () => FileSystemWritableFileStreamTarget,
- Muxer: () => Muxer,
- StreamTarget: () => StreamTarget
- });
-
- // src/misc.ts
- var bytes = new Uint8Array(8);
- var view = new DataView(bytes.buffer);
- var u8 = (value) => {
- return [(value % 256 + 256) % 256];
- };
- var u16 = (value) => {
- view.setUint16(0, value, false);
- return [bytes[0], bytes[1]];
- };
- var i16 = (value) => {
- view.setInt16(0, value, false);
- return [bytes[0], bytes[1]];
- };
- var u24 = (value) => {
- view.setUint32(0, value, false);
- return [bytes[1], bytes[2], bytes[3]];
- };
- var u32 = (value) => {
- view.setUint32(0, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
- };
- var i32 = (value) => {
- view.setInt32(0, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
- };
- var u64 = (value) => {
- view.setUint32(0, Math.floor(value / 2 ** 32), false);
- view.setUint32(4, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];
- };
- var fixed_8_8 = (value) => {
- view.setInt16(0, 2 ** 8 * value, false);
- return [bytes[0], bytes[1]];
- };
- var fixed_16_16 = (value) => {
- view.setInt32(0, 2 ** 16 * value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
- };
- var fixed_2_30 = (value) => {
- view.setInt32(0, 2 ** 30 * value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
- };
- var ascii = (text, nullTerminated = false) => {
- let bytes2 = Array(text.length).fill(null).map((_, i) => text.charCodeAt(i));
- if (nullTerminated)
- bytes2.push(0);
- return bytes2;
- };
- var last = (arr) => {
- return arr && arr[arr.length - 1];
- };
- var lastPresentedSample = (samples) => {
- let result = void 0;
- for (let sample of samples) {
- if (!result || sample.presentationTimestamp > result.presentationTimestamp) {
- result = sample;
- }
- }
- return result;
- };
- var intoTimescale = (timeInSeconds, timescale, round = true) => {
- let value = timeInSeconds * timescale;
- return round ? Math.round(value) : value;
- };
- var rotationMatrix = (rotationInDegrees) => {
- let theta = rotationInDegrees * (Math.PI / 180);
- let cosTheta = Math.cos(theta);
- let sinTheta = Math.sin(theta);
- return [
- cosTheta,
- sinTheta,
- 0,
- -sinTheta,
- cosTheta,
- 0,
- 0,
- 0,
- 1
- ];
- };
- var IDENTITY_MATRIX = rotationMatrix(0);
- var matrixToBytes = (matrix) => {
- return [
- fixed_16_16(matrix[0]),
- fixed_16_16(matrix[1]),
- fixed_2_30(matrix[2]),
- fixed_16_16(matrix[3]),
- fixed_16_16(matrix[4]),
- fixed_2_30(matrix[5]),
- fixed_16_16(matrix[6]),
- fixed_16_16(matrix[7]),
- fixed_2_30(matrix[8])
- ];
- };
- var deepClone = (x) => {
- if (!x)
- return x;
- if (typeof x !== "object")
- return x;
- if (Array.isArray(x))
- return x.map(deepClone);
- return Object.fromEntries(Object.entries(x).map(([key, value]) => [key, deepClone(value)]));
- };
- var isU32 = (value) => {
- return value >= 0 && value < 2 ** 32;
- };
-
- // src/box.ts
- var box = (type, contents, children) => ({
- type,
- contents: contents && new Uint8Array(contents.flat(10)),
- children
- });
- var fullBox = (type, version, flags, contents, children) => box(
- type,
- [u8(version), u24(flags), contents ?? []],
- children
- );
- var ftyp = (details) => {
- let minorVersion = 512;
- if (details.fragmented)
- return box("ftyp", [
- ascii("iso5"),
- // Major brand
- u32(minorVersion),
- // Minor version
- // Compatible brands
- ascii("iso5"),
- ascii("iso6"),
- ascii("mp41")
- ]);
- return box("ftyp", [
- ascii("isom"),
- // Major brand
- u32(minorVersion),
- // Minor version
- // Compatible brands
- ascii("isom"),
- details.holdsAvc ? ascii("avc1") : [],
- ascii("mp41")
- ]);
- };
- var mdat = (reserveLargeSize) => ({ type: "mdat", largeSize: reserveLargeSize });
- var free = (size) => ({ type: "free", size });
- var moov = (tracks, creationTime, fragmented = false) => box("moov", null, [
- mvhd(creationTime, tracks),
- ...tracks.map((x) => trak(x, creationTime)),
- fragmented ? mvex(tracks) : null
- ]);
- var mvhd = (creationTime, tracks) => {
- let duration = intoTimescale(Math.max(
- 0,
- ...tracks.filter((x) => x.samples.length > 0).map((x) => {
- const lastSample = lastPresentedSample(x.samples);
- return lastSample.presentationTimestamp + lastSample.duration;
- })
- ), GLOBAL_TIMESCALE);
- let nextTrackId = Math.max(...tracks.map((x) => x.id)) + 1;
- let needsU64 = !isU32(creationTime) || !isU32(duration);
- let u32OrU64 = needsU64 ? u64 : u32;
- return fullBox("mvhd", +needsU64, 0, [
- u32OrU64(creationTime),
- // Creation time
- u32OrU64(creationTime),
- // Modification time
- u32(GLOBAL_TIMESCALE),
- // Timescale
- u32OrU64(duration),
- // Duration
- fixed_16_16(1),
- // Preferred rate
- fixed_8_8(1),
- // Preferred volume
- Array(10).fill(0),
- // Reserved
- matrixToBytes(IDENTITY_MATRIX),
- // Matrix
- Array(24).fill(0),
- // Pre-defined
- u32(nextTrackId)
- // Next track ID
- ]);
- };
- var trak = (track, creationTime) => box("trak", null, [
- tkhd(track, creationTime),
- mdia(track, creationTime)
- ]);
- var tkhd = (track, creationTime) => {
- let lastSample = lastPresentedSample(track.samples);
- let durationInGlobalTimescale = intoTimescale(
- lastSample ? lastSample.presentationTimestamp + lastSample.duration : 0,
- GLOBAL_TIMESCALE
- );
- let needsU64 = !isU32(creationTime) || !isU32(durationInGlobalTimescale);
- let u32OrU64 = needsU64 ? u64 : u32;
- let matrix;
- if (track.info.type === "video") {
- matrix = typeof track.info.rotation === "number" ? rotationMatrix(track.info.rotation) : track.info.rotation;
- } else {
- matrix = IDENTITY_MATRIX;
- }
- return fullBox("tkhd", +needsU64, 3, [
- u32OrU64(creationTime),
- // Creation time
- u32OrU64(creationTime),
- // Modification time
- u32(track.id),
- // Track ID
- u32(0),
- // Reserved
- u32OrU64(durationInGlobalTimescale),
- // Duration
- Array(8).fill(0),
- // Reserved
- u16(0),
- // Layer
- u16(0),
- // Alternate group
- fixed_8_8(track.info.type === "audio" ? 1 : 0),
- // Volume
- u16(0),
- // Reserved
- matrixToBytes(matrix),
- // Matrix
- fixed_16_16(track.info.type === "video" ? track.info.width : 0),
- // Track width
- fixed_16_16(track.info.type === "video" ? track.info.height : 0)
- // Track height
- ]);
- };
- var mdia = (track, creationTime) => box("mdia", null, [
- mdhd(track, creationTime),
- hdlr(track.info.type === "video" ? "vide" : "soun"),
- minf(track)
- ]);
- var mdhd = (track, creationTime) => {
- let lastSample = lastPresentedSample(track.samples);
- let localDuration = intoTimescale(
- lastSample ? lastSample.presentationTimestamp + lastSample.duration : 0,
- track.timescale
- );
- let needsU64 = !isU32(creationTime) || !isU32(localDuration);
- let u32OrU64 = needsU64 ? u64 : u32;
- return fullBox("mdhd", +needsU64, 0, [
- u32OrU64(creationTime),
- // Creation time
- u32OrU64(creationTime),
- // Modification time
- u32(track.timescale),
- // Timescale
- u32OrU64(localDuration),
- // Duration
- u16(21956),
- // Language ("und", undetermined)
- u16(0)
- // Quality
- ]);
- };
- var hdlr = (componentSubtype) => fullBox("hdlr", 0, 0, [
- ascii("mhlr"),
- // Component type
- ascii(componentSubtype),
- // Component subtype
- u32(0),
- // Component manufacturer
- u32(0),
- // Component flags
- u32(0),
- // Component flags mask
- ascii("mp4-muxer-hdlr", true)
- // Component name
- ]);
- var minf = (track) => box("minf", null, [
- track.info.type === "video" ? vmhd() : smhd(),
- dinf(),
- stbl(track)
- ]);
- var vmhd = () => fullBox("vmhd", 0, 1, [
- u16(0),
- // Graphics mode
- u16(0),
- // Opcolor R
- u16(0),
- // Opcolor G
- u16(0)
- // Opcolor B
- ]);
- var smhd = () => fullBox("smhd", 0, 0, [
- u16(0),
- // Balance
- u16(0)
- // Reserved
- ]);
- var dinf = () => box("dinf", null, [
- dref()
- ]);
- var dref = () => fullBox("dref", 0, 0, [
- u32(1)
- // Entry count
- ], [
- url()
- ]);
- var url = () => fullBox("url ", 0, 1);
- var stbl = (track) => {
- const needsCtts = track.compositionTimeOffsetTable.length > 1 || track.compositionTimeOffsetTable.some((x) => x.sampleCompositionTimeOffset !== 0);
- return box("stbl", null, [
- stsd(track),
- stts(track),
- stss(track),
- stsc(track),
- stsz(track),
- stco(track),
- needsCtts ? ctts(track) : null
- ]);
- };
- var stsd = (track) => fullBox("stsd", 0, 0, [
- u32(1)
- // Entry count
- ], [
- track.info.type === "video" ? videoSampleDescription(
- VIDEO_CODEC_TO_BOX_NAME[track.info.codec],
- track
- ) : soundSampleDescription(
- AUDIO_CODEC_TO_BOX_NAME[track.info.codec],
- track
- )
- ]);
- var videoSampleDescription = (compressionType, track) => box(compressionType, [
- Array(6).fill(0),
- // Reserved
- u16(1),
- // Data reference index
- u16(0),
- // Pre-defined
- u16(0),
- // Reserved
- Array(12).fill(0),
- // Pre-defined
- u16(track.info.width),
- // Width
- u16(track.info.height),
- // Height
- u32(4718592),
- // Horizontal resolution
- u32(4718592),
- // Vertical resolution
- u32(0),
- // Reserved
- u16(1),
- // Frame count
- Array(32).fill(0),
- // Compressor name
- u16(24),
- // Depth
- i16(65535)
- // Pre-defined
- ], [
- VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track)
- ]);
- var avcC = (track) => track.info.decoderConfig && box("avcC", [
- // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here
- ...new Uint8Array(track.info.decoderConfig.description)
- ]);
- var hvcC = (track) => track.info.decoderConfig && box("hvcC", [
- // For HEVC, description is a HEVCDecoderConfigurationRecord, so nothing else to do here
- ...new Uint8Array(track.info.decoderConfig.description)
- ]);
- var vpcC = (track) => {
- if (!track.info.decoderConfig) {
- return null;
- }
- let decoderConfig = track.info.decoderConfig;
- if (!decoderConfig.colorSpace) {
- throw new Error(`'colorSpace' is required in the decoder config for VP9.`);
- }
- let parts = decoderConfig.codec.split(".");
- let profile = Number(parts[1]);
- let level = Number(parts[2]);
- let bitDepth = Number(parts[3]);
- let chromaSubsampling = 0;
- let thirdByte = (bitDepth << 4) + (chromaSubsampling << 1) + Number(decoderConfig.colorSpace.fullRange);
- let colourPrimaries = 2;
- let transferCharacteristics = 2;
- let matrixCoefficients = 2;
- return fullBox("vpcC", 1, 0, [
- u8(profile),
- // Profile
- u8(level),
- // Level
- u8(thirdByte),
- // Bit depth, chroma subsampling, full range
- u8(colourPrimaries),
- // Colour primaries
- u8(transferCharacteristics),
- // Transfer characteristics
- u8(matrixCoefficients),
- // Matrix coefficients
- u16(0)
- // Codec initialization data size
- ]);
- };
- var av1C = () => {
- let marker = 1;
- let version = 1;
- let firstByte = (marker << 7) + version;
- return box("av1C", [
- firstByte,
- 0,
- 0,
- 0
- ]);
- };
- var soundSampleDescription = (compressionType, track) => box(compressionType, [
- Array(6).fill(0),
- // Reserved
- u16(1),
- // Data reference index
- u16(0),
- // Version
- u16(0),
- // Revision level
- u32(0),
- // Vendor
- u16(track.info.numberOfChannels),
- // Number of channels
- u16(16),
- // Sample size (bits)
- u16(0),
- // Compression ID
- u16(0),
- // Packet size
- fixed_16_16(track.info.sampleRate)
- // Sample rate
- ], [
- AUDIO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track)
- ]);
- var esds = (track) => {
- let description = new Uint8Array(track.info.decoderConfig.description);
- return fullBox("esds", 0, 0, [
- // https://stackoverflow.com/a/54803118
- u32(58753152),
- // TAG(3) = Object Descriptor ([2])
- u8(32 + description.byteLength),
- // length of this OD (which includes the next 2 tags)
- u16(1),
- // ES_ID = 1
- u8(0),
- // flags etc = 0
- u32(75530368),
- // TAG(4) = ES Descriptor ([2]) embedded in above OD
- u8(18 + description.byteLength),
- // length of this ESD
- u8(64),
- // MPEG-4 Audio
- u8(21),
- // stream type(6bits)=5 audio, flags(2bits)=1
- u24(0),
- // 24bit buffer size
- u32(130071),
- // max bitrate
- u32(130071),
- // avg bitrate
- u32(92307584),
- // TAG(5) = ASC ([2],[3]) embedded in above OD
- u8(description.byteLength),
- // length
- ...description,
- u32(109084800),
- // TAG(6)
- u8(1),
- // length
- u8(2)
- // data
- ]);
- };
- var dOps = (track) => box("dOps", [
- u8(0),
- // Version
- u8(track.info.numberOfChannels),
- // OutputChannelCount
- u16(3840),
- // PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples
- u32(track.info.sampleRate),
- // InputSampleRate
- fixed_8_8(0),
- // OutputGain
- u8(0)
- // ChannelMappingFamily
- ]);
- var stts = (track) => {
- return fullBox("stts", 0, 0, [
- u32(track.timeToSampleTable.length),
- // Number of entries
- track.timeToSampleTable.map((x) => [
- // Time-to-sample table
- u32(x.sampleCount),
- // Sample count
- u32(x.sampleDelta)
- // Sample duration
- ])
- ]);
- };
- var stss = (track) => {
- if (track.samples.every((x) => x.type === "key"))
- return null;
- let keySamples = [...track.samples.entries()].filter(([, sample]) => sample.type === "key");
- return fullBox("stss", 0, 0, [
- u32(keySamples.length),
- // Number of entries
- keySamples.map(([index]) => u32(index + 1))
- // Sync sample table
- ]);
- };
- var stsc = (track) => {
- return fullBox("stsc", 0, 0, [
- u32(track.compactlyCodedChunkTable.length),
- // Number of entries
- track.compactlyCodedChunkTable.map((x) => [
- // Sample-to-chunk table
- u32(x.firstChunk),
- // First chunk
- u32(x.samplesPerChunk),
- // Samples per chunk
- u32(1)
- // Sample description index
- ])
- ]);
- };
- var stsz = (track) => fullBox("stsz", 0, 0, [
- u32(0),
- // Sample size (0 means non-constant size)
- u32(track.samples.length),
- // Number of entries
- track.samples.map((x) => u32(x.size))
- // Sample size table
- ]);
- var stco = (track) => {
- if (track.finalizedChunks.length > 0 && last(track.finalizedChunks).offset >= 2 ** 32) {
- return fullBox("co64", 0, 0, [
- u32(track.finalizedChunks.length),
- // Number of entries
- track.finalizedChunks.map((x) => u64(x.offset))
- // Chunk offset table
- ]);
- }
- return fullBox("stco", 0, 0, [
- u32(track.finalizedChunks.length),
- // Number of entries
- track.finalizedChunks.map((x) => u32(x.offset))
- // Chunk offset table
- ]);
- };
- var ctts = (track) => {
- return fullBox("ctts", 0, 0, [
- u32(track.compositionTimeOffsetTable.length),
- // Number of entries
- track.compositionTimeOffsetTable.map((x) => [
- // Time-to-sample table
- u32(x.sampleCount),
- // Sample count
- u32(x.sampleCompositionTimeOffset)
- // Sample offset
- ])
- ]);
- };
- var mvex = (tracks) => {
- return box("mvex", null, tracks.map(trex));
- };
- var trex = (track) => {
- return fullBox("trex", 0, 0, [
- u32(track.id),
- // Track ID
- u32(1),
- // Default sample description index
- u32(0),
- // Default sample duration
- u32(0),
- // Default sample size
- u32(0)
- // Default sample flags
- ]);
- };
- var moof = (sequenceNumber, tracks) => {
- return box("moof", null, [
- mfhd(sequenceNumber),
- ...tracks.map(traf)
- ]);
- };
- var mfhd = (sequenceNumber) => {
- return fullBox("mfhd", 0, 0, [
- u32(sequenceNumber)
- // Sequence number
- ]);
- };
- var fragmentSampleFlags = (sample) => {
- let byte1 = 0;
- let byte2 = 0;
- let byte3 = 0;
- let byte4 = 0;
- let sampleIsDifferenceSample = sample.type === "delta";
- byte2 |= +sampleIsDifferenceSample;
- if (sampleIsDifferenceSample) {
- byte1 |= 1;
- } else {
- byte1 |= 2;
- }
- return byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
- };
- var traf = (track) => {
- return box("traf", null, [
- tfhd(track),
- tfdt(track),
- trun(track)
- ]);
- };
- var tfhd = (track) => {
- let tfFlags = 0;
- tfFlags |= 8;
- tfFlags |= 16;
- tfFlags |= 32;
- tfFlags |= 131072;
- let referenceSample = track.currentChunk.samples[1] ?? track.currentChunk.samples[0];
- let referenceSampleInfo = {
- duration: referenceSample.timescaleUnitsToNextSample,
- size: referenceSample.size,
- flags: fragmentSampleFlags(referenceSample)
- };
- return fullBox("tfhd", 0, tfFlags, [
- u32(track.id),
- // Track ID
- u32(referenceSampleInfo.duration),
- // Default sample duration
- u32(referenceSampleInfo.size),
- // Default sample size
- u32(referenceSampleInfo.flags)
- // Default sample flags
- ]);
- };
- var tfdt = (track) => {
- return fullBox("tfdt", 1, 0, [
- u64(intoTimescale(track.currentChunk.startTimestamp, track.timescale))
- // Base Media Decode Time
- ]);
- };
- var trun = (track) => {
- let allSampleDurations = track.currentChunk.samples.map((x) => x.timescaleUnitsToNextSample);
- let allSampleSizes = track.currentChunk.samples.map((x) => x.size);
- let allSampleFlags = track.currentChunk.samples.map(fragmentSampleFlags);
- let allSampleCompositionTimeOffsets = track.currentChunk.samples.map((x) => intoTimescale(x.presentationTimestamp - x.decodeTimestamp, track.timescale));
- let uniqueSampleDurations = new Set(allSampleDurations);
- let uniqueSampleSizes = new Set(allSampleSizes);
- let uniqueSampleFlags = new Set(allSampleFlags);
- let uniqueSampleCompositionTimeOffsets = new Set(allSampleCompositionTimeOffsets);
- let firstSampleFlagsPresent = uniqueSampleFlags.size === 2 && allSampleFlags[0] !== allSampleFlags[1];
- let sampleDurationPresent = uniqueSampleDurations.size > 1;
- let sampleSizePresent = uniqueSampleSizes.size > 1;
- let sampleFlagsPresent = !firstSampleFlagsPresent && uniqueSampleFlags.size > 1;
- let sampleCompositionTimeOffsetsPresent = uniqueSampleCompositionTimeOffsets.size > 1 || [...uniqueSampleCompositionTimeOffsets].some((x) => x !== 0);
- let flags = 0;
- flags |= 1;
- flags |= 4 * +firstSampleFlagsPresent;
- flags |= 256 * +sampleDurationPresent;
- flags |= 512 * +sampleSizePresent;
- flags |= 1024 * +sampleFlagsPresent;
- flags |= 2048 * +sampleCompositionTimeOffsetsPresent;
- return fullBox("trun", 1, flags, [
- u32(track.currentChunk.samples.length),
- // Sample count
- u32(track.currentChunk.offset - track.currentChunk.moofOffset || 0),
- // Data offset
- firstSampleFlagsPresent ? u32(allSampleFlags[0]) : [],
- track.currentChunk.samples.map((_, i) => [
- sampleDurationPresent ? u32(allSampleDurations[i]) : [],
- // Sample duration
- sampleSizePresent ? u32(allSampleSizes[i]) : [],
- // Sample size
- sampleFlagsPresent ? u32(allSampleFlags[i]) : [],
- // Sample flags
- // Sample composition time offsets
- sampleCompositionTimeOffsetsPresent ? i32(allSampleCompositionTimeOffsets[i]) : []
- ])
- ]);
- };
- var mfra = (tracks) => {
- return box("mfra", null, [
- ...tracks.map(tfra),
- mfro()
- ]);
- };
- var tfra = (track, trackIndex) => {
- let version = 1;
- return fullBox("tfra", version, 0, [
- u32(track.id),
- // Track ID
- u32(63),
- // This specifies that traf number, trun number and sample number are 32-bit ints
- u32(track.finalizedChunks.length),
- // Number of entries
- track.finalizedChunks.map((chunk) => [
- u64(intoTimescale(chunk.startTimestamp, track.timescale)),
- // Time
- u64(chunk.moofOffset),
- // moof offset
- u32(trackIndex + 1),
- // traf number
- u32(1),
- // trun number
- u32(1)
- // Sample number
- ])
- ]);
- };
- var mfro = () => {
- return fullBox("mfro", 0, 0, [
- // This value needs to be overwritten manually from the outside, where the actual size of the enclosing mfra box
- // is known
- u32(0)
- // Size
- ]);
- };
- var VIDEO_CODEC_TO_BOX_NAME = {
- "avc": "avc1",
- "hevc": "hvc1",
- "vp9": "vp09",
- "av1": "av01"
- };
- var VIDEO_CODEC_TO_CONFIGURATION_BOX = {
- "avc": avcC,
- "hevc": hvcC,
- "vp9": vpcC,
- "av1": av1C
- };
- var AUDIO_CODEC_TO_BOX_NAME = {
- "aac": "mp4a",
- "opus": "Opus"
- };
- var AUDIO_CODEC_TO_CONFIGURATION_BOX = {
- "aac": esds,
- "opus": dOps
- };
-
- // src/target.ts
- var ArrayBufferTarget = class {
- constructor() {
- this.buffer = null;
- }
- };
- var StreamTarget = class {
- constructor(options) {
- this.options = options;
- }
- };
- var FileSystemWritableFileStreamTarget = class {
- constructor(stream, options) {
- this.stream = stream;
- this.options = options;
- }
- };
-
- // src/writer.ts
- var _helper, _helperView;
- var Writer = class {
- constructor() {
- this.pos = 0;
- __privateAdd(this, _helper, new Uint8Array(8));
- __privateAdd(this, _helperView, new DataView(__privateGet(this, _helper).buffer));
- /**
- * Stores the position from the start of the file to where boxes elements have been written. This is used to
- * rewrite/edit elements that were already added before, and to measure sizes of things.
- */
- this.offsets = /* @__PURE__ */ new WeakMap();
- }
- /** Sets the current position for future writes to a new one. */
- seek(newPos) {
- this.pos = newPos;
- }
- writeU32(value) {
- __privateGet(this, _helperView).setUint32(0, value, false);
- this.write(__privateGet(this, _helper).subarray(0, 4));
- }
- writeU64(value) {
- __privateGet(this, _helperView).setUint32(0, Math.floor(value / 2 ** 32), false);
- __privateGet(this, _helperView).setUint32(4, value, false);
- this.write(__privateGet(this, _helper).subarray(0, 8));
- }
- writeAscii(text) {
- for (let i = 0; i < text.length; i++) {
- __privateGet(this, _helperView).setUint8(i % 8, text.charCodeAt(i));
- if (i % 8 === 7)
- this.write(__privateGet(this, _helper));
- }
- if (text.length % 8 !== 0) {
- this.write(__privateGet(this, _helper).subarray(0, text.length % 8));
- }
- }
- writeBox(box2) {
- this.offsets.set(box2, this.pos);
- if (box2.contents && !box2.children) {
- this.writeBoxHeader(box2, box2.size ?? box2.contents.byteLength + 8);
- this.write(box2.contents);
- } else {
- let startPos = this.pos;
- this.writeBoxHeader(box2, 0);
- if (box2.contents)
- this.write(box2.contents);
- if (box2.children) {
- for (let child of box2.children)
- if (child)
- this.writeBox(child);
- }
- let endPos = this.pos;
- let size = box2.size ?? endPos - startPos;
- this.seek(startPos);
- this.writeBoxHeader(box2, size);
- this.seek(endPos);
- }
- }
- writeBoxHeader(box2, size) {
- this.writeU32(box2.largeSize ? 1 : size);
- this.writeAscii(box2.type);
- if (box2.largeSize)
- this.writeU64(size);
- }
- measureBoxHeader(box2) {
- return 8 + (box2.largeSize ? 8 : 0);
- }
- patchBox(box2) {
- let endPos = this.pos;
- this.seek(this.offsets.get(box2));
- this.writeBox(box2);
- this.seek(endPos);
- }
- measureBox(box2) {
- if (box2.contents && !box2.children) {
- let headerSize = this.measureBoxHeader(box2);
- return headerSize + box2.contents.byteLength;
- } else {
- let result = this.measureBoxHeader(box2);
- if (box2.contents)
- result += box2.contents.byteLength;
- if (box2.children) {
- for (let child of box2.children)
- if (child)
- result += this.measureBox(child);
- }
- return result;
- }
- }
- };
- _helper = new WeakMap();
- _helperView = new WeakMap();
- var _target, _buffer, _bytes, _maxPos, _ensureSize, ensureSize_fn;
- var ArrayBufferTargetWriter = class extends Writer {
- constructor(target) {
- super();
- __privateAdd(this, _ensureSize);
- __privateAdd(this, _target, void 0);
- __privateAdd(this, _buffer, new ArrayBuffer(2 ** 16));
- __privateAdd(this, _bytes, new Uint8Array(__privateGet(this, _buffer)));
- __privateAdd(this, _maxPos, 0);
- __privateSet(this, _target, target);
- }
- write(data) {
- __privateMethod(this, _ensureSize, ensureSize_fn).call(this, this.pos + data.byteLength);
- __privateGet(this, _bytes).set(data, this.pos);
- this.pos += data.byteLength;
- __privateSet(this, _maxPos, Math.max(__privateGet(this, _maxPos), this.pos));
- }
- finalize() {
- __privateMethod(this, _ensureSize, ensureSize_fn).call(this, this.pos);
- __privateGet(this, _target).buffer = __privateGet(this, _buffer).slice(0, Math.max(__privateGet(this, _maxPos), this.pos));
- }
- };
- _target = new WeakMap();
- _buffer = new WeakMap();
- _bytes = new WeakMap();
- _maxPos = new WeakMap();
- _ensureSize = new WeakSet();
- ensureSize_fn = function(size) {
- let newLength = __privateGet(this, _buffer).byteLength;
- while (newLength < size)
- newLength *= 2;
- if (newLength === __privateGet(this, _buffer).byteLength)
- return;
- let newBuffer = new ArrayBuffer(newLength);
- let newBytes = new Uint8Array(newBuffer);
- newBytes.set(__privateGet(this, _bytes), 0);
- __privateSet(this, _buffer, newBuffer);
- __privateSet(this, _bytes, newBytes);
- };
- var _target2, _sections;
- var StreamTargetWriter = class extends Writer {
- constructor(target) {
- super();
- __privateAdd(this, _target2, void 0);
- __privateAdd(this, _sections, []);
- __privateSet(this, _target2, target);
- }
- write(data) {
- __privateGet(this, _sections).push({
- data: data.slice(),
- start: this.pos
- });
- this.pos += data.byteLength;
- }
- flush() {
- if (__privateGet(this, _sections).length === 0)
- return;
- let chunks = [];
- let sorted = [...__privateGet(this, _sections)].sort((a, b) => a.start - b.start);
- chunks.push({
- start: sorted[0].start,
- size: sorted[0].data.byteLength
- });
- for (let i = 1; i < sorted.length; i++) {
- let lastChunk = chunks[chunks.length - 1];
- let section = sorted[i];
- if (section.start <= lastChunk.start + lastChunk.size) {
- lastChunk.size = Math.max(lastChunk.size, section.start + section.data.byteLength - lastChunk.start);
- } else {
- chunks.push({
- start: section.start,
- size: section.data.byteLength
- });
- }
- }
- for (let chunk of chunks) {
- chunk.data = new Uint8Array(chunk.size);
- for (let section of __privateGet(this, _sections)) {
- if (chunk.start <= section.start && section.start < chunk.start + chunk.size) {
- chunk.data.set(section.data, section.start - chunk.start);
- }
- }
- __privateGet(this, _target2).options.onData?.(chunk.data, chunk.start);
- }
- __privateGet(this, _sections).length = 0;
- }
- finalize() {
- }
- };
- _target2 = new WeakMap();
- _sections = new WeakMap();
- var DEFAULT_CHUNK_SIZE = 2 ** 24;
- var MAX_CHUNKS_AT_ONCE = 2;
- var _target3, _chunkSize, _chunks, _writeDataIntoChunks, writeDataIntoChunks_fn, _insertSectionIntoChunk, insertSectionIntoChunk_fn, _createChunk, createChunk_fn, _flushChunks, flushChunks_fn;
- var ChunkedStreamTargetWriter = class extends Writer {
- constructor(target) {
- super();
- __privateAdd(this, _writeDataIntoChunks);
- __privateAdd(this, _insertSectionIntoChunk);
- __privateAdd(this, _createChunk);
- __privateAdd(this, _flushChunks);
- __privateAdd(this, _target3, void 0);
- __privateAdd(this, _chunkSize, void 0);
- /**
- * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out.
- * A chunk is flushed if all of its contents have been written.
- */
- __privateAdd(this, _chunks, []);
- __privateSet(this, _target3, target);
- __privateSet(this, _chunkSize, target.options?.chunkSize ?? DEFAULT_CHUNK_SIZE);
- if (!Number.isInteger(__privateGet(this, _chunkSize)) || __privateGet(this, _chunkSize) < 2 ** 10) {
- throw new Error("Invalid StreamTarget options: chunkSize must be an integer not smaller than 1024.");
- }
- }
- write(data) {
- __privateMethod(this, _writeDataIntoChunks, writeDataIntoChunks_fn).call(this, data, this.pos);
- __privateMethod(this, _flushChunks, flushChunks_fn).call(this);
- this.pos += data.byteLength;
- }
- finalize() {
- __privateMethod(this, _flushChunks, flushChunks_fn).call(this, true);
- }
- };
- _target3 = new WeakMap();
- _chunkSize = new WeakMap();
- _chunks = new WeakMap();
- _writeDataIntoChunks = new WeakSet();
- writeDataIntoChunks_fn = function(data, position) {
- let chunkIndex = __privateGet(this, _chunks).findIndex((x) => x.start <= position && position < x.start + __privateGet(this, _chunkSize));
- if (chunkIndex === -1)
- chunkIndex = __privateMethod(this, _createChunk, createChunk_fn).call(this, position);
- let chunk = __privateGet(this, _chunks)[chunkIndex];
- let relativePosition = position - chunk.start;
- let toWrite = data.subarray(0, Math.min(__privateGet(this, _chunkSize) - relativePosition, data.byteLength));
- chunk.data.set(toWrite, relativePosition);
- let section = {
- start: relativePosition,
- end: relativePosition + toWrite.byteLength
- };
- __privateMethod(this, _insertSectionIntoChunk, insertSectionIntoChunk_fn).call(this, chunk, section);
- if (chunk.written[0].start === 0 && chunk.written[0].end === __privateGet(this, _chunkSize)) {
- chunk.shouldFlush = true;
- }
- if (__privateGet(this, _chunks).length > MAX_CHUNKS_AT_ONCE) {
- for (let i = 0; i < __privateGet(this, _chunks).length - 1; i++) {
- __privateGet(this, _chunks)[i].shouldFlush = true;
- }
- __privateMethod(this, _flushChunks, flushChunks_fn).call(this);
- }
- if (toWrite.byteLength < data.byteLength) {
- __privateMethod(this, _writeDataIntoChunks, writeDataIntoChunks_fn).call(this, data.subarray(toWrite.byteLength), position + toWrite.byteLength);
- }
- };
- _insertSectionIntoChunk = new WeakSet();
- insertSectionIntoChunk_fn = function(chunk, section) {
- let low = 0;
- let high = chunk.written.length - 1;
- let index = -1;
- while (low <= high) {
- let mid = Math.floor(low + (high - low + 1) / 2);
- if (chunk.written[mid].start <= section.start) {
- low = mid + 1;
- index = mid;
- } else {
- high = mid - 1;
- }
- }
- chunk.written.splice(index + 1, 0, section);
- if (index === -1 || chunk.written[index].end < section.start)
- index++;
- while (index < chunk.written.length - 1 && chunk.written[index].end >= chunk.written[index + 1].start) {
- chunk.written[index].end = Math.max(chunk.written[index].end, chunk.written[index + 1].end);
- chunk.written.splice(index + 1, 1);
- }
- };
- _createChunk = new WeakSet();
- createChunk_fn = function(includesPosition) {
- let start = Math.floor(includesPosition / __privateGet(this, _chunkSize)) * __privateGet(this, _chunkSize);
- let chunk = {
- start,
- data: new Uint8Array(__privateGet(this, _chunkSize)),
- written: [],
- shouldFlush: false
- };
- __privateGet(this, _chunks).push(chunk);
- __privateGet(this, _chunks).sort((a, b) => a.start - b.start);
- return __privateGet(this, _chunks).indexOf(chunk);
- };
- _flushChunks = new WeakSet();
- flushChunks_fn = function(force = false) {
- for (let i = 0; i < __privateGet(this, _chunks).length; i++) {
- let chunk = __privateGet(this, _chunks)[i];
- if (!chunk.shouldFlush && !force)
- continue;
- for (let section of chunk.written) {
- __privateGet(this, _target3).options.onData?.(
- chunk.data.subarray(section.start, section.end),
- chunk.start + section.start
- );
- }
- __privateGet(this, _chunks).splice(i--, 1);
- }
- };
- var FileSystemWritableFileStreamTargetWriter = class extends ChunkedStreamTargetWriter {
- constructor(target) {
- super(new StreamTarget({
- onData: (data, position) => target.stream.write({
- type: "write",
- data,
- position
- }),
- chunkSize: target.options?.chunkSize
- }));
- }
- };
-
- // src/muxer.ts
- var GLOBAL_TIMESCALE = 1e3;
- var SUPPORTED_VIDEO_CODECS2 = ["avc", "hevc", "vp9", "av1"];
- var SUPPORTED_AUDIO_CODECS2 = ["aac", "opus"];
- var TIMESTAMP_OFFSET = 2082844800;
- var FIRST_TIMESTAMP_BEHAVIORS = ["strict", "offset", "cross-track-offset"];
- var _options, _writer, _ftypSize, _mdat, _videoTrack, _audioTrack, _creationTime, _finalizedChunks, _nextFragmentNumber, _videoSampleQueue, _audioSampleQueue, _finalized, _validateOptions, validateOptions_fn, _writeHeader, writeHeader_fn, _computeMoovSizeUpperBound, computeMoovSizeUpperBound_fn, _prepareTracks, prepareTracks_fn, _generateMpeg4AudioSpecificConfig, generateMpeg4AudioSpecificConfig_fn, _createSampleForTrack, createSampleForTrack_fn, _addSampleToTrack, addSampleToTrack_fn, _validateTimestamp, validateTimestamp_fn, _finalizeCurrentChunk, finalizeCurrentChunk_fn, _finalizeFragment, finalizeFragment_fn, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn, _ensureNotFinalized, ensureNotFinalized_fn;
- var Muxer = class {
- constructor(options) {
- __privateAdd(this, _validateOptions);
- __privateAdd(this, _writeHeader);
- __privateAdd(this, _computeMoovSizeUpperBound);
- __privateAdd(this, _prepareTracks);
- // https://wiki.multimedia.cx/index.php/MPEG-4_Audio
- __privateAdd(this, _generateMpeg4AudioSpecificConfig);
- __privateAdd(this, _createSampleForTrack);
- __privateAdd(this, _addSampleToTrack);
- __privateAdd(this, _validateTimestamp);
- __privateAdd(this, _finalizeCurrentChunk);
- __privateAdd(this, _finalizeFragment);
- __privateAdd(this, _maybeFlushStreamingTargetWriter);
- __privateAdd(this, _ensureNotFinalized);
- __privateAdd(this, _options, void 0);
- __privateAdd(this, _writer, void 0);
- __privateAdd(this, _ftypSize, void 0);
- __privateAdd(this, _mdat, void 0);
- __privateAdd(this, _videoTrack, null);
- __privateAdd(this, _audioTrack, null);
- __privateAdd(this, _creationTime, Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET);
- __privateAdd(this, _finalizedChunks, []);
- // Fields for fragmented MP4:
- __privateAdd(this, _nextFragmentNumber, 1);
- __privateAdd(this, _videoSampleQueue, []);
- __privateAdd(this, _audioSampleQueue, []);
- __privateAdd(this, _finalized, false);
- __privateMethod(this, _validateOptions, validateOptions_fn).call(this, options);
- options.video = deepClone(options.video);
- options.audio = deepClone(options.audio);
- options.fastStart = deepClone(options.fastStart);
- this.target = options.target;
- __privateSet(this, _options, {
- firstTimestampBehavior: "strict",
- ...options
- });
- if (options.target instanceof ArrayBufferTarget) {
- __privateSet(this, _writer, new ArrayBufferTargetWriter(options.target));
- } else if (options.target instanceof StreamTarget) {
- __privateSet(this, _writer, options.target.options?.chunked ? new ChunkedStreamTargetWriter(options.target) : new StreamTargetWriter(options.target));
- } else if (options.target instanceof FileSystemWritableFileStreamTarget) {
- __privateSet(this, _writer, new FileSystemWritableFileStreamTargetWriter(options.target));
- } else {
- throw new Error(`Invalid target: ${options.target}`);
- }
- __privateMethod(this, _prepareTracks, prepareTracks_fn).call(this);
- __privateMethod(this, _writeHeader, writeHeader_fn).call(this);
- }
- addVideoChunk(sample, meta, timestamp, compositionTimeOffset) {
- let data = new Uint8Array(sample.byteLength);
- sample.copyTo(data);
- this.addVideoChunkRaw(
- data,
- sample.type,
- timestamp ?? sample.timestamp,
- sample.duration,
- meta,
- compositionTimeOffset
- );
- }
- addVideoChunkRaw(data, type, timestamp, duration, meta, compositionTimeOffset) {
- __privateMethod(this, _ensureNotFinalized, ensureNotFinalized_fn).call(this);
- if (!__privateGet(this, _options).video)
- throw new Error("No video track declared.");
- if (typeof __privateGet(this, _options).fastStart === "object" && __privateGet(this, _videoTrack).samples.length === __privateGet(this, _options).fastStart.expectedVideoChunks) {
- throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${__privateGet(this, _options).fastStart.expectedVideoChunks}).`);
- }
- let videoSample = __privateMethod(this, _createSampleForTrack, createSampleForTrack_fn).call(this, __privateGet(this, _videoTrack), data, type, timestamp, duration, meta, compositionTimeOffset);
- if (__privateGet(this, _options).fastStart === "fragmented" && __privateGet(this, _audioTrack)) {
- while (__privateGet(this, _audioSampleQueue).length > 0 && __privateGet(this, _audioSampleQueue)[0].decodeTimestamp <= videoSample.decodeTimestamp) {
- let audioSample = __privateGet(this, _audioSampleQueue).shift();
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- }
- if (videoSample.decodeTimestamp <= __privateGet(this, _audioTrack).lastDecodeTimestamp) {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- } else {
- __privateGet(this, _videoSampleQueue).push(videoSample);
- }
- } else {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- }
- }
- addAudioChunk(sample, meta, timestamp) {
- let data = new Uint8Array(sample.byteLength);
- sample.copyTo(data);
- this.addAudioChunkRaw(data, sample.type, timestamp ?? sample.timestamp, sample.duration, meta);
- }
- addAudioChunkRaw(data, type, timestamp, duration, meta) {
- __privateMethod(this, _ensureNotFinalized, ensureNotFinalized_fn).call(this);
- if (!__privateGet(this, _options).audio)
- throw new Error("No audio track declared.");
- if (typeof __privateGet(this, _options).fastStart === "object" && __privateGet(this, _audioTrack).samples.length === __privateGet(this, _options).fastStart.expectedAudioChunks) {
- throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${__privateGet(this, _options).fastStart.expectedAudioChunks}).`);
- }
- let audioSample = __privateMethod(this, _createSampleForTrack, createSampleForTrack_fn).call(this, __privateGet(this, _audioTrack), data, type, timestamp, duration, meta);
- if (__privateGet(this, _options).fastStart === "fragmented" && __privateGet(this, _videoTrack)) {
- while (__privateGet(this, _videoSampleQueue).length > 0 && __privateGet(this, _videoSampleQueue)[0].decodeTimestamp <= audioSample.decodeTimestamp) {
- let videoSample = __privateGet(this, _videoSampleQueue).shift();
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- }
- if (audioSample.decodeTimestamp <= __privateGet(this, _videoTrack).lastDecodeTimestamp) {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- } else {
- __privateGet(this, _audioSampleQueue).push(audioSample);
- }
- } else {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- }
- }
- /** Finalizes the file, making it ready for use. Must be called after all video and audio chunks have been added. */
- finalize() {
- if (__privateGet(this, _finalized)) {
- throw new Error("Cannot finalize a muxer more than once.");
- }
- if (__privateGet(this, _options).fastStart === "fragmented") {
- for (let videoSample of __privateGet(this, _videoSampleQueue))
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- for (let audioSample of __privateGet(this, _audioSampleQueue))
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- __privateMethod(this, _finalizeFragment, finalizeFragment_fn).call(this, false);
- } else {
- if (__privateGet(this, _videoTrack))
- __privateMethod(this, _finalizeCurrentChunk, finalizeCurrentChunk_fn).call(this, __privateGet(this, _videoTrack));
- if (__privateGet(this, _audioTrack))
- __privateMethod(this, _finalizeCurrentChunk, finalizeCurrentChunk_fn).call(this, __privateGet(this, _audioTrack));
- }
- let tracks = [__privateGet(this, _videoTrack), __privateGet(this, _audioTrack)].filter(Boolean);
- if (__privateGet(this, _options).fastStart === "in-memory") {
- let mdatSize;
- for (let i = 0; i < 2; i++) {
- let movieBox2 = moov(tracks, __privateGet(this, _creationTime));
- let movieBoxSize = __privateGet(this, _writer).measureBox(movieBox2);
- mdatSize = __privateGet(this, _writer).measureBox(__privateGet(this, _mdat));
- let currentChunkPos = __privateGet(this, _writer).pos + movieBoxSize + mdatSize;
- for (let chunk of __privateGet(this, _finalizedChunks)) {
- chunk.offset = currentChunkPos;
- for (let { data } of chunk.samples) {
- currentChunkPos += data.byteLength;
- mdatSize += data.byteLength;
- }
- }
- if (currentChunkPos < 2 ** 32)
- break;
- if (mdatSize >= 2 ** 32)
- __privateGet(this, _mdat).largeSize = true;
- }
- let movieBox = moov(tracks, __privateGet(this, _creationTime));
- __privateGet(this, _writer).writeBox(movieBox);
- __privateGet(this, _mdat).size = mdatSize;
- __privateGet(this, _writer).writeBox(__privateGet(this, _mdat));
- for (let chunk of __privateGet(this, _finalizedChunks)) {
- for (let sample of chunk.samples) {
- __privateGet(this, _writer).write(sample.data);
- sample.data = null;
- }
- }
- } else if (__privateGet(this, _options).fastStart === "fragmented") {
- let startPos = __privateGet(this, _writer).pos;
- let mfraBox = mfra(tracks);
- __privateGet(this, _writer).writeBox(mfraBox);
- let mfraBoxSize = __privateGet(this, _writer).pos - startPos;
- __privateGet(this, _writer).seek(__privateGet(this, _writer).pos - 4);
- __privateGet(this, _writer).writeU32(mfraBoxSize);
- } else {
- let mdatPos = __privateGet(this, _writer).offsets.get(__privateGet(this, _mdat));
- let mdatSize = __privateGet(this, _writer).pos - mdatPos;
- __privateGet(this, _mdat).size = mdatSize;
- __privateGet(this, _mdat).largeSize = mdatSize >= 2 ** 32;
- __privateGet(this, _writer).patchBox(__privateGet(this, _mdat));
- let movieBox = moov(tracks, __privateGet(this, _creationTime));
- if (typeof __privateGet(this, _options).fastStart === "object") {
- __privateGet(this, _writer).seek(__privateGet(this, _ftypSize));
- __privateGet(this, _writer).writeBox(movieBox);
- let remainingBytes = mdatPos - __privateGet(this, _writer).pos;
- __privateGet(this, _writer).writeBox(free(remainingBytes));
- } else {
- __privateGet(this, _writer).writeBox(movieBox);
- }
- }
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
- __privateGet(this, _writer).finalize();
- __privateSet(this, _finalized, true);
- }
- };
- _options = new WeakMap();
- _writer = new WeakMap();
- _ftypSize = new WeakMap();
- _mdat = new WeakMap();
- _videoTrack = new WeakMap();
- _audioTrack = new WeakMap();
- _creationTime = new WeakMap();
- _finalizedChunks = new WeakMap();
- _nextFragmentNumber = new WeakMap();
- _videoSampleQueue = new WeakMap();
- _audioSampleQueue = new WeakMap();
- _finalized = new WeakMap();
- _validateOptions = new WeakSet();
- validateOptions_fn = function(options) {
- if (options.video) {
- if (!SUPPORTED_VIDEO_CODECS2.includes(options.video.codec)) {
- throw new Error(`Unsupported video codec: ${options.video.codec}`);
- }
- const videoRotation = options.video.rotation;
- if (typeof videoRotation === "number" && ![0, 90, 180, 270].includes(videoRotation)) {
- throw new Error(`Invalid video rotation: ${videoRotation}. Has to be 0, 90, 180 or 270.`);
- } else if (Array.isArray(videoRotation) && (videoRotation.length !== 9 || videoRotation.some((value) => typeof value !== "number"))) {
- throw new Error(`Invalid video transformation matrix: ${videoRotation.join()}`);
- }
- }
- if (options.audio && !SUPPORTED_AUDIO_CODECS2.includes(options.audio.codec)) {
- throw new Error(`Unsupported audio codec: ${options.audio.codec}`);
- }
- if (options.firstTimestampBehavior && !FIRST_TIMESTAMP_BEHAVIORS.includes(options.firstTimestampBehavior)) {
- throw new Error(`Invalid first timestamp behavior: ${options.firstTimestampBehavior}`);
- }
- if (typeof options.fastStart === "object") {
- if (options.video && options.fastStart.expectedVideoChunks === void 0) {
- throw new Error(`'fastStart' is an object but is missing property 'expectedVideoChunks'.`);
- }
- if (options.audio && options.fastStart.expectedAudioChunks === void 0) {
- throw new Error(`'fastStart' is an object but is missing property 'expectedAudioChunks'.`);
- }
- } else if (![false, "in-memory", "fragmented"].includes(options.fastStart)) {
- throw new Error(`'fastStart' option must be false, 'in-memory', 'fragmented' or an object.`);
- }
- };
- _writeHeader = new WeakSet();
- writeHeader_fn = function() {
- __privateGet(this, _writer).writeBox(ftyp({
- holdsAvc: __privateGet(this, _options).video?.codec === "avc",
- fragmented: __privateGet(this, _options).fastStart === "fragmented"
- }));
- __privateSet(this, _ftypSize, __privateGet(this, _writer).pos);
- if (__privateGet(this, _options).fastStart === "in-memory") {
- __privateSet(this, _mdat, mdat(false));
- } else if (__privateGet(this, _options).fastStart === "fragmented") {
- } else {
- if (typeof __privateGet(this, _options).fastStart === "object") {
- let moovSizeUpperBound = __privateMethod(this, _computeMoovSizeUpperBound, computeMoovSizeUpperBound_fn).call(this);
- __privateGet(this, _writer).seek(__privateGet(this, _writer).pos + moovSizeUpperBound);
- }
- __privateSet(this, _mdat, mdat(true));
- __privateGet(this, _writer).writeBox(__privateGet(this, _mdat));
- }
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
- };
- _computeMoovSizeUpperBound = new WeakSet();
- computeMoovSizeUpperBound_fn = function() {
- if (typeof __privateGet(this, _options).fastStart !== "object")
- return;
- let upperBound = 0;
- let sampleCounts = [
- __privateGet(this, _options).fastStart.expectedVideoChunks,
- __privateGet(this, _options).fastStart.expectedAudioChunks
- ];
- for (let n of sampleCounts) {
- if (!n)
- continue;
- upperBound += (4 + 4) * Math.ceil(2 / 3 * n);
- upperBound += 4 * n;
- upperBound += (4 + 4 + 4) * Math.ceil(2 / 3 * n);
- upperBound += 4 * n;
- upperBound += 8 * n;
- }
- upperBound += 4096;
- return upperBound;
- };
- _prepareTracks = new WeakSet();
- prepareTracks_fn = function() {
- if (__privateGet(this, _options).video) {
- __privateSet(this, _videoTrack, {
- id: 1,
- info: {
- type: "video",
- codec: __privateGet(this, _options).video.codec,
- width: __privateGet(this, _options).video.width,
- height: __privateGet(this, _options).video.height,
- rotation: __privateGet(this, _options).video.rotation ?? 0,
- decoderConfig: null
- },
- timescale: 11520,
- // Timescale used by FFmpeg, contains many common frame rates as factors
- samples: [],
- finalizedChunks: [],
- currentChunk: null,
- firstDecodeTimestamp: void 0,
- lastDecodeTimestamp: -1,
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- compactlyCodedChunkTable: []
- });
- }
- if (__privateGet(this, _options).audio) {
- let guessedCodecPrivate = __privateMethod(this, _generateMpeg4AudioSpecificConfig, generateMpeg4AudioSpecificConfig_fn).call(
- this,
- 2,
- // Object type for AAC-LC, since it's the most common
- __privateGet(this, _options).audio.sampleRate,
- __privateGet(this, _options).audio.numberOfChannels
- );
- __privateSet(this, _audioTrack, {
- id: __privateGet(this, _options).video ? 2 : 1,
- info: {
- type: "audio",
- codec: __privateGet(this, _options).audio.codec,
- numberOfChannels: __privateGet(this, _options).audio.numberOfChannels,
- sampleRate: __privateGet(this, _options).audio.sampleRate,
- decoderConfig: {
- codec: __privateGet(this, _options).audio.codec,
- description: guessedCodecPrivate,
- numberOfChannels: __privateGet(this, _options).audio.numberOfChannels,
- sampleRate: __privateGet(this, _options).audio.sampleRate
- }
- },
- timescale: __privateGet(this, _options).audio.sampleRate,
- samples: [],
- finalizedChunks: [],
- currentChunk: null,
- firstDecodeTimestamp: void 0,
- lastDecodeTimestamp: -1,
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- compactlyCodedChunkTable: []
- });
- }
- };
- _generateMpeg4AudioSpecificConfig = new WeakSet();
- generateMpeg4AudioSpecificConfig_fn = function(objectType, sampleRate, numberOfChannels) {
- let frequencyIndices = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350];
- let frequencyIndex = frequencyIndices.indexOf(sampleRate);
- let channelConfig = numberOfChannels;
- let configBits = "";
- configBits += objectType.toString(2).padStart(5, "0");
- configBits += frequencyIndex.toString(2).padStart(4, "0");
- if (frequencyIndex === 15)
- configBits += sampleRate.toString(2).padStart(24, "0");
- configBits += channelConfig.toString(2).padStart(4, "0");
- let paddingLength = Math.ceil(configBits.length / 8) * 8;
- configBits = configBits.padEnd(paddingLength, "0");
- let configBytes = new Uint8Array(configBits.length / 8);
- for (let i = 0; i < configBits.length; i += 8) {
- configBytes[i / 8] = parseInt(configBits.slice(i, i + 8), 2);
- }
- return configBytes;
- };
- _createSampleForTrack = new WeakSet();
- createSampleForTrack_fn = function(track, data, type, timestamp, duration, meta, compositionTimeOffset) {
- let presentationTimestampInSeconds = timestamp / 1e6;
- let decodeTimestampInSeconds = (timestamp - (compositionTimeOffset ?? 0)) / 1e6;
- let durationInSeconds = duration / 1e6;
- let adjusted = __privateMethod(this, _validateTimestamp, validateTimestamp_fn).call(this, presentationTimestampInSeconds, decodeTimestampInSeconds, track);
- presentationTimestampInSeconds = adjusted.presentationTimestamp;
- decodeTimestampInSeconds = adjusted.decodeTimestamp;
- if (meta?.decoderConfig) {
- if (track.info.decoderConfig === null) {
- track.info.decoderConfig = meta.decoderConfig;
- } else {
- Object.assign(track.info.decoderConfig, meta.decoderConfig);
- }
- }
- let sample = {
- presentationTimestamp: presentationTimestampInSeconds,
- decodeTimestamp: decodeTimestampInSeconds,
- duration: durationInSeconds,
- data,
- size: data.byteLength,
- type,
- // Will be refined once the next sample comes in
- timescaleUnitsToNextSample: intoTimescale(durationInSeconds, track.timescale)
- };
- return sample;
- };
- _addSampleToTrack = new WeakSet();
- addSampleToTrack_fn = function(track, sample) {
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- track.samples.push(sample);
- }
- const sampleCompositionTimeOffset = intoTimescale(sample.presentationTimestamp - sample.decodeTimestamp, track.timescale);
- if (track.lastTimescaleUnits !== null) {
- let timescaleUnits = intoTimescale(sample.decodeTimestamp, track.timescale, false);
- let delta = Math.round(timescaleUnits - track.lastTimescaleUnits);
- track.lastTimescaleUnits += delta;
- track.lastSample.timescaleUnitsToNextSample = delta;
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- let lastTableEntry = last(track.timeToSampleTable);
- if (lastTableEntry.sampleCount === 1) {
- lastTableEntry.sampleDelta = delta;
- lastTableEntry.sampleCount++;
- } else if (lastTableEntry.sampleDelta === delta) {
- lastTableEntry.sampleCount++;
- } else {
- lastTableEntry.sampleCount--;
- track.timeToSampleTable.push({
- sampleCount: 2,
- sampleDelta: delta
- });
- }
- const lastCompositionTimeOffsetTableEntry = last(track.compositionTimeOffsetTable);
- if (lastCompositionTimeOffsetTableEntry.sampleCompositionTimeOffset === sampleCompositionTimeOffset) {
- lastCompositionTimeOffsetTableEntry.sampleCount++;
- } else {
- track.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset
- });
- }
- }
- } else {
- track.lastTimescaleUnits = 0;
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- track.timeToSampleTable.push({
- sampleCount: 1,
- sampleDelta: intoTimescale(sample.duration, track.timescale)
- });
- track.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset
- });
- }
- }
- track.lastSample = sample;
- let beginNewChunk = false;
- if (!track.currentChunk) {
- beginNewChunk = true;
- } else {
- let currentChunkDuration = sample.presentationTimestamp - track.currentChunk.startTimestamp;
- if (__privateGet(this, _options).fastStart === "fragmented") {
- let mostImportantTrack = __privateGet(this, _videoTrack) ?? __privateGet(this, _audioTrack);
- if (track === mostImportantTrack && sample.type === "key" && currentChunkDuration >= 1) {
- beginNewChunk = true;
- __privateMethod(this, _finalizeFragment, finalizeFragment_fn).call(this);
- }
- } else {
- beginNewChunk = currentChunkDuration >= 0.5;
- }
- }
- if (beginNewChunk) {
- if (track.currentChunk) {
- __privateMethod(this, _finalizeCurrentChunk, finalizeCurrentChunk_fn).call(this, track);
- }
- track.currentChunk = {
- startTimestamp: sample.presentationTimestamp,
- samples: []
- };
- }
- track.currentChunk.samples.push(sample);
- };
- _validateTimestamp = new WeakSet();
- validateTimestamp_fn = function(presentationTimestamp, decodeTimestamp, track) {
- const strictTimestampBehavior = __privateGet(this, _options).firstTimestampBehavior === "strict";
- const noLastDecodeTimestamp = track.lastDecodeTimestamp === -1;
- const timestampNonZero = decodeTimestamp !== 0;
- if (strictTimestampBehavior && noLastDecodeTimestamp && timestampNonZero) {
- throw new Error(
- `The first chunk for your media track must have a timestamp of 0 (received DTS=${decodeTimestamp}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want.
-
-If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options.
-`
- );
- } else if (__privateGet(this, _options).firstTimestampBehavior === "offset" || __privateGet(this, _options).firstTimestampBehavior === "cross-track-offset") {
- if (track.firstDecodeTimestamp === void 0) {
- track.firstDecodeTimestamp = decodeTimestamp;
- }
- let baseDecodeTimestamp;
- if (__privateGet(this, _options).firstTimestampBehavior === "offset") {
- baseDecodeTimestamp = track.firstDecodeTimestamp;
- } else {
- baseDecodeTimestamp = Math.min(
- __privateGet(this, _videoTrack)?.firstDecodeTimestamp ?? Infinity,
- __privateGet(this, _audioTrack)?.firstDecodeTimestamp ?? Infinity
- );
- }
- decodeTimestamp -= baseDecodeTimestamp;
- presentationTimestamp -= baseDecodeTimestamp;
- }
- if (decodeTimestamp < track.lastDecodeTimestamp) {
- throw new Error(
- `Timestamps must be monotonically increasing (DTS went from ${track.lastDecodeTimestamp * 1e6} to ${decodeTimestamp * 1e6}).`
- );
- }
- track.lastDecodeTimestamp = decodeTimestamp;
- return { presentationTimestamp, decodeTimestamp };
- };
- _finalizeCurrentChunk = new WeakSet();
- finalizeCurrentChunk_fn = function(track) {
- if (__privateGet(this, _options).fastStart === "fragmented") {
- throw new Error("Can't finalize individual chunks 'fastStart' is set to 'fragmented'.");
- }
- if (!track.currentChunk)
- return;
- track.finalizedChunks.push(track.currentChunk);
- __privateGet(this, _finalizedChunks).push(track.currentChunk);
- if (track.compactlyCodedChunkTable.length === 0 || last(track.compactlyCodedChunkTable).samplesPerChunk !== track.currentChunk.samples.length) {
- track.compactlyCodedChunkTable.push({
- firstChunk: track.finalizedChunks.length,
- // 1-indexed
- samplesPerChunk: track.currentChunk.samples.length
- });
- }
- if (__privateGet(this, _options).fastStart === "in-memory") {
- track.currentChunk.offset = 0;
- return;
- }
- track.currentChunk.offset = __privateGet(this, _writer).pos;
- for (let sample of track.currentChunk.samples) {
- __privateGet(this, _writer).write(sample.data);
- sample.data = null;
- }
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
- };
- _finalizeFragment = new WeakSet();
- finalizeFragment_fn = function(flushStreamingWriter = true) {
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- throw new Error("Can't finalize a fragment unless 'fastStart' is set to 'fragmented'.");
- }
- let tracks = [__privateGet(this, _videoTrack), __privateGet(this, _audioTrack)].filter((track) => track && track.currentChunk);
- if (tracks.length === 0)
- return;
- let fragmentNumber = __privateWrapper(this, _nextFragmentNumber)._++;
- if (fragmentNumber === 1) {
- let movieBox = moov(tracks, __privateGet(this, _creationTime), true);
- __privateGet(this, _writer).writeBox(movieBox);
- }
- let moofOffset = __privateGet(this, _writer).pos;
- let moofBox = moof(fragmentNumber, tracks);
- __privateGet(this, _writer).writeBox(moofBox);
- {
- let mdatBox = mdat(false);
- let totalTrackSampleSize = 0;
- for (let track of tracks) {
- for (let sample of track.currentChunk.samples) {
- totalTrackSampleSize += sample.size;
- }
- }
- let mdatSize = __privateGet(this, _writer).measureBox(mdatBox) + totalTrackSampleSize;
- if (mdatSize >= 2 ** 32) {
- mdatBox.largeSize = true;
- mdatSize = __privateGet(this, _writer).measureBox(mdatBox) + totalTrackSampleSize;
- }
- mdatBox.size = mdatSize;
- __privateGet(this, _writer).writeBox(mdatBox);
- }
- for (let track of tracks) {
- track.currentChunk.offset = __privateGet(this, _writer).pos;
- track.currentChunk.moofOffset = moofOffset;
- for (let sample of track.currentChunk.samples) {
- __privateGet(this, _writer).write(sample.data);
- sample.data = null;
- }
- }
- let endPos = __privateGet(this, _writer).pos;
- __privateGet(this, _writer).seek(__privateGet(this, _writer).offsets.get(moofBox));
- let newMoofBox = moof(fragmentNumber, tracks);
- __privateGet(this, _writer).writeBox(newMoofBox);
- __privateGet(this, _writer).seek(endPos);
- for (let track of tracks) {
- track.finalizedChunks.push(track.currentChunk);
- __privateGet(this, _finalizedChunks).push(track.currentChunk);
- track.currentChunk = null;
- }
- if (flushStreamingWriter) {
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
- }
- };
- _maybeFlushStreamingTargetWriter = new WeakSet();
- maybeFlushStreamingTargetWriter_fn = function() {
- if (__privateGet(this, _writer) instanceof StreamTargetWriter) {
- __privateGet(this, _writer).flush();
- }
- };
- _ensureNotFinalized = new WeakSet();
- ensureNotFinalized_fn = function() {
- if (__privateGet(this, _finalized)) {
- throw new Error("Cannot add new video or audio chunks after the file has been finalized.");
- }
- };
- return __toCommonJS(src_exports);
-})();
-if (typeof module === "object" && typeof module.exports === "object") Object.assign(module.exports, Mp4Muxer)
diff --git a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.min.js b/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.min.js
deleted file mode 100644
index 4ac985f..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict";var Mp4Muxer=(()=>{var Ne=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var pt=Object.getOwnPropertyNames;var ct=Object.prototype.hasOwnProperty;var Tt=(t,e)=>{for(var s in e)Ne(t,s,{get:e[s],enumerable:!0})},Ct=(t,e,s,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of pt(e))!ct.call(t,n)&&n!==s&&Ne(t,n,{get:()=>e[n],enumerable:!(r=dt(e,n))||r.enumerable});return t};var bt=t=>Ct(Ne({},"__esModule",{value:!0}),t);var Re=(t,e,s)=>{if(!e.has(t))throw TypeError("Cannot "+s)};var i=(t,e,s)=>(Re(t,e,"read from private field"),s?s.call(t):e.get(t)),f=(t,e,s)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,s)},S=(t,e,s,r)=>(Re(t,e,"write to private field"),r?r.call(t,s):e.set(t,s),s),Ye=(t,e,s,r)=>({set _(n){S(t,e,n,s)},get _(){return i(t,e,r)}}),p=(t,e,s)=>(Re(t,e,"access private method"),s);var fs={};Tt(fs,{ArrayBufferTarget:()=>re,FileSystemWritableFileStreamTarget:()=>ne,Muxer:()=>Ue,StreamTarget:()=>$});var c=new Uint8Array(8),E=new DataView(c.buffer),g=t=>[(t%256+256)%256],C=t=>(E.setUint16(0,t,!1),[c[0],c[1]]),Je=t=>(E.setInt16(0,t,!1),[c[0],c[1]]),Fe=t=>(E.setUint32(0,t,!1),[c[1],c[2],c[3]]),o=t=>(E.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),et=t=>(E.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),M=t=>(E.setUint32(0,Math.floor(t/2**32),!1),E.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),ge=t=>(E.setInt16(0,2**8*t,!1),[c[0],c[1]]),U=t=>(E.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Le=t=>(E.setInt32(0,2**30*t,!1),[c[0],c[1],c[2],c[3]]),k=(t,e=!1)=>{let s=Array(t.length).fill(null).map((r,n)=>t.charCodeAt(n));return e&&s.push(0),s},K=t=>t&&t[t.length-1],ye=t=>{let e;for(let s of t)(!e||s.presentationTimestamp>e.presentationTimestamp)&&(e=s);return e},B=(t,e,s=!0)=>{let r=t*e;return s?Math.round(r):r},je=t=>{let e=t*(Math.PI/180),s=Math.cos(e),r=Math.sin(e);return[s,r,0,-r,s,0,0,0,1]},He=je(0),$e=t=>[U(t[0]),U(t[1]),Le(t[2]),U(t[3]),U(t[4]),Le(t[5]),U(t[6]),U(t[7]),Le(t[8])],Z=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(Z):Object.fromEntries(Object.entries(t).map(([e,s])=>[e,Z(s)])),H=t=>t>=0&&t<2**32;var y=(t,e,s)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:s}),b=(t,e,s,r,n)=>y(t,[g(e),Fe(s),r??[]],n),tt=t=>{let e=512;return t.fragmented?y("ftyp",[k("iso5"),o(e),k("iso5"),k("iso6"),k("mp41")]):y("ftyp",[k("isom"),o(e),k("isom"),t.holdsAvc?k("avc1"):[],k("mp41")])},we=t=>({type:"mdat",largeSize:t}),st=t=>({type:"free",size:t}),ie=(t,e,s=!1)=>y("moov",null,[St(e,t),...t.map(r=>gt(r,e)),s?Xt(t):null]),St=(t,e)=>{let s=B(Math.max(0,...e.filter(l=>l.samples.length>0).map(l=>{let m=ye(l.samples);return m.presentationTimestamp+m.duration})),xe),r=Math.max(...e.map(l=>l.id))+1,n=!H(t)||!H(s),a=n?M:o;return b("mvhd",+n,0,[a(t),a(t),o(xe),a(s),U(1),ge(1),Array(10).fill(0),$e(He),Array(24).fill(0),o(r)])},gt=(t,e)=>y("trak",null,[yt(t,e),xt(t,e)]),yt=(t,e)=>{let s=ye(t.samples),r=B(s?s.presentationTimestamp+s.duration:0,xe),n=!H(e)||!H(r),a=n?M:o,l;return t.info.type==="video"?l=typeof t.info.rotation=="number"?je(t.info.rotation):t.info.rotation:l=He,b("tkhd",+n,3,[a(e),a(e),o(t.id),o(0),a(r),Array(8).fill(0),C(0),C(0),ge(t.info.type==="audio"?1:0),C(0),$e(l),U(t.info.type==="video"?t.info.width:0),U(t.info.type==="video"?t.info.height:0)])},xt=(t,e)=>y("mdia",null,[wt(t,e),vt(t.info.type==="video"?"vide":"soun"),Ot(t)]),wt=(t,e)=>{let s=ye(t.samples),r=B(s?s.presentationTimestamp+s.duration:0,t.timescale),n=!H(e)||!H(r),a=n?M:o;return b("mdhd",+n,0,[a(e),a(e),o(t.timescale),a(r),C(21956),C(0)])},vt=t=>b("hdlr",0,0,[k("mhlr"),k(t),o(0),o(0),o(0),k("mp4-muxer-hdlr",!0)]),Ot=t=>y("minf",null,[t.info.type==="video"?At():kt(),Bt(),Dt(t)]),At=()=>b("vmhd",0,1,[C(0),C(0),C(0),C(0)]),kt=()=>b("smhd",0,0,[C(0),C(0)]),Bt=()=>y("dinf",null,[zt()]),zt=()=>b("dref",0,0,[o(1)],[Ut()]),Ut=()=>b("url ",0,1),Dt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(s=>s.sampleCompositionTimeOffset!==0);return y("stbl",null,[Et(t),Ft(t),jt(t),Ht(t),$t(t),qt(t),e?Wt(t):null])},Et=t=>b("stsd",0,0,[o(1)],[t.info.type==="video"?_t(ss[t.info.codec],t):Nt(rs[t.info.codec],t)]),_t=(t,e)=>y(t,[Array(6).fill(0),C(1),C(0),C(0),Array(12).fill(0),C(e.info.width),C(e.info.height),o(4718592),o(4718592),o(0),C(1),Array(32).fill(0),C(24),Je(65535)],[is[e.info.codec](e)]),It=t=>t.info.decoderConfig&&y("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),Mt=t=>t.info.decoderConfig&&y("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),Pt=t=>{if(!t.info.decoderConfig)return null;let e=t.info.decoderConfig;if(!e.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP9.");let s=e.codec.split("."),r=Number(s[1]),n=Number(s[2]),a=Number(s[3]),l=0,m=(a<<4)+(l<<1)+Number(e.colorSpace.fullRange),d=2,T=2,v=2;return b("vpcC",1,0,[g(r),g(n),g(m),g(d),g(T),g(v),C(0)])},Vt=()=>{let t=1,e=1,s=(t<<7)+e;return y("av1C",[s,0,0,0])},Nt=(t,e)=>y(t,[Array(6).fill(0),C(1),C(0),C(0),o(0),C(e.info.numberOfChannels),C(16),C(0),C(0),U(e.info.sampleRate)],[ns[e.info.codec](e)]),Rt=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return b("esds",0,0,[o(58753152),g(32+e.byteLength),C(1),g(0),o(75530368),g(18+e.byteLength),g(64),g(21),Fe(0),o(130071),o(130071),o(92307584),g(e.byteLength),...e,o(109084800),g(1),g(2)])},Lt=t=>y("dOps",[g(0),g(t.info.numberOfChannels),C(3840),o(t.info.sampleRate),ge(0),g(0)]),Ft=t=>b("stts",0,0,[o(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[o(e.sampleCount),o(e.sampleDelta)])]),jt=t=>{if(t.samples.every(s=>s.type==="key"))return null;let e=[...t.samples.entries()].filter(([,s])=>s.type==="key");return b("stss",0,0,[o(e.length),e.map(([s])=>o(s+1))])},Ht=t=>b("stsc",0,0,[o(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[o(e.firstChunk),o(e.samplesPerChunk),o(1)])]),$t=t=>b("stsz",0,0,[o(0),o(t.samples.length),t.samples.map(e=>o(e.size))]),qt=t=>t.finalizedChunks.length>0&&K(t.finalizedChunks).offset>=2**32?b("co64",0,0,[o(t.finalizedChunks.length),t.finalizedChunks.map(e=>M(e.offset))]):b("stco",0,0,[o(t.finalizedChunks.length),t.finalizedChunks.map(e=>o(e.offset))]),Wt=t=>b("ctts",0,0,[o(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[o(e.sampleCount),o(e.sampleCompositionTimeOffset)])]),Xt=t=>y("mvex",null,t.map(Gt)),Gt=t=>b("trex",0,0,[o(t.id),o(1),o(0),o(0),o(0)]),qe=(t,e)=>y("moof",null,[Zt(t),...e.map(Kt)]),Zt=t=>b("mfhd",0,0,[o(t)]),it=t=>{let e=0,s=0,r=0,n=0,a=t.type==="delta";return s|=+a,a?e|=1:e|=2,e<<24|s<<16|r<<8|n},Kt=t=>y("traf",null,[Qt(t),Yt(t),Jt(t)]),Qt=t=>{let e=0;e|=8,e|=16,e|=32,e|=131072;let s=t.currentChunk.samples[1]??t.currentChunk.samples[0],r={duration:s.timescaleUnitsToNextSample,size:s.size,flags:it(s)};return b("tfhd",0,e,[o(t.id),o(r.duration),o(r.size),o(r.flags)])},Yt=t=>b("tfdt",1,0,[M(B(t.currentChunk.startTimestamp,t.timescale))]),Jt=t=>{let e=t.currentChunk.samples.map(_=>_.timescaleUnitsToNextSample),s=t.currentChunk.samples.map(_=>_.size),r=t.currentChunk.samples.map(it),n=t.currentChunk.samples.map(_=>B(_.presentationTimestamp-_.decodeTimestamp,t.timescale)),a=new Set(e),l=new Set(s),m=new Set(r),d=new Set(n),T=m.size===2&&r[0]!==r[1],v=a.size>1,F=l.size>1,se=!T&&m.size>1,Qe=d.size>1||[...d].some(_=>_!==0),j=0;return j|=1,j|=4*+T,j|=256*+v,j|=512*+F,j|=1024*+se,j|=2048*+Qe,b("trun",1,j,[o(t.currentChunk.samples.length),o(t.currentChunk.offset-t.currentChunk.moofOffset||0),T?o(r[0]):[],t.currentChunk.samples.map((_,Se)=>[v?o(e[Se]):[],F?o(s[Se]):[],se?o(r[Se]):[],Qe?et(n[Se]):[]])])},rt=t=>y("mfra",null,[...t.map(es),ts()]),es=(t,e)=>b("tfra",1,0,[o(t.id),o(63),o(t.finalizedChunks.length),t.finalizedChunks.map(r=>[M(B(r.startTimestamp,t.timescale)),M(r.moofOffset),o(e+1),o(1),o(1)])]),ts=()=>b("mfro",0,0,[o(0)]),ss={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},is={avc:It,hevc:Mt,vp9:Pt,av1:Vt},rs={aac:"mp4a",opus:"Opus"},ns={aac:Rt,opus:Lt};var re=class{constructor(){this.buffer=null}},$=class{constructor(e){this.options=e}},ne=class{constructor(e,s){this.stream=e;this.options=s}};var P,q,ae=class{constructor(){this.pos=0;f(this,P,new Uint8Array(8));f(this,q,new DataView(i(this,P).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){i(this,q).setUint32(0,e,!1),this.write(i(this,P).subarray(0,4))}writeU64(e){i(this,q).setUint32(0,Math.floor(e/2**32),!1),i(this,q).setUint32(4,e,!1),this.write(i(this,P).subarray(0,8))}writeAscii(e){for(let s=0;sn.start-a.start);s.push({start:r[0].start,size:r[0].data.byteLength});for(let n=1;nT.start<=r&&ros){for(let T=0;T=s.written[l+1].start;)s.written[l].end=Math.max(s.written[l].end,s.written[l+1].end),s.written.splice(l+1,1)},Be=new WeakSet,at=function(s){let n={start:Math.floor(s/i(this,z))*i(this,z),data:new Uint8Array(i(this,z)),written:[],shouldFlush:!1};return i(this,O).push(n),i(this,O).sort((a,l)=>a.start-l.start),i(this,O).indexOf(n)},J=new WeakSet,ve=function(s=!1){for(let r=0;re.stream.write({type:"write",data:s,position:r}),chunkSize:e.options?.chunkSize}))}};var xe=1e3,ls=["avc","hevc","vp9","av1"],ms=["aac","opus"],hs=2082844800,us=["strict","offset","cross-track-offset"],h,u,ce,A,x,w,W,X,De,R,L,ee,Ee,ot,_e,lt,Ie,mt,Me,ht,Pe,ut,Te,Ge,D,I,Ve,ft,te,ze,Ce,Ze,G,pe,be,Ke,Ue=class{constructor(e){f(this,Ee);f(this,_e);f(this,Ie);f(this,Me);f(this,Pe);f(this,Te);f(this,D);f(this,Ve);f(this,te);f(this,Ce);f(this,G);f(this,be);f(this,h,void 0);f(this,u,void 0);f(this,ce,void 0);f(this,A,void 0);f(this,x,null);f(this,w,null);f(this,W,Math.floor(Date.now()/1e3)+hs);f(this,X,[]);f(this,De,1);f(this,R,[]);f(this,L,[]);f(this,ee,!1);if(p(this,Ee,ot).call(this,e),e.video=Z(e.video),e.audio=Z(e.audio),e.fastStart=Z(e.fastStart),this.target=e.target,S(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof re)S(this,u,new Oe(e.target));else if(e.target instanceof $)S(this,u,e.target.options?.chunked?new le(e.target):new oe(e.target));else if(e.target instanceof ne)S(this,u,new Ae(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Me,ht).call(this),p(this,_e,lt).call(this)}addVideoChunk(e,s,r,n){let a=new Uint8Array(e.byteLength);e.copyTo(a),this.addVideoChunkRaw(a,e.type,r??e.timestamp,e.duration,s,n)}addVideoChunkRaw(e,s,r,n,a,l){if(p(this,be,Ke).call(this),!i(this,h).video)throw new Error("No video track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,x).samples.length===i(this,h).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedVideoChunks}).`);let m=p(this,Te,Ge).call(this,i(this,x),e,s,r,n,a,l);if(i(this,h).fastStart==="fragmented"&&i(this,w)){for(;i(this,L).length>0&&i(this,L)[0].decodeTimestamp<=m.decodeTimestamp;){let d=i(this,L).shift();p(this,D,I).call(this,i(this,w),d)}m.decodeTimestamp<=i(this,w).lastDecodeTimestamp?p(this,D,I).call(this,i(this,x),m):i(this,R).push(m)}else p(this,D,I).call(this,i(this,x),m)}addAudioChunk(e,s,r){let n=new Uint8Array(e.byteLength);e.copyTo(n),this.addAudioChunkRaw(n,e.type,r??e.timestamp,e.duration,s)}addAudioChunkRaw(e,s,r,n,a){if(p(this,be,Ke).call(this),!i(this,h).audio)throw new Error("No audio track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,w).samples.length===i(this,h).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedAudioChunks}).`);let l=p(this,Te,Ge).call(this,i(this,w),e,s,r,n,a);if(i(this,h).fastStart==="fragmented"&&i(this,x)){for(;i(this,R).length>0&&i(this,R)[0].decodeTimestamp<=l.decodeTimestamp;){let m=i(this,R).shift();p(this,D,I).call(this,i(this,x),m)}l.decodeTimestamp<=i(this,x).lastDecodeTimestamp?p(this,D,I).call(this,i(this,w),l):i(this,L).push(l)}else p(this,D,I).call(this,i(this,w),l)}finalize(){if(i(this,ee))throw new Error("Cannot finalize a muxer more than once.");if(i(this,h).fastStart==="fragmented"){for(let s of i(this,R))p(this,D,I).call(this,i(this,x),s);for(let s of i(this,L))p(this,D,I).call(this,i(this,w),s);p(this,Ce,Ze).call(this,!1)}else i(this,x)&&p(this,te,ze).call(this,i(this,x)),i(this,w)&&p(this,te,ze).call(this,i(this,w));let e=[i(this,x),i(this,w)].filter(Boolean);if(i(this,h).fastStart==="in-memory"){let s;for(let n=0;n<2;n++){let a=ie(e,i(this,W)),l=i(this,u).measureBox(a);s=i(this,u).measureBox(i(this,A));let m=i(this,u).pos+l+s;for(let d of i(this,X)){d.offset=m;for(let{data:T}of d.samples)m+=T.byteLength,s+=T.byteLength}if(m<2**32)break;s>=2**32&&(i(this,A).largeSize=!0)}let r=ie(e,i(this,W));i(this,u).writeBox(r),i(this,A).size=s,i(this,u).writeBox(i(this,A));for(let n of i(this,X))for(let a of n.samples)i(this,u).write(a.data),a.data=null}else if(i(this,h).fastStart==="fragmented"){let s=i(this,u).pos,r=rt(e);i(this,u).writeBox(r);let n=i(this,u).pos-s;i(this,u).seek(i(this,u).pos-4),i(this,u).writeU32(n)}else{let s=i(this,u).offsets.get(i(this,A)),r=i(this,u).pos-s;i(this,A).size=r,i(this,A).largeSize=r>=2**32,i(this,u).patchBox(i(this,A));let n=ie(e,i(this,W));if(typeof i(this,h).fastStart=="object"){i(this,u).seek(i(this,ce)),i(this,u).writeBox(n);let a=s-i(this,u).pos;i(this,u).writeBox(st(a))}else i(this,u).writeBox(n)}p(this,G,pe).call(this),i(this,u).finalize(),S(this,ee,!0)}};h=new WeakMap,u=new WeakMap,ce=new WeakMap,A=new WeakMap,x=new WeakMap,w=new WeakMap,W=new WeakMap,X=new WeakMap,De=new WeakMap,R=new WeakMap,L=new WeakMap,ee=new WeakMap,Ee=new WeakSet,ot=function(e){if(e.video){if(!ls.includes(e.video.codec))throw new Error(`Unsupported video codec: ${e.video.codec}`);let s=e.video.rotation;if(typeof s=="number"&&![0,90,180,270].includes(s))throw new Error(`Invalid video rotation: ${s}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(s)&&(s.length!==9||s.some(r=>typeof r!="number")))throw new Error(`Invalid video transformation matrix: ${s.join()}`)}if(e.audio&&!ms.includes(e.audio.codec))throw new Error(`Unsupported audio codec: ${e.audio.codec}`);if(e.firstTimestampBehavior&&!us.includes(e.firstTimestampBehavior))throw new Error(`Invalid first timestamp behavior: ${e.firstTimestampBehavior}`);if(typeof e.fastStart=="object"){if(e.video&&e.fastStart.expectedVideoChunks===void 0)throw new Error("'fastStart' is an object but is missing property 'expectedVideoChunks'.");if(e.audio&&e.fastStart.expectedAudioChunks===void 0)throw new Error("'fastStart' is an object but is missing property 'expectedAudioChunks'.")}else if(![!1,"in-memory","fragmented"].includes(e.fastStart))throw new Error("'fastStart' option must be false, 'in-memory', 'fragmented' or an object.")},_e=new WeakSet,lt=function(){if(i(this,u).writeBox(tt({holdsAvc:i(this,h).video?.codec==="avc",fragmented:i(this,h).fastStart==="fragmented"})),S(this,ce,i(this,u).pos),i(this,h).fastStart==="in-memory")S(this,A,we(!1));else if(i(this,h).fastStart!=="fragmented"){if(typeof i(this,h).fastStart=="object"){let e=p(this,Ie,mt).call(this);i(this,u).seek(i(this,u).pos+e)}S(this,A,we(!0)),i(this,u).writeBox(i(this,A))}p(this,G,pe).call(this)},Ie=new WeakSet,mt=function(){if(typeof i(this,h).fastStart!="object")return;let e=0,s=[i(this,h).fastStart.expectedVideoChunks,i(this,h).fastStart.expectedAudioChunks];for(let r of s)r&&(e+=(4+4)*Math.ceil(2/3*r),e+=4*r,e+=(4+4+4)*Math.ceil(2/3*r),e+=4*r,e+=8*r);return e+=4096,e},Me=new WeakSet,ht=function(){if(i(this,h).video&&S(this,x,{id:1,info:{type:"video",codec:i(this,h).video.codec,width:i(this,h).video.width,height:i(this,h).video.height,rotation:i(this,h).video.rotation??0,decoderConfig:null},timescale:11520,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,h).audio){let e=p(this,Pe,ut).call(this,2,i(this,h).audio.sampleRate,i(this,h).audio.numberOfChannels);S(this,w,{id:i(this,h).video?2:1,info:{type:"audio",codec:i(this,h).audio.codec,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate,decoderConfig:{codec:i(this,h).audio.codec,description:e,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate}},timescale:i(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]})}},Pe=new WeakSet,ut=function(e,s,r){let a=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(s),l=r,m="";m+=e.toString(2).padStart(5,"0"),m+=a.toString(2).padStart(4,"0"),a===15&&(m+=s.toString(2).padStart(24,"0")),m+=l.toString(2).padStart(4,"0");let d=Math.ceil(m.length/8)*8;m=m.padEnd(d,"0");let T=new Uint8Array(m.length/8);for(let v=0;v=1&&(n=!0,p(this,Ce,Ze).call(this))}else n=a>=.5}n&&(e.currentChunk&&p(this,te,ze).call(this,e),e.currentChunk={startTimestamp:s.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(s)},Ve=new WeakSet,ft=function(e,s,r){let n=i(this,h).firstTimestampBehavior==="strict",a=r.lastDecodeTimestamp===-1;if(n&&a&&s!==0)throw new Error(`The first chunk for your media track must have a timestamp of 0 (received DTS=${s}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want.
-
-If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options.
-`);if(i(this,h).firstTimestampBehavior==="offset"||i(this,h).firstTimestampBehavior==="cross-track-offset"){r.firstDecodeTimestamp===void 0&&(r.firstDecodeTimestamp=s);let m;i(this,h).firstTimestampBehavior==="offset"?m=r.firstDecodeTimestamp:m=Math.min(i(this,x)?.firstDecodeTimestamp??1/0,i(this,w)?.firstDecodeTimestamp??1/0),s-=m,e-=m}if(sd&&d.currentChunk);if(s.length===0)return;let r=Ye(this,De)._++;if(r===1){let d=ie(s,i(this,W),!0);i(this,u).writeBox(d)}let n=i(this,u).pos,a=qe(r,s);i(this,u).writeBox(a);{let d=we(!1),T=0;for(let F of s)for(let se of F.currentChunk.samples)T+=se.size;let v=i(this,u).measureBox(d)+T;v>=2**32&&(d.largeSize=!0,v=i(this,u).measureBox(d)+T),d.size=v,i(this,u).writeBox(d)}for(let d of s){d.currentChunk.offset=i(this,u).pos,d.currentChunk.moofOffset=n;for(let T of d.currentChunk.samples)i(this,u).write(T.data),T.data=null}let l=i(this,u).pos;i(this,u).seek(i(this,u).offsets.get(a));let m=qe(r,s);i(this,u).writeBox(m),i(this,u).seek(l);for(let d of s)d.finalizedChunks.push(d.currentChunk),i(this,X).push(d.currentChunk),d.currentChunk=null;e&&p(this,G,pe).call(this)},G=new WeakSet,pe=function(){i(this,u)instanceof oe&&i(this,u).flush()},be=new WeakSet,Ke=function(){if(i(this,ee))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};return bt(fs);})();
-if (typeof module === "object" && typeof module.exports === "object") Object.assign(module.exports, Mp4Muxer)
diff --git a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.min.mjs b/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.min.mjs
deleted file mode 100644
index e1bdb7f..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.min.mjs
+++ /dev/null
@@ -1,4 +0,0 @@
-var Ve=(t,e,s)=>{if(!e.has(t))throw TypeError("Cannot "+s)};var i=(t,e,s)=>(Ve(t,e,"read from private field"),s?s.call(t):e.get(t)),f=(t,e,s)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,s)},S=(t,e,s,r)=>(Ve(t,e,"write to private field"),r?r.call(t,s):e.set(t,s),s),Qe=(t,e,s,r)=>({set _(n){S(t,e,n,s)},get _(){return i(t,e,r)}}),p=(t,e,s)=>(Ve(t,e,"access private method"),s);var c=new Uint8Array(8),E=new DataView(c.buffer),g=t=>[(t%256+256)%256],C=t=>(E.setUint16(0,t,!1),[c[0],c[1]]),Ye=t=>(E.setInt16(0,t,!1),[c[0],c[1]]),Re=t=>(E.setUint32(0,t,!1),[c[1],c[2],c[3]]),o=t=>(E.setUint32(0,t,!1),[c[0],c[1],c[2],c[3]]),Je=t=>(E.setInt32(0,t,!1),[c[0],c[1],c[2],c[3]]),M=t=>(E.setUint32(0,Math.floor(t/2**32),!1),E.setUint32(4,t,!1),[c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7]]),be=t=>(E.setInt16(0,2**8*t,!1),[c[0],c[1]]),U=t=>(E.setInt32(0,2**16*t,!1),[c[0],c[1],c[2],c[3]]),Ne=t=>(E.setInt32(0,2**30*t,!1),[c[0],c[1],c[2],c[3]]),k=(t,e=!1)=>{let s=Array(t.length).fill(null).map((r,n)=>t.charCodeAt(n));return e&&s.push(0),s},Z=t=>t&&t[t.length-1],Se=t=>{let e;for(let s of t)(!e||s.presentationTimestamp>e.presentationTimestamp)&&(e=s);return e},B=(t,e,s=!0)=>{let r=t*e;return s?Math.round(r):r},Le=t=>{let e=t*(Math.PI/180),s=Math.cos(e),r=Math.sin(e);return[s,r,0,-r,s,0,0,0,1]},Fe=Le(0),je=t=>[U(t[0]),U(t[1]),Ne(t[2]),U(t[3]),U(t[4]),Ne(t[5]),U(t[6]),U(t[7]),Ne(t[8])],G=t=>!t||typeof t!="object"?t:Array.isArray(t)?t.map(G):Object.fromEntries(Object.entries(t).map(([e,s])=>[e,G(s)])),H=t=>t>=0&&t<2**32;var y=(t,e,s)=>({type:t,contents:e&&new Uint8Array(e.flat(10)),children:s}),b=(t,e,s,r,n)=>y(t,[g(e),Re(s),r??[]],n),et=t=>{let e=512;return t.fragmented?y("ftyp",[k("iso5"),o(e),k("iso5"),k("iso6"),k("mp41")]):y("ftyp",[k("isom"),o(e),k("isom"),t.holdsAvc?k("avc1"):[],k("mp41")])},ye=t=>({type:"mdat",largeSize:t}),tt=t=>({type:"free",size:t}),ie=(t,e,s=!1)=>y("moov",null,[ft(e,t),...t.map(r=>dt(r,e)),s?Lt(t):null]),ft=(t,e)=>{let s=B(Math.max(0,...e.filter(l=>l.samples.length>0).map(l=>{let m=Se(l.samples);return m.presentationTimestamp+m.duration})),ge),r=Math.max(...e.map(l=>l.id))+1,n=!H(t)||!H(s),a=n?M:o;return b("mvhd",+n,0,[a(t),a(t),o(ge),a(s),U(1),be(1),Array(10).fill(0),je(Fe),Array(24).fill(0),o(r)])},dt=(t,e)=>y("trak",null,[pt(t,e),ct(t,e)]),pt=(t,e)=>{let s=Se(t.samples),r=B(s?s.presentationTimestamp+s.duration:0,ge),n=!H(e)||!H(r),a=n?M:o,l;return t.info.type==="video"?l=typeof t.info.rotation=="number"?Le(t.info.rotation):t.info.rotation:l=Fe,b("tkhd",+n,3,[a(e),a(e),o(t.id),o(0),a(r),Array(8).fill(0),C(0),C(0),be(t.info.type==="audio"?1:0),C(0),je(l),U(t.info.type==="video"?t.info.width:0),U(t.info.type==="video"?t.info.height:0)])},ct=(t,e)=>y("mdia",null,[Tt(t,e),Ct(t.info.type==="video"?"vide":"soun"),bt(t)]),Tt=(t,e)=>{let s=Se(t.samples),r=B(s?s.presentationTimestamp+s.duration:0,t.timescale),n=!H(e)||!H(r),a=n?M:o;return b("mdhd",+n,0,[a(e),a(e),o(t.timescale),a(r),C(21956),C(0)])},Ct=t=>b("hdlr",0,0,[k("mhlr"),k(t),o(0),o(0),o(0),k("mp4-muxer-hdlr",!0)]),bt=t=>y("minf",null,[t.info.type==="video"?St():gt(),yt(),vt(t)]),St=()=>b("vmhd",0,1,[C(0),C(0),C(0),C(0)]),gt=()=>b("smhd",0,0,[C(0),C(0)]),yt=()=>y("dinf",null,[xt()]),xt=()=>b("dref",0,0,[o(1)],[wt()]),wt=()=>b("url ",0,1),vt=t=>{let e=t.compositionTimeOffsetTable.length>1||t.compositionTimeOffsetTable.some(s=>s.sampleCompositionTimeOffset!==0);return y("stbl",null,[Ot(t),It(t),Mt(t),Pt(t),Vt(t),Nt(t),e?Rt(t):null])},Ot=t=>b("stsd",0,0,[o(1)],[t.info.type==="video"?At(Zt[t.info.codec],t):Dt(Qt[t.info.codec],t)]),At=(t,e)=>y(t,[Array(6).fill(0),C(1),C(0),C(0),Array(12).fill(0),C(e.info.width),C(e.info.height),o(4718592),o(4718592),o(0),C(1),Array(32).fill(0),C(24),Ye(65535)],[Kt[e.info.codec](e)]),kt=t=>t.info.decoderConfig&&y("avcC",[...new Uint8Array(t.info.decoderConfig.description)]),Bt=t=>t.info.decoderConfig&&y("hvcC",[...new Uint8Array(t.info.decoderConfig.description)]),zt=t=>{if(!t.info.decoderConfig)return null;let e=t.info.decoderConfig;if(!e.colorSpace)throw new Error("'colorSpace' is required in the decoder config for VP9.");let s=e.codec.split("."),r=Number(s[1]),n=Number(s[2]),a=Number(s[3]),l=0,m=(a<<4)+(l<<1)+Number(e.colorSpace.fullRange),d=2,T=2,v=2;return b("vpcC",1,0,[g(r),g(n),g(m),g(d),g(T),g(v),C(0)])},Ut=()=>{let t=1,e=1,s=(t<<7)+e;return y("av1C",[s,0,0,0])},Dt=(t,e)=>y(t,[Array(6).fill(0),C(1),C(0),C(0),o(0),C(e.info.numberOfChannels),C(16),C(0),C(0),U(e.info.sampleRate)],[Yt[e.info.codec](e)]),Et=t=>{let e=new Uint8Array(t.info.decoderConfig.description);return b("esds",0,0,[o(58753152),g(32+e.byteLength),C(1),g(0),o(75530368),g(18+e.byteLength),g(64),g(21),Re(0),o(130071),o(130071),o(92307584),g(e.byteLength),...e,o(109084800),g(1),g(2)])},_t=t=>y("dOps",[g(0),g(t.info.numberOfChannels),C(3840),o(t.info.sampleRate),be(0),g(0)]),It=t=>b("stts",0,0,[o(t.timeToSampleTable.length),t.timeToSampleTable.map(e=>[o(e.sampleCount),o(e.sampleDelta)])]),Mt=t=>{if(t.samples.every(s=>s.type==="key"))return null;let e=[...t.samples.entries()].filter(([,s])=>s.type==="key");return b("stss",0,0,[o(e.length),e.map(([s])=>o(s+1))])},Pt=t=>b("stsc",0,0,[o(t.compactlyCodedChunkTable.length),t.compactlyCodedChunkTable.map(e=>[o(e.firstChunk),o(e.samplesPerChunk),o(1)])]),Vt=t=>b("stsz",0,0,[o(0),o(t.samples.length),t.samples.map(e=>o(e.size))]),Nt=t=>t.finalizedChunks.length>0&&Z(t.finalizedChunks).offset>=2**32?b("co64",0,0,[o(t.finalizedChunks.length),t.finalizedChunks.map(e=>M(e.offset))]):b("stco",0,0,[o(t.finalizedChunks.length),t.finalizedChunks.map(e=>o(e.offset))]),Rt=t=>b("ctts",0,0,[o(t.compositionTimeOffsetTable.length),t.compositionTimeOffsetTable.map(e=>[o(e.sampleCount),o(e.sampleCompositionTimeOffset)])]),Lt=t=>y("mvex",null,t.map(Ft)),Ft=t=>b("trex",0,0,[o(t.id),o(1),o(0),o(0),o(0)]),He=(t,e)=>y("moof",null,[jt(t),...e.map(Ht)]),jt=t=>b("mfhd",0,0,[o(t)]),st=t=>{let e=0,s=0,r=0,n=0,a=t.type==="delta";return s|=+a,a?e|=1:e|=2,e<<24|s<<16|r<<8|n},Ht=t=>y("traf",null,[$t(t),qt(t),Wt(t)]),$t=t=>{let e=0;e|=8,e|=16,e|=32,e|=131072;let s=t.currentChunk.samples[1]??t.currentChunk.samples[0],r={duration:s.timescaleUnitsToNextSample,size:s.size,flags:st(s)};return b("tfhd",0,e,[o(t.id),o(r.duration),o(r.size),o(r.flags)])},qt=t=>b("tfdt",1,0,[M(B(t.currentChunk.startTimestamp,t.timescale))]),Wt=t=>{let e=t.currentChunk.samples.map(_=>_.timescaleUnitsToNextSample),s=t.currentChunk.samples.map(_=>_.size),r=t.currentChunk.samples.map(st),n=t.currentChunk.samples.map(_=>B(_.presentationTimestamp-_.decodeTimestamp,t.timescale)),a=new Set(e),l=new Set(s),m=new Set(r),d=new Set(n),T=m.size===2&&r[0]!==r[1],v=a.size>1,F=l.size>1,se=!T&&m.size>1,Ke=d.size>1||[...d].some(_=>_!==0),j=0;return j|=1,j|=4*+T,j|=256*+v,j|=512*+F,j|=1024*+se,j|=2048*+Ke,b("trun",1,j,[o(t.currentChunk.samples.length),o(t.currentChunk.offset-t.currentChunk.moofOffset||0),T?o(r[0]):[],t.currentChunk.samples.map((_,Ce)=>[v?o(e[Ce]):[],F?o(s[Ce]):[],se?o(r[Ce]):[],Ke?Je(n[Ce]):[]])])},it=t=>y("mfra",null,[...t.map(Xt),Gt()]),Xt=(t,e)=>b("tfra",1,0,[o(t.id),o(63),o(t.finalizedChunks.length),t.finalizedChunks.map(r=>[M(B(r.startTimestamp,t.timescale)),M(r.moofOffset),o(e+1),o(1),o(1)])]),Gt=()=>b("mfro",0,0,[o(0)]),Zt={avc:"avc1",hevc:"hvc1",vp9:"vp09",av1:"av01"},Kt={avc:kt,hevc:Bt,vp9:zt,av1:Ut},Qt={aac:"mp4a",opus:"Opus"},Yt={aac:Et,opus:_t};var xe=class{constructor(){this.buffer=null}},K=class{constructor(e){this.options=e}},we=class{constructor(e,s){this.stream=e;this.options=s}};var P,$,re=class{constructor(){this.pos=0;f(this,P,new Uint8Array(8));f(this,$,new DataView(i(this,P).buffer));this.offsets=new WeakMap}seek(e){this.pos=e}writeU32(e){i(this,$).setUint32(0,e,!1),this.write(i(this,P).subarray(0,4))}writeU64(e){i(this,$).setUint32(0,Math.floor(e/2**32),!1),i(this,$).setUint32(4,e,!1),this.write(i(this,P).subarray(0,8))}writeAscii(e){for(let s=0;sn.start-a.start);s.push({start:r[0].start,size:r[0].data.byteLength});for(let n=1;nT.start<=r&&res){for(let T=0;T=s.written[l+1].start;)s.written[l].end=Math.max(s.written[l].end,s.written[l+1].end),s.written.splice(l+1,1)},Be=new WeakSet,nt=function(s){let n={start:Math.floor(s/i(this,z))*i(this,z),data:new Uint8Array(i(this,z)),written:[],shouldFlush:!1};return i(this,O).push(n),i(this,O).sort((a,l)=>a.start-l.start),i(this,O).indexOf(n)},J=new WeakSet,ve=function(s=!1){for(let r=0;re.stream.write({type:"write",data:s,position:r}),chunkSize:e.options?.chunkSize}))}};var ge=1e3,ts=["avc","hevc","vp9","av1"],ss=["aac","opus"],is=2082844800,rs=["strict","offset","cross-track-offset"],h,u,de,A,x,w,q,W,Ue,R,L,ee,De,at,Ee,ot,_e,lt,Ie,mt,Me,ht,pe,Xe,D,I,Pe,ut,te,ze,ce,Ge,X,fe,Te,Ze,We=class{constructor(e){f(this,De);f(this,Ee);f(this,_e);f(this,Ie);f(this,Me);f(this,pe);f(this,D);f(this,Pe);f(this,te);f(this,ce);f(this,X);f(this,Te);f(this,h,void 0);f(this,u,void 0);f(this,de,void 0);f(this,A,void 0);f(this,x,null);f(this,w,null);f(this,q,Math.floor(Date.now()/1e3)+is);f(this,W,[]);f(this,Ue,1);f(this,R,[]);f(this,L,[]);f(this,ee,!1);if(p(this,De,at).call(this,e),e.video=G(e.video),e.audio=G(e.audio),e.fastStart=G(e.fastStart),this.target=e.target,S(this,h,{firstTimestampBehavior:"strict",...e}),e.target instanceof xe)S(this,u,new Oe(e.target));else if(e.target instanceof K)S(this,u,e.target.options?.chunked?new ae(e.target):new ne(e.target));else if(e.target instanceof we)S(this,u,new Ae(e.target));else throw new Error(`Invalid target: ${e.target}`);p(this,Ie,mt).call(this),p(this,Ee,ot).call(this)}addVideoChunk(e,s,r,n){let a=new Uint8Array(e.byteLength);e.copyTo(a),this.addVideoChunkRaw(a,e.type,r??e.timestamp,e.duration,s,n)}addVideoChunkRaw(e,s,r,n,a,l){if(p(this,Te,Ze).call(this),!i(this,h).video)throw new Error("No video track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,x).samples.length===i(this,h).fastStart.expectedVideoChunks)throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedVideoChunks}).`);let m=p(this,pe,Xe).call(this,i(this,x),e,s,r,n,a,l);if(i(this,h).fastStart==="fragmented"&&i(this,w)){for(;i(this,L).length>0&&i(this,L)[0].decodeTimestamp<=m.decodeTimestamp;){let d=i(this,L).shift();p(this,D,I).call(this,i(this,w),d)}m.decodeTimestamp<=i(this,w).lastDecodeTimestamp?p(this,D,I).call(this,i(this,x),m):i(this,R).push(m)}else p(this,D,I).call(this,i(this,x),m)}addAudioChunk(e,s,r){let n=new Uint8Array(e.byteLength);e.copyTo(n),this.addAudioChunkRaw(n,e.type,r??e.timestamp,e.duration,s)}addAudioChunkRaw(e,s,r,n,a){if(p(this,Te,Ze).call(this),!i(this,h).audio)throw new Error("No audio track declared.");if(typeof i(this,h).fastStart=="object"&&i(this,w).samples.length===i(this,h).fastStart.expectedAudioChunks)throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${i(this,h).fastStart.expectedAudioChunks}).`);let l=p(this,pe,Xe).call(this,i(this,w),e,s,r,n,a);if(i(this,h).fastStart==="fragmented"&&i(this,x)){for(;i(this,R).length>0&&i(this,R)[0].decodeTimestamp<=l.decodeTimestamp;){let m=i(this,R).shift();p(this,D,I).call(this,i(this,x),m)}l.decodeTimestamp<=i(this,x).lastDecodeTimestamp?p(this,D,I).call(this,i(this,w),l):i(this,L).push(l)}else p(this,D,I).call(this,i(this,w),l)}finalize(){if(i(this,ee))throw new Error("Cannot finalize a muxer more than once.");if(i(this,h).fastStart==="fragmented"){for(let s of i(this,R))p(this,D,I).call(this,i(this,x),s);for(let s of i(this,L))p(this,D,I).call(this,i(this,w),s);p(this,ce,Ge).call(this,!1)}else i(this,x)&&p(this,te,ze).call(this,i(this,x)),i(this,w)&&p(this,te,ze).call(this,i(this,w));let e=[i(this,x),i(this,w)].filter(Boolean);if(i(this,h).fastStart==="in-memory"){let s;for(let n=0;n<2;n++){let a=ie(e,i(this,q)),l=i(this,u).measureBox(a);s=i(this,u).measureBox(i(this,A));let m=i(this,u).pos+l+s;for(let d of i(this,W)){d.offset=m;for(let{data:T}of d.samples)m+=T.byteLength,s+=T.byteLength}if(m<2**32)break;s>=2**32&&(i(this,A).largeSize=!0)}let r=ie(e,i(this,q));i(this,u).writeBox(r),i(this,A).size=s,i(this,u).writeBox(i(this,A));for(let n of i(this,W))for(let a of n.samples)i(this,u).write(a.data),a.data=null}else if(i(this,h).fastStart==="fragmented"){let s=i(this,u).pos,r=it(e);i(this,u).writeBox(r);let n=i(this,u).pos-s;i(this,u).seek(i(this,u).pos-4),i(this,u).writeU32(n)}else{let s=i(this,u).offsets.get(i(this,A)),r=i(this,u).pos-s;i(this,A).size=r,i(this,A).largeSize=r>=2**32,i(this,u).patchBox(i(this,A));let n=ie(e,i(this,q));if(typeof i(this,h).fastStart=="object"){i(this,u).seek(i(this,de)),i(this,u).writeBox(n);let a=s-i(this,u).pos;i(this,u).writeBox(tt(a))}else i(this,u).writeBox(n)}p(this,X,fe).call(this),i(this,u).finalize(),S(this,ee,!0)}};h=new WeakMap,u=new WeakMap,de=new WeakMap,A=new WeakMap,x=new WeakMap,w=new WeakMap,q=new WeakMap,W=new WeakMap,Ue=new WeakMap,R=new WeakMap,L=new WeakMap,ee=new WeakMap,De=new WeakSet,at=function(e){if(e.video){if(!ts.includes(e.video.codec))throw new Error(`Unsupported video codec: ${e.video.codec}`);let s=e.video.rotation;if(typeof s=="number"&&![0,90,180,270].includes(s))throw new Error(`Invalid video rotation: ${s}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(s)&&(s.length!==9||s.some(r=>typeof r!="number")))throw new Error(`Invalid video transformation matrix: ${s.join()}`)}if(e.audio&&!ss.includes(e.audio.codec))throw new Error(`Unsupported audio codec: ${e.audio.codec}`);if(e.firstTimestampBehavior&&!rs.includes(e.firstTimestampBehavior))throw new Error(`Invalid first timestamp behavior: ${e.firstTimestampBehavior}`);if(typeof e.fastStart=="object"){if(e.video&&e.fastStart.expectedVideoChunks===void 0)throw new Error("'fastStart' is an object but is missing property 'expectedVideoChunks'.");if(e.audio&&e.fastStart.expectedAudioChunks===void 0)throw new Error("'fastStart' is an object but is missing property 'expectedAudioChunks'.")}else if(![!1,"in-memory","fragmented"].includes(e.fastStart))throw new Error("'fastStart' option must be false, 'in-memory', 'fragmented' or an object.")},Ee=new WeakSet,ot=function(){if(i(this,u).writeBox(et({holdsAvc:i(this,h).video?.codec==="avc",fragmented:i(this,h).fastStart==="fragmented"})),S(this,de,i(this,u).pos),i(this,h).fastStart==="in-memory")S(this,A,ye(!1));else if(i(this,h).fastStart!=="fragmented"){if(typeof i(this,h).fastStart=="object"){let e=p(this,_e,lt).call(this);i(this,u).seek(i(this,u).pos+e)}S(this,A,ye(!0)),i(this,u).writeBox(i(this,A))}p(this,X,fe).call(this)},_e=new WeakSet,lt=function(){if(typeof i(this,h).fastStart!="object")return;let e=0,s=[i(this,h).fastStart.expectedVideoChunks,i(this,h).fastStart.expectedAudioChunks];for(let r of s)r&&(e+=(4+4)*Math.ceil(2/3*r),e+=4*r,e+=(4+4+4)*Math.ceil(2/3*r),e+=4*r,e+=8*r);return e+=4096,e},Ie=new WeakSet,mt=function(){if(i(this,h).video&&S(this,x,{id:1,info:{type:"video",codec:i(this,h).video.codec,width:i(this,h).video.width,height:i(this,h).video.height,rotation:i(this,h).video.rotation??0,decoderConfig:null},timescale:11520,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]}),i(this,h).audio){let e=p(this,Me,ht).call(this,2,i(this,h).audio.sampleRate,i(this,h).audio.numberOfChannels);S(this,w,{id:i(this,h).video?2:1,info:{type:"audio",codec:i(this,h).audio.codec,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate,decoderConfig:{codec:i(this,h).audio.codec,description:e,numberOfChannels:i(this,h).audio.numberOfChannels,sampleRate:i(this,h).audio.sampleRate}},timescale:i(this,h).audio.sampleRate,samples:[],finalizedChunks:[],currentChunk:null,firstDecodeTimestamp:void 0,lastDecodeTimestamp:-1,timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,compactlyCodedChunkTable:[]})}},Me=new WeakSet,ht=function(e,s,r){let a=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350].indexOf(s),l=r,m="";m+=e.toString(2).padStart(5,"0"),m+=a.toString(2).padStart(4,"0"),a===15&&(m+=s.toString(2).padStart(24,"0")),m+=l.toString(2).padStart(4,"0");let d=Math.ceil(m.length/8)*8;m=m.padEnd(d,"0");let T=new Uint8Array(m.length/8);for(let v=0;v=1&&(n=!0,p(this,ce,Ge).call(this))}else n=a>=.5}n&&(e.currentChunk&&p(this,te,ze).call(this,e),e.currentChunk={startTimestamp:s.presentationTimestamp,samples:[]}),e.currentChunk.samples.push(s)},Pe=new WeakSet,ut=function(e,s,r){let n=i(this,h).firstTimestampBehavior==="strict",a=r.lastDecodeTimestamp===-1;if(n&&a&&s!==0)throw new Error(`The first chunk for your media track must have a timestamp of 0 (received DTS=${s}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want.
-
-If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options.
-`);if(i(this,h).firstTimestampBehavior==="offset"||i(this,h).firstTimestampBehavior==="cross-track-offset"){r.firstDecodeTimestamp===void 0&&(r.firstDecodeTimestamp=s);let m;i(this,h).firstTimestampBehavior==="offset"?m=r.firstDecodeTimestamp:m=Math.min(i(this,x)?.firstDecodeTimestamp??1/0,i(this,w)?.firstDecodeTimestamp??1/0),s-=m,e-=m}if(sd&&d.currentChunk);if(s.length===0)return;let r=Qe(this,Ue)._++;if(r===1){let d=ie(s,i(this,q),!0);i(this,u).writeBox(d)}let n=i(this,u).pos,a=He(r,s);i(this,u).writeBox(a);{let d=ye(!1),T=0;for(let F of s)for(let se of F.currentChunk.samples)T+=se.size;let v=i(this,u).measureBox(d)+T;v>=2**32&&(d.largeSize=!0,v=i(this,u).measureBox(d)+T),d.size=v,i(this,u).writeBox(d)}for(let d of s){d.currentChunk.offset=i(this,u).pos,d.currentChunk.moofOffset=n;for(let T of d.currentChunk.samples)i(this,u).write(T.data),T.data=null}let l=i(this,u).pos;i(this,u).seek(i(this,u).offsets.get(a));let m=He(r,s);i(this,u).writeBox(m),i(this,u).seek(l);for(let d of s)d.finalizedChunks.push(d.currentChunk),i(this,W).push(d.currentChunk),d.currentChunk=null;e&&p(this,X,fe).call(this)},X=new WeakSet,fe=function(){i(this,u)instanceof ne&&i(this,u).flush()},Te=new WeakSet,Ze=function(){if(i(this,ee))throw new Error("Cannot add new video or audio chunks after the file has been finalized.")};export{xe as ArrayBufferTarget,we as FileSystemWritableFileStreamTarget,We as Muxer,K as StreamTarget};
diff --git a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.mjs b/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.mjs
deleted file mode 100644
index 0bb9f6b..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/build/mp4-muxer.mjs
+++ /dev/null
@@ -1,1693 +0,0 @@
-var __accessCheck = (obj, member, msg) => {
- if (!member.has(obj))
- throw TypeError("Cannot " + msg);
-};
-var __privateGet = (obj, member, getter) => {
- __accessCheck(obj, member, "read from private field");
- return getter ? getter.call(obj) : member.get(obj);
-};
-var __privateAdd = (obj, member, value) => {
- if (member.has(obj))
- throw TypeError("Cannot add the same private member more than once");
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
-};
-var __privateSet = (obj, member, value, setter) => {
- __accessCheck(obj, member, "write to private field");
- setter ? setter.call(obj, value) : member.set(obj, value);
- return value;
-};
-var __privateWrapper = (obj, member, setter, getter) => ({
- set _(value) {
- __privateSet(obj, member, value, setter);
- },
- get _() {
- return __privateGet(obj, member, getter);
- }
-});
-var __privateMethod = (obj, member, method) => {
- __accessCheck(obj, member, "access private method");
- return method;
-};
-
-// src/misc.ts
-var bytes = new Uint8Array(8);
-var view = new DataView(bytes.buffer);
-var u8 = (value) => {
- return [(value % 256 + 256) % 256];
-};
-var u16 = (value) => {
- view.setUint16(0, value, false);
- return [bytes[0], bytes[1]];
-};
-var i16 = (value) => {
- view.setInt16(0, value, false);
- return [bytes[0], bytes[1]];
-};
-var u24 = (value) => {
- view.setUint32(0, value, false);
- return [bytes[1], bytes[2], bytes[3]];
-};
-var u32 = (value) => {
- view.setUint32(0, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-var i32 = (value) => {
- view.setInt32(0, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-var u64 = (value) => {
- view.setUint32(0, Math.floor(value / 2 ** 32), false);
- view.setUint32(4, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];
-};
-var fixed_8_8 = (value) => {
- view.setInt16(0, 2 ** 8 * value, false);
- return [bytes[0], bytes[1]];
-};
-var fixed_16_16 = (value) => {
- view.setInt32(0, 2 ** 16 * value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-var fixed_2_30 = (value) => {
- view.setInt32(0, 2 ** 30 * value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-var ascii = (text, nullTerminated = false) => {
- let bytes2 = Array(text.length).fill(null).map((_, i) => text.charCodeAt(i));
- if (nullTerminated)
- bytes2.push(0);
- return bytes2;
-};
-var last = (arr) => {
- return arr && arr[arr.length - 1];
-};
-var lastPresentedSample = (samples) => {
- let result = void 0;
- for (let sample of samples) {
- if (!result || sample.presentationTimestamp > result.presentationTimestamp) {
- result = sample;
- }
- }
- return result;
-};
-var intoTimescale = (timeInSeconds, timescale, round = true) => {
- let value = timeInSeconds * timescale;
- return round ? Math.round(value) : value;
-};
-var rotationMatrix = (rotationInDegrees) => {
- let theta = rotationInDegrees * (Math.PI / 180);
- let cosTheta = Math.cos(theta);
- let sinTheta = Math.sin(theta);
- return [
- cosTheta,
- sinTheta,
- 0,
- -sinTheta,
- cosTheta,
- 0,
- 0,
- 0,
- 1
- ];
-};
-var IDENTITY_MATRIX = rotationMatrix(0);
-var matrixToBytes = (matrix) => {
- return [
- fixed_16_16(matrix[0]),
- fixed_16_16(matrix[1]),
- fixed_2_30(matrix[2]),
- fixed_16_16(matrix[3]),
- fixed_16_16(matrix[4]),
- fixed_2_30(matrix[5]),
- fixed_16_16(matrix[6]),
- fixed_16_16(matrix[7]),
- fixed_2_30(matrix[8])
- ];
-};
-var deepClone = (x) => {
- if (!x)
- return x;
- if (typeof x !== "object")
- return x;
- if (Array.isArray(x))
- return x.map(deepClone);
- return Object.fromEntries(Object.entries(x).map(([key, value]) => [key, deepClone(value)]));
-};
-var isU32 = (value) => {
- return value >= 0 && value < 2 ** 32;
-};
-
-// src/box.ts
-var box = (type, contents, children) => ({
- type,
- contents: contents && new Uint8Array(contents.flat(10)),
- children
-});
-var fullBox = (type, version, flags, contents, children) => box(
- type,
- [u8(version), u24(flags), contents ?? []],
- children
-);
-var ftyp = (details) => {
- let minorVersion = 512;
- if (details.fragmented)
- return box("ftyp", [
- ascii("iso5"),
- // Major brand
- u32(minorVersion),
- // Minor version
- // Compatible brands
- ascii("iso5"),
- ascii("iso6"),
- ascii("mp41")
- ]);
- return box("ftyp", [
- ascii("isom"),
- // Major brand
- u32(minorVersion),
- // Minor version
- // Compatible brands
- ascii("isom"),
- details.holdsAvc ? ascii("avc1") : [],
- ascii("mp41")
- ]);
-};
-var mdat = (reserveLargeSize) => ({ type: "mdat", largeSize: reserveLargeSize });
-var free = (size) => ({ type: "free", size });
-var moov = (tracks, creationTime, fragmented = false) => box("moov", null, [
- mvhd(creationTime, tracks),
- ...tracks.map((x) => trak(x, creationTime)),
- fragmented ? mvex(tracks) : null
-]);
-var mvhd = (creationTime, tracks) => {
- let duration = intoTimescale(Math.max(
- 0,
- ...tracks.filter((x) => x.samples.length > 0).map((x) => {
- const lastSample = lastPresentedSample(x.samples);
- return lastSample.presentationTimestamp + lastSample.duration;
- })
- ), GLOBAL_TIMESCALE);
- let nextTrackId = Math.max(...tracks.map((x) => x.id)) + 1;
- let needsU64 = !isU32(creationTime) || !isU32(duration);
- let u32OrU64 = needsU64 ? u64 : u32;
- return fullBox("mvhd", +needsU64, 0, [
- u32OrU64(creationTime),
- // Creation time
- u32OrU64(creationTime),
- // Modification time
- u32(GLOBAL_TIMESCALE),
- // Timescale
- u32OrU64(duration),
- // Duration
- fixed_16_16(1),
- // Preferred rate
- fixed_8_8(1),
- // Preferred volume
- Array(10).fill(0),
- // Reserved
- matrixToBytes(IDENTITY_MATRIX),
- // Matrix
- Array(24).fill(0),
- // Pre-defined
- u32(nextTrackId)
- // Next track ID
- ]);
-};
-var trak = (track, creationTime) => box("trak", null, [
- tkhd(track, creationTime),
- mdia(track, creationTime)
-]);
-var tkhd = (track, creationTime) => {
- let lastSample = lastPresentedSample(track.samples);
- let durationInGlobalTimescale = intoTimescale(
- lastSample ? lastSample.presentationTimestamp + lastSample.duration : 0,
- GLOBAL_TIMESCALE
- );
- let needsU64 = !isU32(creationTime) || !isU32(durationInGlobalTimescale);
- let u32OrU64 = needsU64 ? u64 : u32;
- let matrix;
- if (track.info.type === "video") {
- matrix = typeof track.info.rotation === "number" ? rotationMatrix(track.info.rotation) : track.info.rotation;
- } else {
- matrix = IDENTITY_MATRIX;
- }
- return fullBox("tkhd", +needsU64, 3, [
- u32OrU64(creationTime),
- // Creation time
- u32OrU64(creationTime),
- // Modification time
- u32(track.id),
- // Track ID
- u32(0),
- // Reserved
- u32OrU64(durationInGlobalTimescale),
- // Duration
- Array(8).fill(0),
- // Reserved
- u16(0),
- // Layer
- u16(0),
- // Alternate group
- fixed_8_8(track.info.type === "audio" ? 1 : 0),
- // Volume
- u16(0),
- // Reserved
- matrixToBytes(matrix),
- // Matrix
- fixed_16_16(track.info.type === "video" ? track.info.width : 0),
- // Track width
- fixed_16_16(track.info.type === "video" ? track.info.height : 0)
- // Track height
- ]);
-};
-var mdia = (track, creationTime) => box("mdia", null, [
- mdhd(track, creationTime),
- hdlr(track.info.type === "video" ? "vide" : "soun"),
- minf(track)
-]);
-var mdhd = (track, creationTime) => {
- let lastSample = lastPresentedSample(track.samples);
- let localDuration = intoTimescale(
- lastSample ? lastSample.presentationTimestamp + lastSample.duration : 0,
- track.timescale
- );
- let needsU64 = !isU32(creationTime) || !isU32(localDuration);
- let u32OrU64 = needsU64 ? u64 : u32;
- return fullBox("mdhd", +needsU64, 0, [
- u32OrU64(creationTime),
- // Creation time
- u32OrU64(creationTime),
- // Modification time
- u32(track.timescale),
- // Timescale
- u32OrU64(localDuration),
- // Duration
- u16(21956),
- // Language ("und", undetermined)
- u16(0)
- // Quality
- ]);
-};
-var hdlr = (componentSubtype) => fullBox("hdlr", 0, 0, [
- ascii("mhlr"),
- // Component type
- ascii(componentSubtype),
- // Component subtype
- u32(0),
- // Component manufacturer
- u32(0),
- // Component flags
- u32(0),
- // Component flags mask
- ascii("mp4-muxer-hdlr", true)
- // Component name
-]);
-var minf = (track) => box("minf", null, [
- track.info.type === "video" ? vmhd() : smhd(),
- dinf(),
- stbl(track)
-]);
-var vmhd = () => fullBox("vmhd", 0, 1, [
- u16(0),
- // Graphics mode
- u16(0),
- // Opcolor R
- u16(0),
- // Opcolor G
- u16(0)
- // Opcolor B
-]);
-var smhd = () => fullBox("smhd", 0, 0, [
- u16(0),
- // Balance
- u16(0)
- // Reserved
-]);
-var dinf = () => box("dinf", null, [
- dref()
-]);
-var dref = () => fullBox("dref", 0, 0, [
- u32(1)
- // Entry count
-], [
- url()
-]);
-var url = () => fullBox("url ", 0, 1);
-var stbl = (track) => {
- const needsCtts = track.compositionTimeOffsetTable.length > 1 || track.compositionTimeOffsetTable.some((x) => x.sampleCompositionTimeOffset !== 0);
- return box("stbl", null, [
- stsd(track),
- stts(track),
- stss(track),
- stsc(track),
- stsz(track),
- stco(track),
- needsCtts ? ctts(track) : null
- ]);
-};
-var stsd = (track) => fullBox("stsd", 0, 0, [
- u32(1)
- // Entry count
-], [
- track.info.type === "video" ? videoSampleDescription(
- VIDEO_CODEC_TO_BOX_NAME[track.info.codec],
- track
- ) : soundSampleDescription(
- AUDIO_CODEC_TO_BOX_NAME[track.info.codec],
- track
- )
-]);
-var videoSampleDescription = (compressionType, track) => box(compressionType, [
- Array(6).fill(0),
- // Reserved
- u16(1),
- // Data reference index
- u16(0),
- // Pre-defined
- u16(0),
- // Reserved
- Array(12).fill(0),
- // Pre-defined
- u16(track.info.width),
- // Width
- u16(track.info.height),
- // Height
- u32(4718592),
- // Horizontal resolution
- u32(4718592),
- // Vertical resolution
- u32(0),
- // Reserved
- u16(1),
- // Frame count
- Array(32).fill(0),
- // Compressor name
- u16(24),
- // Depth
- i16(65535)
- // Pre-defined
-], [
- VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track)
-]);
-var avcC = (track) => track.info.decoderConfig && box("avcC", [
- // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here
- ...new Uint8Array(track.info.decoderConfig.description)
-]);
-var hvcC = (track) => track.info.decoderConfig && box("hvcC", [
- // For HEVC, description is a HEVCDecoderConfigurationRecord, so nothing else to do here
- ...new Uint8Array(track.info.decoderConfig.description)
-]);
-var vpcC = (track) => {
- if (!track.info.decoderConfig) {
- return null;
- }
- let decoderConfig = track.info.decoderConfig;
- if (!decoderConfig.colorSpace) {
- throw new Error(`'colorSpace' is required in the decoder config for VP9.`);
- }
- let parts = decoderConfig.codec.split(".");
- let profile = Number(parts[1]);
- let level = Number(parts[2]);
- let bitDepth = Number(parts[3]);
- let chromaSubsampling = 0;
- let thirdByte = (bitDepth << 4) + (chromaSubsampling << 1) + Number(decoderConfig.colorSpace.fullRange);
- let colourPrimaries = 2;
- let transferCharacteristics = 2;
- let matrixCoefficients = 2;
- return fullBox("vpcC", 1, 0, [
- u8(profile),
- // Profile
- u8(level),
- // Level
- u8(thirdByte),
- // Bit depth, chroma subsampling, full range
- u8(colourPrimaries),
- // Colour primaries
- u8(transferCharacteristics),
- // Transfer characteristics
- u8(matrixCoefficients),
- // Matrix coefficients
- u16(0)
- // Codec initialization data size
- ]);
-};
-var av1C = () => {
- let marker = 1;
- let version = 1;
- let firstByte = (marker << 7) + version;
- return box("av1C", [
- firstByte,
- 0,
- 0,
- 0
- ]);
-};
-var soundSampleDescription = (compressionType, track) => box(compressionType, [
- Array(6).fill(0),
- // Reserved
- u16(1),
- // Data reference index
- u16(0),
- // Version
- u16(0),
- // Revision level
- u32(0),
- // Vendor
- u16(track.info.numberOfChannels),
- // Number of channels
- u16(16),
- // Sample size (bits)
- u16(0),
- // Compression ID
- u16(0),
- // Packet size
- fixed_16_16(track.info.sampleRate)
- // Sample rate
-], [
- AUDIO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track)
-]);
-var esds = (track) => {
- let description = new Uint8Array(track.info.decoderConfig.description);
- return fullBox("esds", 0, 0, [
- // https://stackoverflow.com/a/54803118
- u32(58753152),
- // TAG(3) = Object Descriptor ([2])
- u8(32 + description.byteLength),
- // length of this OD (which includes the next 2 tags)
- u16(1),
- // ES_ID = 1
- u8(0),
- // flags etc = 0
- u32(75530368),
- // TAG(4) = ES Descriptor ([2]) embedded in above OD
- u8(18 + description.byteLength),
- // length of this ESD
- u8(64),
- // MPEG-4 Audio
- u8(21),
- // stream type(6bits)=5 audio, flags(2bits)=1
- u24(0),
- // 24bit buffer size
- u32(130071),
- // max bitrate
- u32(130071),
- // avg bitrate
- u32(92307584),
- // TAG(5) = ASC ([2],[3]) embedded in above OD
- u8(description.byteLength),
- // length
- ...description,
- u32(109084800),
- // TAG(6)
- u8(1),
- // length
- u8(2)
- // data
- ]);
-};
-var dOps = (track) => box("dOps", [
- u8(0),
- // Version
- u8(track.info.numberOfChannels),
- // OutputChannelCount
- u16(3840),
- // PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples
- u32(track.info.sampleRate),
- // InputSampleRate
- fixed_8_8(0),
- // OutputGain
- u8(0)
- // ChannelMappingFamily
-]);
-var stts = (track) => {
- return fullBox("stts", 0, 0, [
- u32(track.timeToSampleTable.length),
- // Number of entries
- track.timeToSampleTable.map((x) => [
- // Time-to-sample table
- u32(x.sampleCount),
- // Sample count
- u32(x.sampleDelta)
- // Sample duration
- ])
- ]);
-};
-var stss = (track) => {
- if (track.samples.every((x) => x.type === "key"))
- return null;
- let keySamples = [...track.samples.entries()].filter(([, sample]) => sample.type === "key");
- return fullBox("stss", 0, 0, [
- u32(keySamples.length),
- // Number of entries
- keySamples.map(([index]) => u32(index + 1))
- // Sync sample table
- ]);
-};
-var stsc = (track) => {
- return fullBox("stsc", 0, 0, [
- u32(track.compactlyCodedChunkTable.length),
- // Number of entries
- track.compactlyCodedChunkTable.map((x) => [
- // Sample-to-chunk table
- u32(x.firstChunk),
- // First chunk
- u32(x.samplesPerChunk),
- // Samples per chunk
- u32(1)
- // Sample description index
- ])
- ]);
-};
-var stsz = (track) => fullBox("stsz", 0, 0, [
- u32(0),
- // Sample size (0 means non-constant size)
- u32(track.samples.length),
- // Number of entries
- track.samples.map((x) => u32(x.size))
- // Sample size table
-]);
-var stco = (track) => {
- if (track.finalizedChunks.length > 0 && last(track.finalizedChunks).offset >= 2 ** 32) {
- return fullBox("co64", 0, 0, [
- u32(track.finalizedChunks.length),
- // Number of entries
- track.finalizedChunks.map((x) => u64(x.offset))
- // Chunk offset table
- ]);
- }
- return fullBox("stco", 0, 0, [
- u32(track.finalizedChunks.length),
- // Number of entries
- track.finalizedChunks.map((x) => u32(x.offset))
- // Chunk offset table
- ]);
-};
-var ctts = (track) => {
- return fullBox("ctts", 0, 0, [
- u32(track.compositionTimeOffsetTable.length),
- // Number of entries
- track.compositionTimeOffsetTable.map((x) => [
- // Time-to-sample table
- u32(x.sampleCount),
- // Sample count
- u32(x.sampleCompositionTimeOffset)
- // Sample offset
- ])
- ]);
-};
-var mvex = (tracks) => {
- return box("mvex", null, tracks.map(trex));
-};
-var trex = (track) => {
- return fullBox("trex", 0, 0, [
- u32(track.id),
- // Track ID
- u32(1),
- // Default sample description index
- u32(0),
- // Default sample duration
- u32(0),
- // Default sample size
- u32(0)
- // Default sample flags
- ]);
-};
-var moof = (sequenceNumber, tracks) => {
- return box("moof", null, [
- mfhd(sequenceNumber),
- ...tracks.map(traf)
- ]);
-};
-var mfhd = (sequenceNumber) => {
- return fullBox("mfhd", 0, 0, [
- u32(sequenceNumber)
- // Sequence number
- ]);
-};
-var fragmentSampleFlags = (sample) => {
- let byte1 = 0;
- let byte2 = 0;
- let byte3 = 0;
- let byte4 = 0;
- let sampleIsDifferenceSample = sample.type === "delta";
- byte2 |= +sampleIsDifferenceSample;
- if (sampleIsDifferenceSample) {
- byte1 |= 1;
- } else {
- byte1 |= 2;
- }
- return byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
-};
-var traf = (track) => {
- return box("traf", null, [
- tfhd(track),
- tfdt(track),
- trun(track)
- ]);
-};
-var tfhd = (track) => {
- let tfFlags = 0;
- tfFlags |= 8;
- tfFlags |= 16;
- tfFlags |= 32;
- tfFlags |= 131072;
- let referenceSample = track.currentChunk.samples[1] ?? track.currentChunk.samples[0];
- let referenceSampleInfo = {
- duration: referenceSample.timescaleUnitsToNextSample,
- size: referenceSample.size,
- flags: fragmentSampleFlags(referenceSample)
- };
- return fullBox("tfhd", 0, tfFlags, [
- u32(track.id),
- // Track ID
- u32(referenceSampleInfo.duration),
- // Default sample duration
- u32(referenceSampleInfo.size),
- // Default sample size
- u32(referenceSampleInfo.flags)
- // Default sample flags
- ]);
-};
-var tfdt = (track) => {
- return fullBox("tfdt", 1, 0, [
- u64(intoTimescale(track.currentChunk.startTimestamp, track.timescale))
- // Base Media Decode Time
- ]);
-};
-var trun = (track) => {
- let allSampleDurations = track.currentChunk.samples.map((x) => x.timescaleUnitsToNextSample);
- let allSampleSizes = track.currentChunk.samples.map((x) => x.size);
- let allSampleFlags = track.currentChunk.samples.map(fragmentSampleFlags);
- let allSampleCompositionTimeOffsets = track.currentChunk.samples.map((x) => intoTimescale(x.presentationTimestamp - x.decodeTimestamp, track.timescale));
- let uniqueSampleDurations = new Set(allSampleDurations);
- let uniqueSampleSizes = new Set(allSampleSizes);
- let uniqueSampleFlags = new Set(allSampleFlags);
- let uniqueSampleCompositionTimeOffsets = new Set(allSampleCompositionTimeOffsets);
- let firstSampleFlagsPresent = uniqueSampleFlags.size === 2 && allSampleFlags[0] !== allSampleFlags[1];
- let sampleDurationPresent = uniqueSampleDurations.size > 1;
- let sampleSizePresent = uniqueSampleSizes.size > 1;
- let sampleFlagsPresent = !firstSampleFlagsPresent && uniqueSampleFlags.size > 1;
- let sampleCompositionTimeOffsetsPresent = uniqueSampleCompositionTimeOffsets.size > 1 || [...uniqueSampleCompositionTimeOffsets].some((x) => x !== 0);
- let flags = 0;
- flags |= 1;
- flags |= 4 * +firstSampleFlagsPresent;
- flags |= 256 * +sampleDurationPresent;
- flags |= 512 * +sampleSizePresent;
- flags |= 1024 * +sampleFlagsPresent;
- flags |= 2048 * +sampleCompositionTimeOffsetsPresent;
- return fullBox("trun", 1, flags, [
- u32(track.currentChunk.samples.length),
- // Sample count
- u32(track.currentChunk.offset - track.currentChunk.moofOffset || 0),
- // Data offset
- firstSampleFlagsPresent ? u32(allSampleFlags[0]) : [],
- track.currentChunk.samples.map((_, i) => [
- sampleDurationPresent ? u32(allSampleDurations[i]) : [],
- // Sample duration
- sampleSizePresent ? u32(allSampleSizes[i]) : [],
- // Sample size
- sampleFlagsPresent ? u32(allSampleFlags[i]) : [],
- // Sample flags
- // Sample composition time offsets
- sampleCompositionTimeOffsetsPresent ? i32(allSampleCompositionTimeOffsets[i]) : []
- ])
- ]);
-};
-var mfra = (tracks) => {
- return box("mfra", null, [
- ...tracks.map(tfra),
- mfro()
- ]);
-};
-var tfra = (track, trackIndex) => {
- let version = 1;
- return fullBox("tfra", version, 0, [
- u32(track.id),
- // Track ID
- u32(63),
- // This specifies that traf number, trun number and sample number are 32-bit ints
- u32(track.finalizedChunks.length),
- // Number of entries
- track.finalizedChunks.map((chunk) => [
- u64(intoTimescale(chunk.startTimestamp, track.timescale)),
- // Time
- u64(chunk.moofOffset),
- // moof offset
- u32(trackIndex + 1),
- // traf number
- u32(1),
- // trun number
- u32(1)
- // Sample number
- ])
- ]);
-};
-var mfro = () => {
- return fullBox("mfro", 0, 0, [
- // This value needs to be overwritten manually from the outside, where the actual size of the enclosing mfra box
- // is known
- u32(0)
- // Size
- ]);
-};
-var VIDEO_CODEC_TO_BOX_NAME = {
- "avc": "avc1",
- "hevc": "hvc1",
- "vp9": "vp09",
- "av1": "av01"
-};
-var VIDEO_CODEC_TO_CONFIGURATION_BOX = {
- "avc": avcC,
- "hevc": hvcC,
- "vp9": vpcC,
- "av1": av1C
-};
-var AUDIO_CODEC_TO_BOX_NAME = {
- "aac": "mp4a",
- "opus": "Opus"
-};
-var AUDIO_CODEC_TO_CONFIGURATION_BOX = {
- "aac": esds,
- "opus": dOps
-};
-
-// src/target.ts
-var ArrayBufferTarget = class {
- constructor() {
- this.buffer = null;
- }
-};
-var StreamTarget = class {
- constructor(options) {
- this.options = options;
- }
-};
-var FileSystemWritableFileStreamTarget = class {
- constructor(stream, options) {
- this.stream = stream;
- this.options = options;
- }
-};
-
-// src/writer.ts
-var _helper, _helperView;
-var Writer = class {
- constructor() {
- this.pos = 0;
- __privateAdd(this, _helper, new Uint8Array(8));
- __privateAdd(this, _helperView, new DataView(__privateGet(this, _helper).buffer));
- /**
- * Stores the position from the start of the file to where boxes elements have been written. This is used to
- * rewrite/edit elements that were already added before, and to measure sizes of things.
- */
- this.offsets = /* @__PURE__ */ new WeakMap();
- }
- /** Sets the current position for future writes to a new one. */
- seek(newPos) {
- this.pos = newPos;
- }
- writeU32(value) {
- __privateGet(this, _helperView).setUint32(0, value, false);
- this.write(__privateGet(this, _helper).subarray(0, 4));
- }
- writeU64(value) {
- __privateGet(this, _helperView).setUint32(0, Math.floor(value / 2 ** 32), false);
- __privateGet(this, _helperView).setUint32(4, value, false);
- this.write(__privateGet(this, _helper).subarray(0, 8));
- }
- writeAscii(text) {
- for (let i = 0; i < text.length; i++) {
- __privateGet(this, _helperView).setUint8(i % 8, text.charCodeAt(i));
- if (i % 8 === 7)
- this.write(__privateGet(this, _helper));
- }
- if (text.length % 8 !== 0) {
- this.write(__privateGet(this, _helper).subarray(0, text.length % 8));
- }
- }
- writeBox(box2) {
- this.offsets.set(box2, this.pos);
- if (box2.contents && !box2.children) {
- this.writeBoxHeader(box2, box2.size ?? box2.contents.byteLength + 8);
- this.write(box2.contents);
- } else {
- let startPos = this.pos;
- this.writeBoxHeader(box2, 0);
- if (box2.contents)
- this.write(box2.contents);
- if (box2.children) {
- for (let child of box2.children)
- if (child)
- this.writeBox(child);
- }
- let endPos = this.pos;
- let size = box2.size ?? endPos - startPos;
- this.seek(startPos);
- this.writeBoxHeader(box2, size);
- this.seek(endPos);
- }
- }
- writeBoxHeader(box2, size) {
- this.writeU32(box2.largeSize ? 1 : size);
- this.writeAscii(box2.type);
- if (box2.largeSize)
- this.writeU64(size);
- }
- measureBoxHeader(box2) {
- return 8 + (box2.largeSize ? 8 : 0);
- }
- patchBox(box2) {
- let endPos = this.pos;
- this.seek(this.offsets.get(box2));
- this.writeBox(box2);
- this.seek(endPos);
- }
- measureBox(box2) {
- if (box2.contents && !box2.children) {
- let headerSize = this.measureBoxHeader(box2);
- return headerSize + box2.contents.byteLength;
- } else {
- let result = this.measureBoxHeader(box2);
- if (box2.contents)
- result += box2.contents.byteLength;
- if (box2.children) {
- for (let child of box2.children)
- if (child)
- result += this.measureBox(child);
- }
- return result;
- }
- }
-};
-_helper = new WeakMap();
-_helperView = new WeakMap();
-var _target, _buffer, _bytes, _maxPos, _ensureSize, ensureSize_fn;
-var ArrayBufferTargetWriter = class extends Writer {
- constructor(target) {
- super();
- __privateAdd(this, _ensureSize);
- __privateAdd(this, _target, void 0);
- __privateAdd(this, _buffer, new ArrayBuffer(2 ** 16));
- __privateAdd(this, _bytes, new Uint8Array(__privateGet(this, _buffer)));
- __privateAdd(this, _maxPos, 0);
- __privateSet(this, _target, target);
- }
- write(data) {
- __privateMethod(this, _ensureSize, ensureSize_fn).call(this, this.pos + data.byteLength);
- __privateGet(this, _bytes).set(data, this.pos);
- this.pos += data.byteLength;
- __privateSet(this, _maxPos, Math.max(__privateGet(this, _maxPos), this.pos));
- }
- finalize() {
- __privateMethod(this, _ensureSize, ensureSize_fn).call(this, this.pos);
- __privateGet(this, _target).buffer = __privateGet(this, _buffer).slice(0, Math.max(__privateGet(this, _maxPos), this.pos));
- }
-};
-_target = new WeakMap();
-_buffer = new WeakMap();
-_bytes = new WeakMap();
-_maxPos = new WeakMap();
-_ensureSize = new WeakSet();
-ensureSize_fn = function(size) {
- let newLength = __privateGet(this, _buffer).byteLength;
- while (newLength < size)
- newLength *= 2;
- if (newLength === __privateGet(this, _buffer).byteLength)
- return;
- let newBuffer = new ArrayBuffer(newLength);
- let newBytes = new Uint8Array(newBuffer);
- newBytes.set(__privateGet(this, _bytes), 0);
- __privateSet(this, _buffer, newBuffer);
- __privateSet(this, _bytes, newBytes);
-};
-var _target2, _sections;
-var StreamTargetWriter = class extends Writer {
- constructor(target) {
- super();
- __privateAdd(this, _target2, void 0);
- __privateAdd(this, _sections, []);
- __privateSet(this, _target2, target);
- }
- write(data) {
- __privateGet(this, _sections).push({
- data: data.slice(),
- start: this.pos
- });
- this.pos += data.byteLength;
- }
- flush() {
- if (__privateGet(this, _sections).length === 0)
- return;
- let chunks = [];
- let sorted = [...__privateGet(this, _sections)].sort((a, b) => a.start - b.start);
- chunks.push({
- start: sorted[0].start,
- size: sorted[0].data.byteLength
- });
- for (let i = 1; i < sorted.length; i++) {
- let lastChunk = chunks[chunks.length - 1];
- let section = sorted[i];
- if (section.start <= lastChunk.start + lastChunk.size) {
- lastChunk.size = Math.max(lastChunk.size, section.start + section.data.byteLength - lastChunk.start);
- } else {
- chunks.push({
- start: section.start,
- size: section.data.byteLength
- });
- }
- }
- for (let chunk of chunks) {
- chunk.data = new Uint8Array(chunk.size);
- for (let section of __privateGet(this, _sections)) {
- if (chunk.start <= section.start && section.start < chunk.start + chunk.size) {
- chunk.data.set(section.data, section.start - chunk.start);
- }
- }
- __privateGet(this, _target2).options.onData?.(chunk.data, chunk.start);
- }
- __privateGet(this, _sections).length = 0;
- }
- finalize() {
- }
-};
-_target2 = new WeakMap();
-_sections = new WeakMap();
-var DEFAULT_CHUNK_SIZE = 2 ** 24;
-var MAX_CHUNKS_AT_ONCE = 2;
-var _target3, _chunkSize, _chunks, _writeDataIntoChunks, writeDataIntoChunks_fn, _insertSectionIntoChunk, insertSectionIntoChunk_fn, _createChunk, createChunk_fn, _flushChunks, flushChunks_fn;
-var ChunkedStreamTargetWriter = class extends Writer {
- constructor(target) {
- super();
- __privateAdd(this, _writeDataIntoChunks);
- __privateAdd(this, _insertSectionIntoChunk);
- __privateAdd(this, _createChunk);
- __privateAdd(this, _flushChunks);
- __privateAdd(this, _target3, void 0);
- __privateAdd(this, _chunkSize, void 0);
- /**
- * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out.
- * A chunk is flushed if all of its contents have been written.
- */
- __privateAdd(this, _chunks, []);
- __privateSet(this, _target3, target);
- __privateSet(this, _chunkSize, target.options?.chunkSize ?? DEFAULT_CHUNK_SIZE);
- if (!Number.isInteger(__privateGet(this, _chunkSize)) || __privateGet(this, _chunkSize) < 2 ** 10) {
- throw new Error("Invalid StreamTarget options: chunkSize must be an integer not smaller than 1024.");
- }
- }
- write(data) {
- __privateMethod(this, _writeDataIntoChunks, writeDataIntoChunks_fn).call(this, data, this.pos);
- __privateMethod(this, _flushChunks, flushChunks_fn).call(this);
- this.pos += data.byteLength;
- }
- finalize() {
- __privateMethod(this, _flushChunks, flushChunks_fn).call(this, true);
- }
-};
-_target3 = new WeakMap();
-_chunkSize = new WeakMap();
-_chunks = new WeakMap();
-_writeDataIntoChunks = new WeakSet();
-writeDataIntoChunks_fn = function(data, position) {
- let chunkIndex = __privateGet(this, _chunks).findIndex((x) => x.start <= position && position < x.start + __privateGet(this, _chunkSize));
- if (chunkIndex === -1)
- chunkIndex = __privateMethod(this, _createChunk, createChunk_fn).call(this, position);
- let chunk = __privateGet(this, _chunks)[chunkIndex];
- let relativePosition = position - chunk.start;
- let toWrite = data.subarray(0, Math.min(__privateGet(this, _chunkSize) - relativePosition, data.byteLength));
- chunk.data.set(toWrite, relativePosition);
- let section = {
- start: relativePosition,
- end: relativePosition + toWrite.byteLength
- };
- __privateMethod(this, _insertSectionIntoChunk, insertSectionIntoChunk_fn).call(this, chunk, section);
- if (chunk.written[0].start === 0 && chunk.written[0].end === __privateGet(this, _chunkSize)) {
- chunk.shouldFlush = true;
- }
- if (__privateGet(this, _chunks).length > MAX_CHUNKS_AT_ONCE) {
- for (let i = 0; i < __privateGet(this, _chunks).length - 1; i++) {
- __privateGet(this, _chunks)[i].shouldFlush = true;
- }
- __privateMethod(this, _flushChunks, flushChunks_fn).call(this);
- }
- if (toWrite.byteLength < data.byteLength) {
- __privateMethod(this, _writeDataIntoChunks, writeDataIntoChunks_fn).call(this, data.subarray(toWrite.byteLength), position + toWrite.byteLength);
- }
-};
-_insertSectionIntoChunk = new WeakSet();
-insertSectionIntoChunk_fn = function(chunk, section) {
- let low = 0;
- let high = chunk.written.length - 1;
- let index = -1;
- while (low <= high) {
- let mid = Math.floor(low + (high - low + 1) / 2);
- if (chunk.written[mid].start <= section.start) {
- low = mid + 1;
- index = mid;
- } else {
- high = mid - 1;
- }
- }
- chunk.written.splice(index + 1, 0, section);
- if (index === -1 || chunk.written[index].end < section.start)
- index++;
- while (index < chunk.written.length - 1 && chunk.written[index].end >= chunk.written[index + 1].start) {
- chunk.written[index].end = Math.max(chunk.written[index].end, chunk.written[index + 1].end);
- chunk.written.splice(index + 1, 1);
- }
-};
-_createChunk = new WeakSet();
-createChunk_fn = function(includesPosition) {
- let start = Math.floor(includesPosition / __privateGet(this, _chunkSize)) * __privateGet(this, _chunkSize);
- let chunk = {
- start,
- data: new Uint8Array(__privateGet(this, _chunkSize)),
- written: [],
- shouldFlush: false
- };
- __privateGet(this, _chunks).push(chunk);
- __privateGet(this, _chunks).sort((a, b) => a.start - b.start);
- return __privateGet(this, _chunks).indexOf(chunk);
-};
-_flushChunks = new WeakSet();
-flushChunks_fn = function(force = false) {
- for (let i = 0; i < __privateGet(this, _chunks).length; i++) {
- let chunk = __privateGet(this, _chunks)[i];
- if (!chunk.shouldFlush && !force)
- continue;
- for (let section of chunk.written) {
- __privateGet(this, _target3).options.onData?.(
- chunk.data.subarray(section.start, section.end),
- chunk.start + section.start
- );
- }
- __privateGet(this, _chunks).splice(i--, 1);
- }
-};
-var FileSystemWritableFileStreamTargetWriter = class extends ChunkedStreamTargetWriter {
- constructor(target) {
- super(new StreamTarget({
- onData: (data, position) => target.stream.write({
- type: "write",
- data,
- position
- }),
- chunkSize: target.options?.chunkSize
- }));
- }
-};
-
-// src/muxer.ts
-var GLOBAL_TIMESCALE = 1e3;
-var SUPPORTED_VIDEO_CODECS2 = ["avc", "hevc", "vp9", "av1"];
-var SUPPORTED_AUDIO_CODECS2 = ["aac", "opus"];
-var TIMESTAMP_OFFSET = 2082844800;
-var FIRST_TIMESTAMP_BEHAVIORS = ["strict", "offset", "cross-track-offset"];
-var _options, _writer, _ftypSize, _mdat, _videoTrack, _audioTrack, _creationTime, _finalizedChunks, _nextFragmentNumber, _videoSampleQueue, _audioSampleQueue, _finalized, _validateOptions, validateOptions_fn, _writeHeader, writeHeader_fn, _computeMoovSizeUpperBound, computeMoovSizeUpperBound_fn, _prepareTracks, prepareTracks_fn, _generateMpeg4AudioSpecificConfig, generateMpeg4AudioSpecificConfig_fn, _createSampleForTrack, createSampleForTrack_fn, _addSampleToTrack, addSampleToTrack_fn, _validateTimestamp, validateTimestamp_fn, _finalizeCurrentChunk, finalizeCurrentChunk_fn, _finalizeFragment, finalizeFragment_fn, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn, _ensureNotFinalized, ensureNotFinalized_fn;
-var Muxer = class {
- constructor(options) {
- __privateAdd(this, _validateOptions);
- __privateAdd(this, _writeHeader);
- __privateAdd(this, _computeMoovSizeUpperBound);
- __privateAdd(this, _prepareTracks);
- // https://wiki.multimedia.cx/index.php/MPEG-4_Audio
- __privateAdd(this, _generateMpeg4AudioSpecificConfig);
- __privateAdd(this, _createSampleForTrack);
- __privateAdd(this, _addSampleToTrack);
- __privateAdd(this, _validateTimestamp);
- __privateAdd(this, _finalizeCurrentChunk);
- __privateAdd(this, _finalizeFragment);
- __privateAdd(this, _maybeFlushStreamingTargetWriter);
- __privateAdd(this, _ensureNotFinalized);
- __privateAdd(this, _options, void 0);
- __privateAdd(this, _writer, void 0);
- __privateAdd(this, _ftypSize, void 0);
- __privateAdd(this, _mdat, void 0);
- __privateAdd(this, _videoTrack, null);
- __privateAdd(this, _audioTrack, null);
- __privateAdd(this, _creationTime, Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET);
- __privateAdd(this, _finalizedChunks, []);
- // Fields for fragmented MP4:
- __privateAdd(this, _nextFragmentNumber, 1);
- __privateAdd(this, _videoSampleQueue, []);
- __privateAdd(this, _audioSampleQueue, []);
- __privateAdd(this, _finalized, false);
- __privateMethod(this, _validateOptions, validateOptions_fn).call(this, options);
- options.video = deepClone(options.video);
- options.audio = deepClone(options.audio);
- options.fastStart = deepClone(options.fastStart);
- this.target = options.target;
- __privateSet(this, _options, {
- firstTimestampBehavior: "strict",
- ...options
- });
- if (options.target instanceof ArrayBufferTarget) {
- __privateSet(this, _writer, new ArrayBufferTargetWriter(options.target));
- } else if (options.target instanceof StreamTarget) {
- __privateSet(this, _writer, options.target.options?.chunked ? new ChunkedStreamTargetWriter(options.target) : new StreamTargetWriter(options.target));
- } else if (options.target instanceof FileSystemWritableFileStreamTarget) {
- __privateSet(this, _writer, new FileSystemWritableFileStreamTargetWriter(options.target));
- } else {
- throw new Error(`Invalid target: ${options.target}`);
- }
- __privateMethod(this, _prepareTracks, prepareTracks_fn).call(this);
- __privateMethod(this, _writeHeader, writeHeader_fn).call(this);
- }
- addVideoChunk(sample, meta, timestamp, compositionTimeOffset) {
- let data = new Uint8Array(sample.byteLength);
- sample.copyTo(data);
- this.addVideoChunkRaw(
- data,
- sample.type,
- timestamp ?? sample.timestamp,
- sample.duration,
- meta,
- compositionTimeOffset
- );
- }
- addVideoChunkRaw(data, type, timestamp, duration, meta, compositionTimeOffset) {
- __privateMethod(this, _ensureNotFinalized, ensureNotFinalized_fn).call(this);
- if (!__privateGet(this, _options).video)
- throw new Error("No video track declared.");
- if (typeof __privateGet(this, _options).fastStart === "object" && __privateGet(this, _videoTrack).samples.length === __privateGet(this, _options).fastStart.expectedVideoChunks) {
- throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${__privateGet(this, _options).fastStart.expectedVideoChunks}).`);
- }
- let videoSample = __privateMethod(this, _createSampleForTrack, createSampleForTrack_fn).call(this, __privateGet(this, _videoTrack), data, type, timestamp, duration, meta, compositionTimeOffset);
- if (__privateGet(this, _options).fastStart === "fragmented" && __privateGet(this, _audioTrack)) {
- while (__privateGet(this, _audioSampleQueue).length > 0 && __privateGet(this, _audioSampleQueue)[0].decodeTimestamp <= videoSample.decodeTimestamp) {
- let audioSample = __privateGet(this, _audioSampleQueue).shift();
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- }
- if (videoSample.decodeTimestamp <= __privateGet(this, _audioTrack).lastDecodeTimestamp) {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- } else {
- __privateGet(this, _videoSampleQueue).push(videoSample);
- }
- } else {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- }
- }
- addAudioChunk(sample, meta, timestamp) {
- let data = new Uint8Array(sample.byteLength);
- sample.copyTo(data);
- this.addAudioChunkRaw(data, sample.type, timestamp ?? sample.timestamp, sample.duration, meta);
- }
- addAudioChunkRaw(data, type, timestamp, duration, meta) {
- __privateMethod(this, _ensureNotFinalized, ensureNotFinalized_fn).call(this);
- if (!__privateGet(this, _options).audio)
- throw new Error("No audio track declared.");
- if (typeof __privateGet(this, _options).fastStart === "object" && __privateGet(this, _audioTrack).samples.length === __privateGet(this, _options).fastStart.expectedAudioChunks) {
- throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${__privateGet(this, _options).fastStart.expectedAudioChunks}).`);
- }
- let audioSample = __privateMethod(this, _createSampleForTrack, createSampleForTrack_fn).call(this, __privateGet(this, _audioTrack), data, type, timestamp, duration, meta);
- if (__privateGet(this, _options).fastStart === "fragmented" && __privateGet(this, _videoTrack)) {
- while (__privateGet(this, _videoSampleQueue).length > 0 && __privateGet(this, _videoSampleQueue)[0].decodeTimestamp <= audioSample.decodeTimestamp) {
- let videoSample = __privateGet(this, _videoSampleQueue).shift();
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- }
- if (audioSample.decodeTimestamp <= __privateGet(this, _videoTrack).lastDecodeTimestamp) {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- } else {
- __privateGet(this, _audioSampleQueue).push(audioSample);
- }
- } else {
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- }
- }
- /** Finalizes the file, making it ready for use. Must be called after all video and audio chunks have been added. */
- finalize() {
- if (__privateGet(this, _finalized)) {
- throw new Error("Cannot finalize a muxer more than once.");
- }
- if (__privateGet(this, _options).fastStart === "fragmented") {
- for (let videoSample of __privateGet(this, _videoSampleQueue))
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _videoTrack), videoSample);
- for (let audioSample of __privateGet(this, _audioSampleQueue))
- __privateMethod(this, _addSampleToTrack, addSampleToTrack_fn).call(this, __privateGet(this, _audioTrack), audioSample);
- __privateMethod(this, _finalizeFragment, finalizeFragment_fn).call(this, false);
- } else {
- if (__privateGet(this, _videoTrack))
- __privateMethod(this, _finalizeCurrentChunk, finalizeCurrentChunk_fn).call(this, __privateGet(this, _videoTrack));
- if (__privateGet(this, _audioTrack))
- __privateMethod(this, _finalizeCurrentChunk, finalizeCurrentChunk_fn).call(this, __privateGet(this, _audioTrack));
- }
- let tracks = [__privateGet(this, _videoTrack), __privateGet(this, _audioTrack)].filter(Boolean);
- if (__privateGet(this, _options).fastStart === "in-memory") {
- let mdatSize;
- for (let i = 0; i < 2; i++) {
- let movieBox2 = moov(tracks, __privateGet(this, _creationTime));
- let movieBoxSize = __privateGet(this, _writer).measureBox(movieBox2);
- mdatSize = __privateGet(this, _writer).measureBox(__privateGet(this, _mdat));
- let currentChunkPos = __privateGet(this, _writer).pos + movieBoxSize + mdatSize;
- for (let chunk of __privateGet(this, _finalizedChunks)) {
- chunk.offset = currentChunkPos;
- for (let { data } of chunk.samples) {
- currentChunkPos += data.byteLength;
- mdatSize += data.byteLength;
- }
- }
- if (currentChunkPos < 2 ** 32)
- break;
- if (mdatSize >= 2 ** 32)
- __privateGet(this, _mdat).largeSize = true;
- }
- let movieBox = moov(tracks, __privateGet(this, _creationTime));
- __privateGet(this, _writer).writeBox(movieBox);
- __privateGet(this, _mdat).size = mdatSize;
- __privateGet(this, _writer).writeBox(__privateGet(this, _mdat));
- for (let chunk of __privateGet(this, _finalizedChunks)) {
- for (let sample of chunk.samples) {
- __privateGet(this, _writer).write(sample.data);
- sample.data = null;
- }
- }
- } else if (__privateGet(this, _options).fastStart === "fragmented") {
- let startPos = __privateGet(this, _writer).pos;
- let mfraBox = mfra(tracks);
- __privateGet(this, _writer).writeBox(mfraBox);
- let mfraBoxSize = __privateGet(this, _writer).pos - startPos;
- __privateGet(this, _writer).seek(__privateGet(this, _writer).pos - 4);
- __privateGet(this, _writer).writeU32(mfraBoxSize);
- } else {
- let mdatPos = __privateGet(this, _writer).offsets.get(__privateGet(this, _mdat));
- let mdatSize = __privateGet(this, _writer).pos - mdatPos;
- __privateGet(this, _mdat).size = mdatSize;
- __privateGet(this, _mdat).largeSize = mdatSize >= 2 ** 32;
- __privateGet(this, _writer).patchBox(__privateGet(this, _mdat));
- let movieBox = moov(tracks, __privateGet(this, _creationTime));
- if (typeof __privateGet(this, _options).fastStart === "object") {
- __privateGet(this, _writer).seek(__privateGet(this, _ftypSize));
- __privateGet(this, _writer).writeBox(movieBox);
- let remainingBytes = mdatPos - __privateGet(this, _writer).pos;
- __privateGet(this, _writer).writeBox(free(remainingBytes));
- } else {
- __privateGet(this, _writer).writeBox(movieBox);
- }
- }
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
- __privateGet(this, _writer).finalize();
- __privateSet(this, _finalized, true);
- }
-};
-_options = new WeakMap();
-_writer = new WeakMap();
-_ftypSize = new WeakMap();
-_mdat = new WeakMap();
-_videoTrack = new WeakMap();
-_audioTrack = new WeakMap();
-_creationTime = new WeakMap();
-_finalizedChunks = new WeakMap();
-_nextFragmentNumber = new WeakMap();
-_videoSampleQueue = new WeakMap();
-_audioSampleQueue = new WeakMap();
-_finalized = new WeakMap();
-_validateOptions = new WeakSet();
-validateOptions_fn = function(options) {
- if (options.video) {
- if (!SUPPORTED_VIDEO_CODECS2.includes(options.video.codec)) {
- throw new Error(`Unsupported video codec: ${options.video.codec}`);
- }
- const videoRotation = options.video.rotation;
- if (typeof videoRotation === "number" && ![0, 90, 180, 270].includes(videoRotation)) {
- throw new Error(`Invalid video rotation: ${videoRotation}. Has to be 0, 90, 180 or 270.`);
- } else if (Array.isArray(videoRotation) && (videoRotation.length !== 9 || videoRotation.some((value) => typeof value !== "number"))) {
- throw new Error(`Invalid video transformation matrix: ${videoRotation.join()}`);
- }
- }
- if (options.audio && !SUPPORTED_AUDIO_CODECS2.includes(options.audio.codec)) {
- throw new Error(`Unsupported audio codec: ${options.audio.codec}`);
- }
- if (options.firstTimestampBehavior && !FIRST_TIMESTAMP_BEHAVIORS.includes(options.firstTimestampBehavior)) {
- throw new Error(`Invalid first timestamp behavior: ${options.firstTimestampBehavior}`);
- }
- if (typeof options.fastStart === "object") {
- if (options.video && options.fastStart.expectedVideoChunks === void 0) {
- throw new Error(`'fastStart' is an object but is missing property 'expectedVideoChunks'.`);
- }
- if (options.audio && options.fastStart.expectedAudioChunks === void 0) {
- throw new Error(`'fastStart' is an object but is missing property 'expectedAudioChunks'.`);
- }
- } else if (![false, "in-memory", "fragmented"].includes(options.fastStart)) {
- throw new Error(`'fastStart' option must be false, 'in-memory', 'fragmented' or an object.`);
- }
-};
-_writeHeader = new WeakSet();
-writeHeader_fn = function() {
- __privateGet(this, _writer).writeBox(ftyp({
- holdsAvc: __privateGet(this, _options).video?.codec === "avc",
- fragmented: __privateGet(this, _options).fastStart === "fragmented"
- }));
- __privateSet(this, _ftypSize, __privateGet(this, _writer).pos);
- if (__privateGet(this, _options).fastStart === "in-memory") {
- __privateSet(this, _mdat, mdat(false));
- } else if (__privateGet(this, _options).fastStart === "fragmented") {
- } else {
- if (typeof __privateGet(this, _options).fastStart === "object") {
- let moovSizeUpperBound = __privateMethod(this, _computeMoovSizeUpperBound, computeMoovSizeUpperBound_fn).call(this);
- __privateGet(this, _writer).seek(__privateGet(this, _writer).pos + moovSizeUpperBound);
- }
- __privateSet(this, _mdat, mdat(true));
- __privateGet(this, _writer).writeBox(__privateGet(this, _mdat));
- }
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
-};
-_computeMoovSizeUpperBound = new WeakSet();
-computeMoovSizeUpperBound_fn = function() {
- if (typeof __privateGet(this, _options).fastStart !== "object")
- return;
- let upperBound = 0;
- let sampleCounts = [
- __privateGet(this, _options).fastStart.expectedVideoChunks,
- __privateGet(this, _options).fastStart.expectedAudioChunks
- ];
- for (let n of sampleCounts) {
- if (!n)
- continue;
- upperBound += (4 + 4) * Math.ceil(2 / 3 * n);
- upperBound += 4 * n;
- upperBound += (4 + 4 + 4) * Math.ceil(2 / 3 * n);
- upperBound += 4 * n;
- upperBound += 8 * n;
- }
- upperBound += 4096;
- return upperBound;
-};
-_prepareTracks = new WeakSet();
-prepareTracks_fn = function() {
- if (__privateGet(this, _options).video) {
- __privateSet(this, _videoTrack, {
- id: 1,
- info: {
- type: "video",
- codec: __privateGet(this, _options).video.codec,
- width: __privateGet(this, _options).video.width,
- height: __privateGet(this, _options).video.height,
- rotation: __privateGet(this, _options).video.rotation ?? 0,
- decoderConfig: null
- },
- timescale: 11520,
- // Timescale used by FFmpeg, contains many common frame rates as factors
- samples: [],
- finalizedChunks: [],
- currentChunk: null,
- firstDecodeTimestamp: void 0,
- lastDecodeTimestamp: -1,
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- compactlyCodedChunkTable: []
- });
- }
- if (__privateGet(this, _options).audio) {
- let guessedCodecPrivate = __privateMethod(this, _generateMpeg4AudioSpecificConfig, generateMpeg4AudioSpecificConfig_fn).call(
- this,
- 2,
- // Object type for AAC-LC, since it's the most common
- __privateGet(this, _options).audio.sampleRate,
- __privateGet(this, _options).audio.numberOfChannels
- );
- __privateSet(this, _audioTrack, {
- id: __privateGet(this, _options).video ? 2 : 1,
- info: {
- type: "audio",
- codec: __privateGet(this, _options).audio.codec,
- numberOfChannels: __privateGet(this, _options).audio.numberOfChannels,
- sampleRate: __privateGet(this, _options).audio.sampleRate,
- decoderConfig: {
- codec: __privateGet(this, _options).audio.codec,
- description: guessedCodecPrivate,
- numberOfChannels: __privateGet(this, _options).audio.numberOfChannels,
- sampleRate: __privateGet(this, _options).audio.sampleRate
- }
- },
- timescale: __privateGet(this, _options).audio.sampleRate,
- samples: [],
- finalizedChunks: [],
- currentChunk: null,
- firstDecodeTimestamp: void 0,
- lastDecodeTimestamp: -1,
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- compactlyCodedChunkTable: []
- });
- }
-};
-_generateMpeg4AudioSpecificConfig = new WeakSet();
-generateMpeg4AudioSpecificConfig_fn = function(objectType, sampleRate, numberOfChannels) {
- let frequencyIndices = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350];
- let frequencyIndex = frequencyIndices.indexOf(sampleRate);
- let channelConfig = numberOfChannels;
- let configBits = "";
- configBits += objectType.toString(2).padStart(5, "0");
- configBits += frequencyIndex.toString(2).padStart(4, "0");
- if (frequencyIndex === 15)
- configBits += sampleRate.toString(2).padStart(24, "0");
- configBits += channelConfig.toString(2).padStart(4, "0");
- let paddingLength = Math.ceil(configBits.length / 8) * 8;
- configBits = configBits.padEnd(paddingLength, "0");
- let configBytes = new Uint8Array(configBits.length / 8);
- for (let i = 0; i < configBits.length; i += 8) {
- configBytes[i / 8] = parseInt(configBits.slice(i, i + 8), 2);
- }
- return configBytes;
-};
-_createSampleForTrack = new WeakSet();
-createSampleForTrack_fn = function(track, data, type, timestamp, duration, meta, compositionTimeOffset) {
- let presentationTimestampInSeconds = timestamp / 1e6;
- let decodeTimestampInSeconds = (timestamp - (compositionTimeOffset ?? 0)) / 1e6;
- let durationInSeconds = duration / 1e6;
- let adjusted = __privateMethod(this, _validateTimestamp, validateTimestamp_fn).call(this, presentationTimestampInSeconds, decodeTimestampInSeconds, track);
- presentationTimestampInSeconds = adjusted.presentationTimestamp;
- decodeTimestampInSeconds = adjusted.decodeTimestamp;
- if (meta?.decoderConfig) {
- if (track.info.decoderConfig === null) {
- track.info.decoderConfig = meta.decoderConfig;
- } else {
- Object.assign(track.info.decoderConfig, meta.decoderConfig);
- }
- }
- let sample = {
- presentationTimestamp: presentationTimestampInSeconds,
- decodeTimestamp: decodeTimestampInSeconds,
- duration: durationInSeconds,
- data,
- size: data.byteLength,
- type,
- // Will be refined once the next sample comes in
- timescaleUnitsToNextSample: intoTimescale(durationInSeconds, track.timescale)
- };
- return sample;
-};
-_addSampleToTrack = new WeakSet();
-addSampleToTrack_fn = function(track, sample) {
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- track.samples.push(sample);
- }
- const sampleCompositionTimeOffset = intoTimescale(sample.presentationTimestamp - sample.decodeTimestamp, track.timescale);
- if (track.lastTimescaleUnits !== null) {
- let timescaleUnits = intoTimescale(sample.decodeTimestamp, track.timescale, false);
- let delta = Math.round(timescaleUnits - track.lastTimescaleUnits);
- track.lastTimescaleUnits += delta;
- track.lastSample.timescaleUnitsToNextSample = delta;
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- let lastTableEntry = last(track.timeToSampleTable);
- if (lastTableEntry.sampleCount === 1) {
- lastTableEntry.sampleDelta = delta;
- lastTableEntry.sampleCount++;
- } else if (lastTableEntry.sampleDelta === delta) {
- lastTableEntry.sampleCount++;
- } else {
- lastTableEntry.sampleCount--;
- track.timeToSampleTable.push({
- sampleCount: 2,
- sampleDelta: delta
- });
- }
- const lastCompositionTimeOffsetTableEntry = last(track.compositionTimeOffsetTable);
- if (lastCompositionTimeOffsetTableEntry.sampleCompositionTimeOffset === sampleCompositionTimeOffset) {
- lastCompositionTimeOffsetTableEntry.sampleCount++;
- } else {
- track.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset
- });
- }
- }
- } else {
- track.lastTimescaleUnits = 0;
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- track.timeToSampleTable.push({
- sampleCount: 1,
- sampleDelta: intoTimescale(sample.duration, track.timescale)
- });
- track.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset
- });
- }
- }
- track.lastSample = sample;
- let beginNewChunk = false;
- if (!track.currentChunk) {
- beginNewChunk = true;
- } else {
- let currentChunkDuration = sample.presentationTimestamp - track.currentChunk.startTimestamp;
- if (__privateGet(this, _options).fastStart === "fragmented") {
- let mostImportantTrack = __privateGet(this, _videoTrack) ?? __privateGet(this, _audioTrack);
- if (track === mostImportantTrack && sample.type === "key" && currentChunkDuration >= 1) {
- beginNewChunk = true;
- __privateMethod(this, _finalizeFragment, finalizeFragment_fn).call(this);
- }
- } else {
- beginNewChunk = currentChunkDuration >= 0.5;
- }
- }
- if (beginNewChunk) {
- if (track.currentChunk) {
- __privateMethod(this, _finalizeCurrentChunk, finalizeCurrentChunk_fn).call(this, track);
- }
- track.currentChunk = {
- startTimestamp: sample.presentationTimestamp,
- samples: []
- };
- }
- track.currentChunk.samples.push(sample);
-};
-_validateTimestamp = new WeakSet();
-validateTimestamp_fn = function(presentationTimestamp, decodeTimestamp, track) {
- const strictTimestampBehavior = __privateGet(this, _options).firstTimestampBehavior === "strict";
- const noLastDecodeTimestamp = track.lastDecodeTimestamp === -1;
- const timestampNonZero = decodeTimestamp !== 0;
- if (strictTimestampBehavior && noLastDecodeTimestamp && timestampNonZero) {
- throw new Error(
- `The first chunk for your media track must have a timestamp of 0 (received DTS=${decodeTimestamp}).Non-zero first timestamps are often caused by directly piping frames or audio data from a MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of thedocument, which is probably what you want.
-
-If you want to offset all timestamps of a track such that the first one is zero, set firstTimestampBehavior: 'offset' in the options.
-`
- );
- } else if (__privateGet(this, _options).firstTimestampBehavior === "offset" || __privateGet(this, _options).firstTimestampBehavior === "cross-track-offset") {
- if (track.firstDecodeTimestamp === void 0) {
- track.firstDecodeTimestamp = decodeTimestamp;
- }
- let baseDecodeTimestamp;
- if (__privateGet(this, _options).firstTimestampBehavior === "offset") {
- baseDecodeTimestamp = track.firstDecodeTimestamp;
- } else {
- baseDecodeTimestamp = Math.min(
- __privateGet(this, _videoTrack)?.firstDecodeTimestamp ?? Infinity,
- __privateGet(this, _audioTrack)?.firstDecodeTimestamp ?? Infinity
- );
- }
- decodeTimestamp -= baseDecodeTimestamp;
- presentationTimestamp -= baseDecodeTimestamp;
- }
- if (decodeTimestamp < track.lastDecodeTimestamp) {
- throw new Error(
- `Timestamps must be monotonically increasing (DTS went from ${track.lastDecodeTimestamp * 1e6} to ${decodeTimestamp * 1e6}).`
- );
- }
- track.lastDecodeTimestamp = decodeTimestamp;
- return { presentationTimestamp, decodeTimestamp };
-};
-_finalizeCurrentChunk = new WeakSet();
-finalizeCurrentChunk_fn = function(track) {
- if (__privateGet(this, _options).fastStart === "fragmented") {
- throw new Error("Can't finalize individual chunks 'fastStart' is set to 'fragmented'.");
- }
- if (!track.currentChunk)
- return;
- track.finalizedChunks.push(track.currentChunk);
- __privateGet(this, _finalizedChunks).push(track.currentChunk);
- if (track.compactlyCodedChunkTable.length === 0 || last(track.compactlyCodedChunkTable).samplesPerChunk !== track.currentChunk.samples.length) {
- track.compactlyCodedChunkTable.push({
- firstChunk: track.finalizedChunks.length,
- // 1-indexed
- samplesPerChunk: track.currentChunk.samples.length
- });
- }
- if (__privateGet(this, _options).fastStart === "in-memory") {
- track.currentChunk.offset = 0;
- return;
- }
- track.currentChunk.offset = __privateGet(this, _writer).pos;
- for (let sample of track.currentChunk.samples) {
- __privateGet(this, _writer).write(sample.data);
- sample.data = null;
- }
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
-};
-_finalizeFragment = new WeakSet();
-finalizeFragment_fn = function(flushStreamingWriter = true) {
- if (__privateGet(this, _options).fastStart !== "fragmented") {
- throw new Error("Can't finalize a fragment unless 'fastStart' is set to 'fragmented'.");
- }
- let tracks = [__privateGet(this, _videoTrack), __privateGet(this, _audioTrack)].filter((track) => track && track.currentChunk);
- if (tracks.length === 0)
- return;
- let fragmentNumber = __privateWrapper(this, _nextFragmentNumber)._++;
- if (fragmentNumber === 1) {
- let movieBox = moov(tracks, __privateGet(this, _creationTime), true);
- __privateGet(this, _writer).writeBox(movieBox);
- }
- let moofOffset = __privateGet(this, _writer).pos;
- let moofBox = moof(fragmentNumber, tracks);
- __privateGet(this, _writer).writeBox(moofBox);
- {
- let mdatBox = mdat(false);
- let totalTrackSampleSize = 0;
- for (let track of tracks) {
- for (let sample of track.currentChunk.samples) {
- totalTrackSampleSize += sample.size;
- }
- }
- let mdatSize = __privateGet(this, _writer).measureBox(mdatBox) + totalTrackSampleSize;
- if (mdatSize >= 2 ** 32) {
- mdatBox.largeSize = true;
- mdatSize = __privateGet(this, _writer).measureBox(mdatBox) + totalTrackSampleSize;
- }
- mdatBox.size = mdatSize;
- __privateGet(this, _writer).writeBox(mdatBox);
- }
- for (let track of tracks) {
- track.currentChunk.offset = __privateGet(this, _writer).pos;
- track.currentChunk.moofOffset = moofOffset;
- for (let sample of track.currentChunk.samples) {
- __privateGet(this, _writer).write(sample.data);
- sample.data = null;
- }
- }
- let endPos = __privateGet(this, _writer).pos;
- __privateGet(this, _writer).seek(__privateGet(this, _writer).offsets.get(moofBox));
- let newMoofBox = moof(fragmentNumber, tracks);
- __privateGet(this, _writer).writeBox(newMoofBox);
- __privateGet(this, _writer).seek(endPos);
- for (let track of tracks) {
- track.finalizedChunks.push(track.currentChunk);
- __privateGet(this, _finalizedChunks).push(track.currentChunk);
- track.currentChunk = null;
- }
- if (flushStreamingWriter) {
- __privateMethod(this, _maybeFlushStreamingTargetWriter, maybeFlushStreamingTargetWriter_fn).call(this);
- }
-};
-_maybeFlushStreamingTargetWriter = new WeakSet();
-maybeFlushStreamingTargetWriter_fn = function() {
- if (__privateGet(this, _writer) instanceof StreamTargetWriter) {
- __privateGet(this, _writer).flush();
- }
-};
-_ensureNotFinalized = new WeakSet();
-ensureNotFinalized_fn = function() {
- if (__privateGet(this, _finalized)) {
- throw new Error("Cannot add new video or audio chunks after the file has been finalized.");
- }
-};
-export {
- ArrayBufferTarget,
- FileSystemWritableFileStreamTarget,
- Muxer,
- StreamTarget
-};
diff --git a/v0-appel-projet/public/mp4-muxer-main/demo-streaming/index.html b/v0-appel-projet/public/mp4-muxer-main/demo-streaming/index.html
deleted file mode 100644
index 8313554..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/demo-streaming/index.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
- MP4 muxer streaming demo
-
-
-
-
-
-
-
MP4 muxer streaming demo - draw something!
-
The live canvas state and your microphone input will be recorded, muxed into a fragmented MP4 stream and shown live in the <video> element.
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/demo-streaming/script.js b/v0-appel-projet/public/mp4-muxer-main/demo-streaming/script.js
deleted file mode 100644
index 249ebca..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/demo-streaming/script.js
+++ /dev/null
@@ -1,204 +0,0 @@
-const canvas = document.querySelector('canvas');
-const ctx = canvas.getContext('2d', { desynchronized: true });
-const streamPreview = document.querySelector('#stream-preview');
-const startRecordingButton = document.querySelector('#start-recording');
-const endRecordingButton = document.querySelector('#end-recording');
-const recordingStatus = document.querySelector('#recording-status');
-
-/** RECORDING & MUXING STUFF */
-
-let muxer = null;
-let videoEncoder = null;
-let audioEncoder = null;
-let startTime = null;
-let recording = false;
-let audioTrack = null;
-let intervalId = null;
-let lastKeyFrame = null;
-let framesGenerated = 0;
-
-const startRecording = async () => {
- // Check for VideoEncoder availability
- if (typeof VideoEncoder === 'undefined') {
- alert("Looks like your user agent doesn't support VideoEncoder / WebCodecs API yet.");
- return;
- }
-
- startRecordingButton.style.display = 'none';
-
- // Check for AudioEncoder availability
- if (typeof AudioEncoder !== 'undefined') {
- // Try to get access to the user's microphone
- try {
- let userMedia = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
- audioTrack = userMedia.getAudioTracks()[0];
- } catch (e) {}
- if (!audioTrack) console.warn("Couldn't acquire a user media audio track.");
- } else {
- console.warn('AudioEncoder not available; no need to acquire a user media audio track.');
- }
-
- let mediaSource = new MediaSource();
- streamPreview.src = URL.createObjectURL(mediaSource);
- streamPreview.play();
-
- await new Promise(resolve => mediaSource.onsourceopen = resolve);
-
- // We'll append ArrayBuffers to this as the muxer starts to spit out chunks
- let sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.64001F, mp4a.40.2"');
-
- endRecordingButton.style.display = 'block';
-
- let audioSampleRate = audioTrack?.getCapabilities().sampleRate.max;
-
- // Create an MP4 muxer with a video track and maybe an audio track
- muxer = new Mp4Muxer.Muxer({
- target: new Mp4Muxer.StreamTarget({
- onData: buffer => sourceBuffer.appendBuffer(buffer)
- }),
-
- video: {
- codec: 'avc',
- width: canvas.width,
- height: canvas.height
- },
- audio: audioTrack ? {
- codec: 'aac',
- sampleRate: audioSampleRate,
- numberOfChannels: 1
- } : undefined,
-
- // Puts metadata to the start of the file. Since we're using ArrayBufferTarget anyway, this makes no difference
- // to memory footprint.
- fastStart: 'fragmented',
-
- // Because we're directly pumping a MediaStreamTrack's data into it, which doesn't start at timestamp = 0
- firstTimestampBehavior: 'offset'
- });
-
- videoEncoder = new VideoEncoder({
- output: (chunk, meta) => muxer.addVideoChunk(chunk, meta),
- error: e => console.error(e)
- });
- videoEncoder.configure({
- codec: 'avc1.64001F',
- width: canvas.width,
- height: canvas.height,
- bitrate: 1e6
- });
-
- if (audioTrack) {
- audioEncoder = new AudioEncoder({
- output: (chunk, meta) => muxer.addAudioChunk(chunk, meta),
- error: e => console.error(e)
- });
- audioEncoder.configure({
- codec: 'mp4a.40.2',
- numberOfChannels: 1,
- sampleRate: audioSampleRate,
- bitrate: 128000
- });
-
- // Create a MediaStreamTrackProcessor to get AudioData chunks from the audio track
- let trackProcessor = new MediaStreamTrackProcessor({ track: audioTrack });
- let consumer = new WritableStream({
- write(audioData) {
- if (!recording) return;
- audioEncoder.encode(audioData);
- audioData.close();
- }
- });
- trackProcessor.readable.pipeTo(consumer);
- }
-
- startTime = document.timeline.currentTime;
- recording = true;
- lastKeyFrame = -Infinity;
- framesGenerated = 0;
-
- encodeVideoFrame();
- intervalId = setInterval(encodeVideoFrame, 1000/30);
-};
-startRecordingButton.addEventListener('click', startRecording);
-
-const encodeVideoFrame = () => {
- let elapsedTime = document.timeline.currentTime - startTime;
- let frame = new VideoFrame(canvas, {
- timestamp: framesGenerated * 1e6 / 30, // Ensure equally-spaced frames every 1/30th of a second
- duration: 1e6 / 30
- });
- framesGenerated++;
-
- // Ensure a video key frame at least every 0.5 seconds
- let needsKeyFrame = elapsedTime - lastKeyFrame >= 500;
- if (needsKeyFrame) lastKeyFrame = elapsedTime;
-
- videoEncoder.encode(frame, { keyFrame: needsKeyFrame });
- frame.close();
-
- recordingStatus.textContent =
- `${elapsedTime % 1000 < 500 ? '🔴' : '⚫'} Recording - ${(elapsedTime / 1000).toFixed(1)} s`;
-};
-
-const endRecording = async () => {
- endRecordingButton.style.display = 'none';
- recordingStatus.textContent = '';
- recording = false;
-
- clearInterval(intervalId);
- audioTrack?.stop();
-
- await videoEncoder?.flush();
- await audioEncoder?.flush();
- muxer.finalize();
-
- videoEncoder = null;
- audioEncoder = null;
- muxer = null;
- startTime = null;
- firstAudioTimestamp = null;
-
- startRecordingButton.style.display = 'block';
-};
-endRecordingButton.addEventListener('click', endRecording);
-
-/** CANVAS DRAWING STUFF */
-
-ctx.fillStyle = 'white';
-ctx.fillRect(0, 0, canvas.width, canvas.height);
-
-let drawing = false;
-let lastPos = { x: 0, y: 0 };
-
-const getRelativeMousePos = (e) => {
- let rect = canvas.getBoundingClientRect();
- return { x: e.clientX - rect.x, y: e.clientY - rect.y };
-};
-
-const drawLine = (from, to) => {
- ctx.beginPath();
- ctx.moveTo(from.x, from.y);
- ctx.lineTo(to.x, to.y);
- ctx.strokeStyle = 'black';
- ctx.lineWidth = 3;
- ctx.lineCap = 'round';
- ctx.stroke();
-};
-
-canvas.addEventListener('pointerdown', (e) => {
- if (e.button !== 0) return;
-
- drawing = true;
- lastPos = getRelativeMousePos(e);
- drawLine(lastPos, lastPos);
-});
-window.addEventListener('pointerup', () => {
- drawing = false;
-});
-window.addEventListener('mousemove', (e) => {
- if (!drawing) return;
-
- let newPos = getRelativeMousePos(e);
- drawLine(lastPos, newPos);
- lastPos = newPos;
-});
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/demo-streaming/style.css b/v0-appel-projet/public/mp4-muxer-main/demo-streaming/style.css
deleted file mode 100644
index fbf448f..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/demo-streaming/style.css
+++ /dev/null
@@ -1,68 +0,0 @@
-html, body {
- margin: 0;
- width: 100%;
- height: 100%;
- background: #120d17;
- color: white;
- font-family: monospace;
-}
-
-body {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-* {
- user-select: none;
-}
-
-main {
- width: 100%;
-}
-
-h1 {
- margin: 0;
- font-weight: normal;
- text-align: center;
- margin-bottom: 10px;
-}
-
-h2 {
- margin: 0;
- font-weight: normal;
- text-align: center;
- font-size: 14px;
- margin-bottom: 20px;
-}
-
-canvas {
- border-radius: 10px;
- outline: 3px solid rgb(202, 202, 202);
-}
-
-#controls {
- margin-bottom: 20px;
- display: flex;
- justify-content: center;
- height: 38px;
-}
-
-#center {
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 10px;
-}
-
-button {
- font-size: 20px;
- padding: 5px 8px;
-}
-
-p {
- margin: 0;
- text-align: center;
- margin-top: 20px;
- height: 20px;
-}
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/demo/index.html b/v0-appel-projet/public/mp4-muxer-main/demo/index.html
deleted file mode 100644
index 3f3d20c..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/demo/index.html
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
- MP4 muxer demo
-
-
-
-
-
-
-
MP4 muxer demo - draw something!
-
The live canvas state and your microphone input will be recorded and muxed into an MP4 file.
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/demo/script.js b/v0-appel-projet/public/mp4-muxer-main/demo/script.js
deleted file mode 100644
index e9baa4f..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/demo/script.js
+++ /dev/null
@@ -1,206 +0,0 @@
-const canvas = document.querySelector('canvas');
-const ctx = canvas.getContext('2d', { desynchronized: true });
-const startRecordingButton = document.querySelector('#start-recording');
-const endRecordingButton = document.querySelector('#end-recording');
-const recordingStatus = document.querySelector('#recording-status');
-
-/** RECORDING & MUXING STUFF */
-
-let muxer = null;
-let videoEncoder = null;
-let audioEncoder = null;
-let startTime = null;
-let recording = false;
-let audioTrack = null;
-let intervalId = null;
-let lastKeyFrame = null;
-let framesGenerated = 0;
-
-const startRecording = async () => {
- // Check for VideoEncoder availability
- if (typeof VideoEncoder === 'undefined') {
- alert("Looks like your user agent doesn't support VideoEncoder / WebCodecs API yet.");
- return;
- }
-
- startRecordingButton.style.display = 'none';
-
- // Check for AudioEncoder availability
- if (typeof AudioEncoder !== 'undefined') {
- // Try to get access to the user's microphone
- try {
- let userMedia = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
- audioTrack = userMedia.getAudioTracks()[0];
- } catch (e) {}
- if (!audioTrack) console.warn("Couldn't acquire a user media audio track.");
- } else {
- console.warn('AudioEncoder not available; no need to acquire a user media audio track.');
- }
-
- endRecordingButton.style.display = 'block';
-
- let audioSampleRate = audioTrack?.getCapabilities().sampleRate.max;
-
- // Create an MP4 muxer with a video track and maybe an audio track
- muxer = new Mp4Muxer.Muxer({
- target: new Mp4Muxer.ArrayBufferTarget(),
-
- video: {
- codec: 'avc',
- width: canvas.width,
- height: canvas.height
- },
- audio: audioTrack ? {
- codec: 'aac',
- sampleRate: audioSampleRate,
- numberOfChannels: 1
- } : undefined,
-
- // Puts metadata to the start of the file. Since we're using ArrayBufferTarget anyway, this makes no difference
- // to memory footprint.
- fastStart: 'in-memory',
-
- // Because we're directly pumping a MediaStreamTrack's data into it, which doesn't start at timestamp = 0
- firstTimestampBehavior: 'offset'
- });
-
- videoEncoder = new VideoEncoder({
- output: (chunk, meta) => muxer.addVideoChunk(chunk, meta),
- error: e => console.error(e)
- });
- videoEncoder.configure({
- codec: 'avc1.42001f',
- width: canvas.width,
- height: canvas.height,
- bitrate: 1e6
- });
-
- if (audioTrack) {
- audioEncoder = new AudioEncoder({
- output: (chunk, meta) => muxer.addAudioChunk(chunk, meta),
- error: e => console.error(e)
- });
- audioEncoder.configure({
- codec: 'mp4a.40.2',
- numberOfChannels: 1,
- sampleRate: audioSampleRate,
- bitrate: 128000
- });
-
- // Create a MediaStreamTrackProcessor to get AudioData chunks from the audio track
- let trackProcessor = new MediaStreamTrackProcessor({ track: audioTrack });
- let consumer = new WritableStream({
- write(audioData) {
- if (!recording) return;
- audioEncoder.encode(audioData);
- audioData.close();
- }
- });
- trackProcessor.readable.pipeTo(consumer);
- }
-
- startTime = document.timeline.currentTime;
- recording = true;
- lastKeyFrame = -Infinity;
- framesGenerated = 0;
-
- encodeVideoFrame();
- intervalId = setInterval(encodeVideoFrame, 1000/30);
-};
-startRecordingButton.addEventListener('click', startRecording);
-
-const encodeVideoFrame = () => {
- let elapsedTime = document.timeline.currentTime - startTime;
- let frame = new VideoFrame(canvas, {
- timestamp: framesGenerated * 1e6 / 30, // Ensure equally-spaced frames every 1/30th of a second
- duration: 1e6 / 30
- });
- framesGenerated++;
-
- // Ensure a video key frame at least every 5 seconds for good scrubbing
- let needsKeyFrame = elapsedTime - lastKeyFrame >= 5000;
- if (needsKeyFrame) lastKeyFrame = elapsedTime;
-
- videoEncoder.encode(frame, { keyFrame: needsKeyFrame });
- frame.close();
-
- recordingStatus.textContent =
- `${elapsedTime % 1000 < 500 ? '🔴' : '⚫'} Recording - ${(elapsedTime / 1000).toFixed(1)} s`;
-};
-
-const endRecording = async () => {
- endRecordingButton.style.display = 'none';
- recordingStatus.textContent = '';
- recording = false;
-
- clearInterval(intervalId);
- audioTrack?.stop();
-
- await videoEncoder?.flush();
- await audioEncoder?.flush();
- muxer.finalize();
-
- let buffer = muxer.target.buffer;
- downloadBlob(new Blob([buffer]));
-
- videoEncoder = null;
- audioEncoder = null;
- muxer = null;
- startTime = null;
- firstAudioTimestamp = null;
-
- startRecordingButton.style.display = 'block';
-};
-endRecordingButton.addEventListener('click', endRecording);
-
-const downloadBlob = (blob) => {
- let url = window.URL.createObjectURL(blob);
- let a = document.createElement('a');
- a.style.display = 'none';
- a.href = url;
- a.download = 'davinci.mp4';
- document.body.appendChild(a);
- a.click();
- window.URL.revokeObjectURL(url);
-};
-
-/** CANVAS DRAWING STUFF */
-
-ctx.fillStyle = 'white';
-ctx.fillRect(0, 0, canvas.width, canvas.height);
-
-let drawing = false;
-let lastPos = { x: 0, y: 0 };
-
-const getRelativeMousePos = (e) => {
- let rect = canvas.getBoundingClientRect();
- return { x: e.clientX - rect.x, y: e.clientY - rect.y };
-};
-
-const drawLine = (from, to) => {
- ctx.beginPath();
- ctx.moveTo(from.x, from.y);
- ctx.lineTo(to.x, to.y);
- ctx.strokeStyle = 'black';
- ctx.lineWidth = 3;
- ctx.lineCap = 'round';
- ctx.stroke();
-};
-
-canvas.addEventListener('pointerdown', (e) => {
- if (e.button !== 0) return;
-
- drawing = true;
- lastPos = getRelativeMousePos(e);
- drawLine(lastPos, lastPos);
-});
-window.addEventListener('pointerup', () => {
- drawing = false;
-});
-window.addEventListener('mousemove', (e) => {
- if (!drawing) return;
-
- let newPos = getRelativeMousePos(e);
- drawLine(lastPos, newPos);
- lastPos = newPos;
-});
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/demo/style.css b/v0-appel-projet/public/mp4-muxer-main/demo/style.css
deleted file mode 100644
index 0a2bbf7..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/demo/style.css
+++ /dev/null
@@ -1,61 +0,0 @@
-html, body {
- margin: 0;
- width: 100%;
- height: 100%;
- background: #120d17;
- color: white;
- font-family: monospace;
-}
-
-body {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-* {
- user-select: none;
-}
-
-main {
- width: 640px;
-}
-
-h1 {
- margin: 0;
- font-weight: normal;
- text-align: center;
- margin-bottom: 10px;
-}
-
-h2 {
- margin: 0;
- font-weight: normal;
- text-align: center;
- font-size: 14px;
- margin-bottom: 20px;
-}
-
-canvas {
- border-radius: 10px;
- outline: 3px solid rgb(202, 202, 202);
-}
-
-#controls {
- margin-bottom: 20px;
- display: flex;
- justify-content: center;
- height: 38px;
-}
-
-button {
- font-size: 20px;
- padding: 5px 8px;
-}
-
-p {
- margin: 0;
- text-align: center;
- margin-top: 20px;
- height: 20px;
-}
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/package-lock.json b/v0-appel-projet/public/mp4-muxer-main/package-lock.json
deleted file mode 100644
index 4786905..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/package-lock.json
+++ /dev/null
@@ -1,2051 +0,0 @@
-{
- "name": "mp4-muxer",
- "version": "3.0.5",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "mp4-muxer",
- "version": "3.0.5",
- "license": "MIT",
- "dependencies": {
- "@types/dom-webcodecs": "^0.1.6",
- "@types/wicg-file-system-access": "^2020.9.5"
- },
- "devDependencies": {
- "@types/node": "^18.15.0",
- "@typescript-eslint/eslint-plugin": "^5.54.1",
- "@typescript-eslint/parser": "^5.54.1",
- "esbuild": "^0.17.11",
- "eslint": "^8.36.0",
- "typescript": "^4.9.5"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.11.tgz",
- "integrity": "sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.11.tgz",
- "integrity": "sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.11.tgz",
- "integrity": "sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.11.tgz",
- "integrity": "sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.11.tgz",
- "integrity": "sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.11.tgz",
- "integrity": "sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.11.tgz",
- "integrity": "sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.11.tgz",
- "integrity": "sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.11.tgz",
- "integrity": "sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.11.tgz",
- "integrity": "sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.11.tgz",
- "integrity": "sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.11.tgz",
- "integrity": "sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.11.tgz",
- "integrity": "sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.11.tgz",
- "integrity": "sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.11.tgz",
- "integrity": "sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.11.tgz",
- "integrity": "sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.11.tgz",
- "integrity": "sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.11.tgz",
- "integrity": "sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.11.tgz",
- "integrity": "sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.11.tgz",
- "integrity": "sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.11.tgz",
- "integrity": "sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.11.tgz",
- "integrity": "sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz",
- "integrity": "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==",
- "dev": true,
- "dependencies": {
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz",
- "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==",
- "dev": true,
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz",
- "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==",
- "dev": true,
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^9.5.0",
- "globals": "^13.19.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/js": {
- "version": "8.36.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz",
- "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/@humanwhocodes/config-array": {
- "version": "0.11.8",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
- "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
- "dev": true,
- "dependencies": {
- "@humanwhocodes/object-schema": "^1.2.1",
- "debug": "^4.1.1",
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
- "dev": true
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@types/dom-webcodecs": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.6.tgz",
- "integrity": "sha512-m+Y2WRIKvLwFzyToNGA5XV+sfihtrfcOaMrXzsZULVdqYyKy4yn0XZ8lES9RRwZTzW7TKcz84xed3e5FBk3wCg=="
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.11",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
- "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
- "dev": true
- },
- "node_modules/@types/node": {
- "version": "18.15.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.0.tgz",
- "integrity": "sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==",
- "dev": true
- },
- "node_modules/@types/semver": {
- "version": "7.3.13",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
- "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
- "dev": true
- },
- "node_modules/@types/wicg-file-system-access": {
- "version": "2020.9.5",
- "resolved": "https://registry.npmjs.org/@types/wicg-file-system-access/-/wicg-file-system-access-2020.9.5.tgz",
- "integrity": "sha512-UYK244awtmcUYQfs7FR8710MJcefL2WvkyHMjA8yJzxd1mo0Gfn88sRZ1Bls7hiUhA2w7ne1gpJ9T5g3G0wOyA=="
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.1.tgz",
- "integrity": "sha512-a2RQAkosH3d3ZIV08s3DcL/mcGc2M/UC528VkPULFxR9VnVPT8pBu0IyBAJJmVsCmhVfwQX1v6q+QGnmSe1bew==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/scope-manager": "5.54.1",
- "@typescript-eslint/type-utils": "5.54.1",
- "@typescript-eslint/utils": "5.54.1",
- "debug": "^4.3.4",
- "grapheme-splitter": "^1.0.4",
- "ignore": "^5.2.0",
- "natural-compare-lite": "^1.4.0",
- "regexpp": "^3.2.0",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^5.0.0",
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.1.tgz",
- "integrity": "sha512-8zaIXJp/nG9Ff9vQNh7TI+C3nA6q6iIsGJ4B4L6MhZ7mHnTMR4YP5vp2xydmFXIy8rpyIVbNAG44871LMt6ujg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/scope-manager": "5.54.1",
- "@typescript-eslint/types": "5.54.1",
- "@typescript-eslint/typescript-estree": "5.54.1",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.1.tgz",
- "integrity": "sha512-zWKuGliXxvuxyM71UA/EcPxaviw39dB2504LqAmFDjmkpO8qNLHcmzlh6pbHs1h/7YQ9bnsO8CCcYCSA8sykUg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "5.54.1",
- "@typescript-eslint/visitor-keys": "5.54.1"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.1.tgz",
- "integrity": "sha512-WREHsTz0GqVYLIbzIZYbmUUr95DKEKIXZNH57W3s+4bVnuF1TKe2jH8ZNH8rO1CeMY3U4j4UQeqPNkHMiGem3g==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/typescript-estree": "5.54.1",
- "@typescript-eslint/utils": "5.54.1",
- "debug": "^4.3.4",
- "tsutils": "^3.21.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "*"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.1.tgz",
- "integrity": "sha512-G9+1vVazrfAfbtmCapJX8jRo2E4MDXxgm/IMOF4oGh3kq7XuK3JRkOg6y2Qu1VsTRmWETyTkWt1wxy7X7/yLkw==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.1.tgz",
- "integrity": "sha512-bjK5t+S6ffHnVwA0qRPTZrxKSaFYocwFIkZx5k7pvWfsB1I57pO/0M0Skatzzw1sCkjJ83AfGTL0oFIFiDX3bg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "5.54.1",
- "@typescript-eslint/visitor-keys": "5.54.1",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.1.tgz",
- "integrity": "sha512-IY5dyQM8XD1zfDe5X8jegX6r2EVU5o/WJnLu/znLPWCBF7KNGC+adacXnt5jEYS9JixDcoccI6CvE4RCjHMzCQ==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.9",
- "@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.54.1",
- "@typescript-eslint/types": "5.54.1",
- "@typescript-eslint/typescript-estree": "5.54.1",
- "eslint-scope": "^5.1.1",
- "eslint-utils": "^3.0.0",
- "semver": "^7.3.7"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.54.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.1.tgz",
- "integrity": "sha512-q8iSoHTgwCfgcRJ2l2x+xCbu8nBlRAlsQ33k24Adj8eoVBE0f8dUeI+bAa8F84Mv05UGbAx57g2zrRsYIooqQg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "5.54.1",
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/acorn": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
- "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
- "dev": true,
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "dev": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
- },
- "node_modules/dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/doctrine": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/esbuild": {
- "version": "0.17.11",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.11.tgz",
- "integrity": "sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg==",
- "dev": true,
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/android-arm": "0.17.11",
- "@esbuild/android-arm64": "0.17.11",
- "@esbuild/android-x64": "0.17.11",
- "@esbuild/darwin-arm64": "0.17.11",
- "@esbuild/darwin-x64": "0.17.11",
- "@esbuild/freebsd-arm64": "0.17.11",
- "@esbuild/freebsd-x64": "0.17.11",
- "@esbuild/linux-arm": "0.17.11",
- "@esbuild/linux-arm64": "0.17.11",
- "@esbuild/linux-ia32": "0.17.11",
- "@esbuild/linux-loong64": "0.17.11",
- "@esbuild/linux-mips64el": "0.17.11",
- "@esbuild/linux-ppc64": "0.17.11",
- "@esbuild/linux-riscv64": "0.17.11",
- "@esbuild/linux-s390x": "0.17.11",
- "@esbuild/linux-x64": "0.17.11",
- "@esbuild/netbsd-x64": "0.17.11",
- "@esbuild/openbsd-x64": "0.17.11",
- "@esbuild/sunos-x64": "0.17.11",
- "@esbuild/win32-arm64": "0.17.11",
- "@esbuild/win32-ia32": "0.17.11",
- "@esbuild/win32-x64": "0.17.11"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint": {
- "version": "8.36.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz",
- "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==",
- "dev": true,
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.4.0",
- "@eslint/eslintrc": "^2.0.1",
- "@eslint/js": "8.36.0",
- "@humanwhocodes/config-array": "^0.11.8",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "ajv": "^6.10.0",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
- "debug": "^4.3.2",
- "doctrine": "^3.0.0",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.1.1",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.5.0",
- "esquery": "^1.4.2",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "globals": "^13.19.0",
- "grapheme-splitter": "^1.0.4",
- "ignore": "^5.2.0",
- "import-fresh": "^3.0.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "js-sdsl": "^4.1.4",
- "js-yaml": "^4.1.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.1",
- "strip-ansi": "^6.0.1",
- "strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-scope": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
- "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "dev": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^4.1.1"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/eslint-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
- "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
- "dev": true,
- "dependencies": {
- "eslint-visitor-keys": "^2.0.0"
- },
- "engines": {
- "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- },
- "peerDependencies": {
- "eslint": ">=5"
- }
- },
- "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
- "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/eslint/node_modules/eslint-scope": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
- "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
- "dev": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/eslint/node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/espree": {
- "version": "9.5.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz",
- "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.8.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
- "dev": true,
- "dependencies": {
- "estraverse": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/esquery/node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
- "dependencies": {
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esrecurse/node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
- },
- "node_modules/fast-glob": {
- "version": "3.2.12",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
- "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true
- },
- "node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
- "dev": true,
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
- "dev": true,
- "dependencies": {
- "flat-cache": "^3.0.4"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
- "dev": true,
- "dependencies": {
- "flatted": "^3.1.0",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/flatted": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
- "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
- "dev": true
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/globals": {
- "version": "13.20.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
- "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
- "dev": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/grapheme-splitter": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
- "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
- "dev": true
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ignore": {
- "version": "5.2.4",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
- "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dev": true,
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
- },
- "node_modules/js-sdsl": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
- "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
- "dev": true,
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/js-sdsl"
- }
- },
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true
- },
- "node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
- "dev": true,
- "dependencies": {
- "braces": "^3.0.2",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true
- },
- "node_modules/natural-compare-lite": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
- "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
- "dev": true
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/optionator": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
- "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
- "dev": true,
- "dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.3"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
- "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/regexpp": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
- "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- }
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
- "dev": true
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true
- },
- "node_modules/tsutils": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
- "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
- "dev": true,
- "dependencies": {
- "tslib": "^1.8.1"
- },
- "engines": {
- "node": ">= 6"
- },
- "peerDependencies": {
- "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
- }
- },
- "node_modules/type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/typescript": {
- "version": "4.9.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
- "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
- "dev": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
- },
- "node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- }
- }
-}
diff --git a/v0-appel-projet/public/mp4-muxer-main/package.json b/v0-appel-projet/public/mp4-muxer-main/package.json
deleted file mode 100644
index 93350ef..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/package.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "name": "mp4-muxer",
- "version": "4.3.3",
- "description": "MP4 multiplexer in pure TypeScript with support for WebCodecs API, video & audio.",
- "main": "./build/mp4-muxer.js",
- "module": "./build/mp4-muxer.mjs",
- "types": "./build/mp4-muxer.d.ts",
- "exports": {
- "types": "./build/mp4-muxer.d.ts",
- "import": "./build/mp4-muxer.mjs",
- "require": "./build/mp4-muxer.js"
- },
- "files": [
- "README.md",
- "package.json",
- "LICENSE",
- "build/mp4-muxer.js",
- "build/mp4-muxer.mjs",
- "build/mp4-muxer.d.ts"
- ],
- "scripts": {
- "watch": "node build.mjs",
- "check": "npx tsc --noEmit --skipLibCheck",
- "lint": "npx eslint src demo build"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/Vanilagy/mp4-muxer.git"
- },
- "author": "Vanilagy",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/Vanilagy/mp4-muxer/issues"
- },
- "homepage": "https://github.com/Vanilagy/mp4-muxer#readme",
- "dependencies": {
- "@types/dom-webcodecs": "^0.1.6",
- "@types/wicg-file-system-access": "^2020.9.5"
- },
- "devDependencies": {
- "@types/node": "^18.15.0",
- "@typescript-eslint/eslint-plugin": "^5.54.1",
- "@typescript-eslint/parser": "^5.54.1",
- "esbuild": "^0.17.11",
- "eslint": "^8.36.0",
- "typescript": "^4.9.5"
- },
- "keywords": [
- "mp4",
- "fmp4",
- "muxer",
- "muxing",
- "multiplexer",
- "video",
- "audio",
- "media",
- "webcodecs"
- ]
-}
diff --git a/v0-appel-projet/public/mp4-muxer-main/src/box.ts b/v0-appel-projet/public/mp4-muxer-main/src/box.ts
deleted file mode 100644
index 48f8037..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/src/box.ts
+++ /dev/null
@@ -1,740 +0,0 @@
-import {
- AudioTrack,
- GLOBAL_TIMESCALE,
- SUPPORTED_AUDIO_CODECS,
- SUPPORTED_VIDEO_CODECS,
- Sample,
- Track,
- VideoTrack
-} from './muxer';
-import {
- ascii,
- i16,
- i32,
- intoTimescale,
- last,
- lastPresentedSample,
- u16,
- u64,
- u8,
- u32,
- fixed_16_16,
- fixed_8_8,
- u24,
- IDENTITY_MATRIX,
- matrixToBytes,
- rotationMatrix,
- isU32,
- TransformationMatrix
-} from './misc';
-
-export interface Box {
- type: string,
- contents?: Uint8Array,
- children?: Box[],
- size?: number,
- largeSize?: boolean
-}
-
-type NestedNumberArray = (number | NestedNumberArray)[];
-
-export const box = (type: string, contents?: NestedNumberArray, children?: Box[]): Box => ({
- type,
- contents: contents && new Uint8Array(contents.flat(10) as number[]),
- children
-});
-
-/** A FullBox always starts with a version byte, followed by three flag bytes. */
-export const fullBox = (
- type: string,
- version: number,
- flags: number,
- contents?: NestedNumberArray,
- children?: Box[]
-) => box(
- type,
- [u8(version), u24(flags), contents ?? []],
- children
-);
-
-/**
- * File Type Compatibility Box: Allows the reader to determine whether this is a type of file that the
- * reader understands.
- */
-export const ftyp = (details: {
- holdsAvc: boolean,
- fragmented: boolean
-}) => {
- // You can find the full logic for this at
- // https://github.com/FFmpeg/FFmpeg/blob/de2fb43e785773738c660cdafb9309b1ef1bc80d/libavformat/movenc.c#L5518
- // Obviously, this lib only needs a small subset of that logic.
-
- let minorVersion = 0x200;
-
- if (details.fragmented) return box('ftyp', [
- ascii('iso5'), // Major brand
- u32(minorVersion), // Minor version
- // Compatible brands
- ascii('iso5'),
- ascii('iso6'),
- ascii('mp41')
- ]);
-
- return box('ftyp', [
- ascii('isom'), // Major brand
- u32(minorVersion), // Minor version
- // Compatible brands
- ascii('isom'),
- details.holdsAvc ? ascii('avc1') : [],
- ascii('mp41')
- ]);
-};
-
-/** Movie Sample Data Box. Contains the actual frames/samples of the media. */
-export const mdat = (reserveLargeSize: boolean): Box => ({ type: 'mdat', largeSize: reserveLargeSize });
-
-/** Free Space Box: A box that designates unused space in the movie data file. */
-export const free = (size: number): Box => ({ type: 'free', size });
-
-/**
- * Movie Box: Used to specify the information that defines a movie - that is, the information that allows
- * an application to interpret the sample data that is stored elsewhere.
- */
-export const moov = (tracks: Track[], creationTime: number, fragmented = false) => box('moov', null, [
- mvhd(creationTime, tracks),
- ...tracks.map(x => trak(x, creationTime)),
- fragmented ? mvex(tracks) : null
-]);
-
-/** Movie Header Box: Used to specify the characteristics of the entire movie, such as timescale and duration. */
-export const mvhd = (
- creationTime: number,
- tracks: Track[]
-) => {
- let duration = intoTimescale(Math.max(
- 0,
- ...tracks.
- filter(x => x.samples.length > 0).
- map(x => {
- const lastSample = lastPresentedSample(x.samples);
- return lastSample.presentationTimestamp + lastSample.duration;
- })
- ), GLOBAL_TIMESCALE);
- let nextTrackId = Math.max(...tracks.map(x => x.id)) + 1;
-
- // Conditionally use u64 if u32 isn't enough
- let needsU64 = !isU32(creationTime) || !isU32(duration);
- let u32OrU64 = needsU64 ? u64 : u32;
-
- return fullBox('mvhd', +needsU64, 0, [
- u32OrU64(creationTime), // Creation time
- u32OrU64(creationTime), // Modification time
- u32(GLOBAL_TIMESCALE), // Timescale
- u32OrU64(duration), // Duration
- fixed_16_16(1), // Preferred rate
- fixed_8_8(1), // Preferred volume
- Array(10).fill(0), // Reserved
- matrixToBytes(IDENTITY_MATRIX), // Matrix
- Array(24).fill(0), // Pre-defined
- u32(nextTrackId) // Next track ID
- ]);
-};
-
-/**
- * Track Box: Defines a single track of a movie. A movie may consist of one or more tracks. Each track is
- * independent of the other tracks in the movie and carries its own temporal and spatial information. Each Track Box
- * contains its associated Media Box.
- */
-export const trak = (track: Track, creationTime: number) => box('trak', null, [
- tkhd(track, creationTime),
- mdia(track, creationTime)
-]);
-
-/** Track Header Box: Specifies the characteristics of a single track within a movie. */
-export const tkhd = (
- track: Track,
- creationTime: number
-) => {
- let lastSample = lastPresentedSample(track.samples);
- let durationInGlobalTimescale = intoTimescale(
- lastSample ? lastSample.presentationTimestamp + lastSample.duration : 0,
- GLOBAL_TIMESCALE
- );
-
- let needsU64 = !isU32(creationTime) || !isU32(durationInGlobalTimescale);
- let u32OrU64 = needsU64 ? u64 : u32;
-
- let matrix: TransformationMatrix;
- if (track.info.type === 'video') {
- matrix = typeof track.info.rotation === 'number' ? rotationMatrix(track.info.rotation) : track.info.rotation;
- } else {
- matrix = IDENTITY_MATRIX;
- }
-
- return fullBox('tkhd', +needsU64, 3, [
- u32OrU64(creationTime), // Creation time
- u32OrU64(creationTime), // Modification time
- u32(track.id), // Track ID
- u32(0), // Reserved
- u32OrU64(durationInGlobalTimescale), // Duration
- Array(8).fill(0), // Reserved
- u16(0), // Layer
- u16(0), // Alternate group
- fixed_8_8(track.info.type === 'audio' ? 1 : 0), // Volume
- u16(0), // Reserved
- matrixToBytes(matrix), // Matrix
- fixed_16_16(track.info.type === 'video' ? track.info.width : 0), // Track width
- fixed_16_16(track.info.type === 'video' ? track.info.height : 0) // Track height
- ]);
-};
-
-/** Media Box: Describes and define a track's media type and sample data. */
-export const mdia = (track: Track, creationTime: number) => box('mdia', null, [
- mdhd(track, creationTime),
- hdlr(track.info.type === 'video' ? 'vide' : 'soun'),
- minf(track)
-]);
-
-/** Media Header Box: Specifies the characteristics of a media, including timescale and duration. */
-export const mdhd = (
- track: Track,
- creationTime: number
-) => {
- let lastSample = lastPresentedSample(track.samples);
- let localDuration = intoTimescale(
- lastSample ? lastSample.presentationTimestamp + lastSample.duration : 0,
- track.timescale
- );
-
- let needsU64 = !isU32(creationTime) || !isU32(localDuration);
- let u32OrU64 = needsU64 ? u64 : u32;
-
- return fullBox('mdhd', +needsU64, 0, [
- u32OrU64(creationTime), // Creation time
- u32OrU64(creationTime), // Modification time
- u32(track.timescale), // Timescale
- u32OrU64(localDuration), // Duration
- u16(0b01010101_11000100), // Language ("und", undetermined)
- u16(0) // Quality
- ]);
-};
-
-/** Handler Reference Box: Specifies the media handler component that is to be used to interpret the media's data. */
-export const hdlr = (componentSubtype: string) => fullBox('hdlr', 0, 0, [
- ascii('mhlr'), // Component type
- ascii(componentSubtype), // Component subtype
- u32(0), // Component manufacturer
- u32(0), // Component flags
- u32(0), // Component flags mask
- ascii('mp4-muxer-hdlr', true) // Component name
-]);
-
-/**
- * Media Information Box: Stores handler-specific information for a track's media data. The media handler uses this
- * information to map from media time to media data and to process the media data.
- */
-export const minf = (track: Track) => box('minf', null, [
- track.info.type === 'video' ? vmhd() : smhd(),
- dinf(),
- stbl(track)
-]);
-
-/** Video Media Information Header Box: Defines specific color and graphics mode information. */
-export const vmhd = () => fullBox('vmhd', 0, 1, [
- u16(0), // Graphics mode
- u16(0), // Opcolor R
- u16(0), // Opcolor G
- u16(0) // Opcolor B
-]);
-
-/** Sound Media Information Header Box: Stores the sound media's control information, such as balance. */
-export const smhd = () => fullBox('smhd', 0, 0, [
- u16(0), // Balance
- u16(0) // Reserved
-]);
-
-/**
- * Data Information Box: Contains information specifying the data handler component that provides access to the
- * media data. The data handler component uses the Data Information Box to interpret the media's data.
- */
-export const dinf = () => box('dinf', null, [
- dref()
-]);
-
-/**
- * Data Reference Box: Contains tabular data that instructs the data handler component how to access the media's data.
- */
-export const dref = () => fullBox('dref', 0, 0, [
- u32(1) // Entry count
-], [
- url()
-]);
-
-export const url = () => fullBox('url ', 0, 1); // Self-reference flag enabled
-
-/**
- * Sample Table Box: Contains information for converting from media time to sample number to sample location. This box
- * also indicates how to interpret the sample (for example, whether to decompress the video data and, if so, how).
- */
-export const stbl = (track: Track) => {
- const needsCtts = track.compositionTimeOffsetTable.length > 1 ||
- track.compositionTimeOffsetTable.some((x) => x.sampleCompositionTimeOffset !== 0);
-
- return box('stbl', null, [
- stsd(track),
- stts(track),
- stss(track),
- stsc(track),
- stsz(track),
- stco(track),
- needsCtts ? ctts(track) : null
- ]);
-};
-
-/**
- * Sample Description Box: Stores information that allows you to decode samples in the media. The data stored in the
- * sample description varies, depending on the media type.
- */
-export const stsd = (track: Track) => fullBox('stsd', 0, 0, [
- u32(1) // Entry count
-], [
- track.info.type === 'video'
- ? videoSampleDescription(
- VIDEO_CODEC_TO_BOX_NAME[track.info.codec],
- track as VideoTrack
- )
- : soundSampleDescription(
- AUDIO_CODEC_TO_BOX_NAME[track.info.codec],
- track as AudioTrack
- )
-]);
-
-/** Video Sample Description Box: Contains information that defines how to interpret video media data. */
-export const videoSampleDescription = (
- compressionType: string,
- track: VideoTrack
-) => box(compressionType, [
- Array(6).fill(0), // Reserved
- u16(1), // Data reference index
- u16(0), // Pre-defined
- u16(0), // Reserved
- Array(12).fill(0), // Pre-defined
- u16(track.info.width), // Width
- u16(track.info.height), // Height
- u32(0x00480000), // Horizontal resolution
- u32(0x00480000), // Vertical resolution
- u32(0), // Reserved
- u16(1), // Frame count
- Array(32).fill(0), // Compressor name
- u16(0x0018), // Depth
- i16(0xffff) // Pre-defined
-], [
- VIDEO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track)
-]);
-
-/** AVC Configuration Box: Provides additional information to the decoder. */
-export const avcC = (track: VideoTrack) => track.info.decoderConfig && box('avcC', [
- // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here
- ...new Uint8Array(track.info.decoderConfig.description as ArrayBuffer)
-]);
-
-/** HEVC Configuration Box: Provides additional information to the decoder. */
-export const hvcC = (track: VideoTrack) => track.info.decoderConfig && box('hvcC', [
- // For HEVC, description is a HEVCDecoderConfigurationRecord, so nothing else to do here
- ...new Uint8Array(track.info.decoderConfig.description as ArrayBuffer)
-]);
-
-/** VP9 Configuration Box: Provides additional information to the decoder. */
-export const vpcC = (track: VideoTrack) => {
- // Reference: https://www.webmproject.org/vp9/mp4/
-
- if (!track.info.decoderConfig) {
- return null;
- }
-
- let decoderConfig = track.info.decoderConfig;
- if (!decoderConfig.colorSpace) {
- throw new Error(`'colorSpace' is required in the decoder config for VP9.`);
- }
-
- let parts = decoderConfig.codec.split('.');
- let profile = Number(parts[1]);
- let level = Number(parts[2]);
-
- let bitDepth = Number(parts[3]);
- let chromaSubsampling = 0;
- let thirdByte = (bitDepth << 4) + (chromaSubsampling << 1) + Number(decoderConfig.colorSpace.fullRange);
-
- // Set all to undetermined. We could determine them using the codec color space info, but there's no need.
- let colourPrimaries = 2;
- let transferCharacteristics = 2;
- let matrixCoefficients = 2;
-
- return fullBox('vpcC', 1, 0, [
- u8(profile), // Profile
- u8(level), // Level
- u8(thirdByte), // Bit depth, chroma subsampling, full range
- u8(colourPrimaries), // Colour primaries
- u8(transferCharacteristics), // Transfer characteristics
- u8(matrixCoefficients), // Matrix coefficients
- u16(0) // Codec initialization data size
- ]);
-};
-
-/** AV1 Configuration Box: Provides additional information to the decoder. */
-export const av1C = () => {
- // Reference: https://aomediacodec.github.io/av1-isobmff/
-
- let marker = 1;
- let version = 1;
- let firstByte = (marker << 7) + version;
-
- // The box contents are not correct like this, but its length is. Getting the values for the last three bytes
- // requires peeking into the bitstream of the coded chunks. Might come back later.
- return box('av1C', [
- firstByte,
- 0,
- 0,
- 0
- ]);
-};
-
-/** Sound Sample Description Box: Contains information that defines how to interpret sound media data. */
-export const soundSampleDescription = (
- compressionType: string,
- track: AudioTrack
-) => box(compressionType, [
- Array(6).fill(0), // Reserved
- u16(1), // Data reference index
- u16(0), // Version
- u16(0), // Revision level
- u32(0), // Vendor
- u16(track.info.numberOfChannels), // Number of channels
- u16(16), // Sample size (bits)
- u16(0), // Compression ID
- u16(0), // Packet size
- fixed_16_16(track.info.sampleRate) // Sample rate
-], [
- AUDIO_CODEC_TO_CONFIGURATION_BOX[track.info.codec](track)
-]);
-
-/** MPEG-4 Elementary Stream Descriptor Box. */
-export const esds = (track: Track) => {
- let description = new Uint8Array(track.info.decoderConfig.description as ArrayBuffer);
-
- return fullBox('esds', 0, 0, [
- // https://stackoverflow.com/a/54803118
- u32(0x03808080), // TAG(3) = Object Descriptor ([2])
- u8(0x20 + description.byteLength), // length of this OD (which includes the next 2 tags)
- u16(1), // ES_ID = 1
- u8(0x00), // flags etc = 0
- u32(0x04808080), // TAG(4) = ES Descriptor ([2]) embedded in above OD
- u8(0x12 + description.byteLength), // length of this ESD
- u8(0x40), // MPEG-4 Audio
- u8(0x15), // stream type(6bits)=5 audio, flags(2bits)=1
- u24(0), // 24bit buffer size
- u32(0x0001FC17), // max bitrate
- u32(0x0001FC17), // avg bitrate
- u32(0x05808080), // TAG(5) = ASC ([2],[3]) embedded in above OD
- u8(description.byteLength), // length
- ...description,
- u32(0x06808080), // TAG(6)
- u8(0x01), // length
- u8(0x02) // data
- ]);
-};
-
-/** Opus Specific Box. */
-export const dOps = (track: AudioTrack) => box('dOps', [
- u8(0), // Version
- u8(track.info.numberOfChannels), // OutputChannelCount
- u16(3840), // PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples
- u32(track.info.sampleRate), // InputSampleRate
- fixed_8_8(0), // OutputGain
- u8(0) // ChannelMappingFamily
-]);
-
-/**
- * Time-To-Sample Box: Stores duration information for a media's samples, providing a mapping from a time in a media
- * to the corresponding data sample. The table is compact, meaning that consecutive samples with the same time delta
- * will be grouped.
- */
-export const stts = (track: Track) => {
- return fullBox('stts', 0, 0, [
- u32(track.timeToSampleTable.length), // Number of entries
- track.timeToSampleTable.map(x => [ // Time-to-sample table
- u32(x.sampleCount), // Sample count
- u32(x.sampleDelta) // Sample duration
- ])
- ]);
-};
-
-/** Sync Sample Box: Identifies the key frames in the media, marking the random access points within a stream. */
-export const stss = (track: Track) => {
- if (track.samples.every(x => x.type === 'key')) return null; // No stss box -> every frame is a key frame
-
- let keySamples = [...track.samples.entries()].filter(([, sample]) => sample.type === 'key');
- return fullBox('stss', 0, 0, [
- u32(keySamples.length), // Number of entries
- keySamples.map(([index]) => u32(index + 1)) // Sync sample table
- ]);
-};
-
-/**
- * Sample-To-Chunk Box: As samples are added to a media, they are collected into chunks that allow optimized data
- * access. A chunk contains one or more samples. Chunks in a media may have different sizes, and the samples within a
- * chunk may have different sizes. The Sample-To-Chunk Box stores chunk information for the samples in a media, stored
- * in a compactly-coded fashion.
- */
-export const stsc = (track: Track) => {
- return fullBox('stsc', 0, 0, [
- u32(track.compactlyCodedChunkTable.length), // Number of entries
- track.compactlyCodedChunkTable.map(x => [ // Sample-to-chunk table
- u32(x.firstChunk), // First chunk
- u32(x.samplesPerChunk), // Samples per chunk
- u32(1) // Sample description index
- ])
- ]);
-};
-
-/** Sample Size Box: Specifies the byte size of each sample in the media. */
-export const stsz = (track: Track) => fullBox('stsz', 0, 0, [
- u32(0), // Sample size (0 means non-constant size)
- u32(track.samples.length), // Number of entries
- track.samples.map(x => u32(x.size)) // Sample size table
-]);
-
-/** Chunk Offset Box: Identifies the location of each chunk of data in the media's data stream, relative to the file. */
-export const stco = (track: Track) => {
- if (track.finalizedChunks.length > 0 && last(track.finalizedChunks).offset >= 2**32) {
- // If the file is large, use the co64 box
- return fullBox('co64', 0, 0, [
- u32(track.finalizedChunks.length), // Number of entries
- track.finalizedChunks.map(x => u64(x.offset)) // Chunk offset table
- ]);
- }
-
- return fullBox('stco', 0, 0, [
- u32(track.finalizedChunks.length), // Number of entries
- track.finalizedChunks.map(x => u32(x.offset)) // Chunk offset table
- ]);
-};
-
-/** Composition Time to Sample Box: Stores composition time offset information (PTS-DTS) for a
- * media's samples. The table is compact, meaning that consecutive samples with the same time
- * composition time offset will be grouped. */
-export const ctts = (track: Track) => {
- return fullBox('ctts', 0, 0, [
- u32(track.compositionTimeOffsetTable.length), // Number of entries
- track.compositionTimeOffsetTable.map(x => [ // Time-to-sample table
- u32(x.sampleCount), // Sample count
- u32(x.sampleCompositionTimeOffset) // Sample offset
- ])
- ]);
-};
-
-/**
- * Movie Extends Box: This box signals to readers that the file is fragmented. Contains a single Track Extends Box
- * for each track in the movie.
- */
-export const mvex = (tracks: Track[]) => {
- return box('mvex', null, tracks.map(trex));
-};
-
-/** Track Extends Box: Contains the default values used by the movie fragments. */
-export const trex = (track: Track) => {
- return fullBox('trex', 0, 0, [
- u32(track.id), // Track ID
- u32(1), // Default sample description index
- u32(0), // Default sample duration
- u32(0), // Default sample size
- u32(0) // Default sample flags
- ]);
-};
-
-/**
- * Movie Fragment Box: The movie fragments extend the presentation in time. They provide the information that would
- * previously have been in the Movie Box.
- */
-export const moof = (sequenceNumber: number, tracks: Track[]) => {
- return box('moof', null, [
- mfhd(sequenceNumber),
- ...tracks.map(traf)
- ]);
-};
-
-/** Movie Fragment Header Box: Contains a sequence number as a safety check. */
-export const mfhd = (sequenceNumber: number) => {
- return fullBox('mfhd', 0, 0, [
- u32(sequenceNumber) // Sequence number
- ]);
-};
-
-const fragmentSampleFlags = (sample: Sample) => {
- let byte1 = 0;
- let byte2 = 0;
- let byte3 = 0;
- let byte4 = 0;
-
- let sampleIsDifferenceSample = sample.type === 'delta';
- byte2 |= +sampleIsDifferenceSample;
-
- if (sampleIsDifferenceSample) {
- byte1 |= 1; // There is redundant coding in this sample
- } else {
- byte1 |= 2; // There is no redundant coding in this sample
- }
-
- // Note that there are a lot of other flags to potentially set here, but most are irrelevant / non-necessary
- return byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
-};
-
-/** Track Fragment Box */
-export const traf = (track: Track) => {
- return box('traf', null, [
- tfhd(track),
- tfdt(track),
- trun(track)
- ]);
-};
-
-/** Track Fragment Header Box: Provides a reference to the extended track, and flags. */
-export const tfhd = (track: Track) => {
- let tfFlags = 0;
- tfFlags |= 0x00008; // Default sample duration present
- tfFlags |= 0x00010; // Default sample size present
- tfFlags |= 0x00020; // Default sample flags present
- tfFlags |= 0x20000; // Default base is moof
-
- // Prefer the second sample over the first one, as the first one is a sync sample and therefore the "odd one out"
- let referenceSample = track.currentChunk.samples[1] ?? track.currentChunk.samples[0];
- let referenceSampleInfo = {
- duration: referenceSample.timescaleUnitsToNextSample,
- size: referenceSample.size,
- flags: fragmentSampleFlags(referenceSample)
- };
-
- return fullBox('tfhd', 0, tfFlags, [
- u32(track.id), // Track ID
- u32(referenceSampleInfo.duration), // Default sample duration
- u32(referenceSampleInfo.size), // Default sample size
- u32(referenceSampleInfo.flags) // Default sample flags
- ]);
-};
-
-/**
- * Track Fragment Decode Time Box: Provides the absolute decode time of the first sample of the fragment. This is
- * useful for performing random access on the media file.
- */
-export const tfdt = (track: Track) => {
- return fullBox('tfdt', 1, 0, [
- u64(intoTimescale(track.currentChunk.startTimestamp, track.timescale)) // Base Media Decode Time
- ]);
-};
-
-/** Track Run Box: Specifies a run of contiguous samples for a given track. */
-export const trun = (track: Track) => {
- let allSampleDurations = track.currentChunk.samples.map(x => x.timescaleUnitsToNextSample);
- let allSampleSizes = track.currentChunk.samples.map(x => x.size);
- let allSampleFlags = track.currentChunk.samples.map(fragmentSampleFlags);
- let allSampleCompositionTimeOffsets = track.currentChunk.samples.
- map(x => intoTimescale(x.presentationTimestamp - x.decodeTimestamp, track.timescale));
-
- let uniqueSampleDurations = new Set(allSampleDurations);
- let uniqueSampleSizes = new Set(allSampleSizes);
- let uniqueSampleFlags = new Set(allSampleFlags);
- let uniqueSampleCompositionTimeOffsets = new Set(allSampleCompositionTimeOffsets);
-
- let firstSampleFlagsPresent = uniqueSampleFlags.size === 2 && allSampleFlags[0] !== allSampleFlags[1];
- let sampleDurationPresent = uniqueSampleDurations.size > 1;
- let sampleSizePresent = uniqueSampleSizes.size > 1;
- let sampleFlagsPresent = !firstSampleFlagsPresent && uniqueSampleFlags.size > 1;
- let sampleCompositionTimeOffsetsPresent =
- uniqueSampleCompositionTimeOffsets.size > 1 || [...uniqueSampleCompositionTimeOffsets].some(x => x !== 0);
-
- let flags = 0;
- flags |= 0x0001; // Data offset present
- flags |= 0x0004 * +firstSampleFlagsPresent; // First sample flags present
- flags |= 0x0100 * +sampleDurationPresent; // Sample duration present
- flags |= 0x0200 * +sampleSizePresent; // Sample size present
- flags |= 0x0400 * +sampleFlagsPresent; // Sample flags present
- flags |= 0x0800 * +sampleCompositionTimeOffsetsPresent; // Sample composition time offsets present
-
- return fullBox('trun', 1, flags, [
- u32(track.currentChunk.samples.length), // Sample count
- u32(track.currentChunk.offset - track.currentChunk.moofOffset || 0), // Data offset
- firstSampleFlagsPresent ? u32(allSampleFlags[0]) : [],
- track.currentChunk.samples.map((_, i) => [
- sampleDurationPresent ? u32(allSampleDurations[i]) : [], // Sample duration
- sampleSizePresent ? u32(allSampleSizes[i]) : [], // Sample size
- sampleFlagsPresent ? u32(allSampleFlags[i]) : [], // Sample flags
- // Sample composition time offsets
- sampleCompositionTimeOffsetsPresent ? i32(allSampleCompositionTimeOffsets[i]) : []
- ])
- ]);
-};
-
-/**
- * Movie Fragment Random Access Box: For each track, provides pointers to sync samples within the file
- * for random access.
- */
-export const mfra = (tracks: Track[]) => {
- return box('mfra', null, [
- ...tracks.map(tfra),
- mfro()
- ]);
-};
-
-/** Track Fragment Random Access Box: Provides pointers to sync samples within the file for random access. */
-export const tfra = (track: Track, trackIndex: number) => {
- let version = 1; // Using this version allows us to use 64-bit time and offset values
-
- return fullBox('tfra', version, 0, [
- u32(track.id), // Track ID
- u32(0b111111), // This specifies that traf number, trun number and sample number are 32-bit ints
- u32(track.finalizedChunks.length), // Number of entries
- track.finalizedChunks.map(chunk => [
- u64(intoTimescale(chunk.startTimestamp, track.timescale)), // Time
- u64(chunk.moofOffset), // moof offset
- u32(trackIndex + 1), // traf number
- u32(1), // trun number
- u32(1) // Sample number
- ])
- ]);
-};
-
-/**
- * Movie Fragment Random Access Offset Box: Provides the size of the enclosing mfra box. This box can be used by readers
- * to quickly locate the mfra box by searching from the end of the file.
- */
-export const mfro = () => {
- return fullBox('mfro', 0, 0, [
- // This value needs to be overwritten manually from the outside, where the actual size of the enclosing mfra box
- // is known
- u32(0) // Size
- ]);
-};
-
-const VIDEO_CODEC_TO_BOX_NAME: Record = {
- 'avc': 'avc1',
- 'hevc': 'hvc1',
- 'vp9': 'vp09',
- 'av1': 'av01'
-};
-
-const VIDEO_CODEC_TO_CONFIGURATION_BOX: Record Box> = {
- 'avc': avcC,
- 'hevc': hvcC,
- 'vp9': vpcC,
- 'av1': av1C
-};
-
-const AUDIO_CODEC_TO_BOX_NAME: Record = {
- 'aac': 'mp4a',
- 'opus': 'Opus'
-};
-
-const AUDIO_CODEC_TO_CONFIGURATION_BOX: Record Box> = {
- 'aac': esds,
- 'opus': dOps
-};
diff --git a/v0-appel-projet/public/mp4-muxer-main/src/index.ts b/v0-appel-projet/public/mp4-muxer-main/src/index.ts
deleted file mode 100644
index 0c1811b..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/src/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { Muxer } from './muxer';
-export * from './target';
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/src/misc.ts b/v0-appel-projet/public/mp4-muxer-main/src/misc.ts
deleted file mode 100644
index f08fa96..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/src/misc.ts
+++ /dev/null
@@ -1,117 +0,0 @@
-import { Sample } from './muxer';
-
-let bytes = new Uint8Array(8);
-let view = new DataView(bytes.buffer);
-
-export const u8 = (value: number) => {
- return [(value % 0x100 + 0x100) % 0x100];
-};
-
-export const u16 = (value: number) => {
- view.setUint16(0, value, false);
- return [bytes[0], bytes[1]];
-};
-
-export const i16 = (value: number) => {
- view.setInt16(0, value, false);
- return [bytes[0], bytes[1]];
-};
-
-export const u24 = (value: number) => {
- view.setUint32(0, value, false);
- return [bytes[1], bytes[2], bytes[3]];
-};
-
-export const u32 = (value: number) => {
- view.setUint32(0, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-
-export const i32 = (value: number) => {
- view.setInt32(0, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-
-export const u64 = (value: number) => {
- view.setUint32(0, Math.floor(value / 2**32), false);
- view.setUint32(4, value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];
-};
-
-export const fixed_8_8 = (value: number) => {
- view.setInt16(0, 2**8 * value, false);
- return [bytes[0], bytes[1]];
-};
-
-export const fixed_16_16 = (value: number) => {
- view.setInt32(0, 2**16 * value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-
-export const fixed_2_30 = (value: number) => {
- view.setInt32(0, 2**30 * value, false);
- return [bytes[0], bytes[1], bytes[2], bytes[3]];
-};
-
-export const ascii = (text: string, nullTerminated = false) => {
- let bytes = Array(text.length).fill(null).map((_, i) => text.charCodeAt(i));
- if (nullTerminated) bytes.push(0x00);
- return bytes;
-};
-
-export const last = (arr: T[]) => {
- return arr && arr[arr.length - 1];
-};
-
-export const lastPresentedSample = (samples: Sample[]): Sample | undefined => {
- let result: Sample | undefined = undefined;
-
- for (let sample of samples) {
- if (!result || sample.presentationTimestamp > result.presentationTimestamp) {
- result = sample;
- }
- }
-
- return result;
-};
-
-export const intoTimescale = (timeInSeconds: number, timescale: number, round = true) => {
- let value = timeInSeconds * timescale;
- return round ? Math.round(value) : value;
-};
-
-export type TransformationMatrix = [number, number, number, number, number, number, number, number, number];
-
-export const rotationMatrix = (rotationInDegrees: number): TransformationMatrix => {
- let theta = rotationInDegrees * (Math.PI / 180);
- let cosTheta = Math.cos(theta);
- let sinTheta = Math.sin(theta);
-
- // Matrices are post-multiplied in MP4, meaning this is the transpose of your typical rotation matrix
- return [
- cosTheta, sinTheta, 0,
- -sinTheta, cosTheta, 0,
- 0, 0, 1
- ];
-};
-
-export const IDENTITY_MATRIX = rotationMatrix(0);
-
-export const matrixToBytes = (matrix: TransformationMatrix) => {
- return [
- fixed_16_16(matrix[0]), fixed_16_16(matrix[1]), fixed_2_30(matrix[2]),
- fixed_16_16(matrix[3]), fixed_16_16(matrix[4]), fixed_2_30(matrix[5]),
- fixed_16_16(matrix[6]), fixed_16_16(matrix[7]), fixed_2_30(matrix[8])
- ];
-};
-
-export const deepClone = (x: T): T => {
- if (!x) return x;
- if (typeof x !== 'object') return x;
- if (Array.isArray(x)) return x.map(deepClone) as T;
- return Object.fromEntries(Object.entries(x).map(([key, value]) => [key, deepClone(value)])) as T;
-};
-
-export const isU32 = (value: number) => {
- return value >= 0 && value < 2**32;
-};
diff --git a/v0-appel-projet/public/mp4-muxer-main/src/muxer.ts b/v0-appel-projet/public/mp4-muxer-main/src/muxer.ts
deleted file mode 100644
index a99bacd..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/src/muxer.ts
+++ /dev/null
@@ -1,842 +0,0 @@
-import { Box, free, ftyp, mdat, mfra, moof, moov } from './box';
-import { deepClone, intoTimescale, last, TransformationMatrix } from './misc';
-import { ArrayBufferTarget, FileSystemWritableFileStreamTarget, StreamTarget, Target } from './target';
-import {
- Writer,
- ArrayBufferTargetWriter,
- StreamTargetWriter,
- ChunkedStreamTargetWriter,
- FileSystemWritableFileStreamTargetWriter
-} from './writer';
-
-export const GLOBAL_TIMESCALE = 1000;
-export const SUPPORTED_VIDEO_CODECS = ['avc', 'hevc', 'vp9', 'av1'] as const;
-export const SUPPORTED_AUDIO_CODECS = ['aac', 'opus'] as const;
-const TIMESTAMP_OFFSET = 2_082_844_800; // Seconds between Jan 1 1904 and Jan 1 1970
-const FIRST_TIMESTAMP_BEHAVIORS = ['strict', 'offset', 'cross-track-offset'] as const;
-
-interface VideoOptions {
- codec: typeof SUPPORTED_VIDEO_CODECS[number],
- width: number,
- height: number,
- rotation?: 0 | 90 | 180 | 270 | TransformationMatrix
-}
-
-interface AudioOptions {
- codec: typeof SUPPORTED_AUDIO_CODECS[number],
- numberOfChannels: number,
- sampleRate: number
-}
-
-type Mp4MuxerOptions = {
- target: T,
- video?: VideoOptions,
- audio?: AudioOptions,
- fastStart: false | 'in-memory' | 'fragmented' | {
- expectedVideoChunks?: number,
- expectedAudioChunks?: number
- },
- firstTimestampBehavior?: typeof FIRST_TIMESTAMP_BEHAVIORS[number]
-};
-
-export interface Track {
- id: number,
- info: {
- type: 'video',
- codec: VideoOptions['codec'],
- width: number,
- height: number,
- rotation: 0 | 90 | 180 | 270 | TransformationMatrix,
- decoderConfig: VideoDecoderConfig
- } | {
- type: 'audio',
- codec: AudioOptions['codec'],
- numberOfChannels: number,
- sampleRate: number,
- decoderConfig: AudioDecoderConfig
- },
- timescale: number,
- samples: Sample[],
-
- firstDecodeTimestamp: number,
- lastDecodeTimestamp: number,
-
- timeToSampleTable: { sampleCount: number, sampleDelta: number }[];
- compositionTimeOffsetTable: { sampleCount: number, sampleCompositionTimeOffset: number }[];
- lastTimescaleUnits: number,
- lastSample: Sample,
-
- finalizedChunks: Chunk[],
- currentChunk: Chunk,
- compactlyCodedChunkTable: {
- firstChunk: number,
- samplesPerChunk: number
- }[]
-}
-
-export type VideoTrack = Track & { info: { type: 'video' } };
-export type AudioTrack = Track & { info: { type: 'audio' } };
-
-export interface Sample {
- presentationTimestamp: number,
- decodeTimestamp: number,
- duration: number,
- data: Uint8Array,
- size: number,
- type: 'key' | 'delta',
- timescaleUnitsToNextSample: number
-}
-
-interface Chunk {
- startTimestamp: number,
- samples: Sample[],
- offset?: number,
- // In the case of a fragmented file, this indicates the position of the moof box pointing to the data in this chunk
- moofOffset?: number
-}
-
-export class Muxer {
- target: T;
-
- #options: Mp4MuxerOptions;
- #writer: Writer;
- #ftypSize: number;
- #mdat: Box;
-
- #videoTrack: Track = null;
- #audioTrack: Track = null;
- #creationTime = Math.floor(Date.now() / 1000) + TIMESTAMP_OFFSET;
- #finalizedChunks: Chunk[] = [];
-
- // Fields for fragmented MP4:
- #nextFragmentNumber = 1;
- #videoSampleQueue: Sample[] = [];
- #audioSampleQueue: Sample[] = [];
-
- #finalized = false;
-
- constructor(options: Mp4MuxerOptions) {
- this.#validateOptions(options);
-
- // Don't want these to be modified from the outside while processing:
- options.video = deepClone(options.video);
- options.audio = deepClone(options.audio);
- options.fastStart = deepClone(options.fastStart);
-
- this.target = options.target;
- this.#options = {
- firstTimestampBehavior: 'strict',
- ...options
- };
-
- if (options.target instanceof ArrayBufferTarget) {
- this.#writer = new ArrayBufferTargetWriter(options.target);
- } else if (options.target instanceof StreamTarget) {
- this.#writer = options.target.options?.chunked
- ? new ChunkedStreamTargetWriter(options.target)
- : new StreamTargetWriter(options.target);
- } else if (options.target instanceof FileSystemWritableFileStreamTarget) {
- this.#writer = new FileSystemWritableFileStreamTargetWriter(options.target);
- } else {
- throw new Error(`Invalid target: ${options.target}`);
- }
-
- this.#prepareTracks();
- this.#writeHeader();
- }
-
- #validateOptions(options: Mp4MuxerOptions) {
- if (options.video) {
- if (!SUPPORTED_VIDEO_CODECS.includes(options.video.codec)) {
- throw new Error(`Unsupported video codec: ${options.video.codec}`);
- }
-
- const videoRotation = options.video.rotation;
- if (typeof videoRotation === 'number' && ![0, 90, 180, 270].includes(videoRotation)) {
- throw new Error(`Invalid video rotation: ${videoRotation}. Has to be 0, 90, 180 or 270.`);
- } else if (
- Array.isArray(videoRotation) &&
- (videoRotation.length !== 9 || videoRotation.some(value => typeof value !== 'number'))
- ) {
- throw new Error(`Invalid video transformation matrix: ${videoRotation.join()}`);
- }
- }
-
- if (options.audio && !SUPPORTED_AUDIO_CODECS.includes(options.audio.codec)) {
- throw new Error(`Unsupported audio codec: ${options.audio.codec}`);
- }
-
- if (options.firstTimestampBehavior && !FIRST_TIMESTAMP_BEHAVIORS.includes(options.firstTimestampBehavior)) {
- throw new Error(`Invalid first timestamp behavior: ${options.firstTimestampBehavior}`);
- }
-
- if (typeof options.fastStart === 'object') {
- if (options.video && options.fastStart.expectedVideoChunks === undefined) {
- throw new Error(`'fastStart' is an object but is missing property 'expectedVideoChunks'.`);
- }
-
- if (options.audio && options.fastStart.expectedAudioChunks === undefined) {
- throw new Error(`'fastStart' is an object but is missing property 'expectedAudioChunks'.`);
- }
- } else if (![false, 'in-memory', 'fragmented'].includes(options.fastStart)) {
- throw new Error(`'fastStart' option must be false, 'in-memory', 'fragmented' or an object.`);
- }
- }
-
- #writeHeader() {
- this.#writer.writeBox(ftyp({
- holdsAvc: this.#options.video?.codec === 'avc',
- fragmented: this.#options.fastStart === 'fragmented'
- }));
-
- this.#ftypSize = this.#writer.pos;
-
- if (this.#options.fastStart === 'in-memory') {
- this.#mdat = mdat(false);
- } else if (this.#options.fastStart === 'fragmented') {
- // We write the moov box once we write out the first fragment to make sure we get the decoder configs
- } else {
- if (typeof this.#options.fastStart === 'object') {
- let moovSizeUpperBound = this.#computeMoovSizeUpperBound();
- this.#writer.seek(this.#writer.pos + moovSizeUpperBound);
- }
-
- this.#mdat = mdat(true); // Reserve large size by default, can refine this when finalizing.
- this.#writer.writeBox(this.#mdat);
- }
-
- this.#maybeFlushStreamingTargetWriter();
- }
-
- #computeMoovSizeUpperBound() {
- if (typeof this.#options.fastStart !== 'object') return;
-
- let upperBound = 0;
- let sampleCounts = [
- this.#options.fastStart.expectedVideoChunks,
- this.#options.fastStart.expectedAudioChunks
- ];
-
- for (let n of sampleCounts) {
- if (!n) continue;
-
- // Given the max allowed sample count, compute the space they'll take up in the Sample Table Box, assuming
- // the worst case for each individual box:
-
- // stts box - since it is compactly coded, the maximum length of this table will be 2/3n
- upperBound += (4 + 4) * Math.ceil(2/3 * n);
- // stss box - 1 entry per sample
- upperBound += 4 * n;
- // stsc box - since it is compactly coded, the maximum length of this table will be 2/3n
- upperBound += (4 + 4 + 4) * Math.ceil(2/3 * n);
- // stsz box - 1 entry per sample
- upperBound += 4 * n;
- // co64 box - we assume 1 sample per chunk and 64-bit chunk offsets
- upperBound += 8 * n;
- }
-
- upperBound += 4096; // Assume a generous 4 kB for everything else: Track metadata, codec descriptors, etc.
-
- return upperBound;
- }
-
- #prepareTracks() {
- if (this.#options.video) {
- this.#videoTrack = {
- id: 1,
- info: {
- type: 'video',
- codec: this.#options.video.codec,
- width: this.#options.video.width,
- height: this.#options.video.height,
- rotation: this.#options.video.rotation ?? 0,
- decoderConfig: null
- },
- timescale: 11520, // Timescale used by FFmpeg, contains many common frame rates as factors
- samples: [],
- finalizedChunks: [],
- currentChunk: null,
- firstDecodeTimestamp: undefined,
- lastDecodeTimestamp: -1,
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- compactlyCodedChunkTable: []
- };
- }
-
- if (this.#options.audio) {
- // For the case that we don't get any further decoder details, we can still make a pretty educated guess:
- let guessedCodecPrivate = this.#generateMpeg4AudioSpecificConfig(
- 2, // Object type for AAC-LC, since it's the most common
- this.#options.audio.sampleRate,
- this.#options.audio.numberOfChannels
- );
-
- this.#audioTrack = {
- id: this.#options.video ? 2 : 1,
- info: {
- type: 'audio',
- codec: this.#options.audio.codec,
- numberOfChannels: this.#options.audio.numberOfChannels,
- sampleRate: this.#options.audio.sampleRate,
- decoderConfig: {
- codec: this.#options.audio.codec,
- description: guessedCodecPrivate,
- numberOfChannels: this.#options.audio.numberOfChannels,
- sampleRate: this.#options.audio.sampleRate
- }
- },
- timescale: this.#options.audio.sampleRate,
- samples: [],
- finalizedChunks: [],
- currentChunk: null,
- firstDecodeTimestamp: undefined,
- lastDecodeTimestamp: -1,
- timeToSampleTable: [],
- compositionTimeOffsetTable: [],
- lastTimescaleUnits: null,
- lastSample: null,
- compactlyCodedChunkTable: []
- };
- }
- }
-
- // https://wiki.multimedia.cx/index.php/MPEG-4_Audio
- #generateMpeg4AudioSpecificConfig(objectType: number, sampleRate: number, numberOfChannels: number) {
- let frequencyIndices =
- [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
- let frequencyIndex = frequencyIndices.indexOf(sampleRate);
- let channelConfig = numberOfChannels;
-
- let configBits = '';
- configBits += objectType.toString(2).padStart(5, '0');
-
- configBits += frequencyIndex.toString(2).padStart(4, '0');
- if (frequencyIndex === 15) configBits += sampleRate.toString(2).padStart(24, '0');
-
- configBits += channelConfig.toString(2).padStart(4, '0');
-
- // Pad with 0 bits to fit into a multiple of bytes
- let paddingLength = Math.ceil(configBits.length / 8) * 8;
- configBits = configBits.padEnd(paddingLength, '0');
-
- let configBytes = new Uint8Array(configBits.length / 8);
- for (let i = 0; i < configBits.length; i += 8) {
- configBytes[i / 8] = parseInt(configBits.slice(i, i + 8), 2);
- }
-
- return configBytes;
- }
-
- addVideoChunk(
- sample: EncodedVideoChunk,
- meta?: EncodedVideoChunkMetadata,
- timestamp?: number,
- compositionTimeOffset?: number
- ) {
- let data = new Uint8Array(sample.byteLength);
- sample.copyTo(data);
-
- this.addVideoChunkRaw(
- data, sample.type, timestamp ?? sample.timestamp, sample.duration, meta, compositionTimeOffset
- );
- }
-
- addVideoChunkRaw(
- data: Uint8Array,
- type: 'key' | 'delta',
- timestamp: number,
- duration: number,
- meta?: EncodedVideoChunkMetadata,
- compositionTimeOffset?: number
- ) {
- this.#ensureNotFinalized();
- if (!this.#options.video) throw new Error('No video track declared.');
-
- if (
- typeof this.#options.fastStart === 'object' &&
- this.#videoTrack.samples.length === this.#options.fastStart.expectedVideoChunks
- ) {
- throw new Error(`Cannot add more video chunks than specified in 'fastStart' (${
- this.#options.fastStart.expectedVideoChunks
- }).`);
- }
-
- let videoSample = this.#createSampleForTrack(
- this.#videoTrack, data, type, timestamp, duration, meta, compositionTimeOffset
- );
-
- // Check if we need to interleave the samples in the case of a fragmented file
- if (this.#options.fastStart === 'fragmented' && this.#audioTrack) {
- // Add all audio samples with a timestamp smaller than the incoming video sample
- while (
- this.#audioSampleQueue.length > 0 &&
- this.#audioSampleQueue[0].decodeTimestamp <= videoSample.decodeTimestamp
- ) {
- let audioSample = this.#audioSampleQueue.shift();
- this.#addSampleToTrack(this.#audioTrack, audioSample);
- }
-
- // Depending on the last audio sample, either add the video sample to the file or enqueue it
- if (videoSample.decodeTimestamp <= this.#audioTrack.lastDecodeTimestamp) {
- this.#addSampleToTrack(this.#videoTrack, videoSample);
- } else {
- this.#videoSampleQueue.push(videoSample);
- }
- } else {
- this.#addSampleToTrack(this.#videoTrack, videoSample);
- }
- }
-
- addAudioChunk(sample: EncodedAudioChunk, meta?: EncodedAudioChunkMetadata, timestamp?: number) {
- let data = new Uint8Array(sample.byteLength);
- sample.copyTo(data);
-
- this.addAudioChunkRaw(data, sample.type, timestamp ?? sample.timestamp, sample.duration, meta);
- }
-
- addAudioChunkRaw(
- data: Uint8Array,
- type: 'key' | 'delta',
- timestamp: number,
- duration: number,
- meta?: EncodedAudioChunkMetadata
- ) {
- this.#ensureNotFinalized();
- if (!this.#options.audio) throw new Error('No audio track declared.');
-
- if (
- typeof this.#options.fastStart === 'object' &&
- this.#audioTrack.samples.length === this.#options.fastStart.expectedAudioChunks
- ) {
- throw new Error(`Cannot add more audio chunks than specified in 'fastStart' (${
- this.#options.fastStart.expectedAudioChunks
- }).`);
- }
-
- let audioSample = this.#createSampleForTrack(this.#audioTrack, data, type, timestamp, duration, meta);
-
- // Check if we need to interleave the samples in the case of a fragmented file
- if (this.#options.fastStart === 'fragmented' && this.#videoTrack) {
- // Add all video samples with a timestamp smaller than the incoming audio sample
- while (
- this.#videoSampleQueue.length > 0 &&
- this.#videoSampleQueue[0].decodeTimestamp <= audioSample.decodeTimestamp
- ) {
- let videoSample = this.#videoSampleQueue.shift();
- this.#addSampleToTrack(this.#videoTrack, videoSample);
- }
-
- // Depending on the last video sample, either add the audio sample to the file or enqueue it
- if (audioSample.decodeTimestamp <= this.#videoTrack.lastDecodeTimestamp) {
- this.#addSampleToTrack(this.#audioTrack, audioSample);
- } else {
- this.#audioSampleQueue.push(audioSample);
- }
- } else {
- this.#addSampleToTrack(this.#audioTrack, audioSample);
- }
- }
-
- #createSampleForTrack(
- track: Track,
- data: Uint8Array,
- type: 'key' | 'delta',
- timestamp: number,
- duration: number,
- meta?: EncodedVideoChunkMetadata | EncodedAudioChunkMetadata,
- compositionTimeOffset?: number
- ) {
- let presentationTimestampInSeconds = timestamp / 1e6;
- let decodeTimestampInSeconds = (timestamp - (compositionTimeOffset ?? 0)) / 1e6;
- let durationInSeconds = duration / 1e6;
-
- let adjusted = this.#validateTimestamp(presentationTimestampInSeconds, decodeTimestampInSeconds, track);
- presentationTimestampInSeconds = adjusted.presentationTimestamp;
- decodeTimestampInSeconds = adjusted.decodeTimestamp;
-
- if (meta?.decoderConfig) {
- if (track.info.decoderConfig === null) {
- track.info.decoderConfig = meta.decoderConfig;
- } else {
- Object.assign(track.info.decoderConfig, meta.decoderConfig);
- }
- }
-
- let sample: Sample = {
- presentationTimestamp: presentationTimestampInSeconds,
- decodeTimestamp: decodeTimestampInSeconds,
- duration: durationInSeconds,
- data: data,
- size: data.byteLength,
- type: type,
- // Will be refined once the next sample comes in
- timescaleUnitsToNextSample: intoTimescale(durationInSeconds, track.timescale)
- };
-
- return sample;
- }
-
- #addSampleToTrack(
- track: Track,
- sample: Sample
- ) {
- if (this.#options.fastStart !== 'fragmented') {
- track.samples.push(sample);
- }
-
- const sampleCompositionTimeOffset =
- intoTimescale(sample.presentationTimestamp - sample.decodeTimestamp, track.timescale);
-
- if (track.lastTimescaleUnits !== null) {
- let timescaleUnits = intoTimescale(sample.decodeTimestamp, track.timescale, false);
- let delta = Math.round(timescaleUnits - track.lastTimescaleUnits);
- track.lastTimescaleUnits += delta;
- track.lastSample.timescaleUnitsToNextSample = delta;
-
- if (this.#options.fastStart !== 'fragmented') {
- let lastTableEntry = last(track.timeToSampleTable);
- if (lastTableEntry.sampleCount === 1) {
- // If we hit this case, we're the second sample
- lastTableEntry.sampleDelta = delta;
- lastTableEntry.sampleCount++;
- } else if (lastTableEntry.sampleDelta === delta) {
- // Simply increment the count
- lastTableEntry.sampleCount++;
- } else {
- // The delta has changed, subtract one from the previous run and create a new run with the new delta
- lastTableEntry.sampleCount--;
- track.timeToSampleTable.push({
- sampleCount: 2,
- sampleDelta: delta
- });
- }
-
- const lastCompositionTimeOffsetTableEntry = last(track.compositionTimeOffsetTable);
- if (lastCompositionTimeOffsetTableEntry.sampleCompositionTimeOffset === sampleCompositionTimeOffset) {
- // Simply increment the count
- lastCompositionTimeOffsetTableEntry.sampleCount++;
- } else {
- // The composition time offset has changed, so create a new entry with the new composition time
- // offset
- track.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset: sampleCompositionTimeOffset
- });
- }
- }
- } else {
- track.lastTimescaleUnits = 0;
-
- if (this.#options.fastStart !== 'fragmented') {
- track.timeToSampleTable.push({
- sampleCount: 1,
- sampleDelta: intoTimescale(sample.duration, track.timescale)
- });
- track.compositionTimeOffsetTable.push({
- sampleCount: 1,
- sampleCompositionTimeOffset: sampleCompositionTimeOffset
- });
- }
- }
-
- track.lastSample = sample;
-
- let beginNewChunk = false;
- if (!track.currentChunk) {
- beginNewChunk = true;
- } else {
- let currentChunkDuration = sample.presentationTimestamp - track.currentChunk.startTimestamp;
-
- if (this.#options.fastStart === 'fragmented') {
- let mostImportantTrack = this.#videoTrack ?? this.#audioTrack;
- if (track === mostImportantTrack && sample.type === 'key' && currentChunkDuration >= 1.0) {
- beginNewChunk = true;
- this.#finalizeFragment();
- }
- } else {
- beginNewChunk = currentChunkDuration >= 0.5; // Chunk is long enough, we need a new one
- }
- }
-
- if (beginNewChunk) {
- if (track.currentChunk) {
- this.#finalizeCurrentChunk(track);
- }
-
- track.currentChunk = {
- startTimestamp: sample.presentationTimestamp,
- samples: []
- };
- }
-
- track.currentChunk.samples.push(sample);
- }
-
- #validateTimestamp(presentationTimestamp: number, decodeTimestamp: number, track: Track) {
- // Check first timestamp behavior
- const strictTimestampBehavior = this.#options.firstTimestampBehavior === 'strict';
- const noLastDecodeTimestamp = track.lastDecodeTimestamp === -1;
- const timestampNonZero = decodeTimestamp !== 0;
- if (strictTimestampBehavior && noLastDecodeTimestamp && timestampNonZero) {
- throw new Error(
- `The first chunk for your media track must have a timestamp of 0 (received DTS=${decodeTimestamp}).` +
- `Non-zero first timestamps are often caused by directly piping frames or audio data from a ` +
- `MediaStreamTrack into the encoder. Their timestamps are typically relative to the age of the` +
- `document, which is probably what you want.\n\nIf you want to offset all timestamps of a track such ` +
- `that the first one is zero, set firstTimestampBehavior: 'offset' in the options.\n`
- );
- } else if (
- this.#options.firstTimestampBehavior === 'offset' ||
- this.#options.firstTimestampBehavior === 'cross-track-offset'
- ) {
- if (track.firstDecodeTimestamp === undefined) {
- track.firstDecodeTimestamp = decodeTimestamp;
- }
-
- let baseDecodeTimestamp: number;
- if (this.#options.firstTimestampBehavior === 'offset') {
- baseDecodeTimestamp = track.firstDecodeTimestamp;
- } else {
- // Since each track may have its firstDecodeTimestamp set independently, but the tracks' timestamps come
- // from the same clock, we should subtract the earlier of the (up to) two tracks' first timestamps to
- // ensure A/V sync.
- baseDecodeTimestamp = Math.min(
- this.#videoTrack?.firstDecodeTimestamp ?? Infinity,
- this.#audioTrack?.firstDecodeTimestamp ?? Infinity
- );
- }
-
- decodeTimestamp -= baseDecodeTimestamp;
- presentationTimestamp -= baseDecodeTimestamp;
- }
-
- if (decodeTimestamp < track.lastDecodeTimestamp) {
- throw new Error(
- `Timestamps must be monotonically increasing ` +
- `(DTS went from ${track.lastDecodeTimestamp * 1e6} to ${decodeTimestamp * 1e6}).`
- );
- }
-
- track.lastDecodeTimestamp = decodeTimestamp;
-
- return { presentationTimestamp, decodeTimestamp };
- }
-
- #finalizeCurrentChunk(track: Track) {
- if (this.#options.fastStart === 'fragmented') {
- throw new Error("Can't finalize individual chunks 'fastStart' is set to 'fragmented'.");
- }
-
- if (!track.currentChunk) return;
-
- track.finalizedChunks.push(track.currentChunk);
- this.#finalizedChunks.push(track.currentChunk);
-
- if (
- track.compactlyCodedChunkTable.length === 0
- || last(track.compactlyCodedChunkTable).samplesPerChunk !== track.currentChunk.samples.length
- ) {
- track.compactlyCodedChunkTable.push({
- firstChunk: track.finalizedChunks.length, // 1-indexed
- samplesPerChunk: track.currentChunk.samples.length
- });
- }
-
- if (this.#options.fastStart === 'in-memory') {
- track.currentChunk.offset = 0; // We'll compute the proper offset when finalizing
- return;
- }
-
- // Write out the data
- track.currentChunk.offset = this.#writer.pos;
- for (let sample of track.currentChunk.samples) {
- this.#writer.write(sample.data);
- sample.data = null; // Can be GC'd
- }
-
- this.#maybeFlushStreamingTargetWriter();
- }
-
- #finalizeFragment(flushStreamingWriter = true) {
- if (this.#options.fastStart !== 'fragmented') {
- throw new Error("Can't finalize a fragment unless 'fastStart' is set to 'fragmented'.");
- }
-
- let tracks = [this.#videoTrack, this.#audioTrack].filter((track) => track && track.currentChunk);
- if (tracks.length === 0) return;
-
- let fragmentNumber = this.#nextFragmentNumber++;
-
- if (fragmentNumber === 1) {
- // Write the moov box now that we have all decoder configs
- let movieBox = moov(tracks, this.#creationTime, true);
- this.#writer.writeBox(movieBox);
- }
-
- // Write out an initial moof box; will be overwritten later once actual chunk offsets are known
- let moofOffset = this.#writer.pos;
- let moofBox = moof(fragmentNumber, tracks);
- this.#writer.writeBox(moofBox);
-
- // Create the mdat box
- {
- let mdatBox = mdat(false); // Initially assume no fragment is larger than 4 GiB
- let totalTrackSampleSize = 0;
-
- // Compute the size of the mdat box
- for (let track of tracks) {
- for (let sample of track.currentChunk.samples) {
- totalTrackSampleSize += sample.size;
- }
- }
-
- let mdatSize = this.#writer.measureBox(mdatBox) + totalTrackSampleSize;
- if (mdatSize >= 2**32) {
- // Fragment is larger than 4 GiB, we need to use the large size
- mdatBox.largeSize = true;
- mdatSize = this.#writer.measureBox(mdatBox) + totalTrackSampleSize;
- }
-
- mdatBox.size = mdatSize;
- this.#writer.writeBox(mdatBox);
- }
-
- // Write sample data
- for (let track of tracks) {
- track.currentChunk.offset = this.#writer.pos;
- track.currentChunk.moofOffset = moofOffset;
-
- for (let sample of track.currentChunk.samples) {
- this.#writer.write(sample.data);
- sample.data = null; // Can be GC'd
- }
- }
-
- // Now that we set the actual chunk offsets, fix the moof box
- let endPos = this.#writer.pos;
- this.#writer.seek(this.#writer.offsets.get(moofBox));
- let newMoofBox = moof(fragmentNumber, tracks);
- this.#writer.writeBox(newMoofBox);
- this.#writer.seek(endPos);
-
- for (let track of tracks) {
- track.finalizedChunks.push(track.currentChunk);
- this.#finalizedChunks.push(track.currentChunk);
- track.currentChunk = null;
- }
-
- if (flushStreamingWriter) {
- this.#maybeFlushStreamingTargetWriter();
- }
- }
-
- #maybeFlushStreamingTargetWriter() {
- if (this.#writer instanceof StreamTargetWriter) {
- this.#writer.flush();
- }
- }
-
- #ensureNotFinalized() {
- if (this.#finalized) {
- throw new Error('Cannot add new video or audio chunks after the file has been finalized.');
- }
- }
-
- /** Finalizes the file, making it ready for use. Must be called after all video and audio chunks have been added. */
- finalize() {
- if (this.#finalized) {
- throw new Error('Cannot finalize a muxer more than once.');
- }
-
- if (this.#options.fastStart === 'fragmented') {
- for (let videoSample of this.#videoSampleQueue) this.#addSampleToTrack(this.#videoTrack, videoSample);
- for (let audioSample of this.#audioSampleQueue) this.#addSampleToTrack(this.#audioTrack, audioSample);
-
- this.#finalizeFragment(false); // Don't flush the last fragment as we will flush it with the mfra box soon
- } else {
- if (this.#videoTrack) this.#finalizeCurrentChunk(this.#videoTrack);
- if (this.#audioTrack) this.#finalizeCurrentChunk(this.#audioTrack);
- }
-
- let tracks = [this.#videoTrack, this.#audioTrack].filter(Boolean);
-
- if (this.#options.fastStart === 'in-memory') {
- let mdatSize: number;
-
- // We know how many chunks there are, but computing the chunk positions requires an iterative approach:
- // In order to know where the first chunk should go, we first need to know the size of the moov box. But we
- // cannot write a proper moov box without first knowing all chunk positions. So, we generate a tentative
- // moov box with placeholder values (0) for the chunk offsets to be able to compute its size. If it then
- // turns out that appending all chunks exceeds 4 GiB, we need to repeat this process, now with the co64 box
- // being used in the moov box instead, which will make it larger. After that, we definitely know the final
- // size of the moov box and can compute the proper chunk positions.
-
- for (let i = 0; i < 2; i++) {
- let movieBox = moov(tracks, this.#creationTime);
- let movieBoxSize = this.#writer.measureBox(movieBox);
- mdatSize = this.#writer.measureBox(this.#mdat);
- let currentChunkPos = this.#writer.pos + movieBoxSize + mdatSize;
-
- for (let chunk of this.#finalizedChunks) {
- chunk.offset = currentChunkPos;
- for (let { data } of chunk.samples) {
- currentChunkPos += data.byteLength;
- mdatSize += data.byteLength;
- }
- }
-
- if (currentChunkPos < 2**32) break;
- if (mdatSize >= 2**32) this.#mdat.largeSize = true;
- }
-
- let movieBox = moov(tracks, this.#creationTime);
- this.#writer.writeBox(movieBox);
-
- this.#mdat.size = mdatSize;
- this.#writer.writeBox(this.#mdat);
-
- for (let chunk of this.#finalizedChunks) {
- for (let sample of chunk.samples) {
- this.#writer.write(sample.data);
- sample.data = null;
- }
- }
- } else if (this.#options.fastStart === 'fragmented') {
- // Append the mfra box to the end of the file for better random access
- let startPos = this.#writer.pos;
- let mfraBox = mfra(tracks);
- this.#writer.writeBox(mfraBox);
-
- // Patch the 'size' field of the mfro box at the end of the mfra box now that we know its actual size
- let mfraBoxSize = this.#writer.pos - startPos;
- this.#writer.seek(this.#writer.pos - 4);
- this.#writer.writeU32(mfraBoxSize);
- } else {
- let mdatPos = this.#writer.offsets.get(this.#mdat);
- let mdatSize = this.#writer.pos - mdatPos;
- this.#mdat.size = mdatSize;
- this.#mdat.largeSize = mdatSize >= 2**32; // Only use the large size if we need it
- this.#writer.patchBox(this.#mdat);
-
- let movieBox = moov(tracks, this.#creationTime);
-
- if (typeof this.#options.fastStart === 'object') {
- this.#writer.seek(this.#ftypSize);
- this.#writer.writeBox(movieBox);
-
- let remainingBytes = mdatPos - this.#writer.pos;
- this.#writer.writeBox(free(remainingBytes));
- } else {
- this.#writer.writeBox(movieBox);
- }
- }
-
- this.#maybeFlushStreamingTargetWriter();
- this.#writer.finalize();
-
- this.#finalized = true;
- }
-}
diff --git a/v0-appel-projet/public/mp4-muxer-main/src/target.ts b/v0-appel-projet/public/mp4-muxer-main/src/target.ts
deleted file mode 100644
index a4f76e4..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/src/target.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export type Target = ArrayBufferTarget | StreamTarget | FileSystemWritableFileStreamTarget;
-
-export class ArrayBufferTarget {
- buffer: ArrayBuffer = null;
-}
-
-export class StreamTarget {
- constructor(public options: {
- onData?: (data: Uint8Array, position: number) => void,
- chunked?: boolean,
- chunkSize?: number
- }) {}
-}
-
-export class FileSystemWritableFileStreamTarget {
- constructor(
- public stream: FileSystemWritableFileStream,
- public options?: { chunkSize?: number }
- ) {}
-}
diff --git a/v0-appel-projet/public/mp4-muxer-main/src/writer.ts b/v0-appel-projet/public/mp4-muxer-main/src/writer.ts
deleted file mode 100644
index 96ba200..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/src/writer.ts
+++ /dev/null
@@ -1,380 +0,0 @@
-import { Box } from './box';
-import { ArrayBufferTarget, FileSystemWritableFileStreamTarget, StreamTarget } from './target';
-
-export abstract class Writer {
- pos = 0;
- #helper = new Uint8Array(8);
- #helperView = new DataView(this.#helper.buffer);
-
- /**
- * Stores the position from the start of the file to where boxes elements have been written. This is used to
- * rewrite/edit elements that were already added before, and to measure sizes of things.
- */
- offsets = new WeakMap();
-
- /** Writes the given data to the target, at the current position. */
- abstract write(data: Uint8Array): void;
- /** Called after muxing has finished. */
- abstract finalize(): void;
-
- /** Sets the current position for future writes to a new one. */
- seek(newPos: number) {
- this.pos = newPos;
- }
-
- writeU32(value: number) {
- this.#helperView.setUint32(0, value, false);
- this.write(this.#helper.subarray(0, 4));
- }
-
- writeU64(value: number) {
- this.#helperView.setUint32(0, Math.floor(value / 2**32), false);
- this.#helperView.setUint32(4, value, false);
- this.write(this.#helper.subarray(0, 8));
- }
-
- writeAscii(text: string) {
- for (let i = 0; i < text.length; i++) {
- this.#helperView.setUint8(i % 8, text.charCodeAt(i));
- if (i % 8 === 7) this.write(this.#helper);
- }
-
- if (text.length % 8 !== 0) {
- this.write(this.#helper.subarray(0, text.length % 8));
- }
- }
-
- writeBox(box: Box) {
- this.offsets.set(box, this.pos);
-
- if (box.contents && !box.children) {
- this.writeBoxHeader(box, box.size ?? box.contents.byteLength + 8);
- this.write(box.contents);
- } else {
- let startPos = this.pos;
- this.writeBoxHeader(box, 0);
-
- if (box.contents) this.write(box.contents);
- if (box.children) for (let child of box.children) if (child) this.writeBox(child);
-
- let endPos = this.pos;
- let size = box.size ?? endPos - startPos;
- this.seek(startPos);
- this.writeBoxHeader(box, size);
- this.seek(endPos);
- }
- }
-
- writeBoxHeader(box: Box, size: number) {
- this.writeU32(box.largeSize ? 1 : size);
- this.writeAscii(box.type);
- if (box.largeSize) this.writeU64(size);
- }
-
- measureBoxHeader(box: Box) {
- return 8 + (box.largeSize ? 8 : 0);
- }
-
- patchBox(box: Box) {
- let endPos = this.pos;
- this.seek(this.offsets.get(box));
- this.writeBox(box);
- this.seek(endPos);
- }
-
- measureBox(box: Box) {
- if (box.contents && !box.children) {
- let headerSize = this.measureBoxHeader(box);
- return headerSize + box.contents.byteLength;
- } else {
- let result = this.measureBoxHeader(box);
- if (box.contents) result += box.contents.byteLength;
- if (box.children) for (let child of box.children) if (child) result += this.measureBox(child);
-
- return result;
- }
- }
-}
-
-/**
- * Writes to an ArrayBufferTarget. Maintains a growable internal buffer during the muxing process, which will then be
- * written to the ArrayBufferTarget once the muxing finishes.
- */
-export class ArrayBufferTargetWriter extends Writer {
- #target: ArrayBufferTarget;
- #buffer = new ArrayBuffer(2**16);
- #bytes = new Uint8Array(this.#buffer);
- #maxPos = 0;
-
- constructor(target: ArrayBufferTarget) {
- super();
-
- this.#target = target;
- }
-
- #ensureSize(size: number) {
- let newLength = this.#buffer.byteLength;
- while (newLength < size) newLength *= 2;
-
- if (newLength === this.#buffer.byteLength) return;
-
- let newBuffer = new ArrayBuffer(newLength);
- let newBytes = new Uint8Array(newBuffer);
- newBytes.set(this.#bytes, 0);
-
- this.#buffer = newBuffer;
- this.#bytes = newBytes;
- }
-
- write(data: Uint8Array) {
- this.#ensureSize(this.pos + data.byteLength);
-
- this.#bytes.set(data, this.pos);
- this.pos += data.byteLength;
-
- this.#maxPos = Math.max(this.#maxPos, this.pos);
- }
-
- finalize() {
- this.#ensureSize(this.pos);
- this.#target.buffer = this.#buffer.slice(0, Math.max(this.#maxPos, this.pos));
- }
-}
-
-/**
- * Writes to a StreamTarget every time it is flushed, sending out all of the new data written since the
- * last flush. This is useful for streaming applications, like piping the output to disk.
- */
-export class StreamTargetWriter extends Writer {
- #target: StreamTarget;
- #sections: {
- data: Uint8Array,
- start: number
- }[] = [];
-
- constructor(target: StreamTarget) {
- super();
-
- this.#target = target;
- }
-
- write(data: Uint8Array) {
- this.#sections.push({
- data: data.slice(),
- start: this.pos
- });
- this.pos += data.byteLength;
- }
-
- flush() {
- if (this.#sections.length === 0) return;
-
- let chunks: {
- start: number,
- size: number,
- data?: Uint8Array
- }[] = [];
- let sorted = [...this.#sections].sort((a, b) => a.start - b.start);
-
- chunks.push({
- start: sorted[0].start,
- size: sorted[0].data.byteLength
- });
-
- // Figure out how many contiguous chunks we have
- for (let i = 1; i < sorted.length; i++) {
- let lastChunk = chunks[chunks.length - 1];
- let section = sorted[i];
-
- if (section.start <= lastChunk.start + lastChunk.size) {
- lastChunk.size = Math.max(lastChunk.size, section.start + section.data.byteLength - lastChunk.start);
- } else {
- chunks.push({
- start: section.start,
- size: section.data.byteLength
- });
- }
- }
-
- for (let chunk of chunks) {
- chunk.data = new Uint8Array(chunk.size);
-
- // Make sure to write the data in the correct order for correct overwriting
- for (let section of this.#sections) {
- // Check if the section is in the chunk
- if (chunk.start <= section.start && section.start < chunk.start + chunk.size) {
- chunk.data.set(section.data, section.start - chunk.start);
- }
- }
-
- this.#target.options.onData?.(chunk.data, chunk.start);
- }
-
- this.#sections.length = 0;
- }
-
- finalize() {}
-}
-
-const DEFAULT_CHUNK_SIZE = 2**24;
-const MAX_CHUNKS_AT_ONCE = 2;
-
-interface Chunk {
- start: number,
- written: ChunkSection[],
- data: Uint8Array,
- shouldFlush: boolean
-}
-
-interface ChunkSection {
- start: number,
- end: number
-}
-
-/**
- * Writes to a StreamTarget using a chunked approach: Data is first buffered in memory until it reaches a large enough
- * size, which is when it is piped to the StreamTarget. This is helpful for reducing the total amount of writes.
- */
-export class ChunkedStreamTargetWriter extends Writer {
- #target: StreamTarget;
- #chunkSize: number;
- /**
- * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out.
- * A chunk is flushed if all of its contents have been written.
- */
- #chunks: Chunk[] = [];
-
- constructor(target: StreamTarget) {
- super();
-
- this.#target = target;
- this.#chunkSize = target.options?.chunkSize ?? DEFAULT_CHUNK_SIZE;
-
- if (!Number.isInteger(this.#chunkSize) || this.#chunkSize < 2**10) {
- throw new Error('Invalid StreamTarget options: chunkSize must be an integer not smaller than 1024.');
- }
- }
-
- write(data: Uint8Array) {
- this.#writeDataIntoChunks(data, this.pos);
- this.#flushChunks();
-
- this.pos += data.byteLength;
- }
-
- #writeDataIntoChunks(data: Uint8Array, position: number) {
- // First, find the chunk to write the data into, or create one if none exists
- let chunkIndex = this.#chunks.findIndex(x => x.start <= position && position < x.start + this.#chunkSize);
- if (chunkIndex === -1) chunkIndex = this.#createChunk(position);
- let chunk = this.#chunks[chunkIndex];
-
- // Figure out how much to write to the chunk, and then write to the chunk
- let relativePosition = position - chunk.start;
- let toWrite = data.subarray(0, Math.min(this.#chunkSize - relativePosition, data.byteLength));
- chunk.data.set(toWrite, relativePosition);
-
- // Create a section describing the region of data that was just written to
- let section: ChunkSection = {
- start: relativePosition,
- end: relativePosition + toWrite.byteLength
- };
- this.#insertSectionIntoChunk(chunk, section);
-
- // Queue chunk for flushing to target if it has been fully written to
- if (chunk.written[0].start === 0 && chunk.written[0].end === this.#chunkSize) {
- chunk.shouldFlush = true;
- }
-
- // Make sure we don't hold too many chunks in memory at once to keep memory usage down
- if (this.#chunks.length > MAX_CHUNKS_AT_ONCE) {
- // Flush all but the last chunk
- for (let i = 0; i < this.#chunks.length-1; i++) {
- this.#chunks[i].shouldFlush = true;
- }
- this.#flushChunks();
- }
-
- // If the data didn't fit in one chunk, recurse with the remaining datas
- if (toWrite.byteLength < data.byteLength) {
- this.#writeDataIntoChunks(data.subarray(toWrite.byteLength), position + toWrite.byteLength);
- }
- }
-
- #insertSectionIntoChunk(chunk: Chunk, section: ChunkSection) {
- let low = 0;
- let high = chunk.written.length - 1;
- let index = -1;
-
- // Do a binary search to find the last section with a start not larger than `section`'s start
- while (low <= high) {
- let mid = Math.floor(low + (high - low + 1) / 2);
-
- if (chunk.written[mid].start <= section.start) {
- low = mid + 1;
- index = mid;
- } else {
- high = mid - 1;
- }
- }
-
- // Insert the new section
- chunk.written.splice(index + 1, 0, section);
- if (index === -1 || chunk.written[index].end < section.start) index++;
-
- // Merge overlapping sections
- while (index < chunk.written.length - 1 && chunk.written[index].end >= chunk.written[index + 1].start) {
- chunk.written[index].end = Math.max(chunk.written[index].end, chunk.written[index + 1].end);
- chunk.written.splice(index + 1, 1);
- }
- }
-
- #createChunk(includesPosition: number) {
- let start = Math.floor(includesPosition / this.#chunkSize) * this.#chunkSize;
- let chunk: Chunk = {
- start,
- data: new Uint8Array(this.#chunkSize),
- written: [],
- shouldFlush: false
- };
- this.#chunks.push(chunk);
- this.#chunks.sort((a, b) => a.start - b.start);
-
- return this.#chunks.indexOf(chunk);
- }
-
- #flushChunks(force = false) {
- for (let i = 0; i < this.#chunks.length; i++) {
- let chunk = this.#chunks[i];
- if (!chunk.shouldFlush && !force) continue;
-
- for (let section of chunk.written) {
- this.#target.options.onData?.(
- chunk.data.subarray(section.start, section.end),
- chunk.start + section.start
- );
- }
- this.#chunks.splice(i--, 1);
- }
- }
-
- finalize() {
- this.#flushChunks(true);
- }
-}
-
-/**
- * Essentially a wrapper around ChunkedStreamTargetWriter, writing directly to disk using the File System Access API.
- * This is useful for large files, as available RAM is no longer a bottleneck.
- */
-export class FileSystemWritableFileStreamTargetWriter extends ChunkedStreamTargetWriter {
- constructor(target: FileSystemWritableFileStreamTarget) {
- super(new StreamTarget({
- onData: (data, position) => target.stream.write({
- type: 'write',
- data,
- position
- }),
- chunkSize: target.options?.chunkSize
- }));
- }
-}
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/test/CantinaBand60.wav b/v0-appel-projet/public/mp4-muxer-main/test/CantinaBand60.wav
deleted file mode 100644
index 47842ed..0000000
Binary files a/v0-appel-projet/public/mp4-muxer-main/test/CantinaBand60.wav and /dev/null differ
diff --git a/v0-appel-projet/public/mp4-muxer-main/test/deconstruct.html b/v0-appel-projet/public/mp4-muxer-main/test/deconstruct.html
deleted file mode 100644
index f0c8cde..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/test/deconstruct.html
+++ /dev/null
@@ -1,199 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/test/test.html b/v0-appel-projet/public/mp4-muxer-main/test/test.html
deleted file mode 100644
index dcf704c..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/test/test.html
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/v0-appel-projet/public/mp4-muxer-main/tsconfig.json b/v0-appel-projet/public/mp4-muxer-main/tsconfig.json
deleted file mode 100644
index 4979124..0000000
--- a/v0-appel-projet/public/mp4-muxer-main/tsconfig.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2021",
- "strict": true,
- "strictNullChecks": false,
- "noImplicitAny": true,
- "noImplicitOverride": true,
- "types": ["@types/wicg-file-system-access", "@types/dom-webcodecs"]
- },
- "include": [
- "src/**/*",
- "build/**/*.ts"
- ]
-}
\ No newline at end of file
diff --git a/v0-appel-projet/public/paramList4Background.png b/v0-appel-projet/public/paramList4Background.png
deleted file mode 100644
index 64281f1..0000000
Binary files a/v0-appel-projet/public/paramList4Background.png and /dev/null differ
diff --git a/v0-appel-projet/src/App.vue b/v0-appel-projet/src/App.vue
deleted file mode 100644
index 71355e1..0000000
--- a/v0-appel-projet/src/App.vue
+++ /dev/null
@@ -1,422 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
DRAGs AND
-
-
-
NERDs#
-
-
- > Appel à Projet
-
- Drag shows, musique électronique, synthés vidéos
-
- et autre performances nerds
-
- On recherche actuellement : artistes drags,
-
- artistes nerds, crafties pour la scéno ...
-
- Nous sommes un collectif antifasciste, nous sommes opposéxs à toute forme d’oppression et nous condamnons:
-
- > le racisme
-
- > la misogynie
-
- > les queerphobies
-
- > la grossophobie
-
- > le validisme
-
- > le classisme
-
- > la putophobie
-
- On veut que nos soirées soient centrées autour de l’inclusivité : chacunx doit s’y sentir bien, nous voulons créer du lien entre les différentes communautés (nerds, LGBTQIA+, les personnes racisées, les personnes handi, les bricoleuxes, les personnes précaires etc…)
-
- Pour cette raison, nous imposons notamment le port du masque FFP2 pour toutes les activités se déroulant à l'intérieur.
-
- On veut aussi que nos soirées soient respectueuses de l’environnement (il faut utiliser un maximum de matériaux de récupérations) et véganes (pas de vente de produits d’origine animale).
-
- A touxs les drags, touxs les nerds et l'ensemble des personnes entre les deux !
- Vous êtes invité·es à participer aux ateliers meetup Drags&Nerds !
-
- Que vous aimiez dessiner, coudre et crafter des costumes à paillettes.
- Coder, souder, clouer, imprimer en 3D ou en 2D...
- Que votre truc ce soit d'écrire des histoires toutes plus queer les unes que les autres, des poèmes lyriques ou encore du code source.
- Drags&Nerds c'est tout ça et bien plus.
-
-
- Pendant les ateliers, on prépare nos performances pour le grand drag show du au Grrrnd Zero.
- On construit des scenes, des histoires, des makeups et des costumes.
- On met tout en place pour que le 22 mai prochain, on puisse briller sur la grande scène du Grrrnd Zero.
-
-
- Tu as envie de faire du lips sync ? De jouer de ton synthé ?
- Ou juste de donner un coup de pouce a des drags pour leurs show.
- Il y a une place pour toi.
-
-
- Venez, quelque soit votre intérêt spécifique.
-
-
-
-
-
.
-
-
-
-
-
-
-
-
diff --git a/v0-appel-projet/src/main.js b/v0-appel-projet/src/main.js
deleted file mode 100644
index 5e05635..0000000
--- a/v0-appel-projet/src/main.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { createApp } from 'vue'
-// import CSS global
-import './assets/style.css'
-// import app vue racine
-import App from './App.vue'
-// import composants
-import AboutPannel from './components/AboutPannel.vue'
-import ContactPannel from './components/ContactPannel.vue'
-import WorkshopPannel from './components/WorkshopPannel.vue'
-import ImagePannel from './components/ImagePannel.vue'
-
-
-// création app racine
-const app = createApp(App);
-
-//Composants
-app.component('aboutPannel', AboutPannel);
-app.component('contactPannel', ContactPannel);
-app.component('workshopPannel', WorkshopPannel);
-app.component('imagePannel', ImagePannel);
-
-
-
-//Démarrage dans div#app de index.html
-app.mount('#app');
diff --git a/v0-appel-projet/vite.config.js b/v0-appel-projet/vite.config.js
deleted file mode 100644
index 7a24acc..0000000
--- a/v0-appel-projet/vite.config.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
-import svgLoader from 'vite-svg-loader'
-
-// https://vite.dev/config/
-export default defineConfig({
- plugins: [vue(), svgLoader()],
- server: {
- host: '0.0.0.0',
- port: 8080,
- },
-})
diff --git a/v1-com-officielle/.gitignore b/v1-com-officielle/.gitignore
deleted file mode 100644
index a547bf3..0000000
--- a/v1-com-officielle/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/v1-com-officielle/.vscode/extensions.json b/v1-com-officielle/.vscode/extensions.json
deleted file mode 100644
index a7cea0b..0000000
--- a/v1-com-officielle/.vscode/extensions.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "recommendations": ["Vue.volar"]
-}
diff --git a/v1-com-officielle/README.md b/v1-com-officielle/README.md
deleted file mode 100644
index 1511959..0000000
--- a/v1-com-officielle/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Vue 3 + Vite
-
-This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `
-