diff --git a/patches/youtube-music-ts-api+1.7.0.patch b/patches/youtube-music-ts-api+1.7.0.patch index a38eb537..68aa5b10 100644 --- a/patches/youtube-music-ts-api+1.7.0.patch +++ b/patches/youtube-music-ts-api+1.7.0.patch @@ -1,8 +1,52 @@ diff --git a/node_modules/youtube-music-ts-api/build/exports.d.ts b/node_modules/youtube-music-ts-api/build/exports.d.ts -index e256777..b64db02 100644 +index e256777..c151c4b 100644 --- a/node_modules/youtube-music-ts-api/build/exports.d.ts +++ b/node_modules/youtube-music-ts-api/build/exports.d.ts -@@ -112,7 +112,7 @@ declare module 'youtube-music-ts-api/interfaces-primary' { +@@ -7,7 +7,7 @@ declare module 'youtube-music-ts-api' { + } + + declare module 'youtube-music-ts-api/service/youtube-music' { +- import { IYouTubeMusic, IYouTubeMusicAuthenticated, IYouTubeMusicGuest } from "youtube-music-ts-api/interfaces-primary"; ++ import { IYouTubeMusic, IYouTubeMusicAuthenticated, IYouTubeMusicGuest, OnAuthChange } from "youtube-music-ts-api/interfaces-primary"; + /** + * Defines the main YouTube Music API object. Using this object, you can either choose to make calls as a guest or an + * authenticated user. Not all APIs are available as a guest, so it is preferred to authenticate the user if possible. +@@ -19,9 +19,10 @@ declare module 'youtube-music-ts-api/service/youtube-music' { + * @param cookiesStr The cookie string of a valid logged in user. To obtain this cookie value, log into https://music.youtube.com as a user + * and use your browser's developer tools to obtain the "cookie" value sent as a request header. Extra values in the cookie will be ignored. + * @param authUser X-Goog-AuthUser header value ++ * @param onAuthChange A callback called when cookies/authuser are updated based on YTM response + * @returns A promise that will yield authenticated access to the YouTube Music API. + */ +- authenticate(cookiesStr: string, authUser?: number): Promise; ++ authenticate(cookiesStr: string, authUser?: number, onAuthChange?: OnAuthChange): Promise; + /** + * Provides guest access to the YouTube Music API. Only non-restrictive APIs (such as public playlists) are available to guests. + * +@@ -33,6 +34,10 @@ declare module 'youtube-music-ts-api/service/youtube-music' { + + declare module 'youtube-music-ts-api/interfaces-primary' { + import { IAlbumDetail, IAlbumSummary, IArtistSummary, IPlaylistDetail, IPlaylistSummary, ITrackDetail } from "youtube-music-ts-api/interfaces-supplementary"; ++ export type OnAuthChange = (cookieStr: string, authUser: number, changed: Map) => void; + /** + * Defines the main YouTube Music API object. Using this object, you can either choose to make calls as a guest or an + * authenticated user. Not all APIs are available as a guest, so it is preferred to authenticate the user if possible. +@@ -44,9 +49,10 @@ declare module 'youtube-music-ts-api/interfaces-primary' { + * @param cookiesStr The cookie string of a valid logged in user. To obtain this cookie value, log into https://music.youtube.com as a user + * and use your browser's developer tools to obtain the "cookie" value sent as a request header. Extra values in the cookie will be ignored. + * @param authUser X-Goog-AuthUser header value ++ * @param onAuthChange A callback called when cookies/authuser are updated based on YTM response + * @returns A promise that will yield authenticated access to the YouTube Music API. + */ +- authenticate(cookiesStr: string, authUser: number): Promise; ++ authenticate(cookiesStr: string, authUser: number, onAuthChange?: OnAuthChange): Promise; + /** + * Provides guest access to the YouTube Music API. Only non-restrictive APIs (such as public playlists) are available to guests. + * +@@ -112,7 +118,7 @@ declare module 'youtube-music-ts-api/interfaces-primary' { * * @returns A promise that will yield a playlist with detailed information on a recently played tracks. */ @@ -12,7 +56,7 @@ index e256777..b64db02 100644 * Moves the specified track within the playlist. * diff --git a/node_modules/youtube-music-ts-api/build/exports.js b/node_modules/youtube-music-ts-api/build/exports.js -index ae406e1..2a8bb14 100644 +index ae406e1..a9d5481 100644 --- a/node_modules/youtube-music-ts-api/build/exports.js +++ b/node_modules/youtube-music-ts-api/build/exports.js @@ -1,2 +1,3 @@ @@ -20,5 +64,5 @@ index ae406e1..2a8bb14 100644 -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("https"),require("sha1")):"function"==typeof define&&define.amd?define(["https","sha1"],t):"object"==typeof exports?exports["youtube-music-ts-api"]=t(require("https"),require("sha1")):e["youtube-music-ts-api"]=t(e.https,e.sha1)}(global,((e,t)=>(()=>{"use strict";var s={523:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default={context:{capabilities:{},client:{clientName:"WEB_REMIX",clientVersion:"0.1",experimentIds:[],experimentsToken:"",gl:"DE",hl:"en",locationInfo:{locationPermissionAuthorizationStatus:"LOCATION_PERMISSION_AUTHORIZATION_STATUS_UNSUPPORTED"},musicAppInfo:{musicActivityMasterSwitch:"MUSIC_ACTIVITY_MASTER_SWITCH_INDETERMINATE",musicLocationMasterSwitch:"MUSIC_LOCATION_MASTER_SWITCH_INDETERMINATE",pwaInstallabilityStatus:"PWA_INSTALLABILITY_STATUS_UNKNOWN"},utcOffsetMinutes:60},request:{internalExperimentFlags:[{key:"force_music_enable_outertube_tastebuilder_browse",value:"true"},{key:"force_music_enable_outertube_playlist_detail_browse",value:"true"},{key:"force_music_enable_outertube_search_suggestions",value:"true"}],sessionIndex:{}},user:{enableSafetyMode:!1}}}},479:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var i=Object.getOwnPropertyDescriptor(t,s);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,i)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__exportStar||function(e,t){for(var s in e)"default"===s||Object.prototype.hasOwnProperty.call(t,s)||r(t,e,s)},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a=s(116);Object.defineProperty(t,"default",{enumerable:!0,get:function(){return n(a).default}}),i(s(800),t),i(s(189),t)},800:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},189:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},175:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(s(841)),n=r(s(421));class a extends i.default{constructor(){super(),this.trackParser=new n.default}parseAlbumsSummaryResponse(e){const t=[],s=this.traverse(e,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents","*","itemSectionRenderer","contents","0","gridRenderer","items");if(Array.isArray(s))for(let e=0;e{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{traverse(e,...t){if(e){if(Array.isArray(t)&&t.length>0){if(Array.isArray(e)&&"*"===t[0]){for(let s=0;s1){t=parseInt(n[1]);break}}return{id:this.traverse(e,"musicTwoRowItemRenderer","title","runs","0","navigationEndpoint","browseEndpoint","browseId"),name:this.traverse(e,"musicTwoRowItemRenderer","title","runs","0","text"),thumbnails:this.traverse(e,"musicTwoRowItemRenderer","thumbnailRenderer","musicThumbnailRenderer","thumbnail","thumbnails"),count:t}}parsePlaylistDetailResponse(e){const t=this.traverse(e,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents","0","musicPlaylistShelfRenderer");if(t)return this.parsePlaylistDetail(e,t)}parsePlaylistDetailContinuation(e,t){const s=this.traverse(t,"continuationContents","musicPlaylistShelfContinuation","contents"),r=this.trackParser.parseTrackDetails(s);Array.isArray(e.tracks)&&e.tracks.push.apply(e.tracks,r),e.continuationToken=this.traverse(t,"continuationContents","musicPlaylistShelfContinuation","continuations","0","nextContinuationData","continuation")}parsePlaylistDetail(e,t){const s=void 0===this.traverse(e,"header","musicEditablePlaylistDetailHeaderRenderer"),r=s?e:this.traverse(e,"header","musicEditablePlaylistDetailHeaderRenderer"),i=s?"PUBLIC":this.traverse(r,"editHeader","musicPlaylistEditHeaderRenderer","privacy"),n=this.traverse(r,"header","musicDetailHeaderRenderer");let a=0;const o=this.traverse(n,"secondSubtitle","runs","0","text");if(o){const e=o.split(" ");e&&e.length>0&&(a=parseInt(e[0]))}const u=this.traverse(t,"contents");return{id:this.traverse(t,"playlistId"),name:this.traverse(n,"title","runs","0","text"),description:this.traverse(n,"description","runs","0","text"),privacy:i,count:a,tracks:this.trackParser.parseTrackDetails(u),continuationToken:this.traverse(t,"continuations","0","nextContinuationData","continuation")}}mergeValidPlaylistTracks(...e){const t=[];for(const s of e)for(const e of s.tracks)this.trackParser.isTrackDataMissing(e)||t.find((t=>t.id===e.id))||t.push(e);return t}}t.default=a},421:function(e,t,s){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(s(841));class n extends i.default{parseTrackDetails(e){const t=[];if(Array.isArray(e))for(const s of e){const e=this.traverse(s,"musicResponsiveListItemRenderer");if(e){const s=this.parseTrackDetail(e);s&&s.id&&t.push(s)}}return t}parseTrackDetail(e){const t=[],s=[],r=this.traverse(e,"flexColumns","1","musicResponsiveListItemFlexColumnRenderer","text","runs");if(Array.isArray(r))for(const e of r){const r=this.traverse(e,"navigationEndpoint","browseEndpoint","browseId"),i=this.traverse(e,"text");i&&(r&&s.push({id:r,name:i}),t.push({id:r,name:i}))}let i;const n=this.traverse(e,"flexColumns","2","musicResponsiveListItemFlexColumnRenderer","text","runs","0");n&&(i={id:this.traverse(n,"navigationEndpoint","browseEndpoint","browseId"),name:this.traverse(n,"text")});const a=this.traverse(e,"fixedColumns","0","musicResponsiveListItemFixedColumnRenderer","text","simpleText")||this.traverse(e,"fixedColumns","0","musicResponsiveListItemFixedColumnRenderer","text","runs","0","text"),o=this.traverse(e,"menu","menuRenderer","topLevelButtons");let u="INDIFFERENT";if(Array.isArray(o))for(const e of o)e.likeButtonRenderer&&(u=e.likeButtonRenderer.likeStatus);return{id:this.traverse(e,"overlay","musicItemThumbnailOverlayRenderer","content","musicPlayButtonRenderer","playNavigationEndpoint","watchEndpoint","videoId"),alternateId:this.traverse(e,"playlistItemData","playlistSetVideoId"),title:this.traverse(e,"flexColumns","0","musicResponsiveListItemFlexColumnRenderer","text","runs","0","text"),artists:s.length>0?s:t,album:i,thumbnails:this.traverse(e,"thumbnail","musicThumbnailRenderer","thumbnail","thumbnails"),likeStatus:u,duration:a}}isTrackDataMissing(e){return"Song is private"==e.title}parseTracksDetailResponse(e){const t=this.traverse(e,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents","*","itemSectionRenderer","contents","0","musicShelfRenderer"),s=this.traverse(t,"contents");return{continuationToken:this.traverse(t,"continuations","0","nextContinuationData","continuation"),tracks:this.parseTrackDetails(s)}}parseTracksDetailContinuation(e,t){const s=this.traverse(t,"continuationContents","musicShelfContinuation","contents"),r=this.parseTrackDetails(s);Array.isArray(e.tracks)&&e.tracks.push.apply(e.tracks,r),e.continuationToken=this.traverse(t,"continuationContents","musicShelfContinuation","continuations","0","nextContinuationData","continuation")}parseAlbumTrackDetails(e,t,s){const r=[];for(const i of e)r.push({id:this.traverse(i,"videoId"),title:this.traverse(i,"title"),artists:t,album:s,durationMillis:parseInt(this.traverse(i,"lengthMs")),trackNumber:parseInt(this.traverse(i,"albumTrackIndex"))});return r}}t.default=n},653:function(e,t,s){var r=this&&this.__awaiter||function(e,t,s,r){return new(s||(s=Promise))((function(i,n){function a(e){try{u(r.next(e))}catch(e){n(e)}}function o(e){try{u(r.throw(e))}catch(e){n(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,o)}u((r=r.apply(e,t||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const n=i(s(26)),a=i(s(418));class o extends a.default{constructor(e,t){super(),this.cookies=e,this.authUser=t}generateHeaders(){return Object.assign(Object.assign({},super.generateHeaders()),{Authorization:this.generateAuthorization(),Cookie:this.generateCookie(),"X-Goog-AuthUser":this.authUser})}generateAuthorization(){let e=(new Date).getTime();const t=`${e} ${this.cookies.get("__Secure-3PAPISID")} ${this.origin}`;return`SAPISIDHASH ${e}_${(0,n.default)(t)}`}generateCookie(){let e="";return this.cookies.forEach((function(t,s){e&&(e+=";"),e+=s+"="+t})),e}getLibraryAlbums(){return r(this,void 0,void 0,(function*(){const e=yield this.sendRequest("browse",{browseId:"FEmusic_liked_albums"});return this.albumParser.parseAlbumsSummaryResponse(e)}))}getLibraryArtists(){return r(this,void 0,void 0,(function*(){const e=yield this.sendRequest("browse",{browseId:"FEmusic_library_corpus_track_artists"});return this.artistParser.parseArtistsSummaryResponse(e)}))}getLibraryPlaylists(){return r(this,void 0,void 0,(function*(){const e=yield this.sendRequest("browse",{browseId:"FEmusic_liked_playlists"});return this.playlistParser.parsePlaylistsSummaryResponse(e)}))}getLibraryTracks(){return r(this,void 0,void 0,(function*(){return this.getLibraryTracksInternal()}))}getLibraryTracksInternal(){return r(this,void 0,void 0,(function*(){const e={browseId:"FEmusic_liked_videos"},t=yield this.sendRequest("browse",e),s=this.trackParser.parseTracksDetailResponse(t);for(;s.continuationToken;){const t=yield this.sendRequest("browse",e,`ctoken=${s.continuationToken}&continuation=${s.continuationToken}`);this.trackParser.parseTracksDetailContinuation(s,t)}return s.tracks}))}getLibraryHistory(){return r(this,void 0,void 0,(function*(){const e=yield this.sendRequest("browse",{browseId:"FEmusic_history"}),t=this.playlistParser.traverse(e,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents"),s=[];for(const e of t)void 0!==e.musicShelfRenderer&&void 0!==e.musicShelfRenderer.contents&&e.musicShelfRenderer.contents.length>0&&s.push(e.musicShelfRenderer.contents);const r=s.flat(1);return{id:"FEmusic_history",name:"History",description:"Recently played music in reverse chronological order",privacy:"PRIVATE",count:r.length,tracks:this.trackParser.parseTrackDetails(r)}}))}createPlaylist(e,t,s,i){return r(this,void 0,void 0,(function*(){const r=yield this.sendRequest("playlist/create",{title:e,description:t,privacyStatus:s||"PRIVATE",sourcePlaylistId:this.playlistIdTrim(i)});if(r&&r.playlistId)return{id:r.playlistId,name:e,count:0}}))}deletePlaylist(e){return r(this,void 0,void 0,(function*(){return"STATUS_SUCCEEDED"===(yield this.sendRequest("playlist/delete",{playlistId:this.playlistIdTrim(e)})).status}))}addTracksToPlaylist(e,...t){return r(this,void 0,void 0,(function*(){return"STATUS_SUCCEEDED"===(yield this.sendRequest("browse/edit_playlist",{playlistId:this.playlistIdTrim(e),actions:t.map((e=>({action:"ACTION_ADD_VIDEO",addedVideoId:e.id})))})).status}))}removeTracksFromPlaylist(e,...t){return r(this,void 0,void 0,(function*(){const s=[];for(const e of t){if(!e.id)throw new Error("Track ID is missing. Ensure you have both the ID and the Alternate ID.");if(!e.alternateId)throw new Error("Track Alternate ID is missing. Ensure you have both the ID and the Alternate ID.");s.push({action:"ACTION_REMOVE_VIDEO",removedVideoId:e.id,setVideoId:e.alternateId})}return"STATUS_SUCCEEDED"===(yield this.sendRequest("browse/edit_playlist",{playlistId:this.playlistIdTrim(e),actions:s})).status}))}moveTrackWithinPlaylist(e,t,s){return r(this,void 0,void 0,(function*(){const r=[];if(!t||!t.alternateId)throw new Error("The track being moved is missing. Ensure you have specified a track to move.");return r.push({action:"ACTION_MOVE_VIDEO_BEFORE",movedSetVideoIdSuccessor:s?s.alternateId:void 0,setVideoId:t.alternateId}),"STATUS_SUCCEEDED"===(yield this.sendRequest("browse/edit_playlist",{playlistId:this.playlistIdTrim(e),actions:r})).status}))}rateTrack(e,t){return r(this,void 0,void 0,(function*(){let s;return s="LIKE"===t?"like/like":"DISLIKE"===t?"like/dislike":"like/removelike","STATUS_SUCCEEDED"===(yield this.sendRequest(s,{target:{videoId:e}})).status}))}}t.default=o},303:function(e,t,s){var r=this&&this.__createBinding||(Object.create?function(e,t,s,r){void 0===r&&(r=s);var i=Object.getOwnPropertyDescriptor(t,s);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,r,i)}:function(e,t,s,r){void 0===r&&(r=s),e[r]=t[s]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),n=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var s in e)"default"!==s&&Object.prototype.hasOwnProperty.call(e,s)&&r(t,e,s);return i(t,e),t},a=this&&this.__awaiter||function(e,t,s,r){return new(s||(s=Promise))((function(i,n){function a(e){try{u(r.next(e))}catch(e){n(e)}}function o(e){try{u(r.throw(e))}catch(e){n(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,o)}u((r=r.apply(e,t||[])).next())}))},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const u=n(s(799)),l=o(s(175)),c=o(s(304)),d=o(s(660)),h=o(s(421)),p=o(s(523));t.default=class{constructor(){this.hostname="music.youtube.com",this.basePath="/youtubei/v1/",this.queryString="?alt=json&key=AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30",this.origin="https://music.youtube.com",this.albumParser=new l.default,this.artistParser=new c.default,this.playlistParser=new d.default,this.trackParser=new h.default}generateHeaders(){return{"X-Origin":this.origin}}sendRequest(e,t,s){return a(this,void 0,void 0,(function*(){let r;t&&(t=Object.assign(Object.assign({},p.default),t),r=JSON.stringify(t));const i=s?`${this.queryString}&${s}`:this.queryString,n=yield this.sendHttpsRequest({hostname:this.hostname,path:`${this.basePath}${e}${i}`,method:"POST",headers:this.generateHeaders()},r);if(200===n.statusCode&&n.body){const e=JSON.parse(n.body);if(e)return e}throw new Error(`Could not send the specified request to ${e}. Status code: ${n.statusCode}`)}))}sendHttpsRequest(e,t){return a(this,void 0,void 0,(function*(){return new Promise(((s,r)=>{const i=e.headers||{};e.headers=i,e.timeout=6e4,t&&(i["Content-Type"]="application/json",i["Content-Length"]=t.length);const n=u.request(e,(e=>{let t="";e.on("data",(e=>{t+=e})),e.on("end",(()=>{e.body=t,s(e)}))})).on("error",(e=>{r(e)}));t&&n.write(t),n.end()}))}))}playlistIdTrim(e){return e&&e.toUpperCase().startsWith("VL")?e.substring(2):e}playlistIdPad(e){return e&&!e.toUpperCase().startsWith("VL")?"VL"+e:e}}},418:function(e,t,s){var r=this&&this.__awaiter||function(e,t,s,r){return new(s||(s=Promise))((function(i,n){function a(e){try{u(r.next(e))}catch(e){n(e)}}function o(e){try{u(r.throw(e))}catch(e){n(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,o)}u((r=r.apply(e,t||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const n=i(s(303));class a extends n.default{constructor(){super()}getAlbum(e){return r(this,void 0,void 0,(function*(){const t={browseId:e,browseEndpointContextSupportedConfigs:{browseEndpointContextMusicConfig:{pageType:"MUSIC_PAGE_TYPE_ALBUM"}}},s=yield this.sendRequest("browse",t);return this.albumParser.parseAlbumDetailResponse(s)}))}getPlaylist(e,t=0){return r(this,void 0,void 0,(function*(){const s=yield this.getPlaylistInternal(e);for(;t>0;){const r=s.tracks.length!==s.count,i=!!s.tracks.find((e=>this.trackParser.isTrackDataMissing(e)));if(!r&&!i)break;{const r=yield this.getPlaylistInternal(e),i=this.playlistParser.mergeValidPlaylistTracks(s,r);s.tracks=i,t--}}return s}))}getPlaylistInternal(e){return r(this,void 0,void 0,(function*(){const t={browseId:this.playlistIdPad(e),browseEndpointContextSupportedConfigs:{browseEndpointContextMusicConfig:{pageType:"MUSIC_PAGE_TYPE_PLAYLIST"}}},s=yield this.sendRequest("browse",t),r=this.playlistParser.parsePlaylistDetailResponse(s);for(;r.continuationToken;){const e=yield this.sendRequest("browse",t,`ctoken=${r.continuationToken}&continuation=${r.continuationToken}`);this.playlistParser.parsePlaylistDetailContinuation(r,e)}return r}))}}t.default=a},116:function(e,t,s){var r=this&&this.__awaiter||function(e,t,s,r){return new(s||(s=Promise))((function(i,n){function a(e){try{u(r.next(e))}catch(e){n(e)}}function o(e){try{u(r.throw(e))}catch(e){n(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,o)}u((r=r.apply(e,t||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const n=i(s(653)),a=i(s(418));t.default=class{authenticate(e,t=0){return r(this,void 0,void 0,(function*(){if(!e)throw new Error("The specific cookie string is missing");const s=e.split(";");if(!s||0===s.length)throw new Error("An invalid cookie string was specified");const r=new Map;for(const e of s){const t=e.split("=");t&&2===t.length&&r.set(t[0].trim(),t[1].trim())}return new n.default(r,t)}))}guest(){return r(this,void 0,void 0,(function*(){return new a.default}))}}},799:t=>{t.exports=e},26:e=>{e.exports=t}},r={};return function e(t){var i=r[t];if(void 0!==i)return i.exports;var n=r[t]={exports:{}};return s[t].call(n.exports,n,n.exports,e),n.exports}(479)})())); \ No newline at end of file +/*! For license information please see exports.js.LICENSE.txt */ -+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("https"),require("sha1")):"function"==typeof define&&define.amd?define(["https","sha1"],e):"object"==typeof exports?exports["youtube-music-ts-api"]=e(require("https"),require("sha1")):t["youtube-music-ts-api"]=e(t.https,t.sha1)}(global,((t,e)=>(()=>{"use strict";var r={611:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default={context:{capabilities:{},client:{clientName:"WEB_REMIX",clientVersion:"0.1",experimentIds:[],experimentsToken:"",gl:"DE",hl:"en",locationInfo:{locationPermissionAuthorizationStatus:"LOCATION_PERMISSION_AUTHORIZATION_STATUS_UNSUPPORTED"},musicAppInfo:{musicActivityMasterSwitch:"MUSIC_ACTIVITY_MASTER_SWITCH_INDETERMINATE",musicLocationMasterSwitch:"MUSIC_LOCATION_MASTER_SWITCH_INDETERMINATE",pwaInstallabilityStatus:"PWA_INSTALLABILITY_STATUS_UNKNOWN"},utcOffsetMinutes:60},request:{internalExperimentFlags:[{key:"force_music_enable_outertube_tastebuilder_browse",value:"true"},{key:"force_music_enable_outertube_playlist_detail_browse",value:"true"},{key:"force_music_enable_outertube_search_suggestions",value:"true"}],sessionIndex:{}},user:{enableSafetyMode:!1}}}},77:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},98:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},710:function(t,e,r){function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return i(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?i(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw a}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r{function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function n(t){return function(t){if(Array.isArray(t))return o(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return o(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?o(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function o(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1?e-1:0),o=1;o0){if(Array.isArray(t)&&"*"===r[0]){for(var i=0;i=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw a}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1){e=parseInt(a[1]);break}}return{id:this.traverse(t,"musicTwoRowItemRenderer","title","runs","0","navigationEndpoint","browseEndpoint","browseId"),name:this.traverse(t,"musicTwoRowItemRenderer","title","runs","0","text"),thumbnails:this.traverse(t,"musicTwoRowItemRenderer","thumbnailRenderer","musicThumbnailRenderer","thumbnail","thumbnails"),count:e}}},{key:"parsePlaylistDetailResponse",value:function(t){var e=this.traverse(t,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents","0","musicPlaylistShelfRenderer");if(e)return this.parsePlaylistDetail(t,e)}},{key:"parsePlaylistDetailContinuation",value:function(t,e){var r=this.traverse(e,"continuationContents","musicPlaylistShelfContinuation","contents"),n=this.trackParser.parseTrackDetails(r);Array.isArray(t.tracks)&&t.tracks.push.apply(t.tracks,n),t.continuationToken=this.traverse(e,"continuationContents","musicPlaylistShelfContinuation","continuations","0","nextContinuationData","continuation")}},{key:"parsePlaylistDetail",value:function(t,e){var r=void 0===this.traverse(t,"header","musicEditablePlaylistDetailHeaderRenderer"),n=r?t:this.traverse(t,"header","musicEditablePlaylistDetailHeaderRenderer"),o=r?"PUBLIC":this.traverse(n,"editHeader","musicPlaylistEditHeaderRenderer","privacy"),i=this.traverse(n,"header","musicDetailHeaderRenderer"),a=0,u=this.traverse(i,"secondSubtitle","runs","0","text");if(u){var s=u.split(" ");s&&s.length>0&&(a=parseInt(s[0]))}var c=this.traverse(e,"contents");return{id:this.traverse(e,"playlistId"),name:this.traverse(i,"title","runs","0","text"),description:this.traverse(i,"description","runs","0","text"),privacy:o,count:a,tracks:this.trackParser.parseTrackDetails(c),continuationToken:this.traverse(e,"continuations","0","nextContinuationData","continuation")}}},{key:"mergeValidPlaylistTracks",value:function(){for(var t=this,e=[],r=arguments.length,n=new Array(r),i=0;i=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw a}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r0?r:e,album:l,thumbnails:this.traverse(t,"thumbnail","musicThumbnailRenderer","thumbnail","thumbnails"),likeStatus:y,duration:h}}},{key:"isTrackDataMissing",value:function(t){return"Song is private"==t.title}},{key:"parseTracksDetailResponse",value:function(t){var e=this.traverse(t,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents","*","itemSectionRenderer","contents","0","musicShelfRenderer"),r=this.traverse(e,"contents");return{continuationToken:this.traverse(e,"continuations","0","nextContinuationData","continuation"),tracks:this.parseTrackDetails(r)}}},{key:"parseTracksDetailContinuation",value:function(t,e){var r=this.traverse(e,"continuationContents","musicShelfContinuation","contents"),n=this.parseTrackDetails(r);Array.isArray(t.tracks)&&t.tracks.push.apply(t.tracks,n),t.continuationToken=this.traverse(e,"continuationContents","musicShelfContinuation","continuations","0","nextContinuationData","continuation")}},{key:"parseAlbumTrackDetails",value:function(t,e,r){var n,i=[],a=o(t);try{for(a.s();!(n=a.n()).done;){var u=n.value;i.push({id:this.traverse(u,"videoId"),title:this.traverse(u,"title"),artists:e,album:r,durationMillis:parseInt(this.traverse(u,"lengthMs")),trackNumber:parseInt(this.traverse(u,"albumTrackIndex"))})}}catch(t){a.e(t)}finally{a.f()}return i}}])&&a(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),f}(c(r(445)).default);e.default=l},573:function(t,e,r){function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return i(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?i(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw a}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r=0;--i){var a=this.tryEntries[i],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=o.call(a,"catchLoc"),c=o.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&o.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:A(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function u(t,e){for(var r=0;r0&&(t?u.push({id:c.toString(),name:h.musicShelfRenderer.title.runs[0].text,description:"Recently played from ".concat(h.musicShelfRenderer.title.runs[0].text),privacy:"PRIVATE",count:h.musicShelfRenderer.contents.length,tracks:this.trackParser.parseTrackDetails(h.musicShelfRenderer.contents)}):s.push(h.musicShelfRenderer.contents)),c++}catch(t){l.e(t)}finally{l.f()}if(!t){e.next=12;break}return e.abrupt("return",u);case 12:return p=s.flat(1),e.abrupt("return",{id:"FEmusic_history",name:"History",description:"Recently played music in reverse chronological order",privacy:"PRIVATE",count:p.length,tracks:this.trackParser.parseTrackDetails(p)});case 14:case"end":return e.stop()}}),e,this)})))}},{key:"createPlaylist",value:function(t,e,r,n){return f(this,void 0,void 0,a().mark((function o(){var i;return a().wrap((function(o){for(;;)switch(o.prev=o.next){case 0:return o.next=2,this.sendRequest("playlist/create",{title:t,description:e,privacyStatus:r||"PRIVATE",sourcePlaylistId:this.playlistIdTrim(n)});case 2:if((i=o.sent)&&i.playlistId){o.next=5;break}return o.abrupt("return",void 0);case 5:return o.abrupt("return",{id:i.playlistId,name:t,count:0});case 6:case"end":return o.stop()}}),o,this)})))}},{key:"deletePlaylist",value:function(t){return f(this,void 0,void 0,a().mark((function e(){var r;return a().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.sendRequest("playlist/delete",{playlistId:this.playlistIdTrim(t)});case 2:return r=e.sent,e.abrupt("return","STATUS_SUCCEEDED"===r.status);case 4:case"end":return e.stop()}}),e,this)})))}},{key:"addTracksToPlaylist",value:function(t){for(var e=arguments.length,r=new Array(e>1?e-1:0),n=1;n1?e-1:0),n=1;n=0;--o){var a=this.tryEntries[o],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=i.call(a,"catchLoc"),c=i.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:A(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function i(t,e){for(var r=0;r=0;--o){var a=this.tryEntries[o],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=i.call(a,"catchLoc"),c=i.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:A(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function i(t,e){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:0;return s(this,void 0,void 0,o().mark((function r(){var n,i,a,u,s,c=this;return o().wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,this.getPlaylistInternal(t);case 2:n=r.sent;case 3:if(!(e>0)){r.next=18;break}if(i=n.tracks.length!==n.count,a=!!n.tracks.find((function(t){return c.trackParser.isTrackDataMissing(t)})),!i&&!a){r.next=15;break}return r.next=9,this.getPlaylistInternal(t);case 9:u=r.sent,s=this.playlistParser.mergeValidPlaylistTracks(n,u),n.tracks=s,e--,r.next=16;break;case 15:return r.abrupt("break",18);case 16:r.next=3;break;case 18:return r.abrupt("return",n);case 19:case"end":return r.stop()}}),r,this)})))}},{key:"getPlaylistInternal",value:function(t){return s(this,void 0,void 0,o().mark((function e(){var r,n,i,a;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r={browseId:this.playlistIdPad(t),browseEndpointContextSupportedConfigs:{browseEndpointContextMusicConfig:{pageType:"MUSIC_PAGE_TYPE_PLAYLIST"}}},e.next=3,this.sendRequest("browse",r);case 3:n=e.sent,i=this.playlistParser.parsePlaylistDetailResponse(n);case 5:if(!i.continuationToken){e.next=12;break}return e.next=8,this.sendRequest("browse",r,"ctoken=".concat(i.continuationToken,"&continuation=").concat(i.continuationToken));case 8:a=e.sent,this.playlistParser.parsePlaylistDetailContinuation(i,a),e.next=5;break;case 12:return e.abrupt("return",i);case 13:case"end":return e.stop()}}),e,this)})))}}],r&&i(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),h}(c(r(409)).default);e.default=l},365:function(t,e,r){function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(){o=function(){return e};var t,e={},r=Object.prototype,i=r.hasOwnProperty,a=Object.defineProperty||function(t,e,r){t[e]=r.value},u="function"==typeof Symbol?Symbol:{},s=u.iterator||"@@iterator",c=u.asyncIterator||"@@asyncIterator",l=u.toStringTag||"@@toStringTag";function f(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{f({},"")}catch(t){f=function(t,e,r){return t[e]=r}}function h(t,e,r,n){var o=e&&e.prototype instanceof g?e:g,i=Object.create(o.prototype),u=new L(n||[]);return a(i,"_invoke",{value:j(t,r,u)}),i}function p(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}e.wrap=h;var y="suspendedStart",v="suspendedYield",d="executing",m="completed",b={};function g(){}function w(){}function _(){}var x={};f(x,s,(function(){return this}));var k=Object.getPrototypeOf,S=k&&k(k(A([])));S&&S!==r&&i.call(S,s)&&(x=S);var O=_.prototype=g.prototype=Object.create(x);function E(t){["next","throw","return"].forEach((function(e){f(t,e,(function(t){return this._invoke(e,t)}))}))}function P(t,e){function r(o,a,u,s){var c=p(t[o],t,a);if("throw"!==c.type){var l=c.arg,f=l.value;return f&&"object"==n(f)&&i.call(f,"__await")?e.resolve(f.__await).then((function(t){r("next",t,u,s)}),(function(t){r("throw",t,u,s)})):e.resolve(f).then((function(t){l.value=t,u(l)}),(function(t){return r("throw",t,u,s)}))}s(c.arg)}var o;a(this,"_invoke",{value:function(t,n){function i(){return new e((function(e,o){r(t,n,e,o)}))}return o=o?o.then(i,i):i()}})}function j(e,r,n){var o=y;return function(i,a){if(o===d)throw new Error("Generator is already running");if(o===m){if("throw"===i)throw a;return{value:t,done:!0}}for(n.method=i,n.arg=a;;){var u=n.delegate;if(u){var s=R(u,n);if(s){if(s===b)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===y)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var c=p(e,r,n);if("normal"===c.type){if(o=n.done?m:v,c.arg===b)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=m,n.method="throw",n.arg=c.arg)}}}function R(e,r){var n=r.method,o=e.iterator[n];if(o===t)return r.delegate=null,"throw"===n&&e.iterator.return&&(r.method="return",r.arg=t,R(e,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),b;var i=p(o,e.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,b;var a=i.arg;return a?a.done?(r[e.resultName]=a.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,b):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,b)}function T(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function I(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function L(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(T,this),this.reset(!0)}function A(e){if(e||""===e){var r=e[s];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,a=function r(){for(;++o=0;--o){var a=this.tryEntries[o],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=i.call(a,"catchLoc"),c=i.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:A(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function i(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return a(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,i=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw i}}}}function a(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1&&void 0!==arguments[1]?arguments[1]:0;return s(this,void 0,void 0,o().mark((function r(){var n,a,u,s,c,f;return o().wrap((function(r){for(;;)switch(r.prev=r.next){case 0:if(t){r.next=2;break}throw new Error("The specific cookie string is missing");case 2:if((n=t.split(";"))&&0!==n.length){r.next=5;break}throw new Error("An invalid cookie string was specified");case 5:a=new Map,u=i(n);try{for(u.s();!(s=u.n()).done;)c=s.value,(f=c.split("="))&&2===f.length&&a.set(f[0].trim(),f[1].trim())}catch(t){u.e(t)}finally{u.f()}return r.abrupt("return",new l.default(a,e));case 9:case"end":return r.stop()}}),r)})))}},{key:"guest",value:function(){return s(this,void 0,void 0,o().mark((function t(){return o().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.abrupt("return",new f.default);case 1:case"end":return t.stop()}}),t)})))}}],r&&u(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),t}();e.default=h},479:function(t,e,r){var n=this&&this.__createBinding||(Object.create?function(t,e,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(e,r);o&&!("get"in o?!e.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,o)}:function(t,e,r,n){void 0===n&&(n=r),t[n]=e[r]}),o=this&&this.__exportStar||function(t,e){for(var r in t)"default"===r||Object.prototype.hasOwnProperty.call(e,r)||n(e,t,r)},i=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var a=r(365);Object.defineProperty(e,"default",{enumerable:!0,get:function(){return i(a).default}}),o(r(77),e),o(r(98),e)},799:e=>{e.exports=t},26:t=>{t.exports=e}},n={};return function t(e){var o=n[e];if(void 0!==o)return o.exports;var i=n[e]={exports:{}};return r[e].call(i.exports,i,i.exports,t),i.exports}(479)})())); ++!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("https"),require("sha1")):"function"==typeof define&&define.amd?define(["https","sha1"],e):"object"==typeof exports?exports["youtube-music-ts-api"]=e(require("https"),require("sha1")):t["youtube-music-ts-api"]=e(t.https,t.sha1)}(global,((t,e)=>(()=>{"use strict";var r={611:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default={context:{capabilities:{},client:{clientName:"WEB_REMIX",clientVersion:"0.1",experimentIds:[],experimentsToken:"",gl:"DE",hl:"en",locationInfo:{locationPermissionAuthorizationStatus:"LOCATION_PERMISSION_AUTHORIZATION_STATUS_UNSUPPORTED"},musicAppInfo:{musicActivityMasterSwitch:"MUSIC_ACTIVITY_MASTER_SWITCH_INDETERMINATE",musicLocationMasterSwitch:"MUSIC_LOCATION_MASTER_SWITCH_INDETERMINATE",pwaInstallabilityStatus:"PWA_INSTALLABILITY_STATUS_UNKNOWN"},utcOffsetMinutes:60},request:{internalExperimentFlags:[{key:"force_music_enable_outertube_tastebuilder_browse",value:"true"},{key:"force_music_enable_outertube_playlist_detail_browse",value:"true"},{key:"force_music_enable_outertube_search_suggestions",value:"true"}],sessionIndex:{}},user:{enableSafetyMode:!1}}}},77:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},98:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},710:function(t,e,r){function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return i(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?i(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw a}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r{function r(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1&&void 0!==arguments[1]?arguments[1]:0;if(!t)throw new Error("The specific cookie string is missing");var n=t.split(";");if(!n||0===n.length)throw new Error("An invalid cookie string was specified");var o,i=new Map,a=function(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return r(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var o=0,i=function(){};return{s:i,n:function(){return o>=t.length?{done:!0}:{done:!1,value:t[o++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==n.return||n.return()}finally{if(s)throw a}}}}(n);try{for(a.s();!(o=a.n()).done;){var u=o.value.split("=");u&&2===u.length&&i.set(u[0].trim(),u[1].trim())}}catch(t){a.e(t)}finally{a.f()}return[i,e]},e.buildCookies=function(t){var e="";return t.forEach((function(t,r){e&&(e+=";"),e+=r+"="+t})),e}},445:(t,e)=>{function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function n(t){return function(t){if(Array.isArray(t))return o(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return o(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?o(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function o(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1?e-1:0),o=1;o0){if(Array.isArray(t)&&"*"===r[0]){for(var i=0;i=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw a}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1){e=parseInt(a[1]);break}}return{id:this.traverse(t,"musicTwoRowItemRenderer","title","runs","0","navigationEndpoint","browseEndpoint","browseId"),name:this.traverse(t,"musicTwoRowItemRenderer","title","runs","0","text"),thumbnails:this.traverse(t,"musicTwoRowItemRenderer","thumbnailRenderer","musicThumbnailRenderer","thumbnail","thumbnails"),count:e}}},{key:"parsePlaylistDetailResponse",value:function(t){var e=this.traverse(t,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents","0","musicPlaylistShelfRenderer");if(e)return this.parsePlaylistDetail(t,e)}},{key:"parsePlaylistDetailContinuation",value:function(t,e){var r=this.traverse(e,"continuationContents","musicPlaylistShelfContinuation","contents"),n=this.trackParser.parseTrackDetails(r);Array.isArray(t.tracks)&&t.tracks.push.apply(t.tracks,n),t.continuationToken=this.traverse(e,"continuationContents","musicPlaylistShelfContinuation","continuations","0","nextContinuationData","continuation")}},{key:"parsePlaylistDetail",value:function(t,e){var r=void 0===this.traverse(t,"header","musicEditablePlaylistDetailHeaderRenderer"),n=r?t:this.traverse(t,"header","musicEditablePlaylistDetailHeaderRenderer"),o=r?"PUBLIC":this.traverse(n,"editHeader","musicPlaylistEditHeaderRenderer","privacy"),i=this.traverse(n,"header","musicDetailHeaderRenderer"),a=0,u=this.traverse(i,"secondSubtitle","runs","0","text");if(u){var s=u.split(" ");s&&s.length>0&&(a=parseInt(s[0]))}var c=this.traverse(e,"contents");return{id:this.traverse(e,"playlistId"),name:this.traverse(i,"title","runs","0","text"),description:this.traverse(i,"description","runs","0","text"),privacy:o,count:a,tracks:this.trackParser.parseTrackDetails(c),continuationToken:this.traverse(e,"continuations","0","nextContinuationData","continuation")}}},{key:"mergeValidPlaylistTracks",value:function(){for(var t=this,e=[],r=arguments.length,n=new Array(r),i=0;i=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,u=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return u=t.done,t},e:function(t){s=!0,a=t},f:function(){try{u||null==r.return||r.return()}finally{if(s)throw a}}}}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r0?r:e,album:l,thumbnails:this.traverse(t,"thumbnail","musicThumbnailRenderer","thumbnail","thumbnails"),likeStatus:y,duration:h}}},{key:"isTrackDataMissing",value:function(t){return"Song is private"==t.title}},{key:"parseTracksDetailResponse",value:function(t){var e=this.traverse(t,"contents","singleColumnBrowseResultsRenderer","tabs","0","tabRenderer","content","sectionListRenderer","contents","*","itemSectionRenderer","contents","0","musicShelfRenderer"),r=this.traverse(e,"contents");return{continuationToken:this.traverse(e,"continuations","0","nextContinuationData","continuation"),tracks:this.parseTrackDetails(r)}}},{key:"parseTracksDetailContinuation",value:function(t,e){var r=this.traverse(e,"continuationContents","musicShelfContinuation","contents"),n=this.parseTrackDetails(r);Array.isArray(t.tracks)&&t.tracks.push.apply(t.tracks,n),t.continuationToken=this.traverse(e,"continuationContents","musicShelfContinuation","continuations","0","nextContinuationData","continuation")}},{key:"parseAlbumTrackDetails",value:function(t,e,r){var n,i=[],a=o(t);try{for(a.s();!(n=a.n()).done;){var u=n.value;i.push({id:this.traverse(u,"videoId"),title:this.traverse(u,"title"),artists:e,album:r,durationMillis:parseInt(this.traverse(u,"lengthMs")),trackNumber:parseInt(this.traverse(u,"albumTrackIndex"))})}}catch(t){a.e(t)}finally{a.f()}return i}}])&&a(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),f}(c(r(445)).default);e.default=l},573:function(t,e,r){function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(){o=function(){return e};var t,e={},r=Object.prototype,i=r.hasOwnProperty,a=Object.defineProperty||function(t,e,r){t[e]=r.value},u="function"==typeof Symbol?Symbol:{},s=u.iterator||"@@iterator",c=u.asyncIterator||"@@asyncIterator",l=u.toStringTag||"@@toStringTag";function f(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{f({},"")}catch(t){f=function(t,e,r){return t[e]=r}}function h(t,e,r,n){var o=e&&e.prototype instanceof g?e:g,i=Object.create(o.prototype),u=new A(n||[]);return a(i,"_invoke",{value:j(t,r,u)}),i}function p(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}e.wrap=h;var y="suspendedStart",v="suspendedYield",d="executing",m="completed",b={};function g(){}function w(){}function _(){}var k={};f(k,s,(function(){return this}));var x=Object.getPrototypeOf,S=x&&x(x(L([])));S&&S!==r&&i.call(S,s)&&(k=S);var O=_.prototype=g.prototype=Object.create(k);function E(t){["next","throw","return"].forEach((function(e){f(t,e,(function(t){return this._invoke(e,t)}))}))}function P(t,e){function r(o,a,u,s){var c=p(t[o],t,a);if("throw"!==c.type){var l=c.arg,f=l.value;return f&&"object"==n(f)&&i.call(f,"__await")?e.resolve(f.__await).then((function(t){r("next",t,u,s)}),(function(t){r("throw",t,u,s)})):e.resolve(f).then((function(t){l.value=t,u(l)}),(function(t){return r("throw",t,u,s)}))}s(c.arg)}var o;a(this,"_invoke",{value:function(t,n){function i(){return new e((function(e,o){r(t,n,e,o)}))}return o=o?o.then(i,i):i()}})}function j(e,r,n){var o=y;return function(i,a){if(o===d)throw new Error("Generator is already running");if(o===m){if("throw"===i)throw a;return{value:t,done:!0}}for(n.method=i,n.arg=a;;){var u=n.delegate;if(u){var s=R(u,n);if(s){if(s===b)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===y)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var c=p(e,r,n);if("normal"===c.type){if(o=n.done?m:v,c.arg===b)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=m,n.method="throw",n.arg=c.arg)}}}function R(e,r){var n=r.method,o=e.iterator[n];if(o===t)return r.delegate=null,"throw"===n&&e.iterator.return&&(r.method="return",r.arg=t,R(e,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),b;var i=p(o,e.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,b;var a=i.arg;return a?a.done?(r[e.resultName]=a.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,b):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,b)}function T(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function I(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function A(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(T,this),this.reset(!0)}function L(e){if(e||""===e){var r=e[s];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,a=function r(){for(;++o=0;--o){var a=this.tryEntries[o],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=i.call(a,"catchLoc"),c=i.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:L(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function i(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=u(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,s=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return a=t.done,t},e:function(t){s=!0,i=t},f:function(){try{a||null==r.return||r.return()}finally{if(s)throw i}}}}function a(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],s=!0,c=!1;try{if(i=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=i.call(r)).done)&&(u.push(n.value),u.length!==e);s=!0);}catch(t){c=!0,o=t}finally{try{if(!s&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(c)throw o}}return u}}(t,e)||u(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(t,e){if(t){if("string"==typeof t)return s(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?s(t,e):void 0}}function s(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r0&&(t?u.push({id:c.toString(),name:h.musicShelfRenderer.title.runs[0].text,description:"Recently played from ".concat(h.musicShelfRenderer.title.runs[0].text),privacy:"PRIVATE",count:h.musicShelfRenderer.contents.length,tracks:this.trackParser.parseTrackDetails(h.musicShelfRenderer.contents)}):s.push(h.musicShelfRenderer.contents)),c++}catch(t){l.e(t)}finally{l.f()}if(!t){e.next=12;break}return e.abrupt("return",u);case 12:return p=s.flat(1),e.abrupt("return",{id:"FEmusic_history",name:"History",description:"Recently played music in reverse chronological order",privacy:"PRIVATE",count:p.length,tracks:this.trackParser.parseTrackDetails(p)});case 14:case"end":return e.stop()}}),e,this)})))}},{key:"createPlaylist",value:function(t,e,r,n){return p(this,void 0,void 0,o().mark((function i(){var a;return o().wrap((function(o){for(;;)switch(o.prev=o.next){case 0:return o.next=2,this.sendRequest("playlist/create",{title:t,description:e,privacyStatus:r||"PRIVATE",sourcePlaylistId:this.playlistIdTrim(n)});case 2:if((a=o.sent)&&a.playlistId){o.next=5;break}return o.abrupt("return",void 0);case 5:return o.abrupt("return",{id:a.playlistId,name:t,count:0});case 6:case"end":return o.stop()}}),i,this)})))}},{key:"deletePlaylist",value:function(t){return p(this,void 0,void 0,o().mark((function e(){var r;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.sendRequest("playlist/delete",{playlistId:this.playlistIdTrim(t)});case 2:return r=e.sent,e.abrupt("return","STATUS_SUCCEEDED"===r.status);case 4:case"end":return e.stop()}}),e,this)})))}},{key:"addTracksToPlaylist",value:function(t){for(var e=arguments.length,r=new Array(e>1?e-1:0),n=1;n1?e-1:0),n=1;n=0;--o){var a=this.tryEntries[o],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=i.call(a,"catchLoc"),c=i.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:L(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function i(t,e){for(var r=0;r=0;--o){var a=this.tryEntries[o],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=i.call(a,"catchLoc"),c=i.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:L(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function i(t,e){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:0;return s(this,void 0,void 0,o().mark((function r(){var n,i,a,u,s,c=this;return o().wrap((function(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,this.getPlaylistInternal(t);case 2:n=r.sent;case 3:if(!(e>0)){r.next=18;break}if(i=n.tracks.length!==n.count,a=!!n.tracks.find((function(t){return c.trackParser.isTrackDataMissing(t)})),!i&&!a){r.next=15;break}return r.next=9,this.getPlaylistInternal(t);case 9:u=r.sent,s=this.playlistParser.mergeValidPlaylistTracks(n,u),n.tracks=s,e--,r.next=16;break;case 15:return r.abrupt("break",18);case 16:r.next=3;break;case 18:return r.abrupt("return",n);case 19:case"end":return r.stop()}}),r,this)})))}},{key:"getPlaylistInternal",value:function(t){return s(this,void 0,void 0,o().mark((function e(){var r,n,i,a;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r={browseId:this.playlistIdPad(t),browseEndpointContextSupportedConfigs:{browseEndpointContextMusicConfig:{pageType:"MUSIC_PAGE_TYPE_PLAYLIST"}}},e.next=3,this.sendRequest("browse",r);case 3:n=e.sent,i=this.playlistParser.parsePlaylistDetailResponse(n);case 5:if(!i.continuationToken){e.next=12;break}return e.next=8,this.sendRequest("browse",r,"ctoken=".concat(i.continuationToken,"&continuation=").concat(i.continuationToken));case 8:a=e.sent,this.playlistParser.parsePlaylistDetailContinuation(i,a),e.next=5;break;case 12:return e.abrupt("return",i);case 13:case"end":return e.stop()}}),e,this)})))}}],r&&i(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),h}(c(r(409)).default);e.default=l},365:function(t,e,r){function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(){o=function(){return e};var t,e={},r=Object.prototype,i=r.hasOwnProperty,a=Object.defineProperty||function(t,e,r){t[e]=r.value},u="function"==typeof Symbol?Symbol:{},s=u.iterator||"@@iterator",c=u.asyncIterator||"@@asyncIterator",l=u.toStringTag||"@@toStringTag";function f(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{f({},"")}catch(t){f=function(t,e,r){return t[e]=r}}function h(t,e,r,n){var o=e&&e.prototype instanceof g?e:g,i=Object.create(o.prototype),u=new A(n||[]);return a(i,"_invoke",{value:j(t,r,u)}),i}function p(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}e.wrap=h;var y="suspendedStart",v="suspendedYield",d="executing",m="completed",b={};function g(){}function w(){}function _(){}var k={};f(k,s,(function(){return this}));var x=Object.getPrototypeOf,S=x&&x(x(L([])));S&&S!==r&&i.call(S,s)&&(k=S);var O=_.prototype=g.prototype=Object.create(k);function E(t){["next","throw","return"].forEach((function(e){f(t,e,(function(t){return this._invoke(e,t)}))}))}function P(t,e){function r(o,a,u,s){var c=p(t[o],t,a);if("throw"!==c.type){var l=c.arg,f=l.value;return f&&"object"==n(f)&&i.call(f,"__await")?e.resolve(f.__await).then((function(t){r("next",t,u,s)}),(function(t){r("throw",t,u,s)})):e.resolve(f).then((function(t){l.value=t,u(l)}),(function(t){return r("throw",t,u,s)}))}s(c.arg)}var o;a(this,"_invoke",{value:function(t,n){function i(){return new e((function(e,o){r(t,n,e,o)}))}return o=o?o.then(i,i):i()}})}function j(e,r,n){var o=y;return function(i,a){if(o===d)throw new Error("Generator is already running");if(o===m){if("throw"===i)throw a;return{value:t,done:!0}}for(n.method=i,n.arg=a;;){var u=n.delegate;if(u){var s=R(u,n);if(s){if(s===b)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===y)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var c=p(e,r,n);if("normal"===c.type){if(o=n.done?m:v,c.arg===b)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=m,n.method="throw",n.arg=c.arg)}}}function R(e,r){var n=r.method,o=e.iterator[n];if(o===t)return r.delegate=null,"throw"===n&&e.iterator.return&&(r.method="return",r.arg=t,R(e,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),b;var i=p(o,e.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,b;var a=i.arg;return a?a.done?(r[e.resultName]=a.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,b):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,b)}function T(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function I(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function A(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(T,this),this.reset(!0)}function L(e){if(e||""===e){var r=e[s];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,a=function r(){for(;++o=0;--o){var a=this.tryEntries[o],u=a.completion;if("root"===a.tryLoc)return n("end");if(a.tryLoc<=this.prev){var s=i.call(a,"catchLoc"),c=i.call(a,"finallyLoc");if(s&&c){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&i.call(n,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),I(r),b}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;I(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:L(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),b}},e}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2?arguments[2]:void 0;return u(this,void 0,void 0,o().mark((function n(){var a,u,s;return o().wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.prev=0,a=(0,c.parseAuth)(t,e),f=2,u=function(t){if(Array.isArray(t))return t}(o=a)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,u=[],s=!0,c=!1;try{if(i=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=i.call(r)).done)&&(u.push(n.value),u.length!==e);s=!0);}catch(t){c=!0,o=t}finally{try{if(!s&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(c)throw o}}return u}}(o,f)||function(t,e){if(t){if("string"==typeof t)return i(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?i(t,e):void 0}}(o,f)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),s=u[0],u[1],n.abrupt("return",new l.default(s,e,r));case 5:throw n.prev=5,n.t0=n.catch(0),n.t0;case 8:case"end":return n.stop()}var o,f}),n,null,[[0,5]])})))}},{key:"guest",value:function(){return u(this,void 0,void 0,o().mark((function t(){return o().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.abrupt("return",new f.default);case 1:case"end":return t.stop()}}),t)})))}}],r&&a(e.prototype,r),Object.defineProperty(e,"prototype",{writable:!1}),t}();e.default=h},479:function(t,e,r){var n=this&&this.__createBinding||(Object.create?function(t,e,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(e,r);o&&!("get"in o?!e.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,o)}:function(t,e,r,n){void 0===n&&(n=r),t[n]=e[r]}),o=this&&this.__exportStar||function(t,e){for(var r in t)"default"===r||Object.prototype.hasOwnProperty.call(e,r)||n(e,t,r)},i=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var a=r(365);Object.defineProperty(e,"default",{enumerable:!0,get:function(){return i(a).default}}),o(r(77),e),o(r(98),e)},799:e=>{e.exports=t},26:t=>{t.exports=e}},n={};return function t(e){var o=n[e];if(void 0!==o)return o.exports;var i=n[e]={exports:{}};return r[e].call(i.exports,i,i.exports,t),i.exports}(479)})())); \ No newline at end of file diff --git a/src/backend/common/infrastructure/config/source/ytmusic.ts b/src/backend/common/infrastructure/config/source/ytmusic.ts index a5b71e00..dd1af851 100644 --- a/src/backend/common/infrastructure/config/source/ytmusic.ts +++ b/src/backend/common/infrastructure/config/source/ytmusic.ts @@ -1,7 +1,7 @@ import { PollingOptions } from "../common.js"; -import { CommonSourceConfig, CommonSourceData } from "./index.js"; +import { CommonSourceConfig, CommonSourceData, CommonSourceOptions } from "./index.js"; -export interface YTMusicData extends CommonSourceData, PollingOptions { +export interface YTMusicCredentials { /** * The cookie retrieved from the Request Headers of music.youtube.com after logging in. * @@ -17,8 +17,17 @@ export interface YTMusicData extends CommonSourceData, PollingOptions { * */ authUser?: number } + +export interface YTMusicData extends YTMusicCredentials, CommonSourceData, PollingOptions { +} export interface YTMusicSourceConfig extends CommonSourceConfig { data: YTMusicData + options?: CommonSourceOptions & { + /** + * When true MS will log to DEBUG what parts of the cookie are updated by YTM + * */ + logAuthUpdateChanges?: boolean + } } export interface YTMusicSourceAIOConfig extends YTMusicSourceConfig { diff --git a/src/backend/common/schema/aio-source.json b/src/backend/common/schema/aio-source.json index 9db002d3..b5d3ae91 100644 --- a/src/backend/common/schema/aio-source.json +++ b/src/backend/common/schema/aio-source.json @@ -1955,7 +1955,21 @@ "type": "string" }, "options": { - "$ref": "#/definitions/CommonSourceOptions", + "allOf": [ + { + "$ref": "#/definitions/CommonSourceOptions" + }, + { + "properties": { + "logAuthUpdateChanges": { + "description": "When true MS will log to DEBUG what parts of the cookie are updated by YTM", + "title": "logAuthUpdateChanges", + "type": "boolean" + } + }, + "type": "object" + } + ], "title": "options" }, "type": { diff --git a/src/backend/common/schema/aio.json b/src/backend/common/schema/aio.json index 33d299bf..55a4560a 100644 --- a/src/backend/common/schema/aio.json +++ b/src/backend/common/schema/aio.json @@ -2865,7 +2865,21 @@ "type": "string" }, "options": { - "$ref": "#/definitions/CommonSourceOptions", + "allOf": [ + { + "$ref": "#/definitions/CommonSourceOptions" + }, + { + "properties": { + "logAuthUpdateChanges": { + "description": "When true MS will log to DEBUG what parts of the cookie are updated by YTM", + "title": "logAuthUpdateChanges", + "type": "boolean" + } + }, + "type": "object" + } + ], "title": "options" }, "type": { diff --git a/src/backend/common/schema/source.json b/src/backend/common/schema/source.json index f3f8a7e2..8d15a29c 100644 --- a/src/backend/common/schema/source.json +++ b/src/backend/common/schema/source.json @@ -1797,7 +1797,21 @@ "type": "string" }, "options": { - "$ref": "#/definitions/CommonSourceOptions", + "allOf": [ + { + "$ref": "#/definitions/CommonSourceOptions" + }, + { + "properties": { + "logAuthUpdateChanges": { + "description": "When true MS will log to DEBUG what parts of the cookie are updated by YTM", + "title": "logAuthUpdateChanges", + "type": "boolean" + } + }, + "type": "object" + } + ], "title": "options" } }, diff --git a/src/backend/sources/YTMusicSource.ts b/src/backend/sources/YTMusicSource.ts index f58315ee..9f8ed559 100644 --- a/src/backend/sources/YTMusicSource.ts +++ b/src/backend/sources/YTMusicSource.ts @@ -5,8 +5,8 @@ import { IYouTubeMusicAuthenticated } from "youtube-music-ts-api/interfaces-prim import { IPlaylistDetail, ITrackDetail } from "youtube-music-ts-api/interfaces-supplementary"; import { PlayObject } from "../../core/Atomic.js"; import { FormatPlayObjectOptions, InternalConfig } from "../common/infrastructure/Atomic.js"; -import { YTMusicSourceConfig } from "../common/infrastructure/config/source/ytmusic.js"; -import { parseDurationFromTimestamp, playObjDataMatch } from "../utils.js"; +import { YTMusicCredentials, YTMusicSourceConfig } from "../common/infrastructure/config/source/ytmusic.js"; +import { parseDurationFromTimestamp, playObjDataMatch, readJson, writeFile } from "../utils.js"; import AbstractSource, { RecentlyPlayedOptions } from "./AbstractSource.js"; export default class YTMusicSource extends AbstractSource { @@ -18,10 +18,57 @@ export default class YTMusicSource extends AbstractSource { recentlyPlayed: PlayObject[] = []; + workingCredsPath: string; + currentCreds!: YTMusicCredentials; + constructor(name: string, config: YTMusicSourceConfig, internal: InternalConfig, emitter: EventEmitter) { super('ytmusic', name, config, internal, emitter); this.canPoll = true; this.supportsUpstreamRecentlyPlayed = true; + this.workingCredsPath = `${this.configDir}/currentAuth-ytm-${name}.json`; + } + + protected writeCurrentAuth = async (cookie: string, authUser: number) => { + await writeFile(this.workingCredsPath, JSON.stringify({ + cookie, + authUser + })); + } + + protected async doBuildInitData(): Promise { + let creds: YTMusicCredentials; + try { + creds = await readJson(this.workingCredsPath, {throwOnNotFound: false}) as YTMusicCredentials; + if(creds !== undefined) { + this.currentCreds = creds; + return `Read updated credentials from file currentAuth-ytm-${this.name}.json`; + } + } catch (e) { + this.logger.warn('Current YTMusic credentials file exists but could not be parsed', { path: this.workingCredsPath }); + } + if(creds === undefined) { + if(this.config.data.cookie === undefined) { + throw new Error('No YTM cookies were found in configuration'); + } + this.currentCreds = this.config.data; + return 'Read initial credentials from config'; + } + } + + doAuthentication = async () => { + try { + await this.getRecentlyPlayed(); + return true; + } catch (e) { + if(e.message.includes('Status code: 401')) { + let hint = 'Verify your cookie and authUser are correct.'; + if(this.currentCreds.authUser === undefined) { + hint = `${hint} TIP: 'authUser' is not defined your credentials. If you are using Chrome to retrieve credentials from music.youtube.com make sure the value from the 'X-Goog-AuthUser' is used as 'authUser'.`; + } + this.logger.error(`Authentication failed with the given credentials. ${hint} | Error => ${e.message}`); + } + throw e; + } } static formatPlayObj(obj: ITrackDetail, options: FormatPlayObjectOptions = {}): PlayObject { @@ -71,6 +118,35 @@ export default class YTMusicSource extends AbstractSource { recentlyPlayedTrackIsValid = (playObj: PlayObject) => playObj.meta.newFromSource + protected onAuthUpdate = (cookieStr: string, authUser: number, updated: Map) => { + const { + options: { + logAuthUpdateChanges = false + } = {} + } = this.config; + + if(logAuthUpdateChanges) { + const parts: string[] = []; + if(authUser !== this.currentCreds.authUser) { + parts.push(`X-Goog-Authuser: ${authUser}`); + } + for(const [k,v] of updated) { + parts.push(`Cookie ${k}: Old => ${v.old} | New => ${v.new}`); + } + this.logger.debug(`Updated Auth -->\n${parts.join('\n')}`); + } else { + this.logger.debug(`Updated Auth`); + } + + this.currentCreds = { + cookie: cookieStr, + authUser + }; + + + this.writeCurrentAuth(cookieStr, authUser).then(() => {}); + } + api = async (): Promise => { if(this.apiInstance !== undefined) { return this.apiInstance; @@ -78,7 +154,7 @@ export default class YTMusicSource extends AbstractSource { // @ts-expect-error default does exist const ytm = new YouTubeMusic.default() as YouTubeMusic; try { - this.apiInstance = await ytm.authenticate(this.config.data.cookie, this.config.data.authUser); + this.apiInstance = await ytm.authenticate(this.config.data.cookie, this.config.data.authUser, this.onAuthUpdate); } catch (e: any) { this.logger.error('Failed to authenticate', e); throw e; @@ -197,22 +273,6 @@ export default class YTMusicSource extends AbstractSource { } - doAuthentication = async () => { - try { - await this.getRecentlyPlayed(); - return true; - } catch (e) { - if(e.message.includes('Status code: 401')) { - let hint = 'Verify your cookie and authUser are correct.'; - if(this.config.data.authUser === undefined) { - hint = `${hint} TIP: 'authUser' is not defined your credentials. If you are using Chrome to retrieve credentials from music.youtube.com make sure the value from the 'X-Goog-AuthUser' is used as 'authUser'.`; - } - this.logger.error(`Authentication failed with the given credentials. ${hint} | Error => ${e.message}`); - } - throw e; - } - } - onPollPostAuthCheck = async () => { if(!this.polling) { this.logger.verbose('Hydrating initial recently played tracks for reference.');