commit 8c98c2624bb748b88cc9eccab109f0ff5ee8a80a Author: trafficlunar Date: Tue Mar 3 18:32:00 2026 +0000 feat: initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..46c9a9b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +dist/* linguist-vendored \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ce2d6ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,144 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/node diff --git a/README.md b/README.md new file mode 100644 index 0000000..7fe779f --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Warning + +This project is deprecated and should not be used for bundling spicetify extensions or custom apps. Please use [`esbuild`](https://esbuild.github.io/), [`Bun's bundler`](https://bun.com/docs/bundler), [`Rollup`](https://rollupjs.org/) or [`webpack`](https://webpack.js.org/)/[`rspack`](https://rspack.rs/) with your own config. This project won't be receiving any more updates until further notice. + +# Spicetify Creator + +Spicetify Creator is a tool to compile modern Typescript/Javascript code to Spicetify extensions and custom apps. + +## Features +- Typescript and React syntax +- Import node packages +- CSS/SCSS with PostCSS support +- Extremely fast compile time with esbuild. +- Plugins + +## Docs +Check out [Spicetify's docs](https://spicetify.app/docs/development/spicetify-creator/the-basics)! + +## Made with Spicetify Creator +- https://github.com/spicetify/spicetify-creator diff --git a/package.json b/package.json new file mode 100644 index 0000000..a91a6bb --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "jellyfin-spicetify", + "version": "0.1.0", + "private": true, + "scripts": { + "build": "spicetify-creator", + "build-local": "spicetify-creator --out=dist --minify", + "watch": "spicetify-creator --watch" + }, + "license": "MIT", + "devDependencies": { + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "spicetify-creator": "^1.0.17" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..1500af5 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1581 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + spicetify-creator: + specifier: ^1.0.17 + version: 1.0.17(less@4.5.1)(postcss@8.5.8)(sass@1.97.3)(stylus@0.64.0) + +packages: + + '@adobe/css-tools@4.3.3': + resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} + + '@esbuild/linux-loong64@0.14.54': + resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.10.0: + resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} + engines: {node: '>=6.0.0'} + hasBin: true + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + caniuse-lite@1.0.30001776: + resolution: {integrity: sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + copy-anything@2.0.6: + resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + cwd@0.10.0: + resolution: {integrity: sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==} + engines: {node: '>=0.8'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + electron-to-chromium@1.5.307: + resolution: {integrity: sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true + + esbuild-android-64@0.14.54: + resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + esbuild-android-arm64@0.14.54: + resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + esbuild-darwin-64@0.14.54: + resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + esbuild-darwin-arm64@0.14.54: + resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + esbuild-freebsd-64@0.14.54: + resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + esbuild-freebsd-arm64@0.14.54: + resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + esbuild-linux-32@0.14.54: + resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + esbuild-linux-64@0.14.54: + resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + esbuild-linux-arm64@0.14.54: + resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + esbuild-linux-arm@0.14.54: + resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + esbuild-linux-mips64le@0.14.54: + resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + esbuild-linux-ppc64le@0.14.54: + resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + esbuild-linux-riscv64@0.14.54: + resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + esbuild-linux-s390x@0.14.54: + resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + esbuild-netbsd-64@0.14.54: + resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + esbuild-openbsd-64@0.14.54: + resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + esbuild-plugin-external-global@1.0.1: + resolution: {integrity: sha512-NDzYHRoShpvLqNcrgV8ZQh61sMIFAry5KLTQV83BPG5iTXCCu7h72SCfJ97bW0GqtuqDD/1aqLbKinI/rNgUsg==} + + esbuild-plugin-postcss2@0.1.1: + resolution: {integrity: sha512-BMHnOTfZo+ghrzYnBtcXlHuMpOEwfTFarhGG4o6mivzPZGUXzeMn/hdFhtRpmCKzUvXsaxnZ3N72xA8CwdtZ3w==} + peerDependencies: + less: ^4.x + postcss: 8.x + sass: ^1.x + stylus: ^0.x + + esbuild-sunos-64@0.14.54: + resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + esbuild-windows-32@0.14.54: + resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + esbuild-windows-64@0.14.54: + resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + esbuild-windows-arm64@0.14.54: + resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + esbuild@0.14.54: + resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + expand-tilde@1.2.2: + resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==} + engines: {node: '>=0.10.0'} + + expand-tilde@2.0.2: + resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} + engines: {node: '>=0.10.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + find-file-up@0.1.3: + resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==} + engines: {node: '>=0.10.0'} + + find-pkg@0.1.2: + resolution: {integrity: sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==} + engines: {node: '>=0.10.0'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fs-exists-sync@0.1.0: + resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==} + engines: {node: '>=0.10.0'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + generic-names@4.0.0: + resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} + + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + global-modules@0.2.3: + resolution: {integrity: sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==} + engines: {node: '>=0.10.0'} + + global-prefix@0.1.5: + resolution: {integrity: sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==} + engines: {node: '>=0.10.0'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + homedir-polyfill@1.0.3: + resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + icss-replace-symbols@1.1.0: + resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + immutable@5.1.4: + resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-what@3.14.1: + resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + + is-windows@0.2.0: + resolution: {integrity: sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + lazy-cache@2.0.2: + resolution: {integrity: sha512-7vp2Acd2+Kz4XkzxGxaB1FWOi8KjWIWsgdfD5MCb86DWvlLqhRPM+d6Pro3iNEL5VT9mstz5hKAlcd+QR6H3aA==} + engines: {node: '>=0.10.0'} + + less@4.5.1: + resolution: {integrity: sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw==} + engines: {node: '>=14'} + hasBin: true + + loader-utils@3.3.1: + resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} + engines: {node: '>= 12.13.0'} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + needle@3.3.1: + resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} + engines: {node: '>= 4.4.x'} + hasBin: true + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parse-node-version@1.0.1: + resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} + engines: {node: '>= 0.10'} + + parse-passwd@1.0.0: + resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} + engines: {node: '>=0.10.0'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules@4.3.1: + resolution: {integrity: sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==} + peerDependencies: + postcss: ^8.0.0 + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + resolve-dir@0.1.1: + resolution: {integrity: sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==} + engines: {node: '>=0.10.0'} + + resolve-file@0.3.0: + resolution: {integrity: sha512-9RXicAgDvLD272hZ3HwJv9MJUGxCBRRwwSBRdOGWgcO03MtC9UTGC6XG1VbS4T5MvDrb+tVZx2RhZ90uk3uczg==} + engines: {node: '>=0.10.0'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass@1.97.3: + resolution: {integrity: sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==} + engines: {node: '>=14.0.0'} + hasBin: true + + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} + + sax@1.5.0: + resolution: {integrity: sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==} + engines: {node: '>=11.0.0'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + set-getter@0.1.1: + resolution: {integrity: sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + spicetify-creator@1.0.17: + resolution: {integrity: sha512-PajJIP0mi8UPErSeuqDf2wF4j8aHF4O+1S9JDIuY4wYKcHHWSvQ21FGnfyxzO6rS4/MkwMDzO6uERnrNAu+sHw==} + hasBin: true + + string-hash@1.1.3: + resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + stylus@0.64.0: + resolution: {integrity: sha512-ZIdT8eUv8tegmqy1tTIdJv9We2DumkNZFdCF5mz/Kpq3OcTaxSuCAYZge6HKK2CmNC02G1eJig2RV7XTw5hQrA==} + engines: {node: '>=16'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + +snapshots: + + '@adobe/css-tools@4.3.3': {} + + '@esbuild/linux-loong64@0.14.54': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.3 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + at-least-node@1.0.0: {} + + autoprefixer@10.4.27(postcss@8.5.8): + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001776 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.10.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.10.0 + caniuse-lite: 1.0.30001776 + electron-to-chromium: 1.5.307 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + caniuse-lite@1.0.30001776: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + copy-anything@2.0.6: + dependencies: + is-what: 3.14.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + cwd@0.10.0: + dependencies: + find-pkg: 0.1.2 + fs-exists-sync: 0.1.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + detect-libc@2.1.2: + optional: true + + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.5.307: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + optional: true + + esbuild-android-64@0.14.54: + optional: true + + esbuild-android-arm64@0.14.54: + optional: true + + esbuild-darwin-64@0.14.54: + optional: true + + esbuild-darwin-arm64@0.14.54: + optional: true + + esbuild-freebsd-64@0.14.54: + optional: true + + esbuild-freebsd-arm64@0.14.54: + optional: true + + esbuild-linux-32@0.14.54: + optional: true + + esbuild-linux-64@0.14.54: + optional: true + + esbuild-linux-arm64@0.14.54: + optional: true + + esbuild-linux-arm@0.14.54: + optional: true + + esbuild-linux-mips64le@0.14.54: + optional: true + + esbuild-linux-ppc64le@0.14.54: + optional: true + + esbuild-linux-riscv64@0.14.54: + optional: true + + esbuild-linux-s390x@0.14.54: + optional: true + + esbuild-netbsd-64@0.14.54: + optional: true + + esbuild-openbsd-64@0.14.54: + optional: true + + esbuild-plugin-external-global@1.0.1: {} + + esbuild-plugin-postcss2@0.1.1(less@4.5.1)(postcss@8.5.8)(sass@1.97.3)(stylus@0.64.0): + dependencies: + autoprefixer: 10.4.27(postcss@8.5.8) + fs-extra: 9.1.0 + less: 4.5.1 + postcss: 8.5.8 + postcss-modules: 4.3.1(postcss@8.5.8) + resolve-file: 0.3.0 + sass: 1.97.3 + stylus: 0.64.0 + tmp: 0.2.5 + + esbuild-sunos-64@0.14.54: + optional: true + + esbuild-windows-32@0.14.54: + optional: true + + esbuild-windows-64@0.14.54: + optional: true + + esbuild-windows-arm64@0.14.54: + optional: true + + esbuild@0.14.54: + optionalDependencies: + '@esbuild/linux-loong64': 0.14.54 + esbuild-android-64: 0.14.54 + esbuild-android-arm64: 0.14.54 + esbuild-darwin-64: 0.14.54 + esbuild-darwin-arm64: 0.14.54 + esbuild-freebsd-64: 0.14.54 + esbuild-freebsd-arm64: 0.14.54 + esbuild-linux-32: 0.14.54 + esbuild-linux-64: 0.14.54 + esbuild-linux-arm: 0.14.54 + esbuild-linux-arm64: 0.14.54 + esbuild-linux-mips64le: 0.14.54 + esbuild-linux-ppc64le: 0.14.54 + esbuild-linux-riscv64: 0.14.54 + esbuild-linux-s390x: 0.14.54 + esbuild-netbsd-64: 0.14.54 + esbuild-openbsd-64: 0.14.54 + esbuild-sunos-64: 0.14.54 + esbuild-windows-32: 0.14.54 + esbuild-windows-64: 0.14.54 + esbuild-windows-arm64: 0.14.54 + + escalade@3.2.0: {} + + expand-tilde@1.2.2: + dependencies: + os-homedir: 1.0.2 + + expand-tilde@2.0.2: + dependencies: + homedir-polyfill: 1.0.3 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + find-file-up@0.1.3: + dependencies: + fs-exists-sync: 0.1.0 + resolve-dir: 0.1.1 + + find-pkg@0.1.2: + dependencies: + find-file-up: 0.1.3 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fraction.js@5.3.4: {} + + fs-exists-sync@0.1.0: {} + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + function-bind@1.1.2: {} + + generic-names@4.0.0: + dependencies: + loader-utils: 3.3.1 + + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + global-modules@0.2.3: + dependencies: + global-prefix: 0.1.5 + is-windows: 0.2.0 + + global-prefix@0.1.5: + dependencies: + homedir-polyfill: 1.0.3 + ini: 1.3.8 + is-windows: 0.2.0 + which: 1.3.1 + + graceful-fs@4.2.11: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + homedir-polyfill@1.0.3: + dependencies: + parse-passwd: 1.0.0 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + icss-replace-symbols@1.1.0: {} + + icss-utils@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + image-size@0.5.5: + optional: true + + immutable@5.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + is-buffer@1.1.6: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: + optional: true + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + optional: true + + is-what@3.14.1: {} + + is-windows@0.2.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + lazy-cache@2.0.2: + dependencies: + set-getter: 0.1.1 + + less@4.5.1: + dependencies: + copy-anything: 2.0.6 + parse-node-version: 1.0.1 + tslib: 2.8.1 + optionalDependencies: + errno: 0.1.8 + graceful-fs: 4.2.11 + image-size: 0.5.5 + make-dir: 2.1.0 + mime: 1.6.0 + needle: 3.3.1 + source-map: 0.6.1 + + loader-utils@3.3.1: {} + + lodash.camelcase@4.3.0: {} + + lru-cache@10.4.3: {} + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + optional: true + + mime@1.6.0: + optional: true + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.2 + + minimist@1.2.8: {} + + minipass@7.1.3: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + needle@3.3.1: + dependencies: + iconv-lite: 0.6.3 + sax: 1.5.0 + optional: true + + node-addon-api@7.1.1: + optional: true + + node-releases@2.0.27: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + os-homedir@1.0.2: {} + + package-json-from-dist@1.0.1: {} + + parse-node-version@1.0.1: {} + + parse-passwd@1.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + picocolors@1.1.1: {} + + picomatch@4.0.3: + optional: true + + pify@4.0.1: + optional: true + + postcss-modules-extract-imports@3.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.8): + dependencies: + icss-utils: 5.1.0(postcss@8.5.8) + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + + postcss-modules-values@4.0.0(postcss@8.5.8): + dependencies: + icss-utils: 5.1.0(postcss@8.5.8) + postcss: 8.5.8 + + postcss-modules@4.3.1(postcss@8.5.8): + dependencies: + generic-names: 4.0.0 + icss-replace-symbols: 1.1.0 + lodash.camelcase: 4.3.0 + postcss: 8.5.8 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.8) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.8) + postcss-modules-scope: 3.2.1(postcss@8.5.8) + postcss-modules-values: 4.0.0(postcss@8.5.8) + string-hash: 1.1.3 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prr@1.0.1: + optional: true + + readdirp@4.1.2: {} + + resolve-dir@0.1.1: + dependencies: + expand-tilde: 1.2.2 + global-modules: 0.2.3 + + resolve-file@0.3.0: + dependencies: + cwd: 0.10.0 + expand-tilde: 2.0.2 + extend-shallow: 2.0.1 + fs-exists-sync: 0.1.0 + homedir-polyfill: 1.0.3 + lazy-cache: 2.0.2 + resolve: 1.22.11 + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + safer-buffer@2.1.2: + optional: true + + sass@1.97.3: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.4 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + + sax@1.4.4: {} + + sax@1.5.0: + optional: true + + semver@5.7.2: + optional: true + + set-getter@0.1.1: + dependencies: + to-object-path: 0.3.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + source-map-js@1.2.1: {} + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + spicetify-creator@1.0.17(less@4.5.1)(postcss@8.5.8)(sass@1.97.3)(stylus@0.64.0): + dependencies: + chalk: 4.1.2 + clean-css: 5.3.3 + esbuild: 0.14.54 + esbuild-plugin-external-global: 1.0.1 + esbuild-plugin-postcss2: 0.1.1(less@4.5.1)(postcss@8.5.8)(sass@1.97.3)(stylus@0.64.0) + glob: 7.2.3 + minimist: 1.2.8 + uglify-js: 3.19.3 + transitivePeerDependencies: + - less + - postcss + - sass + - stylus + + string-hash@1.1.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + stylus@0.64.0: + dependencies: + '@adobe/css-tools': 4.3.3 + debug: 4.4.3 + glob: 10.5.0 + sax: 1.4.4 + source-map: 0.7.6 + transitivePeerDependencies: + - supports-color + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tmp@0.2.5: {} + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + tslib@2.8.1: {} + + uglify-js@3.19.3: {} + + universalify@2.0.1: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + util-deprecate@1.0.2: {} + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} diff --git a/src/app.tsx b/src/app.tsx new file mode 100644 index 0000000..9fb4fae --- /dev/null +++ b/src/app.tsx @@ -0,0 +1,10 @@ +async function main() { + while (!Spicetify?.showNotification) { + await new Promise((resolve) => setTimeout(resolve, 100)); + } + + // Show message on start. + Spicetify.showNotification("Hello!"); +} + +export default main; diff --git a/src/settings.json b/src/settings.json new file mode 100644 index 0000000..ce334a2 --- /dev/null +++ b/src/settings.json @@ -0,0 +1,3 @@ +{ + "nameId": "jellyfin-spicetify" +} \ No newline at end of file diff --git a/src/types/css-modules.d.ts b/src/types/css-modules.d.ts new file mode 100644 index 0000000..8c454a3 --- /dev/null +++ b/src/types/css-modules.d.ts @@ -0,0 +1,9 @@ +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; +} + +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; +} diff --git a/src/types/spicetify.d.ts b/src/types/spicetify.d.ts new file mode 100644 index 0000000..5e99878 --- /dev/null +++ b/src/types/spicetify.d.ts @@ -0,0 +1,2353 @@ +declare namespace Spicetify { + type Icon = + | "album" + | "artist" + | "block" + | "brightness" + | "car" + | "chart-down" + | "chart-up" + | "check" + | "check-alt-fill" + | "chevron-left" + | "chevron-right" + | "chromecast-disconnected" + | "clock" + | "collaborative" + | "computer" + | "copy" + | "download" + | "downloaded" + | "edit" + | "enhance" + | "exclamation-circle" + | "external-link" + | "facebook" + | "follow" + | "fullscreen" + | "gamepad" + | "grid-view" + | "heart" + | "heart-active" + | "instagram" + | "laptop" + | "library" + | "list-view" + | "location" + | "locked" + | "locked-active" + | "lyrics" + | "menu" + | "minimize" + | "minus" + | "more" + | "new-spotify-connect" + | "offline" + | "pause" + | "phone" + | "play" + | "playlist" + | "playlist-folder" + | "plus-alt" + | "plus2px" + | "podcasts" + | "projector" + | "queue" + | "repeat" + | "repeat-once" + | "search" + | "search-active" + | "shuffle" + | "skip-back" + | "skip-back15" + | "skip-forward" + | "skip-forward15" + | "soundbetter" + | "speaker" + | "spotify" + | "subtitles" + | "tablet" + | "ticket" + | "twitter" + | "visualizer" + | "voice" + | "volume" + | "volume-off" + | "volume-one-wave" + | "volume-two-wave" + | "watch" + | "x"; + type Variant = + | "bass" + | "forte" + | "brio" + | "altoBrio" + | "alto" + | "canon" + | "celloCanon" + | "cello" + | "ballad" + | "balladBold" + | "viola" + | "violaBold" + | "mesto" + | "mestoBold" + | "metronome" + | "finale" + | "finaleBold" + | "minuet" + | "minuetBold"; + type SemanticColor = + | "textBase" + | "textSubdued" + | "textBrightAccent" + | "textNegative" + | "textWarning" + | "textPositive" + | "textAnnouncement" + | "essentialBase" + | "essentialSubdued" + | "essentialBrightAccent" + | "essentialNegative" + | "essentialWarning" + | "essentialPositive" + | "essentialAnnouncement" + | "decorativeBase" + | "decorativeSubdued" + | "backgroundBase" + | "backgroundHighlight" + | "backgroundPress" + | "backgroundElevatedBase" + | "backgroundElevatedHighlight" + | "backgroundElevatedPress" + | "backgroundTintedBase" + | "backgroundTintedHighlight" + | "backgroundTintedPress" + | "backgroundUnsafeForSmallTextBase" + | "backgroundUnsafeForSmallTextHighlight" + | "backgroundUnsafeForSmallTextPress"; + type ColorSet = + | "base" + | "brightAccent" + | "negative" + | "warning" + | "positive" + | "announcement" + | "invertedDark" + | "invertedLight" + | "mutedAccent" + | "overMedia"; + type ColorSetBackgroundColors = { + base: string; + highlight: string; + press: string; + }; + type ColorSetNamespaceColors = { + announcement: string; + base: string; + brightAccent: string; + negative: string; + positive: string; + subdued: string; + warning: string; + }; + type ColorSetBody = { + background: ColorSetBackgroundColors & { + elevated: ColorSetBackgroundColors; + tinted: ColorSetBackgroundColors; + unsafeForSmallText: ColorSetBackgroundColors; + }; + decorative: { + base: string; + subdued: string; + }; + essential: ColorSetNamespaceColors; + text: ColorSetNamespaceColors; + }; + type Metadata = Partial>; + type ContextTrack = { + uri: string; + uid?: string; + metadata?: Metadata; + }; + type PlayerState = { + timestamp: number; + context: PlayerContext; + index: PlayerIndex; + item: PlayerTrack; + shuffle: boolean; + repeat: number; + speed: number; + positionAsOfTimestamp: number; + duration: number; + hasContext: boolean; + isPaused: boolean; + isBuffering: boolean; + restrictions: Restrictions; + previousItems?: PlayerTrack[]; + nextItems?: PlayerTrack[]; + playbackQuality: PlaybackQuality; + playbackId: string; + sessionId: string; + signals?: any[]; + }; + type PlayerContext = { + uri: string; + url: string; + metadata: { + "player.arch": string; + }; + }; + type PlayerIndex = { + pageURI?: string | null; + pageIndex: number; + itemIndex: number; + }; + type PlayerTrack = { + type: string; + uri: string; + uid: string; + name: string; + mediaType: string; + duration: { + milliseconds: number; + }; + album: Album; + artists?: ArtistsEntity[]; + isLocal: boolean; + isExplicit: boolean; + is19PlusOnly: boolean; + provider: string; + metadata: TrackMetadata; + images?: ImagesEntity[]; + }; + type TrackMetadata = { + artist_uri: string; + entity_uri: string; + iteration: string; + title: string; + "collection.is_banned": string; + "artist_uri:1": string; + "collection.in_collection": string; + image_small_url: string; + "collection.can_ban": string; + is_explicit: string; + album_disc_number: string; + album_disc_count: string; + track_player: string; + album_title: string; + "collection.can_add": string; + image_large_url: string; + "actions.skipping_prev_past_track": string; + page_instance_id: string; + image_xlarge_url: string; + marked_for_download: string; + "actions.skipping_next_past_track": string; + context_uri: string; + "artist_name:1": string; + has_lyrics: string; + interaction_id: string; + image_url: string; + album_uri: string; + album_artist_name: string; + album_track_number: string; + artist_name: string; + duration: string; + album_track_count: string; + popularity: string; + }; + type Album = { + type: string; + uri: string; + name: string; + images?: ImagesEntity[]; + }; + type ImagesEntity = { + url: string; + label: string; + }; + type ArtistsEntity = { + type: string; + uri: string; + name: string; + }; + type Restrictions = { + canPause: boolean; + canResume: boolean; + canSeek: boolean; + canSkipPrevious: boolean; + canSkipNext: boolean; + canToggleRepeatContext: boolean; + canToggleRepeatTrack: boolean; + canToggleShuffle: boolean; + disallowPausingReasons?: string[]; + disallowResumingReasons?: string[]; + disallowSeekingReasons?: string[]; + disallowSkippingPreviousReasons?: string[]; + disallowSkippingNextReasons?: string[]; + disallowTogglingRepeatContextReasons?: string[]; + disallowTogglingRepeatTrackReasons?: string[]; + disallowTogglingShuffleReasons?: string[]; + disallowTransferringPlaybackReasons?: string[]; + }; + type PlaybackQuality = { + bitrateLevel: number; + strategy: number; + targetBitrateLevel: number; + targetBitrateAvailable: boolean; + hifiStatus: number; + }; + namespace Player { + /** + * Register a listener `type` on Spicetify.Player. + * + * On default, `Spicetify.Player` always dispatch: + * - `songchange` type when player changes track. + * - `onplaypause` type when player plays or pauses. + * - `onprogress` type when track progress changes. + * - `appchange` type when user changes page. + */ + function addEventListener(type: string, callback: (event?: Event) => void): void; + function addEventListener(type: "songchange", callback: (event?: Event & { data: PlayerState }) => void): void; + function addEventListener(type: "onplaypause", callback: (event?: Event & { data: PlayerState }) => void): void; + function addEventListener(type: "onprogress", callback: (event?: Event & { data: number }) => void): void; + function addEventListener( + type: "appchange", + callback: ( + event?: Event & { + data: { + /** + * App href path + */ + path: string; + /** + * App container + */ + container: HTMLElement; + }; + } + ) => void + ): void; + /** + * Skip to previous track. + */ + function back(): void; + /** + * An object contains all information about current track and player. + */ + const data: PlayerState; + /** + * Decrease a small amount of volume. + */ + function decreaseVolume(): void; + /** + * Dispatches an event at `Spicetify.Player`. + * + * On default, `Spicetify.Player` always dispatch + * - `songchange` type when player changes track. + * - `onplaypause` type when player plays or pauses. + * - `onprogress` type when track progress changes. + * - `appchange` type when user changes page. + */ + function dispatchEvent(event: Event): void; + const eventListeners: { + [key: string]: Array<(event?: Event) => void>; + }; + /** + * Convert milisecond to `mm:ss` format + * @param milisecond + */ + function formatTime(milisecond: number): string; + /** + * Return song total duration in milisecond. + */ + function getDuration(): number; + /** + * Return mute state + */ + function getMute(): boolean; + /** + * Return elapsed duration in milisecond. + */ + function getProgress(): number; + /** + * Return elapsed duration in percentage (0 to 1). + */ + function getProgressPercent(): number; + /** + * Return current Repeat state (No repeat = 0/Repeat all = 1/Repeat one = 2). + */ + function getRepeat(): number; + /** + * Return current shuffle state. + */ + function getShuffle(): boolean; + /** + * Return track heart state. + */ + function getHeart(): boolean; + /** + * Return current volume level (0 to 1). + */ + function getVolume(): number; + /** + * Increase a small amount of volume. + */ + function increaseVolume(): void; + /** + * Return a boolean whether player is playing. + */ + function isPlaying(): boolean; + /** + * Skip to next track. + */ + function next(): void; + /** + * Pause track. + */ + function pause(): void; + /** + * Resume track. + */ + function play(): void; + /** + * Play a track, playlist, album, etc. immediately + * @param uri Spotify URI + * @param context + * @param options + */ + function playUri(uri: string, context?: any, options?: any): Promise; + /** + * Unregister added event listener `type`. + * @param type + * @param callback + */ + function removeEventListener(type: string, callback: (event?: Event) => void): void; + /** + * Seek track to position. + * @param position can be in percentage (0 to 1) or in milisecond. + */ + function seek(position: number): void; + /** + * Turn mute on/off + * @param state + */ + function setMute(state: boolean): void; + /** + * Change Repeat mode + * @param mode `0` No repeat. `1` Repeat all. `2` Repeat one track. + */ + function setRepeat(mode: number): void; + /** + * Turn shuffle on/off. + * @param state + */ + function setShuffle(state: boolean): void; + /** + * Set volume level + * @param level 0 to 1 + */ + function setVolume(level: number): void; + /** + * Seek to previous `amount` of milisecond + * @param amount in milisecond. Default: 15000. + */ + function skipBack(amount?: number): void; + /** + * Seek to next `amount` of milisecond + * @param amount in milisecond. Default: 15000. + */ + function skipForward(amount?: number): void; + /** + * Toggle Heart (Favourite) track state. + */ + function toggleHeart(): void; + /** + * Toggle Mute/No mute. + */ + function toggleMute(): void; + /** + * Toggle Play/Pause. + */ + function togglePlay(): void; + /** + * Toggle No repeat/Repeat all/Repeat one. + */ + function toggleRepeat(): void; + /** + * Toggle Shuffle/No shuffle. + */ + function toggleShuffle(): void; + } + /** + * Adds a track or array of tracks to prioritized queue. + */ + function addToQueue(uri: ContextTrack[]): Promise; + /** + * @deprecated + */ + const BridgeAPI: any; + /** + * @deprecated + */ + const CosmosAPI: any; + /** + * Async wrappers of CosmosAPI + */ + namespace CosmosAsync { + type Method = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "SUB"; + interface Error { + code: number; + error: string; + message: string; + stack?: string; + } + + type Headers = Record; + type Body = Record; + + interface Response { + body: any; + headers: Headers; + status: number; + uri?: string; + } + + function head(url: string, headers?: Headers): Promise; + function get(url: string, body?: Body, headers?: Headers): Promise; + function post(url: string, body?: Body, headers?: Headers): Promise; + function put(url: string, body?: Body, headers?: Headers): Promise; + function del(url: string, body?: Body, headers?: Headers): Promise; + function patch(url: string, body?: Body, headers?: Headers): Promise; + function sub( + url: string, + callback: (b: Response["body"]) => void, + onError?: (e: Error) => void, + body?: Body, + headers?: Headers + ): Promise; + function postSub( + url: string, + body: Body | null, + callback: (b: Response["body"]) => void, + onError?: (e: Error) => void + ): Promise; + function request(method: Method, url: string, body?: Body, headers?: Headers): Promise; + function resolve(method: Method, url: string, body?: Body, headers?: Headers): Promise; + } + /** + * Fetch interesting colors from URI. + * @param uri Any type of URI that has artwork (playlist, track, album, artist, show, ...) + */ + function colorExtractor(uri: string): Promise<{ + DARK_VIBRANT: string; + DESATURATED: string; + LIGHT_VIBRANT: string; + PROMINENT: string; + VIBRANT: string; + VIBRANT_NON_ALARMING: string; + }>; + /** + * @deprecated + */ + function getAblumArtColors(): any; + /** + * Fetch track analyzed audio data. + * Beware, not all tracks have audio data. + * @param uri is optional. Leave it blank to get current track + * or specify another track uri. + */ + function getAudioData(uri?: string): Promise; + /** + * Set of APIs method to register, deregister hotkeys/shortcuts + */ + namespace Keyboard { + type ValidKey = + | "BACKSPACE" + | "TAB" + | "ENTER" + | "SHIFT" + | "CTRL" + | "ALT" + | "CAPS" + | "ESCAPE" + | "SPACE" + | "PAGE_UP" + | "PAGE_DOWN" + | "END" + | "HOME" + | "ARROW_LEFT" + | "ARROW_UP" + | "ARROW_RIGHT" + | "ARROW_DOWN" + | "INSERT" + | "DELETE" + | "A" + | "B" + | "C" + | "D" + | "E" + | "F" + | "G" + | "H" + | "I" + | "J" + | "K" + | "L" + | "M" + | "N" + | "O" + | "P" + | "Q" + | "R" + | "S" + | "T" + | "U" + | "V" + | "W" + | "X" + | "Y" + | "Z" + | "WINDOW_LEFT" + | "WINDOW_RIGHT" + | "SELECT" + | "NUMPAD_0" + | "NUMPAD_1" + | "NUMPAD_2" + | "NUMPAD_3" + | "NUMPAD_4" + | "NUMPAD_5" + | "NUMPAD_6" + | "NUMPAD_7" + | "NUMPAD_8" + | "NUMPAD_9" + | "MULTIPLY" + | "ADD" + | "SUBTRACT" + | "DECIMAL_POINT" + | "DIVIDE" + | "F1" + | "F2" + | "F3" + | "F4" + | "F5" + | "F6" + | "F7" + | "F8" + | "F9" + | "F10" + | "F11" + | "F12" + | ";" + | "=" + | " | " + | "-" + | "." + | "/" + | "`" + | "[" + | "\\" + | "]" + | '"' + | "~" + | "!" + | "@" + | "#" + | "$" + | "%" + | "^" + | "&" + | "*" + | "(" + | ")" + | "_" + | "+" + | ":" + | "<" + | ">" + | "?" + | "|"; + type KeysDefine = + | string + | { + key: string; + ctrl?: boolean; + shift?: boolean; + alt?: boolean; + meta?: boolean; + }; + const KEYS: Record; + function registerShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void): void; + function registerIsolatedShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void): void; + function registerImportantShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void): void; + function _deregisterShortcut(keys: KeysDefine): void; + function deregisterImportantShortcut(keys: KeysDefine): void; + function changeShortcut(keys: KeysDefine, newKeys: KeysDefine): void; + } + + /** + * @deprecated + */ + const LiveAPI: any; + + namespace LocalStorage { + /** + * Empties the list associated with the object of all key/value pairs, if there are any. + */ + function clear(): void; + /** + * Get key value + */ + function get(key: string): string | null; + /** + * Delete key + */ + function remove(key: string): void; + /** + * Set new value for key + */ + function set(key: string, value: string): void; + } + /** + * To create and prepend custom menu item in profile menu. + */ + namespace Menu { + /** + * Create a single toggle. + */ + class Item { + constructor(name: string, isEnabled: boolean, onClick: (self: Item) => void, icon?: Icon | string); + name: string; + isEnabled: boolean; + /** + * Change item name + */ + setName(name: string): void; + /** + * Change item enabled state. + * Visually, item would has a tick next to it if its state is enabled. + */ + setState(isEnabled: boolean): void; + /** + * Change icon + */ + setIcon(icon: Icon | string): void; + /** + * Item is only available in Profile menu when method "register" is called. + */ + register(): void; + /** + * Stop item to be prepended into Profile menu. + */ + deregister(): void; + } + + /** + * Create a sub menu to contain Item toggles. + * `Item`s in `subItems` array shouldn't be registered. + */ + class SubMenu { + constructor(name: string, subItems: Item[]); + name: string; + /** + * Change SubMenu name + */ + setName(name: string): void; + /** + * Add an item to sub items list + */ + addItem(item: Item); + /** + * Remove an item from sub items list + */ + removeItem(item: Item); + /** + * SubMenu is only available in Profile menu when method "register" is called. + */ + register(): void; + /** + * Stop SubMenu to be prepended into Profile menu. + */ + deregister(): void; + } + } + + /** + * Keyboard shortcut library + * + * Documentation: https://craig.is/killing/mice v1.6.5 + * + * Spicetify.Keyboard is wrapper of this library to be compatible with legacy Spotify, + * so new extension should use this library instead. + */ + function Mousetrap(element?: any): void; + + /** + * Contains vast array of internal APIs. + * Please explore in Devtool Console. + */ + const Platform: any; + /** + * Queue object contains list of queuing tracks, + * history of played tracks and current track metadata. + */ + const Queue: { + nextTracks: any[]; + prevTracks: any[]; + queueRevision: string; + track: any; + }; + /** + * Remove a track or array of tracks from current queue. + */ + function removeFromQueue(uri: ContextTrack[]): Promise; + /** + * Display a bubble of notification. Useful for a visual feedback. + * @param message Message to display. Can use inline HTML for styling. + * @param isError If true, bubble will be red. Defaults to false. + * @param msTimeout Time in milliseconds to display the bubble. Defaults to Spotify's value. + */ + function showNotification(message: React.ReactNode, isError?: boolean, msTimeout?: number): void; + /** + * Set of APIs method to parse and validate URIs. + */ + class URI { + constructor(type: string, props: any); + public type: string; + public hasBase62Id: boolean; + + public id?: string; + public disc?: any; + public args?: any; + public category?: string; + public username?: string; + public track?: string; + public artist?: string; + public album?: string; + public duration?: number; + public query?: string; + public country?: string; + public global?: boolean; + public context?: string | typeof URI | null; + public anchor?: string; + public play?: any; + public toplist?: any; + + /** + * + * @return The URI representation of this uri. + */ + toURI(): string; + + /** + * + * @return The URI representation of this uri. + */ + toString(): string; + + /** + * Get the URL path of this uri. + * + * @param opt_leadingSlash True if a leading slash should be prepended. + * @return The path of this uri. + */ + toURLPath(opt_leadingSlash: boolean): string; + + /** + * + * @param origin The origin to use for the URL. + * @return The URL string for the uri. + */ + toURL(origin?: string): string; + + /** + * Clones a given SpotifyURI instance. + * + * @return An instance of URI. + */ + clone(): URI | null; + + /** + * Gets the path of the URI object by removing all hash and query parameters. + * + * @return The path of the URI object. + */ + getPath(): string; + + /** + * The various URI Types. + * + * Note that some of the types in this enum are not real URI types, but are + * actually URI particles. They are marked so. + * + */ + static Type: { + AD: string; + ALBUM: string; + GENRE: string; + QUEUE: string; + APPLICATION: string; + ARTIST: string; + ARTIST_TOPLIST: string; + ARTIST_CONCERTS: string; + AUDIO_FILE: string; + COLLECTION: string; + COLLECTION_ALBUM: string; + COLLECTION_ARTIST: string; + COLLECTION_MISSING_ALBUM: string; + COLLECTION_TRACK_LIST: string; + CONCERT: string; + CONTEXT_GROUP: string; + DAILY_MIX: string; + EMPTY: string; + EPISODE: string; + /** URI particle; not an actual URI. */ + FACEBOOK: string; + FOLDER: string; + FOLLOWERS: string; + FOLLOWING: string; + IMAGE: string; + INBOX: string; + INTERRUPTION: string; + LIBRARY: string; + LIVE: string; + ROOM: string; + EXPRESSION: string; + LOCAL: string; + LOCAL_TRACK: string; + LOCAL_ALBUM: string; + LOCAL_ARTIST: string; + MERCH: string; + MOSAIC: string; + PLAYLIST: string; + PLAYLIST_V2: string; + PRERELEASE: string; + PROFILE: string; + PUBLISHED_ROOTLIST: string; + RADIO: string; + ROOTLIST: string; + SEARCH: string; + SHOW: string; + SOCIAL_SESSION: string; + SPECIAL: string; + STARRED: string; + STATION: string; + TEMP_PLAYLIST: string; + TOPLIST: string; + TRACK: string; + TRACKSET: string; + USER_TOPLIST: string; + USER_TOP_TRACKS: string; + UNKNOWN: string; + MEDIA: string; + QUESTION: string; + POLL: string; + }; + + /** + * Creates a new URI object from a parsed string argument. + * + * @param str The string that will be parsed into a URI object. + * @throws TypeError If the string argument is not a valid URI, a TypeError will + * be thrown. + * @return The parsed URI object. + */ + static fromString(str: string): URI; + + /** + * Parses a given object into a URI instance. + * + * Unlike URI.fromString, this function could receive any kind of value. If + * the value is already a URI instance, it is simply returned. + * Otherwise the value will be stringified before parsing. + * + * This function also does not throw an error like URI.fromString, but + * instead simply returns null if it can't parse the value. + * + * @param value The value to parse. + * @return The corresponding URI instance, or null if the + * passed value is not a valid value. + */ + static from(value: any): URI | null; + + /** + * Checks whether two URI:s refer to the same thing even though they might + * not necessarily be equal. + * + * These two Playlist URIs, for example, refer to the same playlist: + * + * spotify:user:napstersean:playlist:3vxotOnOGDlZXyzJPLFnm2 + * spotify:playlist:3vxotOnOGDlZXyzJPLFnm2 + * + * @param baseUri The first URI to compare. + * @param refUri The second URI to compare. + * @return Whether they shared idenitity + */ + static isSameIdentity(baseUri: URI | string, refUri: URI | string): boolean; + + /** + * Returns the hex representation of a Base62 encoded id. + * + * @param id The base62 encoded id. + * @return The hex representation of the base62 id. + */ + static idToHex(id: string): string; + + /** + * Returns the base62 representation of a hex encoded id. + * + * @param hex The hex encoded id. + * @return The base62 representation of the id. + */ + static hexToId(hex: string): string; + + /** + * Creates a new 'album' type URI. + * + * @param id The id of the album. + * @param disc The disc number of the album. + * @return The album URI. + */ + static albumURI(id: string, disc: number): URI; + + /** + * Creates a new 'application' type URI. + * + * @param id The id of the application. + * @param args An array containing the arguments to the app. + * @return The application URI. + */ + static applicationURI(id: string, args: string[]): URI; + + /** + * Creates a new 'artist' type URI. + * + * @param id The id of the artist. + * @return The artist URI. + */ + static artistURI(id: string): URI; + + /** + * Creates a new 'collection' type URI. + * + * @param username The non-canonical username of the rootlist owner. + * @param category The category of the collection. + * @return The collection URI. + */ + static collectionURI(username: string, category: string): URI; + + /** + * Creates a new 'collection-album' type URI. + * + * @param username The non-canonical username of the rootlist owner. + * @param id The id of the album. + * @return The collection album URI. + */ + static collectionAlbumURI(username: string, id: string): URI; + + /** + * Creates a new 'collection-artist' type URI. + * + * @param username The non-canonical username of the rootlist owner. + * @param id The id of the artist. + * @return The collection artist URI. + */ + static collectionAlbumURI(username: string, id: string): URI; + + /** + * Creates a new 'concert' type URI. + * + * @param id The id of the concert. + * @return The concert URI. + */ + static concertURI(id: string): URI; + + /** + * Creates a new 'episode' type URI. + * + * @param id The id of the episode. + * @return The episode URI. + */ + static episodeURI(id: string): URI; + + /** + * Creates a new 'folder' type URI. + * + * @param id The id of the folder. + * @return The folder URI. + */ + static folderURI(id: string): URI; + + /** + * Creates a new 'local-album' type URI. + * + * @param artist The artist of the album. + * @param album The name of the album. + * @return The local album URI. + */ + static localAlbumURI(artist: string, album: string): URI; + + /** + * Creates a new 'local-artist' type URI. + * + * @param artist The name of the artist. + * @return The local artist URI. + */ + static localArtistURI(artist: string): URI; + + /** + * Creates a new 'playlist-v2' type URI. + * + * @param id The id of the playlist. + * @return The playlist URI. + */ + static playlistV2URI(id: string): URI; + + /** + * Creates a new 'prerelease' type URI. + * + * @param id The id of the prerelease. + * @return The prerelease URI. + */ + static prereleaseURI(id: string): URI; + + /** + * Creates a new 'profile' type URI. + * + * @param username The non-canonical username of the rootlist owner. + * @param args A list of arguments. + * @return The profile URI. + */ + static profileURI(username: string, args: string[]): URI; + + /** + * Creates a new 'search' type URI. + * + * @param query The unencoded search query. + * @return The search URI + */ + static searchURI(query: string): URI; + + /** + * Creates a new 'show' type URI. + * + * @param id The id of the show. + * @return The show URI. + */ + static showURI(id: string): URI; + + /** + * Creates a new 'station' type URI. + * + * @param args An array of arguments for the station. + * @return The station URI. + */ + static stationURI(args: string[]): URI; + + /** + * Creates a new 'track' type URI. + * + * @param id The id of the track. + * @param anchor The point in the track formatted as mm:ss + * @param context An optional context URI + * @param play Toggles autoplay + * @return The track URI. + */ + static trackURI(id: string, anchor: string, context?: string, play?: boolean): URI; + + /** + * Creates a new 'user-toplist' type URI. + * + * @param username The non-canonical username of the toplist owner. + * @param toplist The toplist type. + * @return The user-toplist URI. + */ + static userToplistURI(username: string, toplist: string): URI; + + static isAd(uri: URI | string): boolean; + static isAlbum(uri: URI | string): boolean; + static isGenre(uri: URI | string): boolean; + static isQueue(uri: URI | string): boolean; + static isApplication(uri: URI | string): boolean; + static isArtist(uri: URI | string): boolean; + static isArtistToplist(uri: URI | string): boolean; + static isArtistConcerts(uri: URI | string): boolean; + static isAudioFile(uri: URI | string): boolean; + static isCollection(uri: URI | string): boolean; + static isCollectionAlbum(uri: URI | string): boolean; + static isCollectionArtist(uri: URI | string): boolean; + static isCollectionMissingAlbum(uri: URI | string): boolean; + static isCollectionTrackList(uri: URI | string): boolean; + static isConcert(uri: URI | string): boolean; + static isContextGroup(uri: URI | string): boolean; + static isDailyMix(uri: URI | string): boolean; + static isEmpty(uri: URI | string): boolean; + static isEpisode(uri: URI | string): boolean; + static isFacebook(uri: URI | string): boolean; + static isFolder(uri: URI | string): boolean; + static isFollowers(uri: URI | string): boolean; + static isFollowing(uri: URI | string): boolean; + static isImage(uri: URI | string): boolean; + static isInbox(uri: URI | string): boolean; + static isInterruption(uri: URI | string): boolean; + static isLibrary(uri: URI | string): boolean; + static isLive(uri: URI | string): boolean; + static isRoom(uri: URI | string): boolean; + static isExpression(uri: URI | string): boolean; + static isLocal(uri: URI | string): boolean; + static isLocalTrack(uri: URI | string): boolean; + static isLocalAlbum(uri: URI | string): boolean; + static isLocalArtist(uri: URI | string): boolean; + static isMerch(uri: URI | string): boolean; + static isMosaic(uri: URI | string): boolean; + static isPlaylist(uri: URI | string): boolean; + static isPlaylistV2(uri: URI | string): boolean; + static isPrerelease(uri: URI | string): boolean; + static isProfile(uri: URI | string): boolean; + static isPublishedRootlist(uri: URI | string): boolean; + static isRadio(uri: URI | string): boolean; + static isRootlist(uri: URI | string): boolean; + static isSearch(uri: URI | string): boolean; + static isShow(uri: URI | string): boolean; + static isSocialSession(uri: URI | string): boolean; + static isSpecial(uri: URI | string): boolean; + static isStarred(uri: URI | string): boolean; + static isStation(uri: URI | string): boolean; + static isTempPlaylist(uri: URI | string): boolean; + static isToplist(uri: URI | string): boolean; + static isTrack(uri: URI | string): boolean; + static isTrackset(uri: URI | string): boolean; + static isUserToplist(uri: URI | string): boolean; + static isUserTopTracks(uri: URI | string): boolean; + static isUnknown(uri: URI | string): boolean; + static isMedia(uri: URI | string): boolean; + static isQuestion(uri: URI | string): boolean; + static isPoll(uri: URI | string): boolean; + static isPlaylistV1OrV2(uri: URI | string): boolean; + } + + /** + * Create custom menu item and prepend to right click context menu + */ + namespace ContextMenu { + type OnClickCallback = (uris: string[], uids?: string[], contextUri?: string) => void; + type ShouldAddCallback = (uris: string[], uids?: string[], contextUri?: string) => boolean; + + // Single context menu item + class Item { + /** + * List of valid icons to use. + */ + static readonly iconList: Icon[]; + constructor(name: string, onClick: OnClickCallback, shouldAdd?: ShouldAddCallback, icon?: Icon, disabled?: boolean); + name: string; + icon: Icon | string; + disabled: boolean; + /** + * A function returning boolean determines whether item should be prepended. + */ + shouldAdd: ShouldAddCallback; + /** + * A function to call when item is clicked + */ + onClick: OnClickCallback; + /** + * Item is only available in Context Menu when method "register" is called. + */ + register: () => void; + /** + * Stop Item to be prepended into Context Menu. + */ + deregister: () => void; + } + + /** + * Create a sub menu to contain `Item`s. + * `Item`s in `subItems` array shouldn't be registered. + */ + class SubMenu { + constructor(name: string, subItems: Iterable, shouldAdd?: ShouldAddCallback, disabled?: boolean); + name: string; + disabled: boolean; + /** + * A function returning boolean determines whether item should be prepended. + */ + shouldAdd: ShouldAddCallback; + addItem: (item: Item) => void; + removeItem: (item: Item) => void; + /** + * SubMenu is only available in Context Menu when method "register" is called. + */ + register: () => void; + /** + * Stop SubMenu to be prepended into Context Menu. + */ + deregister: () => void; + } + } + + /** + * Popup Modal + */ + namespace PopupModal { + interface Content { + title: string; + /** + * You can specify a string for simple text display + * or a HTML element for interactive config/setting menu + */ + content: string | Element; + /** + * Bigger window + */ + isLarge?: boolean; + } + + function display(e: Content): void; + function hide(): void; + } + + /** React instance to create components */ + const React: any; + /** React DOM instance to render and mount components */ + const ReactDOM: any; + /** React DOM Server instance to render components to string */ + const ReactDOMServer: any; + + /** Stock React components exposed from Spotify library */ + namespace ReactComponent { + type ContextMenuProps = { + /** + * Decide whether to use the global singleton context menu (rendered in ) + * or a new inline context menu (rendered in a sibling + * element to `children`) + */ + renderInline?: boolean; + /** + * Determins what will trigger the context menu. For example, a click, or a right-click + */ + trigger?: "click" | "right-click"; + /** + * Determins is the context menu should open or toggle when triggered + */ + action?: "toggle" | "open"; + /** + * The preferred placement of the context menu when it opens. + * Relative to trigger element. + */ + placement?: + | "top" + | "top-start" + | "top-end" + | "right" + | "right-start" + | "right-end" + | "bottom" + | "bottom-start" + | "bottom-end" + | "left" + | "left-start" + | "left-end"; + /** + * The x and y offset distances at which the context menu should open. + * Relative to trigger element and `position`. + */ + offset?: [number, number]; + /** + * Will stop the client from scrolling while the context menu is open + */ + preventScrollingWhileOpen?: boolean; + /** + * The menu UI to render inside of the context menu. + */ + menu: + | typeof Spicetify.ReactComponent.Menu + | typeof Spicetify.ReactComponent.AlbumMenu + | typeof Spicetify.ReactComponent.PodcastShowMenu + | typeof Spicetify.ReactComponent.ArtistMenu + | typeof Spicetify.ReactComponent.PlaylistMenu; + /** + * A child of the context menu. Should be `