diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..acad636
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,14 @@
+module.exports = {
+ env: {
+ es2021: true,
+ node: true
+ },
+ extends: 'standard-with-typescript',
+ parserOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ project: './tsconfig.json'
+ },
+ rules: {
+ }
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..aadf5a8
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true,
+ "source.formatDocument": false,
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index ff8ff6d..6173d02 100644
--- a/README.md
+++ b/README.md
@@ -45,14 +45,21 @@ Once you have selected a playlist, you can use the new topbar button to quickly
![](https://i.imgur.com/JrgLaUk.png)
+This extension is fully compatible all spicetify theme, thanks to its settions section.
+
+You can find it by clicking on your avatar -> Settings -> Quick add to playlist (at the very bottom)
+There, you can customize the "selected playlist" background color to match your current theme!
+
+![](https://i.imgur.com/kjkgPrO.png)
+
## Usage Notes
-- If you find any issues, please report them on the [issues page.](https://github.com/woosy/spicetify-quick-add-to-playlist/issues/new/choose)
+- If you find any issues, please report them on the [issues page](https://github.com/woosy/spicetify-quick-add-to-playlist/issues/new/choose).
## Upcoming Features
-- Settings, to customize the "selected playlist" background color
+- Feel free to suggest any features in the [issues page](https://github.com/woosy/spicetify-quick-add-to-playlist/issues/new/choose).
## Credits
diff --git a/dist/quick-add-to-playlist.js b/dist/quick-add-to-playlist.js
index 952bc80..7b6410d 100644
--- a/dist/quick-add-to-playlist.js
+++ b/dist/quick-add-to-playlist.js
@@ -1,14 +1,17 @@
-var quickDaddDtoDplaylist=(()=>{var l="add_to_playlist.playlist",s='',o='',c='';async function n(t){p(t,"?"),d()&&(await async function(){const i=Spicetify.Player.data.track;var t=d();return!!t&&(await Spicetify.CosmosAsync.get("https://api.spotify.com/v1/playlists/"+t.id)).tracks.items.some(t=>t.track.uri===i.uri)}()?p(t,"-"):p(t,"+"))}function p(t,i){var e=d();switch(i){case"+":t.icon=s,t.label="Add to "+e.name;break;case"-":t.icon=o,t.label="Remove from "+e.name;break;case"?":t.icon=c,t.label="Loading..."}}function r(t,i){t&&null!=(t=null==(t=null==(t=document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${t}"]`))?void 0:t.parentElement)?void 0:t.parentElement)&&t.classList.remove("quick-add-to-playlist--selected-playlist"),i&&null!=(t=null==(i=null==(t=document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${i}"]`))?void 0:t.parentElement)?void 0:i.parentElement)&&t.classList.add("quick-add-to-playlist--selected-playlist")}function d(){return JSON.parse(Spicetify.LocalStorage.get(l))}var t=async function(){for(;null==Spicetify||!Spicetify.showNotification;)await new Promise(t=>setTimeout(t,2e3));var t=document.body,i=document.createElement("style");t.classList.contains("quick-add-to-playlist--selected-playlist")||(i.innerHTML=`
- .quick-add-to-playlist--selected-playlist {
- background-color: #1c1818 !important;
- }
+var quickDaddDtoDplaylist=(()=>{var o=Object.create,d=Object.defineProperty,r=Object.getOwnPropertyDescriptor,c=Object.getOwnPropertyNames,p=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty,e=(e,t)=>function(){return t||(0,e[c(e)[0]])((t={exports:{}}).exports,t),t.exports},t=(e,t,i)=>{i=null!=e?o(p(e)):{};var l=!t&&e&&e.__esModule?i:d(i,"default",{value:e,enumerable:!0}),a=e,n=void 0,s=void 0;if(a&&"object"==typeof a||"function"==typeof a)for(let e of c(a))u.call(l,e)||e===n||d(l,e,{get:()=>a[e],enumerable:!(s=r(a,e))||s.enumerable});return l},i=e({"external-global-plugin:react-dom"(e,t){t.exports=Spicetify.ReactDOM}}),s=t(e({"external-global-plugin:react"(e,t){t.exports=Spicetify.React}})()),l=t(i()),f={settingsContainer:"settings-module__settingsContainer___10GVL_quickDaddDtoDplaylist",heading:"settings-module__heading___H3Y7k_quickDaddDtoDplaylist",description:"settings-module__description___SrDvZ_quickDaddDtoDplaylist",inputWrapper:"settings-module__inputWrapper___a0OZK_quickDaddDtoDplaylist"},a=class{constructor(e,t,i={}){this.name=e,this.settingsId=t,this.initialSettingsFields=i,this.settingsFields=this.initialSettingsFields,this.setRerender=null,this.buttonClassnames=null,this.pushSettings=async()=>{for(Object.entries(this.settingsFields).forEach(([e,t])=>{"button"!==t.type&&void 0===this.getFieldValue(e)&&this.setFieldValue(e,t.defaultValue)});!Spicetify?.Platform?.History?.listen;)await new Promise(e=>setTimeout(e,100));this.stopHistoryListener&&this.stopHistoryListener(),this.stopHistoryListener=Spicetify.Platform.History.listen(e=>{"/preferences"===e.pathname&&this.render()}),"/preferences"===Spicetify.Platform.History.location.pathname&&await this.render()},this.rerender=()=>{this.setRerender&&this.setRerender(Math.random())},this.render=async()=>{for(;!document.getElementById("desktop.settings.selectLanguage");){if("/preferences"!==Spicetify.Platform.History.location.pathname)return;await new Promise(e=>setTimeout(e,100))}var e=document.querySelector(".main-view-container__scroll-node-child main div");if(!e)return console.error("[spcr-settings] settings container not found");this.buttonClassnames=Array.from(e.querySelectorAll(":scope > button")).at(-1)?.className??null;let t=Array.from(e.children).find(e=>e.id===this.settingsId);t?console.log(t):((t=document.createElement("div")).id=this.settingsId,t.className=f.settingsContainer,e.appendChild(t)),l.default.render(s.default.createElement(this.FieldsContainer,null),t)},this.addButton=(e,t,i,l,a)=>{this.settingsFields[e]={type:"button",description:t,value:i,events:{onClick:l,...a}}},this.addInput=(e,t,i,l,a)=>{this.settingsFields[e]={type:"input",description:t,defaultValue:i,events:{onChange:l,...a}}},this.addHidden=(e,t)=>{this.settingsFields[e]={type:"hidden",defaultValue:t}},this.addToggle=(e,t,i,l,a)=>{this.settingsFields[e]={type:"toggle",description:t,defaultValue:i,events:{onChange:l,...a}}},this.addDropDown=(e,t,i,l,a,n)=>{this.settingsFields[e]={type:"dropdown",description:t,defaultValue:i[l],options:i,events:{onSelect:a,...n}}},this.getFieldValue=e=>JSON.parse(Spicetify.LocalStorage.get(this.settingsId+"."+e)||"{}")?.value,this.setFieldValue=(e,t)=>{Spicetify.LocalStorage.set(this.settingsId+"."+e,JSON.stringify({value:t}))},this.FieldsContainer=()=>{var[e,t]=(0,s.useState)(0);return this.setRerender=t,s.default.createElement("div",{className:f.settingsContainer,key:e},s.default.createElement("h2",{className:["main-shelf-title main-type-cello",f.heading].join(" ")},this.name),Object.entries(this.settingsFields).map(([e,t])=>s.default.createElement(this.Field,{nameId:e,field:t})))},this.Field=i=>{var e=this.settingsId+"."+i.nameId;let t;if(t="button"===i.field.type?i.field.value:this.getFieldValue(i.nameId),"hidden"===i.field.type)return s.default.createElement(s.default.Fragment,null);const[l,a]=(0,s.useState)(t),n=e=>{void 0!==e&&(a(e),this.setFieldValue(i.nameId,e))};return s.default.createElement(s.default.Fragment,null,s.default.createElement("div",{className:"main-type-mesto",style:{color:"var(--spice-subtext)"}},s.default.createElement("label",{className:f.description,htmlFor:e},i.field.description||"")),s.default.createElement("span",{className:["x-settings-secondColumn",f.inputWrapper].join(" ")},"input"===i.field.type?s.default.createElement("input",{className:"main-dropDown-dropDown",id:e,dir:"ltr",value:l,type:"text",...i.field.events,onChange:e=>{n(e.currentTarget.value);var t=i.field.events?.onChange;t&&t(e)}}):"button"===i.field.type?s.default.createElement("span",{className:""},s.default.createElement("button",{id:e,className:this.buttonClassnames??"",...i.field.events,onClick:e=>{n();var t=i.field.events?.onClick;t&&t(e)},type:"button"},l)):"toggle"===i.field.type?s.default.createElement("label",{className:"x-toggle-wrapper x-settings-secondColumn"},s.default.createElement("input",{id:e,className:"x-toggle-input",type:"checkbox",checked:l,...i.field.events,onClick:e=>{n(e.currentTarget.checked);var t=i.field.events?.onClick;t&&t(e)}}),s.default.createElement("span",{className:"x-toggle-indicatorWrapper"},s.default.createElement("span",{className:"x-toggle-indicator"}))):"dropdown"===i.field.type?s.default.createElement("select",{className:"main-dropDown-dropDown",id:e,...i.field.events,onChange:e=>{n(i.field.options[e.currentTarget.selectedIndex]);var t=i.field.events?.onChange;t&&t(e)}},i.field.options.map((e,t)=>s.default.createElement("option",{selected:e===l,value:t+1},e))):s.default.createElement(s.default.Fragment,null)))}}},n="add_to_playlist.playlist",h='',m='',y='';function g(){var e;return null!=(e=JSON.parse(Spicetify.LocalStorage.get(n)))?e:null}async function C(e){e.icon=y,e.label="Loading...";var t=g();null!==t&&(await async function(e){var t=Spicetify.Player.data.track,i=[];let l=await Spicetify.CosmosAsync.get(`https://api.spotify.com/v1/playlists/${e}/tracks?limit=100&fields=next,items(track(uri))`);for(i.push(...l.items.map(e=>e.track.uri));null!=l.next;)l=await Spicetify.CosmosAsync.get(l.next),i.push(...l.items.map(e=>e.track.uri));return i.includes(null==t?void 0:t.uri)}(t.id)?(e.icon=m,e.label="Remove from "+t.name):(e.icon=h,e.label="Add to "+t.name))}function v(e,t){null!=e&&null!=(e=null==(e=null==(e=document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${e}"]`))?void 0:e.parentElement)?void 0:e.parentElement)&&e.classList.remove("quick-add-to-playlist--selected-playlist"),null!=t&&null!=(e=null==(t=null==(e=document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${t}"]`))?void 0:e.parentElement)?void 0:t.parentElement)&&e.classList.add("quick-add-to-playlist--selected-playlist")}function w(e="#1c1818"){return`
+ .quick-add-to-playlist--selected-playlist {
+ background-color: ${e} !important;
+ border-radius: 6px;
+ }
- .quick-add-to-playlist--selected-playlist span.ListRowTitle__LineClamp-sc-1xe2if1-0:after {
- position: absolute;
- right: 10px;
- content: " (selected 📂)";
- text-align: right;
- color: gray;
- font-size: 11px;
- }
- `,t.appendChild(i)),(t=d())&&r(null,t.id),setTimeout(()=>{var t=document.querySelector(".main-rootlist-wrapper");t&&new MutationObserver(t=>{for(const e of t){var i;"attributes"===e.type&&"style"===e.attributeName&&(i=d())&&r(null,i.id)}}).observe(t,{attributes:!0,childList:!0,subtree:!0})},2e3);const a=new Spicetify.Topbar.Button("Loading...",c,async t=>{var i=Spicetify.Player.data.track;const e=d();e&&(t.icon===s?Spicetify.CosmosAsync.post(`https://api.spotify.com/v1/playlists/${e.id}/tracks`,{uris:[null==i?void 0:i.uri]}).then(()=>{Spicetify.showNotification("Added to "+e.name),p(a,"-")}).catch(()=>{Spicetify.showNotification("An error has occured!")}):t.icon===o&&Spicetify.CosmosAsync.del(`https://api.spotify.com/v1/playlists/${e.id}/tracks`,{tracks:[{uri:null==i?void 0:i.uri}]}).then(()=>{Spicetify.showNotification("Removed from "+e.name),p(a,"+")}).catch(()=>{Spicetify.showNotification("An error has occured!")}))});await n(a),Spicetify.Player.addEventListener("appchange",async()=>{await n(a)}),Spicetify.Player.addEventListener("songchange",async()=>{await n(a)}),new Spicetify.ContextMenu.Item("Select playlist",async([t],[]=[],i)=>{var e=d(),t=await Spicetify.CosmosAsync.get("https://api.spotify.com/v1/playlists/"+t.split(":")[2]);Spicetify.LocalStorage.set(l,JSON.stringify({name:t.name,id:t.id})),r(e?e.id:null,t.id),Spicetify.showNotification(`Selected playlist "${t.name}"`),await n(a)},([t])=>{switch(t.split(":")[1]){case Spicetify.URI.Type.PLAYLIST:case Spicetify.URI.Type.PLAYLIST_V2:return!0;default:return!1}},"playlist-folder").register()};(async()=>{await t()})()})();
\ No newline at end of file
+ .quick-add-to-playlist--selected-playlist span.ListRowTitle__LineClamp-sc-1xe2if1-0:after {
+ position: absolute;
+ right: 10px;
+ content: " (selected 📂)";
+ text-align: right;
+ color: gray;
+ font-size: 11px;
+ }
+ `}function _(e){var t=document.body,i=t.querySelector("#quick-add-to-playlist-style");null!=i?(i.innerHTML=e,t.appendChild(i)):((i=document.createElement("style")).setAttribute("id","quick-add-to-playlist-style"),i.innerHTML=e,t.appendChild(i))}var S=async function(){var e=await async function(){const e=new a("Quick add to playlist","quick-add-to-playlist");return e.addInput("selected-bgcolor","Selected playlist background color","#1c1818"),e.addButton("save","Apply changes now","Apply",()=>{_(w(e.getFieldValue("selected-bgcolor"))),Spicetify.showNotification("Changes applied!")}),await e.pushSettings(),e}();_(w(e.getFieldValue("selected-bgcolor")));const l=new Spicetify.Topbar.Button("Loading...",y,async e=>{const t=g();var i;null!=t&&null!=(i=Spicetify.Player.data.track)&&(e.icon===h?Spicetify.CosmosAsync.post(`https://api.spotify.com/v1/playlists/${t.id}/tracks`,{uris:[null==i?void 0:i.uri]}).then(()=>{Spicetify.showNotification("Added to "+t.name),l.icon=m,l.label="Remove from "+t.name}).catch(()=>{Spicetify.showNotification("An error has occured!")}):e.icon===m&&Spicetify.CosmosAsync.del(`https://api.spotify.com/v1/playlists/${t.id}/tracks`,{tracks:[{uri:null==i?void 0:i.uri}]}).then(()=>{Spicetify.showNotification("Removed from "+t.name),l.icon=h,l.label="Add to "+t.name}).catch(()=>{Spicetify.showNotification("An error has occured!")}))});await C(l),new Spicetify.ContextMenu.Item("Select playlist",async([e],[]=[],t)=>{var i=g(),e=await Spicetify.CosmosAsync.get("https://api.spotify.com/v1/playlists/"+e.split(":")[2]);Spicetify.LocalStorage.set(n,JSON.stringify({name:e.name,id:e.id})),v(null!=i?i.id:null,e.id),Spicetify.showNotification(`Selected playlist: "${e.name}"`),await C(l)},([e])=>{switch(e.split(":")[1]){case Spicetify.URI.Type.PLAYLIST:case Spicetify.URI.Type.PLAYLIST_V2:return!0;default:return!1}},"playlist-folder").register(),Spicetify.Player.addEventListener("songchange",async()=>{await C(l)}),null!=(e=g())&&v(null,e.id)};(async()=>{await S()})()})();(async()=>{var e;document.getElementById("quickDaddDtoDplaylist")||((e=document.createElement("style")).id="quickDaddDtoDplaylist",e.textContent=String.raw`
+ .settings-module__settingsContainer___10GVL_quickDaddDtoDplaylist{display:contents}.settings-module__heading___H3Y7k_quickDaddDtoDplaylist{grid-column:1/-1;font-size:1.125rem;line-height:1.5rem;color:#fff;margin-top:24px}.settings-module__description___SrDvZ_quickDaddDtoDplaylist{font-size:.875rem;line-height:1.25rem}.settings-module__inputWrapper___a0OZK_quickDaddDtoDplaylist{display:flex;justify-self:end}
+ `.trim(),document.head.appendChild(e))})();
\ No newline at end of file
diff --git a/package.json b/package.json
index ea034e7..b71ae16 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,28 @@
{
"name": "quick-add-to-playlist",
- "version": "1.0.3",
+ "version": "1.1.0",
"private": true,
"scripts": {
"build": "spicetify-creator",
"build-local": "spicetify-creator --out=dist --minify",
- "watch": "spicetify-creator --watch"
+ "watch": "spicetify-creator --watch",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "eslint . --ext .ts,.tsx --fix"
},
"license": "MIT",
"devDependencies": {
- "@types/react": "^18.2.9",
+ "@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
- "spicetify-creator": "^1.0.13"
+ "@typescript-eslint/eslint-plugin": "^5.59.9",
+ "eslint": "^8.42.0",
+ "eslint-config-standard-with-typescript": "^35.0.0",
+ "eslint-plugin-import": "^2.27.5",
+ "eslint-plugin-n": "^15.0.0",
+ "eslint-plugin-promise": "^6.1.1",
+ "spicetify-creator": "^1.0.13",
+ "typescript": "5.0.4"
+ },
+ "dependencies": {
+ "spcr-settings": "^1.1.0"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8c82256..4381261 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,15 +1,41 @@
lockfileVersion: '6.0'
+dependencies:
+ spcr-settings:
+ specifier: ^1.1.0
+ version: 1.1.0
+
devDependencies:
'@types/react':
- specifier: ^18.2.9
- version: 18.2.9
+ specifier: ^18.2.11
+ version: 18.2.11
'@types/react-dom':
specifier: ^18.2.4
version: 18.2.4
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^5.59.9
+ version: 5.59.9(@typescript-eslint/parser@5.59.9)(eslint@8.42.0)(typescript@5.0.4)
+ eslint:
+ specifier: ^8.42.0
+ version: 8.42.0
+ eslint-config-standard-with-typescript:
+ specifier: ^35.0.0
+ version: 35.0.0(@typescript-eslint/eslint-plugin@5.59.9)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.0.0)(eslint-plugin-promise@6.1.1)(eslint@8.42.0)(typescript@5.0.4)
+ eslint-plugin-import:
+ specifier: ^2.27.5
+ version: 2.27.5(@typescript-eslint/parser@5.59.9)(eslint@8.42.0)
+ eslint-plugin-n:
+ specifier: ^15.0.0
+ version: 15.0.0(eslint@8.42.0)
+ eslint-plugin-promise:
+ specifier: ^6.1.1
+ version: 6.1.1(eslint@8.42.0)
spicetify-creator:
specifier: ^1.0.13
version: 1.0.13(less@4.1.3)(postcss@8.4.24)(sass@1.63.2)(stylus@0.59.0)
+ typescript:
+ specifier: 5.0.4
+ version: 5.0.4
packages:
@@ -26,6 +52,63 @@ packages:
dev: true
optional: true
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0):
+ resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ dependencies:
+ eslint: 8.42.0
+ eslint-visitor-keys: 3.4.1
+ dev: true
+
+ /@eslint-community/regexpp@4.5.1:
+ resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+ dev: true
+
+ /@eslint/eslintrc@2.0.3:
+ resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.4
+ espree: 9.5.2
+ globals: 13.20.0
+ ignore: 5.2.4
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@eslint/js@8.42.0:
+ resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /@humanwhocodes/config-array@0.11.10:
+ resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 1.2.1
+ debug: 4.3.4
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@humanwhocodes/module-importer@1.0.1:
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+ dev: true
+
+ /@humanwhocodes/object-schema@1.2.1:
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
+ dev: true
+
/@jridgewell/gen-mapping@0.3.3:
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
engines: {node: '>=6.0.0'}
@@ -67,6 +150,27 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
+ /@nodelib/fs.scandir@2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+ dev: true
+
+ /@nodelib/fs.stat@2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /@nodelib/fs.walk@1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.15.0
+ dev: true
+
/@types/clean-css@4.2.6:
resolution: {integrity: sha512-Ze1tf+LnGPmG6hBFMi0B4TEB0mhF7EiMM5oyjLDNPE9hxrPU0W+5+bHvO+eFPA+bt0iC1zkQMoU/iGdRVjcRbw==}
dependencies:
@@ -85,6 +189,14 @@ packages:
resolution: {integrity: sha512-hw3bhStrg5e3FQT8qZKCJTrzt/UbEaunU1xRWJ+aNOTmeBMvE3S4Ml2HiiNnZgL8izu0LFVkHUoPFXL1s5QNpQ==}
dev: true
+ /@types/json-schema@7.0.12:
+ resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
+ dev: true
+
+ /@types/json5@0.0.29:
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ dev: true
+
/@types/minify@8.0.0:
resolution: {integrity: sha512-gjkm4vR7KC4raQ/Q9GmWEtDSOvoUa5tV6e/1zRFMmRFe5er6OSMFlkpIXzQNdBS4Qk6H1Y7OCR8J4ur3s0UapA==}
dependencies:
@@ -103,16 +215,29 @@ packages:
/@types/prop-types@15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
- dev: true
+
+ /@types/react-dom@17.0.20:
+ resolution: {integrity: sha512-4pzIjSxDueZZ90F52mU3aPoogkHIoSIDG+oQ+wQK7Cy2B9S+MvOqY0uEA/qawKz381qrEDkvpwyt8Bm31I8sbA==}
+ dependencies:
+ '@types/react': 17.0.60
+ dev: false
/@types/react-dom@18.2.4:
resolution: {integrity: sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==}
dependencies:
- '@types/react': 18.2.9
+ '@types/react': 18.2.11
dev: true
- /@types/react@18.2.9:
- resolution: {integrity: sha512-pL3JAesUkF7PEQGxh5XOwdXGV907te6m1/Qe1ERJLgomojS6Ne790QiA7GUl434JEkFA2aAaB6qJ5z4e1zJn/w==}
+ /@types/react@17.0.60:
+ resolution: {integrity: sha512-pCH7bqWIfzHs3D+PDs3O/COCQJka+Kcw3RnO9rFA2zalqoXg7cNjJDh6mZ7oRtY1wmY4LVwDdAbA1F7Z8tv3BQ==}
+ dependencies:
+ '@types/prop-types': 15.7.5
+ '@types/scheduler': 0.16.3
+ csstype: 3.1.2
+ dev: false
+
+ /@types/react@18.2.11:
+ resolution: {integrity: sha512-+hsJr9hmwyDecSMQAmX7drgbDpyE+EgSF6t7+5QEBAn1tQK7kl1vWZ4iRf6SjQ8lk7dyEULxUmZOIpN0W5baZA==}
dependencies:
'@types/prop-types': 15.7.5
'@types/scheduler': 0.16.3
@@ -121,6 +246,9 @@ packages:
/@types/scheduler@0.16.3:
resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
+
+ /@types/semver@7.5.0:
+ resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
dev: true
/@types/uglify-js@3.17.1:
@@ -129,12 +257,164 @@ packages:
source-map: 0.6.1
dev: true
+ /@typescript-eslint/eslint-plugin@5.59.9(@typescript-eslint/parser@5.59.9)(eslint@8.42.0)(typescript@5.0.4):
+ resolution: {integrity: sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^5.0.0
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@eslint-community/regexpp': 4.5.1
+ '@typescript-eslint/parser': 5.59.9(eslint@8.42.0)(typescript@5.0.4)
+ '@typescript-eslint/scope-manager': 5.59.9
+ '@typescript-eslint/type-utils': 5.59.9(eslint@8.42.0)(typescript@5.0.4)
+ '@typescript-eslint/utils': 5.59.9(eslint@8.42.0)(typescript@5.0.4)
+ debug: 4.3.4
+ eslint: 8.42.0
+ grapheme-splitter: 1.0.4
+ ignore: 5.2.4
+ natural-compare-lite: 1.4.0
+ semver: 7.5.1
+ tsutils: 3.21.0(typescript@5.0.4)
+ typescript: 5.0.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/parser@5.59.9(eslint@8.42.0)(typescript@5.0.4):
+ resolution: {integrity: sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 5.59.9
+ '@typescript-eslint/types': 5.59.9
+ '@typescript-eslint/typescript-estree': 5.59.9(typescript@5.0.4)
+ debug: 4.3.4
+ eslint: 8.42.0
+ typescript: 5.0.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/scope-manager@5.59.9:
+ resolution: {integrity: sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.59.9
+ '@typescript-eslint/visitor-keys': 5.59.9
+ dev: true
+
+ /@typescript-eslint/type-utils@5.59.9(eslint@8.42.0)(typescript@5.0.4):
+ resolution: {integrity: sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '*'
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 5.59.9(typescript@5.0.4)
+ '@typescript-eslint/utils': 5.59.9(eslint@8.42.0)(typescript@5.0.4)
+ debug: 4.3.4
+ eslint: 8.42.0
+ tsutils: 3.21.0(typescript@5.0.4)
+ typescript: 5.0.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/types@5.59.9:
+ resolution: {integrity: sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /@typescript-eslint/typescript-estree@5.59.9(typescript@5.0.4):
+ resolution: {integrity: sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 5.59.9
+ '@typescript-eslint/visitor-keys': 5.59.9
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.5.1
+ tsutils: 3.21.0(typescript@5.0.4)
+ typescript: 5.0.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/utils@5.59.9(eslint@8.42.0)(typescript@5.0.4):
+ resolution: {integrity: sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
+ '@types/json-schema': 7.0.12
+ '@types/semver': 7.5.0
+ '@typescript-eslint/scope-manager': 5.59.9
+ '@typescript-eslint/types': 5.59.9
+ '@typescript-eslint/typescript-estree': 5.59.9(typescript@5.0.4)
+ eslint: 8.42.0
+ eslint-scope: 5.1.1
+ semver: 7.5.1
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
+ /@typescript-eslint/visitor-keys@5.59.9:
+ resolution: {integrity: sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.59.9
+ eslint-visitor-keys: 3.4.1
+ dev: true
+
+ /acorn-jsx@5.3.2(acorn@8.8.2):
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ acorn: 8.8.2
+ dev: true
+
/acorn@8.8.2:
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
+ /ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+ dev: true
+
+ /ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+ dev: true
+
/ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
@@ -150,6 +430,53 @@ packages:
picomatch: 2.3.1
dev: true
+ /argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ dev: true
+
+ /array-buffer-byte-length@1.0.0:
+ resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
+ dependencies:
+ call-bind: 1.0.2
+ is-array-buffer: 3.0.2
+ dev: true
+
+ /array-includes@3.1.6:
+ resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ get-intrinsic: 1.2.1
+ is-string: 1.0.7
+ dev: true
+
+ /array-union@2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /array.prototype.flat@1.3.1:
+ resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ es-shim-unscopables: 1.0.0
+ dev: true
+
+ /array.prototype.flatmap@1.3.1:
+ resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ es-shim-unscopables: 1.0.0
+ dev: true
+
/at-least-node@1.0.0:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
engines: {node: '>= 4.0.0'}
@@ -171,6 +498,11 @@ packages:
postcss-value-parser: 4.2.0
dev: true
+ /available-typed-arrays@1.0.5:
+ resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
/balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
@@ -209,6 +541,18 @@ packages:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
+ /call-bind@1.0.2:
+ resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+ dependencies:
+ function-bind: 1.1.1
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+ dev: true
+
/caniuse-lite@1.0.30001497:
resolution: {integrity: sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw==}
dev: true
@@ -268,6 +612,15 @@ packages:
is-what: 3.14.1
dev: true
+ /cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+ dev: true
+
/cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@@ -276,7 +629,6 @@ packages:
/csstype@3.1.2:
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
- dev: true
/cwd@0.10.0:
resolution: {integrity: sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==}
@@ -296,7 +648,6 @@ packages:
dependencies:
ms: 2.1.3
dev: true
- optional: true
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
@@ -310,6 +661,39 @@ packages:
ms: 2.1.2
dev: true
+ /deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+ dev: true
+
+ /define-properties@1.2.0:
+ resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-property-descriptors: 1.0.0
+ object-keys: 1.1.1
+ dev: true
+
+ /dir-glob@3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-type: 4.0.0
+ dev: true
+
+ /doctrine@2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
+ /doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
/electron-to-chromium@1.4.425:
resolution: {integrity: sha512-wv1NufHxu11zfDbY4fglYQApMswleE9FL/DSeyOyauVXDZ+Kco96JK/tPfBUaDqfRarYp2WH2hJ/5UnVywp9Jg==}
dev: true
@@ -323,6 +707,70 @@ packages:
dev: true
optional: true
+ /es-abstract@1.21.2:
+ resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ array-buffer-byte-length: 1.0.0
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ es-set-tostringtag: 2.0.1
+ es-to-primitive: 1.2.1
+ function.prototype.name: 1.1.5
+ get-intrinsic: 1.2.1
+ get-symbol-description: 1.0.0
+ globalthis: 1.0.3
+ gopd: 1.0.1
+ has: 1.0.3
+ has-property-descriptors: 1.0.0
+ has-proto: 1.0.1
+ has-symbols: 1.0.3
+ internal-slot: 1.0.5
+ is-array-buffer: 3.0.2
+ is-callable: 1.2.7
+ is-negative-zero: 2.0.2
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.2
+ is-string: 1.0.7
+ is-typed-array: 1.1.10
+ is-weakref: 1.0.2
+ object-inspect: 1.12.3
+ object-keys: 1.1.1
+ object.assign: 4.1.4
+ regexp.prototype.flags: 1.5.0
+ safe-regex-test: 1.0.0
+ string.prototype.trim: 1.2.7
+ string.prototype.trimend: 1.0.6
+ string.prototype.trimstart: 1.0.6
+ typed-array-length: 1.0.4
+ unbox-primitive: 1.0.2
+ which-typed-array: 1.1.9
+ dev: true
+
+ /es-set-tostringtag@2.0.1:
+ resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.1
+ has: 1.0.3
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /es-shim-unscopables@1.0.0:
+ resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
+ dependencies:
+ has: 1.0.3
+ dev: true
+
+ /es-to-primitive@1.2.1:
+ resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-callable: 1.2.7
+ is-date-object: 1.0.5
+ is-symbol: 1.0.4
+ dev: true
+
/esbuild-android-64@0.14.54:
resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==}
engines: {node: '>=12'}
@@ -560,59 +1008,404 @@ packages:
engines: {node: '>=6'}
dev: true
- /expand-tilde@1.2.2:
- resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==}
- engines: {node: '>=0.10.0'}
- dependencies:
- os-homedir: 1.0.2
+ /escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
dev: true
- /expand-tilde@2.0.2:
- resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==}
- engines: {node: '>=0.10.0'}
- dependencies:
- homedir-polyfill: 1.0.3
+ /eslint-config-standard-with-typescript@35.0.0(@typescript-eslint/eslint-plugin@5.59.9)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.0.0)(eslint-plugin-promise@6.1.1)(eslint@8.42.0)(typescript@5.0.4):
+ resolution: {integrity: sha512-Xa7DY9GgduZyp0qmXxBF0/dB+Vm4/DgWu1lGpNLJV2d46aCaUxTKDEnkzjUWX/1O9S0a+Dhnw7A4oI0JpYzwtw==}
+ peerDependencies:
+ '@typescript-eslint/eslint-plugin': ^5.50.0
+ eslint: ^8.0.1
+ eslint-plugin-import: ^2.25.2
+ eslint-plugin-n: ^15.0.0
+ eslint-plugin-promise: ^6.0.0
+ typescript: '*'
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 5.59.9(@typescript-eslint/parser@5.59.9)(eslint@8.42.0)(typescript@5.0.4)
+ '@typescript-eslint/parser': 5.59.9(eslint@8.42.0)(typescript@5.0.4)
+ eslint: 8.42.0
+ eslint-config-standard: 17.0.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.0.0)(eslint-plugin-promise@6.1.1)(eslint@8.42.0)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.9)(eslint@8.42.0)
+ eslint-plugin-n: 15.0.0(eslint@8.42.0)
+ eslint-plugin-promise: 6.1.1(eslint@8.42.0)
+ typescript: 5.0.4
+ transitivePeerDependencies:
+ - supports-color
dev: true
- /extend-shallow@2.0.1:
- resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
- engines: {node: '>=0.10.0'}
+ /eslint-config-standard@17.0.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.0.0)(eslint-plugin-promise@6.1.1)(eslint@8.42.0):
+ resolution: {integrity: sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==}
+ peerDependencies:
+ eslint: ^8.0.1
+ eslint-plugin-import: ^2.25.2
+ eslint-plugin-n: ^15.0.0
+ eslint-plugin-promise: ^6.0.0
dependencies:
- is-extendable: 0.1.1
+ eslint: 8.42.0
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.9)(eslint@8.42.0)
+ eslint-plugin-n: 15.0.0(eslint@8.42.0)
+ eslint-plugin-promise: 6.1.1(eslint@8.42.0)
dev: true
- /fill-range@7.0.1:
- resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
- engines: {node: '>=8'}
+ /eslint-import-resolver-node@0.3.7:
+ resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==}
dependencies:
- to-regex-range: 5.0.1
+ debug: 3.2.7
+ is-core-module: 2.12.1
+ resolve: 1.22.2
+ transitivePeerDependencies:
+ - supports-color
dev: true
- /find-file-up@0.1.3:
- resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==}
- engines: {node: '>=0.10.0'}
+ /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint@8.42.0):
+ resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
dependencies:
- fs-exists-sync: 0.1.0
- resolve-dir: 0.1.1
+ '@typescript-eslint/parser': 5.59.9(eslint@8.42.0)(typescript@5.0.4)
+ debug: 3.2.7
+ eslint: 8.42.0
+ eslint-import-resolver-node: 0.3.7
+ transitivePeerDependencies:
+ - supports-color
dev: true
- /find-pkg@0.1.2:
- resolution: {integrity: sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==}
- engines: {node: '>=0.10.0'}
+ /eslint-plugin-es@4.1.0(eslint@8.42.0):
+ resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==}
+ engines: {node: '>=8.10.0'}
+ peerDependencies:
+ eslint: '>=4.19.1'
dependencies:
- find-file-up: 0.1.3
+ eslint: 8.42.0
+ eslint-utils: 2.1.0
+ regexpp: 3.2.0
dev: true
- /fraction.js@4.2.0:
- resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
+ /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.9)(eslint@8.42.0):
+ resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 5.59.9(eslint@8.42.0)(typescript@5.0.4)
+ array-includes: 3.1.6
+ array.prototype.flat: 1.3.1
+ array.prototype.flatmap: 1.3.1
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.42.0
+ eslint-import-resolver-node: 0.3.7
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint@8.42.0)
+ has: 1.0.3
+ is-core-module: 2.12.1
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.values: 1.1.6
+ resolve: 1.22.2
+ semver: 6.3.0
+ tsconfig-paths: 3.14.2
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
dev: true
- /fs-exists-sync@0.1.0:
- resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==}
- engines: {node: '>=0.10.0'}
+ /eslint-plugin-n@15.0.0(eslint@8.42.0):
+ resolution: {integrity: sha512-cb70VSsNjteEL+sInXvlyewuE4OCW9CFmcOQKxyQzdAsoK+7pWpygf2q/Vsw/5dKSniO7qbawLjDqAakaILCIw==}
+ engines: {node: '>=12.22.0'}
+ peerDependencies:
+ eslint: '>=7.0.0'
+ dependencies:
+ eslint: 8.42.0
+ eslint-plugin-es: 4.1.0(eslint@8.42.0)
+ eslint-utils: 3.0.0(eslint@8.42.0)
+ ignore: 5.2.4
+ is-core-module: 2.12.1
+ minimatch: 3.1.2
+ resolve: 1.22.2
+ semver: 6.3.0
dev: true
- /fs-extra@9.1.0:
+ /eslint-plugin-promise@6.1.1(eslint@8.42.0):
+ resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ dependencies:
+ eslint: 8.42.0
+ dev: true
+
+ /eslint-scope@5.1.1:
+ resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
+ engines: {node: '>=8.0.0'}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 4.3.0
+ dev: true
+
+ /eslint-scope@7.2.0:
+ resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+ dev: true
+
+ /eslint-utils@2.1.0:
+ resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
+ engines: {node: '>=6'}
+ dependencies:
+ eslint-visitor-keys: 1.3.0
+ dev: true
+
+ /eslint-utils@3.0.0(eslint@8.42.0):
+ resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
+ engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
+ peerDependencies:
+ eslint: '>=5'
+ dependencies:
+ eslint: 8.42.0
+ eslint-visitor-keys: 2.1.0
+ dev: true
+
+ /eslint-visitor-keys@1.3.0:
+ resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /eslint-visitor-keys@2.1.0:
+ resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /eslint-visitor-keys@3.4.1:
+ resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /eslint@8.42.0:
+ resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ hasBin: true
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
+ '@eslint-community/regexpp': 4.5.1
+ '@eslint/eslintrc': 2.0.3
+ '@eslint/js': 8.42.0
+ '@humanwhocodes/config-array': 0.11.10
+ '@humanwhocodes/module-importer': 1.0.1
+ '@nodelib/fs.walk': 1.2.8
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.4
+ doctrine: 3.0.0
+ escape-string-regexp: 4.0.0
+ eslint-scope: 7.2.0
+ eslint-visitor-keys: 3.4.1
+ espree: 9.5.2
+ esquery: 1.5.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ globals: 13.20.0
+ graphemer: 1.4.0
+ ignore: 5.2.4
+ import-fresh: 3.3.0
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ is-path-inside: 3.0.3
+ 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.1
+ text-table: 0.2.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /espree@9.5.2:
+ resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ acorn: 8.8.2
+ acorn-jsx: 5.3.2(acorn@8.8.2)
+ eslint-visitor-keys: 3.4.1
+ dev: true
+
+ /esquery@1.5.0:
+ resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /estraverse@4.3.0:
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
+ engines: {node: '>=4.0'}
+ dev: true
+
+ /estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+ dev: true
+
+ /esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /expand-tilde@1.2.2:
+ resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ os-homedir: 1.0.2
+ dev: true
+
+ /expand-tilde@2.0.2:
+ resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ homedir-polyfill: 1.0.3
+ dev: true
+
+ /extend-shallow@2.0.1:
+ resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extendable: 0.1.1
+ dev: true
+
+ /fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ dev: true
+
+ /fast-glob@3.2.12:
+ resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+ dev: true
+
+ /fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+ dev: true
+
+ /fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+ dev: true
+
+ /fastq@1.15.0:
+ resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+ dependencies:
+ reusify: 1.0.4
+ dev: true
+
+ /file-entry-cache@6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flat-cache: 3.0.4
+ dev: true
+
+ /fill-range@7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+ dev: true
+
+ /find-file-up@0.1.3:
+ resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ fs-exists-sync: 0.1.0
+ resolve-dir: 0.1.1
+ dev: true
+
+ /find-pkg@0.1.2:
+ resolution: {integrity: sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ find-file-up: 0.1.3
+ dev: true
+
+ /find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+ dev: true
+
+ /flat-cache@3.0.4:
+ resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flatted: 3.2.7
+ rimraf: 3.0.2
+ dev: true
+
+ /flatted@3.2.7:
+ resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
+ dev: true
+
+ /for-each@0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+ dependencies:
+ is-callable: 1.2.7
+ dev: true
+
+ /fraction.js@4.2.0:
+ resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
+ dev: true
+
+ /fs-exists-sync@0.1.0:
+ resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /fs-extra@9.1.0:
resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
engines: {node: '>=10'}
dependencies:
@@ -638,12 +1431,43 @@ packages:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true
+ /function.prototype.name@1.1.5:
+ resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ functions-have-names: 1.2.3
+ dev: true
+
+ /functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ dev: true
+
/generic-names@4.0.0:
resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==}
dependencies:
loader-utils: 3.2.1
dev: true
+ /get-intrinsic@1.2.1:
+ resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
+ dependencies:
+ function-bind: 1.1.1
+ has: 1.0.3
+ has-proto: 1.0.1
+ has-symbols: 1.0.3
+ dev: true
+
+ /get-symbol-description@1.0.0:
+ resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ dev: true
+
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -651,6 +1475,13 @@ packages:
is-glob: 4.0.3
dev: true
+ /glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+ dependencies:
+ is-glob: 4.0.3
+ dev: true
+
/glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies:
@@ -680,15 +1511,82 @@ packages:
which: 1.3.1
dev: true
+ /globals@13.20.0:
+ resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ type-fest: 0.20.2
+ dev: true
+
+ /globalthis@1.0.3:
+ resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ define-properties: 1.2.0
+ dev: true
+
+ /globby@11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.2.12
+ ignore: 5.2.4
+ merge2: 1.4.1
+ slash: 3.0.0
+ dev: true
+
+ /gopd@1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+ dependencies:
+ get-intrinsic: 1.2.1
+ dev: true
+
/graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
dev: true
+ /grapheme-splitter@1.0.4:
+ resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
+ dev: true
+
+ /graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+ dev: true
+
+ /has-bigints@1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+ dev: true
+
/has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
dev: true
+ /has-property-descriptors@1.0.0:
+ resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
+ dependencies:
+ get-intrinsic: 1.2.1
+ dev: true
+
+ /has-proto@1.0.1:
+ resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /has-symbols@1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /has-tostringtag@1.0.0:
+ resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: true
+
/has@1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
@@ -724,6 +1622,11 @@ packages:
postcss: 8.4.24
dev: true
+ /ignore@5.2.4:
+ resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
+ engines: {node: '>= 4'}
+ dev: true
+
/image-size@0.5.5:
resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
engines: {node: '>=0.10.0'}
@@ -736,6 +1639,19 @@ packages:
resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==}
dev: true
+ /import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+ dev: true
+
+ /imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+ dev: true
+
/inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
@@ -751,6 +1667,29 @@ packages:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: true
+ /internal-slot@1.0.5:
+ resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.2.1
+ has: 1.0.3
+ side-channel: 1.0.4
+ dev: true
+
+ /is-array-buffer@3.0.2:
+ resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-typed-array: 1.1.10
+ dev: true
+
+ /is-bigint@1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ dependencies:
+ has-bigints: 1.0.2
+ dev: true
+
/is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
@@ -758,16 +1697,36 @@ packages:
binary-extensions: 2.2.0
dev: true
+ /is-boolean-object@1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
/is-buffer@1.1.6:
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
dev: true
+ /is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
/is-core-module@2.12.1:
resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==}
dependencies:
has: 1.0.3
dev: true
+ /is-date-object@1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
/is-extendable@0.1.1:
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
engines: {node: '>=0.10.0'}
@@ -785,11 +1744,73 @@ packages:
is-extglob: 2.1.1
dev: true
+ /is-negative-zero@2.0.2:
+ resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /is-number-object@1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
/is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
dev: true
+ /is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /is-regex@1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-shared-array-buffer@1.0.2:
+ resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: true
+
+ /is-string@1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-symbol@1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: true
+
+ /is-typed-array@1.1.10:
+ resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-weakref@1.0.2:
+ resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: true
+
/is-what@3.14.1:
resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
dev: true
@@ -803,6 +1824,28 @@ packages:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
+ /js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+ dev: true
+
+ /json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ dev: true
+
+ /json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+ dev: true
+
+ /json5@1.0.2:
+ resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.8
+ dev: true
+
/jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
dependencies:
@@ -845,15 +1888,41 @@ packages:
- supports-color
dev: true
+ /levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ dev: true
+
/loader-utils@3.2.1:
resolution: {integrity: sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==}
engines: {node: '>= 12.13.0'}
dev: true
+ /locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-locate: 5.0.0
+ dev: true
+
/lodash.camelcase@4.3.0:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
dev: true
+ /lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ dev: true
+
+ /lru-cache@6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+ dependencies:
+ yallist: 4.0.0
+ dev: true
+
/make-dir@2.1.0:
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
engines: {node: '>=6'}
@@ -864,6 +1933,19 @@ packages:
dev: true
optional: true
+ /merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /micromatch@4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+ dev: true
+
/mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
engines: {node: '>=4'}
@@ -889,7 +1971,6 @@ packages:
/ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
dev: true
- optional: true
/nanoid@3.3.6:
resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
@@ -897,6 +1978,14 @@ packages:
hasBin: true
dev: true
+ /natural-compare-lite@1.4.0:
+ resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
+ dev: true
+
+ /natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ dev: true
+
/needle@3.2.0:
resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==}
engines: {node: '>= 4.4.x'}
@@ -925,17 +2014,78 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /object-inspect@1.12.3:
+ resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
+ dev: true
+
+ /object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+ dev: true
+
+ /object.assign@4.1.4:
+ resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+ dev: true
+
+ /object.values@1.1.6:
+ resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ dev: true
+
/once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: true
+ /optionator@0.9.1:
+ resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.3
+ dev: true
+
/os-homedir@1.0.2:
resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==}
engines: {node: '>=0.10.0'}
dev: true
+ /p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ yocto-queue: 0.1.0
+ dev: true
+
+ /p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-limit: 3.1.0
+ dev: true
+
+ /parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+ dev: true
+
/parse-node-version@1.0.1:
resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
engines: {node: '>= 0.10'}
@@ -946,15 +2096,30 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+ dev: true
+
/path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
dev: true
+ /path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+ dev: true
+
/path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
+ /path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+ dev: true
+
/picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
@@ -1048,11 +2213,25 @@ packages:
source-map-js: 1.0.2
dev: true
+ /prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+ dev: true
+
/prr@1.0.1:
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
dev: true
optional: true
+ /punycode@2.3.0:
+ resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ dev: true
+
/readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
@@ -1060,6 +2239,20 @@ packages:
picomatch: 2.3.1
dev: true
+ /regexp.prototype.flags@1.5.0:
+ resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ functions-have-names: 1.2.3
+ dev: true
+
+ /regexpp@3.2.0:
+ resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
+ engines: {node: '>=8'}
+ dev: true
+
/resolve-dir@0.1.1:
resolution: {integrity: sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==}
engines: {node: '>=0.10.0'}
@@ -1081,6 +2274,11 @@ packages:
resolve: 1.22.2
dev: true
+ /resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+ dev: true
+
/resolve@1.22.2:
resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
hasBin: true
@@ -1090,6 +2288,11 @@ packages:
supports-preserve-symlinks-flag: 1.0.0
dev: true
+ /reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ dev: true
+
/rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
hasBin: true
@@ -1097,6 +2300,20 @@ packages:
glob: 7.2.3
dev: true
+ /run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ dependencies:
+ queue-microtask: 1.2.3
+ dev: true
+
+ /safe-regex-test@1.0.0:
+ resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ is-regex: 1.1.4
+ dev: true
+
/safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
dev: true
@@ -1122,6 +2339,19 @@ packages:
dev: true
optional: true
+ /semver@6.3.0:
+ resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
+ hasBin: true
+ dev: true
+
+ /semver@7.5.1:
+ resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+
/set-getter@0.1.1:
resolution: {integrity: sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==}
engines: {node: '>=0.10.0'}
@@ -1129,6 +2359,31 @@ packages:
to-object-path: 0.3.0
dev: true
+ /shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+ dependencies:
+ shebang-regex: 3.0.0
+ dev: true
+
+ /shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /side-channel@1.0.4:
+ resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.2.1
+ object-inspect: 1.12.3
+ dev: true
+
+ /slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+ dev: true
+
/source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
@@ -1151,6 +2406,13 @@ packages:
engines: {node: '>= 8'}
dev: true
+ /spcr-settings@1.1.0:
+ resolution: {integrity: sha512-aLtJDmhHRCmRBJb/gHlRkKd+7+Tz8Y1h2W26YA4vhDu/p4UEH9/1IMKDGI/7robYc512OYYfUAzYHA+tDMSCfg==}
+ dependencies:
+ '@types/react': 17.0.60
+ '@types/react-dom': 17.0.20
+ dev: false
+
/spicetify-creator@1.0.13(less@4.1.3)(postcss@8.4.24)(sass@1.63.2)(stylus@0.59.0):
resolution: {integrity: sha512-c8vVlPrQoYoaiioj+D2hXup2sGjVP//9Tyzdh3vwBkBh2IAe7jvGMkbI03jwga3W5GPBdRBzdXyKjYWNV9/GBA==}
hasBin: true
@@ -1178,6 +2440,48 @@ packages:
resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==}
dev: true
+ /string.prototype.trim@1.2.7:
+ resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ dev: true
+
+ /string.prototype.trimend@1.0.6:
+ resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ dev: true
+
+ /string.prototype.trimstart@1.0.6:
+ resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.2.0
+ es-abstract: 1.21.2
+ dev: true
+
+ /strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.1
+ dev: true
+
+ /strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+ dev: true
+
/stylus@0.59.0:
resolution: {integrity: sha512-lQ9w/XIOH5ZHVNuNbWW8D822r+/wBSO/d6XvtyHLF7LW4KaCIDeVbvn5DF8fGCJAUCwVhVi/h6J0NUcnylUEjg==}
hasBin: true
@@ -1214,6 +2518,10 @@ packages:
source-map-support: 0.5.21
dev: true
+ /text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ dev: true
+
/tmp@0.2.1:
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
engines: {node: '>=8.17.0'}
@@ -1235,16 +2543,74 @@ packages:
is-number: 7.0.0
dev: true
+ /tsconfig-paths@3.14.2:
+ resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==}
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.2
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+ dev: true
+
+ /tslib@1.14.1:
+ resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
+ dev: true
+
/tslib@2.5.3:
resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==}
dev: true
+ /tsutils@3.21.0(typescript@5.0.4):
+ resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
+ 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'
+ dependencies:
+ tslib: 1.14.1
+ typescript: 5.0.4
+ dev: true
+
+ /type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ dev: true
+
+ /type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /typed-array-length@1.0.4:
+ resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==}
+ dependencies:
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ is-typed-array: 1.1.10
+ dev: true
+
+ /typescript@5.0.4:
+ resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
+ engines: {node: '>=12.20'}
+ hasBin: true
+ dev: true
+
/uglify-js@3.17.4:
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
engines: {node: '>=0.8.0'}
hasBin: true
dev: true
+ /unbox-primitive@1.0.2:
+ resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+ dependencies:
+ call-bind: 1.0.2
+ has-bigints: 1.0.2
+ has-symbols: 1.0.3
+ which-boxed-primitive: 1.0.2
+ dev: true
+
/universalify@2.0.0:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 10.0.0'}
@@ -1261,10 +2627,38 @@ packages:
picocolors: 1.0.0
dev: true
+ /uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ dependencies:
+ punycode: 2.3.0
+ dev: true
+
/util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: true
+ /which-boxed-primitive@1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ dependencies:
+ is-bigint: 1.0.4
+ is-boolean-object: 1.1.2
+ is-number-object: 1.0.7
+ is-string: 1.0.7
+ is-symbol: 1.0.4
+ dev: true
+
+ /which-typed-array@1.1.9:
+ resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ available-typed-arrays: 1.0.5
+ call-bind: 1.0.2
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.0
+ is-typed-array: 1.1.10
+ dev: true
+
/which@1.3.1:
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
hasBin: true
@@ -1272,6 +2666,28 @@ packages:
isexe: 2.0.0
dev: true
+ /which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+ dev: true
+
+ /word-wrap@1.2.3:
+ resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true
+
+ /yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ dev: true
+
+ /yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+ dev: true
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..39a2b6e
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": [
+ "config:base"
+ ]
+}
diff --git a/src/app.tsx b/src/app.tsx
index 285fbb9..a05551e 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -1,248 +1,218 @@
-const LOCALSTORAGE_PLAYLIST_KEY = 'add_to_playlist.playlist'
-
-const ICON_PLUS = ``
-const ICON_MINUS = ``
-const ICON_LOADING = ``
-
-async function main() {
- // ==============================================================================================================
- // ==============================================================================================================
- // ==============================================================================================================
-
- // ------------------------------------------------------------
- // Wait for Spotify + Spicetify to load
-
- while (!Spicetify?.showNotification) {
- await new Promise(resolve => setTimeout(resolve, 2000))
- }
-
- // Inject CSS
- initInjectCss()
-
- // ------------------------------------------------------------
- // Create extension Button
-
- const topBarButton: Spicetify.Topbar.Button = new Spicetify.Topbar.Button(
- 'Loading...',
- ICON_LOADING,
- async (self) => {
- const track: any = Spicetify.Player.data.track
- const playlist = getPlaylistFromLocalstorage()
- if (!playlist) return
-
- // Add to playlist
- if (self.icon === ICON_PLUS) {
- Spicetify.CosmosAsync.post(`https://api.spotify.com/v1/playlists/${playlist.id}/tracks`, { uris: [track?.uri] })
- .then(() => {
- Spicetify.showNotification(`Added to ${playlist.name}`)
- updateTopBarButton(topBarButton, '-')
- })
- .catch(() => { Spicetify.showNotification(`An error has occured!`) })
-
- // Remove from playlist
- } else if (self.icon === ICON_MINUS) {
- Spicetify.CosmosAsync.del(`https://api.spotify.com/v1/playlists/${playlist.id}/tracks`, { tracks: [{ uri: track?.uri }] })
- .then(() => {
- Spicetify.showNotification(`Removed from ${playlist.name}`)
- updateTopBarButton(topBarButton, '+')
- })
- .catch(() => { Spicetify.showNotification(`An error has occured!`) })
- }
- }
- )
-
- await updateTopBar(topBarButton)
-
- // ------------------------------------------------------------
- // Event listeners: update icon (if already in playlist or not)
- // ------------------------------------------------------------
-
- // On app start
- Spicetify.Player.addEventListener('appchange', async () => {
- await updateTopBar(topBarButton)
- })
-
- // On song change
- Spicetify.Player.addEventListener("songchange", async () => {
- await updateTopBar(topBarButton)
- })
-
-
- // ==============================================================================================================
- // ==============================================================================================================
- // ==============================================================================================================
-
- // ------------------------------------------------------------
- // Create option in ContextMenu
-
- new Spicetify.ContextMenu.Item(
- 'Select playlist',
- // Anonymous function called when selecting a playlist
- async ([uri], [uid] = [], context = undefined) => {
- const oldPlaylist = getPlaylistFromLocalstorage()
- const newPlaylist = await Spicetify.CosmosAsync.get(`https://api.spotify.com/v1/playlists/${uri.split(":")[2]}`)
-
- Spicetify.LocalStorage.set(
- LOCALSTORAGE_PLAYLIST_KEY,
- JSON.stringify({
- name: newPlaylist.name,
- id: newPlaylist.id
- })
- )
-
- updateStyle(oldPlaylist? oldPlaylist.id : null, newPlaylist.id)
- Spicetify.showNotification(`Selected playlist "${newPlaylist.name}"`)
- await updateTopBar(topBarButton)
- },
- // Enable "Select playlist" only when right-clicking playlists
- ([uri]) => {
- const type = uri.split(":")[1]
- switch (type) {
- case Spicetify.URI.Type.PLAYLIST:
- case Spicetify.URI.Type.PLAYLIST_V2:
- return true
- default:
- return false
- }
- },
- 'playlist-folder'
- ).register()
-}
-
-// ==============================================================================================================
-// ==============================================================================================================
-// ==============================================================================================================
-
-// Check if current track is in playlist
-async function isCurrentTrackInSelectedPlaylist (): Promise {
- const track: any = Spicetify.Player.data.track
- const playlist = getPlaylistFromLocalstorage()
- if (!playlist) return false
- const updatedPlaylist = await Spicetify.CosmosAsync.get(`https://api.spotify.com/v1/playlists/${playlist.id}`)
-
- return updatedPlaylist.tracks.items.some((item: any) => item.track.uri === track.uri)
-}
-
-// ==============================================================================================================
-// ==============================================================================================================
-// ==============================================================================================================
-
-// Update Topbar icon/label
-async function updateTopBar (topBarButton: Spicetify.Topbar.Button): Promise {
- updateTopBarButton(topBarButton, '?')
-
- // first load: no playlist selected
- const playlist = getPlaylistFromLocalstorage()
- if (!playlist) return
-
- await isCurrentTrackInSelectedPlaylist()
- ? updateTopBarButton(topBarButton, '-')
- : updateTopBarButton(topBarButton, '+')
-}
-
-// Update Topbar.Button icon & label
-function updateTopBarButton (topBarButton: Spicetify.Topbar.Button, icon: '+' | '-' | '?'): void {
- const playlist = getPlaylistFromLocalstorage()
-
- switch (icon) {
- case '+':
- topBarButton.icon = ICON_PLUS
- topBarButton.label = `Add to ${playlist.name}`
- break
- case '-':
- topBarButton.icon = ICON_MINUS
- topBarButton.label = `Remove from ${playlist.name}`
- break
- case '?':
- topBarButton.icon = ICON_LOADING
- topBarButton.label = 'Loading...'
- break
- }
-}
-
-// ==============================================================================================================
-// ==============================================================================================================
-// ==============================================================================================================
-
-// Inject a new class used to highlight selected playlist
-function initInjectCss (): void {
- const body = document.body
- const style = document.createElement('style')
-
- // ----------------------------------------------------------
- // Avoid double injection
-
- if (!body.classList.contains('quick-add-to-playlist--selected-playlist')) {
- style.innerHTML = `
- .quick-add-to-playlist--selected-playlist {
- background-color: #1c1818 !important;
- }
-
- .quick-add-to-playlist--selected-playlist span.ListRowTitle__LineClamp-sc-1xe2if1-0:after {
- position: absolute;
- right: 10px;
- content: " (selected 📂)";
- text-align: right;
- color: gray;
- font-size: 11px;
- }
- `
-
- body.appendChild(style)
- }
-
- // ----------------------------------------------------------
- // init selected playlist style
-
- const playlist = getPlaylistFromLocalstorage()
- if (playlist) updateStyle(null, playlist.id)
-
- // ----------------------------------------------------------
- // create an observer to watch for playlist folders wrapping
-
- setTimeout(() => {
- // Select the node that will be observed for mutations
- const targetNode = document.querySelector('.main-rootlist-wrapper')
- if (!targetNode) return
-
- // Options for the observer (which mutations to observe)
- const config = { attributes: true, childList: true, subtree: true }
-
- // Callback function to execute when mutations are observed
- const callback = (mutationList: any) => {
- for (const mutation of mutationList) {
- if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
- const playlist = getPlaylistFromLocalstorage()
- if (playlist) updateStyle(null, playlist.id)
- }
- }
- }
-
- // Create an observer instance linked to the callback function
- const observer = new MutationObserver(callback)
- observer.observe(targetNode, config)
- }, 2000)
-}
-
-// Add/remove class to playlist's div container
-function updateStyle (oldPlaylistId: string | null, newPlaylistId: string | null): void {
- if (oldPlaylistId) {
- const oldPlaylistLink = document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${oldPlaylistId}"]`)
- oldPlaylistLink?.parentElement?.parentElement?.classList.remove('quick-add-to-playlist--selected-playlist')
- }
-
- if (newPlaylistId) {
- const newPlaylistLink = document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${newPlaylistId}"]`)
- newPlaylistLink?.parentElement?.parentElement?.classList.add('quick-add-to-playlist--selected-playlist')
- }
-}
-
-// ==============================================================================================================
-// ==============================================================================================================
-// ==============================================================================================================
-
-function getPlaylistFromLocalstorage () {
- return JSON.parse(Spicetify.LocalStorage.get(LOCALSTORAGE_PLAYLIST_KEY) as string)
-}
-
-export default main
+/* eslint-disable @typescript-eslint/no-misused-promises */
+import { SettingsSection } from 'spcr-settings'
+
+const LOCALSTORAGE_PLAYLIST_KEY = 'add_to_playlist.playlist'
+
+const ICON_PLUS = ''
+const ICON_MINUS = ''
+const ICON_LOADING = ''
+
+async function setupSettings (): Promise {
+ const settings = new SettingsSection('Quick add to playlist', 'quick-add-to-playlist')
+
+ settings.addInput('selected-bgcolor', 'Selected playlist background color', '#1c1818')
+
+ settings.addButton('save', 'Apply changes now', 'Apply', () => {
+ const styles = generateStyles(settings.getFieldValue('selected-bgcolor'))
+ injectStyles(styles)
+ Spicetify.showNotification('Changes applied!')
+ })
+
+ await settings.pushSettings()
+ return settings
+}
+
+function getPlaylistFromLocalstorage (): { name: string, id: string } | null {
+ return JSON.parse(Spicetify.LocalStorage.get(LOCALSTORAGE_PLAYLIST_KEY) as string) ?? null
+}
+
+async function getIsCurrentTrackInPlaylist (playlistId: string): Promise {
+ const track = Spicetify.Player.data.track
+
+ const tracks = []
+
+ let playlist: { next: string, items: unknown[] } = await Spicetify.CosmosAsync.get(`https://api.spotify.com/v1/playlists/${playlistId}/tracks?limit=100&fields=next,items(track(uri))`)
+ tracks.push(...playlist.items.map((item: any) => item.track.uri))
+
+ while (playlist.next != null) {
+ playlist = await Spicetify.CosmosAsync.get(playlist.next)
+ tracks.push(...playlist.items.map((item: any) => item.track.uri))
+ }
+
+ return tracks.includes(track?.uri)
+}
+
+async function updateTopbarButton (topbarButton: Spicetify.Topbar.Button): Promise {
+ topbarButton.icon = ICON_LOADING
+ topbarButton.label = 'Loading...'
+
+ // check if current track is in selected playlist
+ const playlist = getPlaylistFromLocalstorage()
+ if (playlist === null) return
+ const isTrackInPlaylist = await getIsCurrentTrackInPlaylist(playlist.id)
+
+ // if yes => set icon to "-"
+ if (isTrackInPlaylist) {
+ topbarButton.icon = ICON_MINUS
+ topbarButton.label = `Remove from ${playlist.name}`
+ // if no => set icon to "+"
+ } else {
+ topbarButton.icon = ICON_PLUS
+ topbarButton.label = `Add to ${playlist.name}`
+ }
+}
+
+function updateSelectedStyles (oldPlaylistId: string | null, newPlaylistId: string | null): void {
+ if (oldPlaylistId != null) {
+ const oldPlaylistLink = document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${oldPlaylistId}"]`)
+ oldPlaylistLink?.parentElement?.parentElement?.classList.remove('quick-add-to-playlist--selected-playlist')
+ }
+
+ if (newPlaylistId != null) {
+ const newPlaylistLink = document.querySelector(`[aria-describedby="onClickHintspotify:playlist:${newPlaylistId}"]`)
+ newPlaylistLink?.parentElement?.parentElement?.classList.add('quick-add-to-playlist--selected-playlist')
+ }
+}
+
+function generateStyles (selectedPlaylistBgColor: string = '#1c1818'): string {
+ return `
+ .quick-add-to-playlist--selected-playlist {
+ background-color: ${selectedPlaylistBgColor} !important;
+ border-radius: 6px;
+ }
+
+ .quick-add-to-playlist--selected-playlist span.ListRowTitle__LineClamp-sc-1xe2if1-0:after {
+ position: absolute;
+ right: 10px;
+ content: " (selected 📂)";
+ text-align: right;
+ color: gray;
+ font-size: 11px;
+ }
+ `
+}
+
+function injectStyles (styles: string): void {
+ const body = document.body
+
+ // if already injected, update it
+ const style = body.querySelector('#quick-add-to-playlist-style')
+ if (style != null) {
+ style.innerHTML = styles
+ body.appendChild(style)
+ // otherwise, initialize it
+ } else {
+ const style = document.createElement('style')
+ style.setAttribute('id', 'quick-add-to-playlist-style')
+ style.innerHTML = styles
+ body.appendChild(style)
+ }
+}
+
+// ==============================================================================================================
+// ==============================================================================================================
+// ==============================================================================================================
+
+async function main (): Promise {
+ const settings = await setupSettings()
+
+ // ------------------------------------------------------------
+ // Initialize extension's styles
+
+ const styles = generateStyles(settings.getFieldValue('selected-bgcolor'))
+ injectStyles(styles)
+
+ // ------------------------------------------------------------
+ // Create Topbar Button
+
+ const topbarButton: Spicetify.Topbar.Button = new Spicetify.Topbar.Button(
+ 'Loading...',
+ ICON_LOADING,
+ async (self) => {
+ // retrieve previously selected playlist
+ const playlist = getPlaylistFromLocalstorage()
+ if (playlist == null) return
+
+ // get current track
+ const track = Spicetify.Player.data.track
+ if (track == null) return
+
+ // if track isn't in playlist => add it
+ if (self.icon === ICON_PLUS) {
+ Spicetify.CosmosAsync.post(`https://api.spotify.com/v1/playlists/${playlist.id}/tracks`, { uris: [track?.uri] })
+ .then(() => {
+ Spicetify.showNotification(`Added to ${playlist.name}`)
+ topbarButton.icon = ICON_MINUS
+ topbarButton.label = `Remove from ${playlist.name}`
+ })
+ .catch(() => { Spicetify.showNotification('An error has occured!') })
+ // if track is in playlist => remove it
+ } else if (self.icon === ICON_MINUS) {
+ Spicetify.CosmosAsync.del(`https://api.spotify.com/v1/playlists/${playlist.id}/tracks`, { tracks: [{ uri: track?.uri }] })
+ .then(() => {
+ Spicetify.showNotification(`Removed from ${playlist.name}`)
+ topbarButton.icon = ICON_PLUS
+ topbarButton.label = `Add to ${playlist.name}`
+ })
+ .catch(() => { Spicetify.showNotification('An error has occured!') })
+ }
+ }
+ )
+
+ // update topbarButton on startup
+ await updateTopbarButton(topbarButton)
+
+ // ------------------------------------------------------------
+ // Create option in ContextMenu
+
+ new Spicetify.ContextMenu.Item(
+ 'Select playlist',
+ // anonymous function called when selecting a playlist
+ async ([uri], [uid] = [], _context = undefined) => {
+ const oldPlaylist = getPlaylistFromLocalstorage()
+ const newPlaylist: { name: string, id: string } = await Spicetify.CosmosAsync.get(`https://api.spotify.com/v1/playlists/${uri.split(':')[2]}`)
+
+ // save playlist in localStorage to persist it across app restart
+ Spicetify.LocalStorage.set(
+ LOCALSTORAGE_PLAYLIST_KEY,
+ JSON.stringify({
+ name: newPlaylist.name,
+ id: newPlaylist.id
+ })
+ )
+
+ updateSelectedStyles((oldPlaylist != null) ? oldPlaylist.id : null, newPlaylist.id)
+ Spicetify.showNotification(`Selected playlist: "${newPlaylist.name}"`)
+
+ await updateTopbarButton(topbarButton)
+ },
+ // only show when right-clicking playlists
+ ([uri]) => {
+ const type = uri.split(':')[1]
+ switch (type) {
+ case Spicetify.URI.Type.PLAYLIST:
+ case Spicetify.URI.Type.PLAYLIST_V2:
+ return true
+ default:
+ return false
+ }
+ },
+ 'playlist-folder'
+ ).register()
+
+ // ------------------------------------------------------------
+ // Create listeners
+
+ // @song-change: update Topbar icon
+ Spicetify.Player.addEventListener('songchange', async () => {
+ await updateTopbarButton(topbarButton)
+ })
+
+ // ----------------------------------------------------------
+ // Init selected playlist style
+
+ const playlist = getPlaylistFromLocalstorage()
+ if (playlist != null) updateSelectedStyles(null, playlist.id)
+}
+
+export default main
diff --git a/src/types/css-modules.d.ts b/src/types/css-modules.d.ts
index 8c454a3..7e07787 100644
--- a/src/types/css-modules.d.ts
+++ b/src/types/css-modules.d.ts
@@ -1,9 +1,9 @@
declare module '*.module.css' {
- const classes: { [key: string]: string };
- export default classes;
+ const classes: Record
+ export default classes
}
declare module '*.module.scss' {
- const classes: { [key: string]: string };
- export default classes;
+ const classes: Record
+ export default classes
}
diff --git a/src/types/spicetify.d.ts b/src/types/spicetify.d.ts
index c5d579a..fc14433 100644
--- a/src/types/spicetify.d.ts
+++ b/src/types/spicetify.d.ts
@@ -1,78 +1,78 @@
declare namespace Spicetify {
- type Metadata = Partial>;
- type ContextTrack = {
- uri: string;
- uid?: string;
- metadata?: Metadata;
- };
+ type Metadata = Partial>
+ interface ContextTrack {
+ uri: string
+ uid?: string
+ metadata?: Metadata
+ }
type ProvidedTrack = ContextTrack & {
- removed?: string[];
- blocked?: string[];
- provider?: string;
- };
+ removed?: string[]
+ blocked?: string[]
+ provider?: string
+ }
interface ContextOption {
- contextURI?: string;
- index?: number;
- trackUri?: string;
- page?: number;
- trackUid?: string;
- sortedBy?: string;
- filteredBy?: string;
- shuffleContext?: boolean;
- repeatContext?: boolean;
- repeatTrack?: boolean;
- offset?: number;
- next_page_url?: string;
- restrictions?: Record;
- referrer?: string;
- };
- type PlayerState = {
- timestamp: number;
- context_uri: string;
- context_url: string;
- context_restrictions: Record;
- index?: {
- page: number;
- track: number;
- };
- track?: ProvidedTrack;
- playback_id?: string;
- playback_quality?: string;
- playback_speed?: number;
- position_as_of_timestamp: number;
- duration: number;
- is_playing: boolean;
- is_paused: boolean;
- is_buffering: boolean;
- play_origin: {
- feature_identifier: string;
- feature_version: string;
- view_uri?: string;
- external_referrer?: string;
- referrer_identifier?: string;
- device_identifier?: string;
- };
- options: {
- shuffling_context?: boolean;
- repeating_context?: boolean;
- repeating_track?: boolean;
- };
- restrictions: Record;
- suppressions: {
- providers: string[];
- };
- debug: {
- log: string[];
- };
- prev_tracks: ProvidedTrack[];
- next_tracks: ProvidedTrack[];
- context_metadata: Metadata;
- page_metadata: Metadata;
- session_id: string;
- queue_revision: string;
+ contextURI?: string
+ index?: number
+ trackUri?: string
+ page?: number
+ trackUid?: string
+ sortedBy?: string
+ filteredBy?: string
+ shuffleContext?: boolean
+ repeatContext?: boolean
+ repeatTrack?: boolean
+ offset?: number
+ next_page_url?: string
+ restrictions?: Record
+ referrer?: string
};
+ interface PlayerState {
+ timestamp: number
+ context_uri: string
+ context_url: string
+ context_restrictions: Record
+ index?: {
+ page: number
+ track: number
+ }
+ track?: ProvidedTrack
+ playback_id?: string
+ playback_quality?: string
+ playback_speed?: number
+ position_as_of_timestamp: number
+ duration: number
+ is_playing: boolean
+ is_paused: boolean
+ is_buffering: boolean
+ play_origin: {
+ feature_identifier: string
+ feature_version: string
+ view_uri?: string
+ external_referrer?: string
+ referrer_identifier?: string
+ device_identifier?: string
+ }
+ options: {
+ shuffling_context?: boolean
+ repeating_context?: boolean
+ repeating_track?: boolean
+ }
+ restrictions: Record
+ suppressions: {
+ providers: string[]
+ }
+ debug: {
+ log: string[]
+ }
+ prev_tracks: ProvidedTrack[]
+ next_tracks: ProvidedTrack[]
+ context_metadata: Metadata
+ page_metadata: Metadata
+ session_id: string
+ queue_revision: string
+ }
namespace Player {
- /**
+ /**
* Register a listener `type` on Spicetify.Player.
*
* On default, `Spicetify.Player` always dispatch:
@@ -81,33 +81,33 @@ declare namespace Spicetify {
* - `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: {
- /**
+ 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;
- /**
+ path: string
+ /**
* App container
*/
- container: HTMLElement;
- } }) => void): void;
- /**
+ container: HTMLElement
+ } }) => void): void
+ /**
* Skip to previous track.
*/
- function back(): void;
- /**
+ function back (): void
+ /**
* An object contains all information about current track and player.
*/
- const data: PlayerState;
- /**
+ const data: PlayerState
+ /**
* Decrease a small amount of volume.
*/
- function decreaseVolume(): void;
- /**
+ function decreaseVolume (): void
+ /**
* Dispatches an event at `Spicetify.Player`.
*
* On default, `Spicetify.Player` always dispatch
@@ -116,305 +116,304 @@ declare namespace Spicetify {
* - `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>
- };
- /**
+ function dispatchEvent (event: Event): void
+ const eventListeners: Record void>>
+ /**
* Convert milisecond to `mm:ss` format
* @param milisecond
*/
- function formatTime(milisecond: number): string;
- /**
+ function formatTime (milisecond: number): string
+ /**
* Return song total duration in milisecond.
*/
- function getDuration(): number;
- /**
+ function getDuration (): number
+ /**
* Return mute state
*/
- function getMute(): boolean;
- /**
+ function getMute (): boolean
+ /**
* Return elapsed duration in milisecond.
*/
- function getProgress(): number;
- /**
+ function getProgress (): number
+ /**
* Return elapsed duration in percentage (0 to 1).
*/
- function getProgressPercent(): number;
- /**
+ function getProgressPercent (): number
+ /**
* Return current Repeat state (No repeat = 0/Repeat all = 1/Repeat one = 2).
*/
- function getRepeat(): number;
- /**
+ function getRepeat (): number
+ /**
* Return current shuffle state.
*/
- function getShuffle(): boolean;
- /**
+ function getShuffle (): boolean
+ /**
* Return track heart state.
*/
- function getHeart(): boolean;
- /**
+ function getHeart (): boolean
+ /**
* Return current volume level (0 to 1).
*/
- function getVolume(): number;
- /**
+ function getVolume (): number
+ /**
* Increase a small amount of volume.
*/
- function increaseVolume(): void;
- /**
+ function increaseVolume (): void
+ /**
* Return a boolean whether player is playing.
*/
- function isPlaying(): boolean;
- /**
+ function isPlaying (): boolean
+ /**
* Skip to next track.
*/
- function next(): void;
- /**
+ function next (): void
+ /**
* Pause track.
*/
- function pause(): void;
- /**
+ function pause (): void
+ /**
* Resume track.
*/
- function play(): void;
- /**
+ function play (): void
+ /**
* Play a track, playlist, album, etc. immediately
* @param uri Spotify URI
* @param context
* @param options
*/
- async function playUri(uri: string, context: any = {}, options: Options = {});
- /**
+ async function playUri (uri: string, context: any = {}, options: Options = {})
+ /**
* Unregister added event listener `type`.
* @param type
* @param callback
*/
- function removeEventListener(type: string, callback: (event?: Event) => void): void;
- /**
+ 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;
- /**
+ function seek (position: number): void
+ /**
* Turn mute on/off
* @param state
*/
- function setMute(state: boolean): void;
- /**
+ 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;
- /**
+ function setRepeat (mode: number): void
+ /**
* Turn shuffle on/off.
* @param state
*/
- function setShuffle(state: boolean): void;
- /**
+ function setShuffle (state: boolean): void
+ /**
* Set volume level
* @param level 0 to 1
*/
- function setVolume(level: number): void;
- /**
+ function setVolume (level: number): void
+ /**
* Seek to previous `amount` of milisecond
* @param amount in milisecond. Default: 15000.
*/
- function skipBack(amount?: number): void;
- /**
+ function skipBack (amount?: number): void
+ /**
* Seek to next `amount` of milisecond
* @param amount in milisecond. Default: 15000.
*/
- function skipForward(amount?: number): void;
- /**
+ function skipForward (amount?: number): void
+ /**
* Toggle Heart (Favourite) track state.
*/
- function toggleHeart(): void;
- /**
+ function toggleHeart (): void
+ /**
* Toggle Mute/No mute.
*/
- function toggleMute(): void;
- /**
+ function toggleMute (): void
+ /**
* Toggle Play/Pause.
*/
- function togglePlay(): void;
- /**
+ function togglePlay (): void
+ /**
* Toggle No repeat/Repeat all/Repeat one.
*/
- function toggleRepeat(): void;
- /**
+ function toggleRepeat (): void
+ /**
* Toggle Shuffle/No shuffle.
*/
- function toggleShuffle(): void;
+ function toggleShuffle (): void
}
/**
* Adds a track/album or array of tracks/albums to prioritized queue.
*/
- function addToQueue(uri: string | string[]): Promise;
+ function addToQueue (uri: string | string[]): Promise
/**
* @deprecated
*/
- const BridgeAPI: any;
+ const BridgeAPI: any
/**
* @deprecated
*/
- const CosmosAPI: any;
+ const CosmosAPI: any
/**
* Async wrappers of CosmosAPI
*/
namespace CosmosAsync {
- type Method = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "SUB";
+ type Method = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'SUB'
interface Error {
- code: number;
- error: string;
- message: string;
- stack?: string;
+ code: number
+ error: string
+ message: string
+ stack?: string
}
- type Headers = Record;
- type Body = Record;
+ type Headers = Record
+ type Body = Record
interface Response {
- body: any;
- headers: Headers;
- status: number;
- uri: string;
- static isSuccessStatus(status: number): boolean;
+ body: any
+ headers: Headers
+ status: number
+ uri: string
+ // eslint-disable-next-line @typescript-eslint/method-signature-style
+ static isSuccessStatus(status: number): boolean
}
- 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, 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;
+ 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, 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<{
- DESATURATED: string;
- LIGHT_VIBRANT: string;
- PROMINENT: string;
- VIBRANT: string;
- VIBRANT_NON_ALARMING: string;
- }>;
+ function colorExtractor (uri: string): Promise<{
+ DESATURATED: string
+ LIGHT_VIBRANT: string
+ PROMINENT: string
+ VIBRANT: string
+ VIBRANT_NON_ALARMING: string
+ }>
/**
* @deprecated
*/
- function getAblumArtColors(): any;
+ 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;
+ 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 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);
- function registerIsolatedShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void);
- function registerImportantShortcut(keys: KeysDefine, callback: (event: KeyboardEvent) => void);
- function _deregisterShortcut(keys: KeysDefine);
- function deregisterImportantShortcut(keys: KeysDefine);
+ key: string
+ ctrl?: boolean
+ shift?: boolean
+ alt?: boolean
+ meta?: boolean
+ }
+ const KEYS: Record
+ function registerShortcut (keys: KeysDefine, callback: (event: KeyboardEvent) => void)
+ function registerIsolatedShortcut (keys: KeysDefine, callback: (event: KeyboardEvent) => void)
+ function registerImportantShortcut (keys: KeysDefine, callback: (event: KeyboardEvent) => void)
+ function _deregisterShortcut (keys: KeysDefine)
+ function deregisterImportantShortcut (keys: KeysDefine)
};
/**
* @deprecated
*/
- const LiveAPI: any;
+ const LiveAPI: any
namespace LocalStorage {
- /**
+ /**
* Empties the list associated with the object of all key/value pairs, if there are any.
*/
- function clear(): void;
- /**
+ function clear (): void
+ /**
* Get key value
*/
- function get(key: string): string | null;
- /**
+ function get (key: string): string | null
+ /**
* Delete key
*/
- function remove(key: string): void;
- /**
+ function remove (key: string): void
+ /**
* Set new value for key
*/
- function set(key: string, value: string): void;
+ 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);
- name: string;
- isEnabled: boolean;
- /**
+ class Item {
+ constructor (name: string, isEnabled: boolean, onClick: (self: Item) => void)
+ name: string
+ isEnabled: boolean
+ /**
* Change item name
*/
- setName(name: string): void;
- /**
+ 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;
- /**
+ setState (isEnabled: boolean): void
+ /**
* Item is only available in Profile menu when method "register" is called.
*/
- register(): void;
- /**
+ register (): void
+ /**
* Stop item to be prepended into Profile menu.
*/
- deregister(): void;
- }
+ 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;
- /**
+ class SubMenu {
+ constructor (name: string, subItems: Item[])
+ name: string
+ /**
* Change SubMenu name
*/
- setName(name: string): void;
- /**
+ setName (name: string): void
+ /**
* Add an item to sub items list
*/
- addItem(item: Item);
- /**
+ addItem (item: Item)
+ /**
* Remove an item from sub items list
*/
- removeItem(item: Item);
- /**
+ removeItem (item: Item)
+ /**
* SubMenu is only available in Profile menu when method "register" is called.
*/
- register(): void;
- /**
+ register (): void
+ /**
* Stop SubMenu to be prepended into Profile menu.
*/
- deregister(): void;
- }
+ deregister (): void
+ }
}
/**
@@ -425,124 +424,125 @@ declare namespace Spicetify {
* 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;
+ function Mousetrap (element?: any): void
/**
* Contains vast array of internal APIs.
* Please explore in Devtool Console.
*/
- const Platform: any;
+ 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;
- };
+ nextTracks: any[]
+ prevTracks: any[]
+ queueRevision: string
+ track: any
+ }
/**
* Remove a track/album or array of tracks/albums from current queue.
*/
- function removeFromQueue(uri: string | string[]): Promise;
+ function removeFromQueue (uri: string | string[]): Promise
/**
* Display a bubble of notification. Useful for a visual feedback.
*/
- function showNotification(text: string): void;
+ function showNotification (text: string): void
/**
* Set of APIs method to parse and validate URIs.
*/
class URI {
- constructor(type: string, props: any);
- public type: string;
- public id: string;
+ constructor (type: string, props: any)
+ public type: string
+ public id: string
- /**
+ /**
* Creates an application URI object from the current URI object.
*
* If the current URI object is already an application type, a copy is made.
*
* @return The current URI as an application URI.
*/
- toAppType(): URI;
+ toAppType (): URI
- /**
+ /**
* Creates a URI object from an application URI object.
*
* If the current URI object is not an application type, a copy is made.
*
* @return The current URI as a real typed URI.
*/
- toRealType(): URI;
+ toRealType (): URI
- /**
+ /**
*
* @return The URI representation of this uri.
*/
- toURI(): string;
+ toURI (): string
- /**
+ /**
*
* @return The URI representation of this uri.
*/
- toString(): string;
+ 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;
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ toURLPath (opt_leadingSlash: boolean): string
- /**
+ /**
*
* @return The Play URL string for the uri.
*/
- toPlayURL(): string;
+ toPlayURL (): string
- /**
+ /**
*
* @return The URL string for the uri.
*/
- toURL(): string;
+ toURL (): string
- /**
+ /**
*
* @return The Open URL string for the uri.
*/
- toOpenURL(): string;
+ toOpenURL (): string
- /**
+ /**
*
* @return The Play HTTPS URL string for the uri.
*/
- toSecurePlayURL(): string;
+ toSecurePlayURL (): string
- /**
+ /**
*
* @return The HTTPS URL string for the uri.
*/
- toSecureURL(): string;
+ toSecureURL (): string
- /**
+ /**
*
* @return The Open HTTPS URL string for the uri.
*/
- toSecureOpenURL(): string;
+ toSecureOpenURL (): string
- /**
+ /**
*
* @return The id of the uri as a bytestring.
*/
- idToByteString(): string;
+ idToByteString (): string
- getPath(): string;
+ getPath (): string
- getBase62Id(): string;
+ getBase62Id (): string
- /**
+ /**
* Checks whether two URI:s refer to the same thing even though they might
* not necessarily be equal.
*
@@ -554,75 +554,75 @@ declare namespace Spicetify {
* @param uri The uri to compare identity for.
* @return Whether they shared idenitity
*/
- isSameIdentity(uri: any): boolean;
+ isSameIdentity (uri: any): boolean
- /**
+ /**
* 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: {
- EMPTY: string;
- ALBUM: string;
- AD: string;
- /** URI particle; not an actual URI. */
- APP: string;
- APPLICATION: string;
- ARTIST: string;
- ARTIST_TOPLIST: string;
- AUDIO_FILE: string;
- COLLECTION: string;
- COLLECTION_ALBUM: string;
- COLLECTION_MISSING_ALBUM: string;
- COLLECTION_ARTIST: string;
- CONTEXT_GROUP: string;
- DAILY_MIX: string;
- EPISODE: string;
- /** URI particle; not an actual URI. */
- FACEBOOK: string;
- FOLDER: string;
- FOLLOWERS: string;
- FOLLOWING: string;
- /** URI particle; not an actual URI. */
- GLOBAL: string;
- IMAGE: string;
- INBOX: string;
- INTERRUPTION: string;
- LOCAL_ARTIST: string;
- LOCAL_ALBUM: string;
- LOCAL: string;
- LIBRARY: string;
- MOSAIC: string;
- PLAYLIST: string;
- /** Only used for URI classification. Not a valid URI fragment. */
- PLAYLIST_V2: string;
- PROFILE: string;
- PUBLISHED_ROOTLIST: string;
- RADIO: string;
- ROOTLIST: string;
- COLLECTION_TRACK_LIST: string;
- SEARCH: string;
- SHOW: string;
- SOCIAL_SESSION: string,
- CONCERT: string;
- SPECIAL: string;
- STARRED: string;
- STATION: string;
- TEMP_PLAYLIST: string;
- /** URI particle; not an actual URI. */
- TOP: string;
- TOPLIST: string;
- TRACK: string;
- TRACKSET: string;
- /** URI particle; not an actual URI. */
- USER: string;
- USER_TOPLIST: string;
- USER_TOP_TRACKS: string;
- };
-
- /**
+ static Type: {
+ EMPTY: string
+ ALBUM: string
+ AD: string
+ /** URI particle; not an actual URI. */
+ APP: string
+ APPLICATION: string
+ ARTIST: string
+ ARTIST_TOPLIST: string
+ AUDIO_FILE: string
+ COLLECTION: string
+ COLLECTION_ALBUM: string
+ COLLECTION_MISSING_ALBUM: string
+ COLLECTION_ARTIST: string
+ CONTEXT_GROUP: string
+ DAILY_MIX: string
+ EPISODE: string
+ /** URI particle; not an actual URI. */
+ FACEBOOK: string
+ FOLDER: string
+ FOLLOWERS: string
+ FOLLOWING: string
+ /** URI particle; not an actual URI. */
+ GLOBAL: string
+ IMAGE: string
+ INBOX: string
+ INTERRUPTION: string
+ LOCAL_ARTIST: string
+ LOCAL_ALBUM: string
+ LOCAL: string
+ LIBRARY: string
+ MOSAIC: string
+ PLAYLIST: string
+ /** Only used for URI classification. Not a valid URI fragment. */
+ PLAYLIST_V2: string
+ PROFILE: string
+ PUBLISHED_ROOTLIST: string
+ RADIO: string
+ ROOTLIST: string
+ COLLECTION_TRACK_LIST: string
+ SEARCH: string
+ SHOW: string
+ SOCIAL_SESSION: string
+ CONCERT: string
+ SPECIAL: string
+ STARRED: string
+ STATION: string
+ TEMP_PLAYLIST: string
+ /** URI particle; not an actual URI. */
+ TOP: string
+ TOPLIST: string
+ TRACK: string
+ TRACKSET: string
+ /** URI particle; not an actual URI. */
+ USER: string
+ USER_TOPLIST: string
+ USER_TOP_TRACKS: string
+ }
+
+ /**
* Creates a new URI object from a parsed string argument.
*
* @param str The string that will be parsed into a URI object.
@@ -630,9 +630,9 @@ declare namespace Spicetify {
* be thrown.
* @return The parsed URI object.
*/
- static fromString(str: string): URI;
+ 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
@@ -646,9 +646,9 @@ declare namespace Spicetify {
* @return The corresponding URI instance, or null if the
* passed value is not a valid value.
*/
- static from(value: any): URI | null;
+ static from (value: any): URI | null
- /**
+ /**
* Creates a new URI from a bytestring.
*
* @param type The type of the URI.
@@ -656,115 +656,116 @@ declare namespace Spicetify {
* @param opt_args Optional arguments to the URI constructor.
* @return The URI object created.
*/
- static fromByteString(type: string, idByteString: string, opt_args?: any): URI;
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ static fromByteString (type: string, idByteString: string, opt_args?: any): URI
- /**
+ /**
* Clones a given SpotifyURI instance.
*
* @param uri The uri to clone.
* @return An instance of URI.
*/
- static clone(uri: URI): URI | null;
+ static clone (uri: URI): URI | null
- /**
+ /**
* Returns the canonical representation of a username.
*
* @param username The username to encode.
* @return The encoded canonical representation of the username.
*/
- static getCanonicalUsername(username: string): string;
+ static getCanonicalUsername (username: string): string
- /**
+ /**
* Returns the non-canonical representation of a username.
*
* @param username The username to encode.
* @return The unencoded canonical representation of the username.
*/
- static getDisplayUsername(username: string): string;
+ static getDisplayUsername (username: string): string
- /**
+ /**
* 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;
+ 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;
+ static hexToId (hex: string): string
- /**
+ /**
* Creates a new empty URI.
*
* @return The empty URI.
*/
- static emptyURI(): URI;
+ static emptyURI (): URI
- /**
+ /**
* 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;
+ static albumURI (id: string, disc: number): URI
- /**
+ /**
* Creates a new 'ad' type URI.
*
* @param id The id of the ad.
* @return The ad URI.
*/
- static adURI(id: string): URI;
+ static adURI (id: string): URI
- /**
+ /**
* Creates a new 'audiofile' type URI.
*
* @param extension The extension of the audiofile.
* @param id The id of the extension.
* @return The audiofile URI.
*/
- static audioFileURI(extension: string, id: string): URI;
+ static audioFileURI (extension: string, id: string): URI
- /**
+ /**
* Creates a new 'artist' type URI.
*
* @param id The id of the artist.
* @return The artist URI.
*/
- static artistURI(id: string): URI;
+ static artistURI (id: string): URI
- /**
+ /**
* Creates a new 'artist-toplist' type URI.
*
* @param id The id of the artist.
* @param toplist The toplist type.
* @return The artist-toplist URI.
*/
- static artistToplistURI(id: string, toplist: string): URI;
+ static artistToplistURI (id: string, toplist: string): URI
- /**
+ /**
* Creates a new 'dailymix' type URI.
*
* @param args An array of arguments for the dailymix.
* @return The dailymix URI.
*/
- static dailyMixURI(args: string[]): URI;
+ static dailyMixURI (args: string[]): URI
- /**
+ /**
* Creates a new 'search' type URI.
*
* @param query The unencoded search query.
* @return The search URI
*/
- static searchURI(query: string): URI;
+ static searchURI (query: string): URI
- /**
+ /**
* Creates a new 'track' type URI.
*
* @param id The id of the track.
@@ -773,9 +774,9 @@ declare namespace Spicetify {
* @param play Toggles autoplay
* @return The track URI.
*/
- static trackURI(id: string, anchor: string, context: string, play: boolean): URI;
+ static trackURI (id: string, anchor: string, context: string, play: boolean): URI
- /**
+ /**
* Creates a new 'trackset' type URI.
*
* @param tracks An array of 'track' type URIs.
@@ -783,94 +784,94 @@ declare namespace Spicetify {
* @param index The index in the trackset.
* @return The trackset URI.
*/
- static tracksetURI(tracks: URI[], name: string, index: number): URI;
+ static tracksetURI (tracks: URI[], name: string, index: number): URI
- /**
+ /**
* Creates a new 'facebook' type URI.
*
* @param uid The user id.
* @return The facebook URI.
*/
- static facebookURI(uid: string): URI;
+ static facebookURI (uid: string): URI
- /**
+ /**
* Creates a new 'followers' type URI.
*
* @param username The non-canonical username.
* @return The followers URI.
*/
- static followersURI(username: string): URI;
+ static followersURI (username: string): URI
- /**
+ /**
* Creates a new 'following' type URI.
*
* @param username The non-canonical username.
* @return The following URI.
*/
- static followingURI(username: string): URI;
+ static followingURI (username: string): URI
- /**
+ /**
* Creates a new 'playlist' type URI.
*
* @param username The non-canonical username of the playlist owner.
* @param id The id of the playlist.
* @return The playlist URI.
*/
- static playlistURI(username: string, id: string): URI;
+ static playlistURI (username: string, id: 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;
+ static playlistV2URI (id: string): URI
- /**
+ /**
* Creates a new 'folder' type URI.
*
* @param username The non-canonical username of the folder owner.
* @param id The id of the folder.
* @return The folder URI.
*/
- static folderURI(username: string, id: string): URI;
+ static folderURI (username: string, id: string): URI
- /**
+ /**
* Creates a new 'collectiontracklist' type URI.
*
* @param username The non-canonical username of the collection owner.
* @param id The id of the tracklist.
* @return The collectiontracklist URI.
*/
- static collectionTrackList(username: string, id: string): URI;
+ static collectionTrackList (username: string, id: string): URI
- /**
+ /**
* Creates a new 'starred' type URI.
*
* @param username The non-canonical username of the starred list owner.
* @return The starred URI.
*/
- static starredURI(username: string): URI;
+ static starredURI (username: string): 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 userToplistURI (username: string, toplist: string): URI
- /**
+ /**
* Creates a new 'user-top-tracks' type URI.
*
* @deprecated
* @param username The non-canonical username of the toplist owner.
* @return The user-top-tracks URI.
*/
- static userTopTracksURI(username: string): URI;
+ static userTopTracksURI (username: string): URI
- /**
+ /**
* Creates a new 'toplist' type URI.
*
* @param toplist The toplist type.
@@ -878,50 +879,50 @@ declare namespace Spicetify {
* @param global True if this is a global rather than a country list.
* @return The toplist URI.
*/
- static toplistURI(toplist: string, country: string, global: boolean): URI;
+ static toplistURI (toplist: string, country: string, global: boolean): URI
- /**
+ /**
* Creates a new 'inbox' type URI.
*
* @param username The non-canonical username of the inbox owner.
* @return The inbox URI.
*/
- static inboxURI(username: string): URI;
+ static inboxURI (username: string): URI
- /**
+ /**
* Creates a new 'rootlist' type URI.
*
* @param username The non-canonical username of the rootlist owner.
* @return The rootlist URI.
*/
- static rootlistURI(username: string): URI;
+ static rootlistURI (username: string): URI
- /**
+ /**
* Creates a new 'published-rootlist' type URI.
*
* @param username The non-canonical username of the published-rootlist owner.
* @return The published-rootlist URI.
*/
- static publishedRootlistURI(username: string): URI;
+ static publishedRootlistURI (username: string): URI
- /**
+ /**
* Creates a new 'local-artist' type URI.
*
* @param artist The artist name.
* @return The local-artist URI.
*/
- static localArtistURI(artist: string): URI;
+ static localArtistURI (artist: string): URI
- /**
+ /**
* Creates a new 'local-album' type URI.
*
* @param artist The artist name.
* @param album The album name.
* @return The local-album URI.
*/
- static localAlbumURI(artist: string, album: string): URI;
+ static localAlbumURI (artist: string, album: string): URI
- /**
+ /**
* Creates a new 'local' type URI.
*
* @param artist The artist name.
@@ -930,36 +931,36 @@ declare namespace Spicetify {
* @param duration The track duration in ms.
* @return The local URI.
*/
- static localURI(artist: string, album: string, track: string, duration: number): URI;
+ static localURI (artist: string, album: string, track: string, duration: number): URI
- /**
+ /**
* Creates a new 'library' type URI.
*
* @param username The non-canonical username of the rootlist owner.
* @param category The category of the library.
* @return The library URI.
*/
- static libraryURI(username: string, category: string): URI;
+ static libraryURI (username: string, category: 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;
+ static collectionURI (username: string, category: string): URI
- /**
+ /**
* Creates a new 'temp-playlist' type URI.
*
* @param origin The origin of the temporary playlist.
* @param data Additional data for the playlist.
* @return The temp-playlist URI.
*/
- static temporaryPlaylistURI(origin: string, data: string): URI;
+ static temporaryPlaylistURI (origin: string, data: string): URI
- /**
+ /**
* Creates a new 'context-group' type URI.
*
* @deprecated
@@ -967,95 +968,94 @@ declare namespace Spicetify {
* @param name The name of the context group.
* @return The context-group URI.
*/
- static contextGroupURI(origin: string, name: string): URI;
+ static contextGroupURI (origin: string, name: 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;
+ static profileURI (username: string, args: string[]): URI
- /**
+ /**
* Creates a new 'image' type URI.
*
* @param id The id of the image.
* @return The image URI.
*/
- static imageURI(id: string): URI;
-
+ static imageURI (id: string): URI
- /**
+ /**
* Creates a new 'mosaic' type URI.
*
* @param ids The ids of the mosaic immages.
* @return The mosaic URI.
*/
- static mosaicURI(ids: string[]): URI;
+ static mosaicURI (ids: string[]): URI
- /**
+ /**
* Creates a new 'radio' type URI.
*
* @param args The radio seed arguments.
* @return The radio URI.
*/
- static radioURI(args: string): URI;
+ static radioURI (args: string): URI
- /**
+ /**
* Creates a new 'special' type URI.
*
* @param args An array containing the other arguments.
* @return The special URI.
*/
- static specialURI(args: string[]): URI;
+ static specialURI (args: 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;
+ static stationURI (args: string[]): 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;
+ static applicationURI (id: string, args: 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;
+ static collectionAlbumURI (username: string, id: string): URI
- /**
+ /**
* Creates a new 'collection-album-missing' type URI.
*
* @param username The non-canonical username of the rootlist owner.
* @param id The id of the album.
* @return The collection-album-missing URI.
*/
- static collectionMissingAlbumURI(username: string, id: string): URI;
+ static collectionMissingAlbumURI (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 collectionArtistURI(username: string, id: string): URI;
+ static collectionArtistURI (username: string, id: string): URI
- /**
+ /**
* Creates a new 'episode' type URI.
*
* @param id The id of the episode.
@@ -1063,104 +1063,104 @@ declare namespace Spicetify {
* @param play Toggles autoplay in the episode URI
* @return The episode URI.
*/
- static episodeURI(id: string, context: string, play: boolean): URI;
+ static episodeURI (id: string, context: string, play: boolean): URI
- /**
+ /**
* Creates a new 'show' type URI.
*
* @param id The id of the show.
* @return The show URI.
*/
- static showURI(id: string): URI;
+ static showURI (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;
+ static concertURI (id: string): URI
- /**
+ /**
* Creates a new 'socialsession' type URI.
*
* @param id The token needed to join a social session.
* @return The socialsession URI.
*/
- static socialSessionURI(id: string): URI;
+ static socialSessionURI (id: string): URI
- /**
+ /**
* Creates a new 'interruption' type URI.
*
* @param id The id of the interruption.
* @return The ad URI.
*/
- static interruptionURI(id: string): URI;
-
- static isAlbum(uri: any): boolean;
- static isAd(uri: any): boolean;
- static isApplication(uri: any): boolean;
- static isArtist(uri: any): boolean;
- static isCollection(uri: any): boolean;
- static isCollectionAlbum(uri: any): boolean;
- static isCollectionArtist(uri: any): boolean;
- static isDailyMix(uri: any): boolean;
- static isEpisode(uri: any): boolean;
- static isFacebook(uri: any): boolean;
- static isFolder(uri: any): boolean;
- static isLocalArtist(uri: any): boolean;
- static isLocalAlbum(uri: any): boolean;
- static isLocalTrack(uri: any): boolean;
- static isMosaic(uri: any): boolean;
- static isPlaylistV1(uri: any): boolean;
- static isPlaylistV2(uri: any): boolean;
- static isRadio(uri: any): boolean;
- static isRootlist(uri: any): boolean;
- static isSearch(uri: any): boolean;
- static isShow(uri: any): boolean;
- static isConcert(uri: any): boolean;
- static isStation(uri: any): boolean;
- static isTrack(uri: any): boolean;
- static isProfile(uri: any): boolean;
- static isPlaylistV1OrV2(uri: any): boolean;
- static isSocialSession(uri: any): boolean;
- static isInterruption(uri: any): boolean;
+ static interruptionURI (id: string): URI
+
+ static isAlbum (uri: any): boolean
+ static isAd (uri: any): boolean
+ static isApplication (uri: any): boolean
+ static isArtist (uri: any): boolean
+ static isCollection (uri: any): boolean
+ static isCollectionAlbum (uri: any): boolean
+ static isCollectionArtist (uri: any): boolean
+ static isDailyMix (uri: any): boolean
+ static isEpisode (uri: any): boolean
+ static isFacebook (uri: any): boolean
+ static isFolder (uri: any): boolean
+ static isLocalArtist (uri: any): boolean
+ static isLocalAlbum (uri: any): boolean
+ static isLocalTrack (uri: any): boolean
+ static isMosaic (uri: any): boolean
+ static isPlaylistV1 (uri: any): boolean
+ static isPlaylistV2 (uri: any): boolean
+ static isRadio (uri: any): boolean
+ static isRootlist (uri: any): boolean
+ static isSearch (uri: any): boolean
+ static isShow (uri: any): boolean
+ static isConcert (uri: any): boolean
+ static isStation (uri: any): boolean
+ static isTrack (uri: any): boolean
+ static isProfile (uri: any): boolean
+ static isPlaylistV1OrV2 (uri: any): boolean
+ static isSocialSession (uri: any): boolean
+ static isInterruption (uri: any): boolean
}
/**
* Create custom menu item and prepend to right click context menu
*/
namespace ContextMenu {
- type Icon = "album" | "artist" | "block" | "chart-down" | "chart-up" | "check" | "check-alt-fill" | "chevron-left" | "chevron-right" | "chromecast-disconnected" | "copy" | "download" | "downloaded" | "edit" | "exclamation-circle" | "external-link" | "facebook" | "follow" | "fullscreen" | "grid-view" | "heart" | "heart-active" | "instagram" | "list-view" | "locked" | "locked-active" | "lyrics" | "minimize" | "more" | "new-spotify-connect" | "offline" | "pause" | "play" | "playlist" | "playlist-folder" | "plus2px" | "plus-alt" | "podcasts" | "repeat" | "repeat-once" | "search" | "search-active" | "shuffle" | "skip-back" | "skip-back15" | "skip-forward" | "skip-forward15" | "soundbetter" | "subtitles" | "twitter" | "volume" | "volume-off" | "volume-one-wave" | "volume-two-wave" | "x";
- type OnClickCallback = (uris: string[], uids?: string[], contextUri?: string) => void;
- type ShouldAddCallback = (uris: string[], uids?: string[], contextUri?: string) => boolean;
+ type Icon = 'album' | 'artist' | 'block' | 'chart-down' | 'chart-up' | 'check' | 'check-alt-fill' | 'chevron-left' | 'chevron-right' | 'chromecast-disconnected' | 'copy' | 'download' | 'downloaded' | 'edit' | 'exclamation-circle' | 'external-link' | 'facebook' | 'follow' | 'fullscreen' | 'grid-view' | 'heart' | 'heart-active' | 'instagram' | 'list-view' | 'locked' | 'locked-active' | 'lyrics' | 'minimize' | 'more' | 'new-spotify-connect' | 'offline' | 'pause' | 'play' | 'playlist' | 'playlist-folder' | 'plus2px' | 'plus-alt' | 'podcasts' | 'repeat' | 'repeat-once' | 'search' | 'search-active' | 'shuffle' | 'skip-back' | 'skip-back15' | 'skip-forward' | 'skip-forward15' | 'soundbetter' | 'subtitles' | 'twitter' | 'volume' | 'volume-off' | 'volume-one-wave' | 'volume-two-wave' | 'x'
+ 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;
- /**
+ 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;
- /**
+ shouldAdd: ShouldAddCallback
+ /**
* A function to call when item is clicked
*/
- onClick: OnClickCallback;
- /**
+ onClick: OnClickCallback
+ /**
* Item is only available in Context Menu when method "register" is called.
*/
- register: () => void;
- /**
+ register: () => void
+ /**
* Stop Item to be prepended into Context Menu.
*/
- deregister: () => void;
+ deregister: () => void
}
/**
@@ -1168,23 +1168,23 @@ declare namespace Spicetify {
* `Item`s in `subItems` array shouldn't be registered.
*/
class SubMenu {
- constructor(name: string, subItems: Iterable- , shouldAdd?: ShouldAddCallback, disabled?: boolean);
- name: string;
- disabled: boolean;
- /**
+ 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;
- /**
+ shouldAdd: ShouldAddCallback
+ addItem: (item: Item) => void
+ removeItem: (item: Item) => void
+ /**
* SubMenu is only available in Context Menu when method "register" is called.
*/
- register: () => void;
- /**
+ register: () => void
+ /**
* Stop SubMenu to be prepended into Context Menu.
*/
- deregister: () => void;
+ deregister: () => void
}
}
@@ -1192,135 +1192,135 @@ declare namespace Spicetify {
* Popup Modal
*/
namespace PopupModal {
- interface Content {
- title: string;
- /**
+ 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;
- /**
+ content: string | Element
+ /**
* Bigger window
*/
- isLarge?: boolean;
- }
+ isLarge?: boolean
+ }
- function display(e: Content): void;
- function hide(): void;
+ function display (e: Content): void
+ function hide (): void
}
/** React instance to create components */
- const React: any;
+ const React: any
/** React DOM instance to render and mount components */
- const ReactDOM: any;
+ const ReactDOM: any
/** Stock React components exposed from Spotify library */
namespace ReactComponent {
- type ContextMenuProps = {
- /**
+ interface 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;
- /**
+ renderInline?: boolean
+ /**
* Determins what will trigger the context menu. For example, a click, or a right-click
*/
- trigger?: 'click' | 'right-click';
- /**
+ trigger?: 'click' | 'right-click'
+ /**
* Determins is the context menu should open or toggle when triggered
*/
- action?: 'toggle' | 'open';
- /**
+ 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';
- /**
+ 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];
- /**
+ offset?: [number, number]
+ /**
* Will stop the client from scrolling while the context menu is open
*/
- preventScrollingWhileOpen?: boolean;
- /**
+ preventScrollingWhileOpen?: boolean
+ /**
* The menu UI to render inside of the context menu.
*/
- menu: Spicetify.ReactComponent.Menu |
- Spicetify.ReactComponent.AlbumMenu |
- Spicetify.ReactComponent.PodcastShowMenu |
- Spicetify.ReactComponent.ArtistMenu |
- Spicetify.ReactComponent.PlaylistMenu;
- /**
+ menu: Spicetify.ReactComponent.Menu |
+ Spicetify.ReactComponent.AlbumMenu |
+ Spicetify.ReactComponent.PodcastShowMenu |
+ Spicetify.ReactComponent.ArtistMenu |
+ Spicetify.ReactComponent.PlaylistMenu
+ /**
* A child of the context menu. Should be `